Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix 549 #682

Merged
merged 25 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 0 additions & 31 deletions puzzles files/skyscrapers/1646651

This file was deleted.

47 changes: 0 additions & 47 deletions puzzles files/skyscrapers/easy1.xml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public void executeCommand() {
board.setModifiable(false);
transition.setBoard(board);
transition.setRule(caseRule);
transition.setSelection(elementView.getPuzzleElement().copy());
caseTrans.add(transition);

TreeNode childNode = (TreeNode) tree.addTreeElement(transition);
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/edu/rpi/legup/model/gameboard/PuzzleElement.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public abstract class PuzzleElement<T> {
protected boolean isModified;
protected boolean isGiven;
protected boolean isValid;
protected int casesDepended;

/**
* PuzzleElement Constructor creates a new puzzle element.
Expand All @@ -22,6 +23,7 @@ public PuzzleElement() {
this.isModified = false;
this.isGiven = false;
this.isValid = true;
this.casesDepended = 0;
}

/**
Expand Down Expand Up @@ -148,6 +150,24 @@ public void setValid(boolean isValid) {
this.isValid = isValid;
}

/**
* Get the number of case rules that depend upon the state of this element
*
* @return number of cases
*/
public int getCasesDepended() {
return this.casesDepended;
}

/**
* Sets the number of case rules that depend upon the state of this element
*
* @param cases number of cases
*/
public void setCasesDepended(int cases) {
this.casesDepended = cases;
}

/**
* Tests whether two puzzle elements objects have the same puzzle element
*
Expand Down
29 changes: 27 additions & 2 deletions src/main/java/edu/rpi/legup/model/rules/CaseRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
import edu.rpi.legup.model.tree.TreeTransition;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static edu.rpi.legup.model.rules.RuleType.CASE;

Expand Down Expand Up @@ -79,6 +78,7 @@ public String checkRule(TreeTransition transition) {

String check = checkRuleRaw(transition);

// Mark transition and new data as valid or not
boolean isCorrect = (check == null);
for (TreeTransition childTrans : parentNodes.get(0).getChildren()) {
childTrans.setCorrect(isCorrect);
Expand Down Expand Up @@ -125,6 +125,31 @@ public String checkRuleAt(TreeTransition transition, PuzzleElement puzzleElement
*/
@Override
public abstract String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement);

/**
* Returns the elements necessary for the cases returned by getCases(board,puzzleElement) to be valid
* Overridden by case rules dependent on more than just the modified data
*
* @param board board state at application
* @param puzzleElement selected puzzleElement
* @return List of puzzle elements (typically cells) this application of the case rule depends upon.
* Defaults to any element modified by any case
*/
public List<PuzzleElement> dependentElements(Board board, PuzzleElement puzzleElement) {
List<PuzzleElement> elements = new ArrayList<>();

List<Board> cases = getCases(board,puzzleElement);
for (Board caseBoard : cases) {
Set<PuzzleElement> data = caseBoard.getModifiedData();
for (PuzzleElement element : data) {
if(!elements.contains(board.getPuzzleElement(element))){
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your code still has inconsistent spacing (this comment is only the surface of formatting issues).

elements.add(board.getPuzzleElement(element));
}
}
}

return elements;
}
}


4 changes: 4 additions & 0 deletions src/main/java/edu/rpi/legup/model/rules/DirectRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ public String checkRule(TreeTransition transition) {
transition.getParents().get(0).getChildren().size() != 1) {
return "State must have only 1 parent and 1 child";
}
else if (finalBoard.getModifiedData().isEmpty()) {
// null transition
return null;
}
else {
return checkRuleRaw(transition);
}
Expand Down
64 changes: 59 additions & 5 deletions src/main/java/edu/rpi/legup/model/tree/TreeTransition.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import edu.rpi.legup.model.gameboard.Board;
import edu.rpi.legup.model.gameboard.PuzzleElement;
import edu.rpi.legup.model.rules.CaseRule;
import edu.rpi.legup.model.rules.Rule;
import edu.rpi.legup.model.rules.RuleType;

Expand All @@ -12,6 +13,8 @@ public class TreeTransition extends TreeElement {
private ArrayList<TreeNode> parents;
private TreeNode childNode;
private Rule rule;

private PuzzleElement selection;
private boolean isCorrect;
private boolean isVerified;

Expand All @@ -26,6 +29,7 @@ public TreeTransition(Board board) {
this.childNode = null;
this.board = board;
this.rule = null;
this.selection = null;
this.isCorrect = false;
this.isVerified = false;
}
Expand Down Expand Up @@ -87,13 +91,42 @@ public void propagateChange(PuzzleElement element) {
}
}
else {
// Overwrite previous modifications to this element
board.removeModifiedData(board.getPuzzleElement(element));

// apply changes to tranistion
board.notifyChange(element);

// mark first transition as modified
if (!board.getPuzzleElement(element).equalsData(parents.get(0).getBoard().getPuzzleElement(element))) {
board.addModifiedData(element);
}

// propagate to children
if (childNode != null) {
board.notifyChange(element);
childNode.getBoard().notifyChange(element.copy());
for (TreeTransition child : childNode.getChildren()) {
PuzzleElement copy = element.copy();

// find starting board
TreeNode head = childNode;
while (head.getParent() != null) {
head = head.getParent().getParents().get(0);
}
Board headBoard = head.getBoard();

PuzzleElement copy = element.copy();
// Set as modifiable if reverted to starting value (and started modifiable)
if (headBoard.getPuzzleElement(element).equalsData(element)) {
copy.setModifiable(headBoard.getPuzzleElement(element).isModifiable());
}
else{
copy.setModifiable(false);
child.propagateChange(copy);
}

// apply changes to result node
childNode.getBoard().notifyChange(copy);

// apply to all child transitions
for (TreeTransition child : childNode.getChildren()) {
child.propagateChange(copy.copy());
}
}
}
Expand Down Expand Up @@ -327,6 +360,27 @@ public void setRule(Rule rule) {
isVerified = false;
}

/**
* Gets he selected element associated with this transition
*
* @return If this is a case rule, the selected element for that rule, null otherwise
*/
public PuzzleElement getSelection() {
if (this.rule instanceof CaseRule) {
return selection;
}
return null;
}

/**
* Sets the selected element associated with this transition
*
* @param selection selected element for this transition
*/
public void setSelection(PuzzleElement selection) {
this.selection = selection;
}

/**
* Gets whether this transition is correctly justified
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,4 +287,67 @@ private List<LightUpCell> getAdjacentCells(LightUpBoard board, LightUpCell cell)
}
return cells;
}

/**
* Returns the elements necessary for the cases returned by getCases(board,puzzleElement) to be valid
* Overridden by case rules dependent on more than just the modified data
*
* @param board board state at application
* @param puzzleElement selected puzzleElement
* @return List of puzzle elements (typically cells) this application of the case rule depends upon.
* Defaults to any element modified by any case
*/
@Override
public List<PuzzleElement> dependentElements(Board board, PuzzleElement puzzleElement) {
List<PuzzleElement> elements = new ArrayList<>();

LightUpBoard puzzleBoard = (LightUpBoard) board;
LightUpCell point = (LightUpCell)puzzleBoard.getPuzzleElement(puzzleElement);

List<LightUpCell> cells = getAdjacentCells(puzzleBoard,point);

for (LightUpCell cell : cells) {
//add cells that can light adjacents from any direction
Point location = cell.getLocation();
for (int i = location.x; i < puzzleBoard.getWidth(); i++) {
System.out.println(i);
LightUpCell c = puzzleBoard.getCell(i, location.y);
if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
break;
}
else if (!elements.contains(board.getPuzzleElement(c))) {
elements.add(board.getPuzzleElement(c));
}
}
for (int i = location.x; i >= 0; i--) {
LightUpCell c = puzzleBoard.getCell(i, location.y);
if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
break;
}
else if (!elements.contains(board.getPuzzleElement(c))) {
elements.add(board.getPuzzleElement(c));
}
}
for (int i = location.y; i < puzzleBoard.getHeight(); i++) {
LightUpCell c = puzzleBoard.getCell(location.x, i);
if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
break;
}
else if (!elements.contains(board.getPuzzleElement(c))) {
elements.add(board.getPuzzleElement(c));
}
}
for (int i = location.y; i >= 0; i--) {
LightUpCell c = puzzleBoard.getCell(location.x, i);
if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
break;
}
else if (!elements.contains(board.getPuzzleElement(c))) {
elements.add(board.getPuzzleElement(c));
}
}
}

return elements;
}
}
Loading
Loading