From b2da85ca5116ecff5dbd48b8eccc12d8d30755bc Mon Sep 17 00:00:00 2001 From: Jayden Carlson Date: Fri, 2 Oct 2026 16:43:53 -0400 Subject: [PATCH 1/4] Remove assumeSolution from goal conditions --- .../Goal Conditions/prove cell must be | 2 +- ...st be no assumption => prove cell must be} | 0 .../prove cell must be with assumption | 16 -------- .../controller/EditorElementController.java | 8 ---- .../legup/controller/ElementController.java | 8 ---- src/main/java/edu/rpi/legup/model/Goal.java | 37 ++----------------- .../java/edu/rpi/legup/model/GoalNotes.md | 28 ++++++-------- src/main/java/edu/rpi/legup/model/Puzzle.java | 18 +++------ .../edu/rpi/legup/model/PuzzleExporter.java | 5 +-- .../legup/model/gameboard/ElementFactory.java | 17 +-------- .../elementsview/ElementFrame.java | 6 --- .../goalConditions/ProveCellMustBeTest.java | 17 ++------- .../ProveSingleCellValueTest.java | 16 ++------ .../ProveValuesArePossible.java | 20 ++-------- ...ompleteLineWithAssumption => CompleteLine} | 2 +- .../ProveCellMustBe/CompleteLineNoAssumption | 29 --------------- .../ProveCellMustBe/MergedSolutions | 2 +- .../ProveCellMustBe/OvercompleteLine | 2 +- ...ootIncompleteNoAssumption => RootComplete} | 0 .../ProveCellMustBe/RootCompleteNoAssumption | 13 ------- .../RootCompleteWithAssumption | 18 --------- ...ncompleteWithAssumption => RootIncomplete} | 2 +- .../ProveCellMustBe/SimpleContradiction | 2 +- .../SingleSolutionAndUnfinished | 2 +- .../ProveCellMustBe/UnmergedSolutions | 2 +- ...{CompleteLineNoAssumption => CompleteLine} | 0 .../CompleteLineWithAssumption | 24 ------------ .../ProveSingleCellValue/MergedSolutions | 2 +- .../ProveSingleCellValue/OvercompleteLine | 2 +- ...ootCompleteWithAssumption => RootComplete} | 2 +- .../RootCompleteNoAssumption | 14 ------- ...ncompleteWithAssumption => RootIncomplete} | 2 +- .../RootIncompleteNoAssumption | 14 ------- .../ProveSingleCellValue/SimpleContradiction | 2 +- .../ProveSingleCellValue/UnmergedSolutions | 2 +- ...{CompleteLineNoAssumption => CompleteLine} | 0 .../CompleteLineWithAssumption | 25 ------------- .../IncompleteLineWithMatchAndAssumption | 25 ------------- ...ootIncompleteNoAssumption => RootComplete} | 0 .../RootCompleteNoAssumption | 17 --------- .../RootCompleteWithAssumption | 14 ------- ...ncompleteWithAssumption => RootIncomplete} | 2 +- 42 files changed, 50 insertions(+), 369 deletions(-) rename puzzles files/nurikabe/Goal Conditions/{prove cell must be no assumption => prove cell must be} (100%) delete mode 100644 puzzles files/nurikabe/Goal Conditions/prove cell must be with assumption rename src/test/resources/goalConditions/ProveCellMustBe/{CompleteLineWithAssumption => CompleteLine} (93%) delete mode 100644 src/test/resources/goalConditions/ProveCellMustBe/CompleteLineNoAssumption rename src/test/resources/goalConditions/ProveCellMustBe/{RootIncompleteNoAssumption => RootComplete} (100%) delete mode 100644 src/test/resources/goalConditions/ProveCellMustBe/RootCompleteNoAssumption delete mode 100644 src/test/resources/goalConditions/ProveCellMustBe/RootCompleteWithAssumption rename src/test/resources/goalConditions/ProveCellMustBe/{RootIncompleteWithAssumption => RootIncomplete} (89%) rename src/test/resources/goalConditions/ProveSingleCellValue/{CompleteLineNoAssumption => CompleteLine} (100%) delete mode 100644 src/test/resources/goalConditions/ProveSingleCellValue/CompleteLineWithAssumption rename src/test/resources/goalConditions/ProveSingleCellValue/{RootCompleteWithAssumption => RootComplete} (85%) delete mode 100644 src/test/resources/goalConditions/ProveSingleCellValue/RootCompleteNoAssumption rename src/test/resources/goalConditions/ProveSingleCellValue/{RootIncompleteWithAssumption => RootIncomplete} (85%) delete mode 100644 src/test/resources/goalConditions/ProveSingleCellValue/RootIncompleteNoAssumption rename src/test/resources/goalConditions/ProveValuesArePossible/{CompleteLineNoAssumption => CompleteLine} (100%) delete mode 100644 src/test/resources/goalConditions/ProveValuesArePossible/CompleteLineWithAssumption delete mode 100644 src/test/resources/goalConditions/ProveValuesArePossible/IncompleteLineWithMatchAndAssumption rename src/test/resources/goalConditions/ProveValuesArePossible/{RootIncompleteNoAssumption => RootComplete} (100%) delete mode 100644 src/test/resources/goalConditions/ProveValuesArePossible/RootCompleteNoAssumption delete mode 100644 src/test/resources/goalConditions/ProveValuesArePossible/RootCompleteWithAssumption rename src/test/resources/goalConditions/ProveValuesArePossible/{RootIncompleteWithAssumption => RootIncomplete} (85%) diff --git a/puzzles files/lightup/Goal Conditions/prove cell must be b/puzzles files/lightup/Goal Conditions/prove cell must be index fbd128924..b58b077ba 100644 --- a/puzzles files/lightup/Goal Conditions/prove cell must be +++ b/puzzles files/lightup/Goal Conditions/prove cell must be @@ -1,7 +1,7 @@ - + diff --git a/puzzles files/nurikabe/Goal Conditions/prove cell must be no assumption b/puzzles files/nurikabe/Goal Conditions/prove cell must be similarity index 100% rename from puzzles files/nurikabe/Goal Conditions/prove cell must be no assumption rename to puzzles files/nurikabe/Goal Conditions/prove cell must be diff --git a/puzzles files/nurikabe/Goal Conditions/prove cell must be with assumption b/puzzles files/nurikabe/Goal Conditions/prove cell must be with assumption deleted file mode 100644 index b45838761..000000000 --- a/puzzles files/nurikabe/Goal Conditions/prove cell must be with assumption +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/java/edu/rpi/legup/controller/EditorElementController.java b/src/main/java/edu/rpi/legup/controller/EditorElementController.java index 7d8122cf6..e8995bfbf 100644 --- a/src/main/java/edu/rpi/legup/controller/EditorElementController.java +++ b/src/main/java/edu/rpi/legup/controller/EditorElementController.java @@ -28,7 +28,6 @@ public enum SelectionMode { protected ElementButton prevButton; private SelectionMode selectionMode; private Object goalValueData; - private boolean assumeSolution; public EditorElementController() { super(); @@ -36,7 +35,6 @@ public EditorElementController() { prevButton = null; selectionMode = SelectionMode.PLACEABLE; goalValueData = null; - assumeSolution = false; } /** @@ -77,12 +75,6 @@ public void setGoalDataType(PlaceableElement elementType) { } } - public void setAssumeSolution(boolean assume) { - if (elementController != null) { - assumeSolution = assume; - elementController.setAssumeSolution(assume); - } - } /** * Handles the event when a button associated with an Element is pressed * diff --git a/src/main/java/edu/rpi/legup/controller/ElementController.java b/src/main/java/edu/rpi/legup/controller/ElementController.java index 05cb6e5ee..870447cf5 100644 --- a/src/main/java/edu/rpi/legup/controller/ElementController.java +++ b/src/main/java/edu/rpi/legup/controller/ElementController.java @@ -43,7 +43,6 @@ public class ElementController private GoalType currentGoalType; private PlaceableElement currentGoalValue; private Object goalValueData; - private boolean assumeSolution; /** * ElementController Constructor controller to handle ui events associated interacting with a @@ -56,7 +55,6 @@ public ElementController() { this.currentGoalType = GoalType.DEFAULT; this.currentGoalValue = null; this.goalValueData = null; - this.assumeSolution = false; } public void setSelectedElement(Element selectedElement) { @@ -102,12 +100,6 @@ public PlaceableElement getCurrentGoalValue() { return this.currentGoalValue; } - public void setAssumeSolution(boolean assume) { - this.assumeSolution = assume; - Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule(); - puzzle.getGoal().setAssumeSolution(assume); - } - /** * Sets the {@link BoardView} * diff --git a/src/main/java/edu/rpi/legup/model/Goal.java b/src/main/java/edu/rpi/legup/model/Goal.java index 2f8ac05ee..af836645b 100644 --- a/src/main/java/edu/rpi/legup/model/Goal.java +++ b/src/main/java/edu/rpi/legup/model/Goal.java @@ -17,31 +17,18 @@ public class Goal { private ArrayList cellList; private final GoalType goalType; - private boolean assumeSolution; /** - * Constructs a Goal object with an empty cell list with no assumed solution + * Constructs a Goal object with an empty cell list * * @param goalType type of goal */ public Goal(GoalType goalType) { this.cellList = new ArrayList<>(); this.goalType = goalType; - this.assumeSolution = false; } - /** - * Constructs a Goal object with an empty cell list - * - * @param goalType type of goal - * @param assume whether to assume there is a solution to the puzzle - */ - public Goal(GoalType goalType, boolean assume) - { - this.cellList = new ArrayList<>(); - this.goalType = goalType; - this.assumeSolution = assume; - } + /** * Constructs a Goal object only requiring a given cell * @@ -54,7 +41,6 @@ public Goal(GridCell cell, GoalType goalType) { cellList.add(cell); } this.goalType = goalType; - this.assumeSolution = false; } /** @@ -75,20 +61,6 @@ public Goal(GridCell cell, GoalType goalType) { */ public GoalType getType() { return goalType; } - /** - * Get the value of assumeSolution - * - * @return assumeSolution - */ - public boolean assumeSolution() {return assumeSolution;} - - /** - * Set the value of assumeSolution - * - * @param assume whether to assume there is a solution to the puzzle - */ - public void setAssumeSolution(boolean assume) {assumeSolution = assume;} - /** * Creates tool tip text for a cell being hovered over. * @@ -130,7 +102,6 @@ public String getGoalText() { if (goalType == GoalType.DEFAULT) return "Find all solutions to the puzzle or prove none exist."; String text = "Prove "; - if(assumeSolution) {text += "that if there is a solution, then ";} return switch(goalType) { case GoalType.PROVE_CELL_MUST_BE -> text + getValueSeparatedGoalText( " is forced to be ", " are forced to be ") + "."; @@ -151,9 +122,9 @@ public String getGoalText() { case GoalType.PROVE_ANY_SOLUTION -> "Find any solution to the puzzle."; case GoalType.PROVE_NO_SOLUTION -> "Prove that there are no solutions to the puzzle."; case GoalType.PROVE_VALUES_ARE_POSSIBLE -> text + getValueSeparatedGoalText( - " can be ", " can be ") + " at the same time."; + " can be ", " can be ") + (cellList.size() > 1? " at the same time." : "."); case GoalType.PROVE_VALUES_ARE_IMPOSSIBLE -> text + getValueSeparatedGoalText( - " cannot be ", " cannot be ") + " at the same time"; + " cannot be ", " cannot be ") + (cellList.size() > 1? " at the same time." : "."); default -> "Unrecognized goal condition."; }; diff --git a/src/main/java/edu/rpi/legup/model/GoalNotes.md b/src/main/java/edu/rpi/legup/model/GoalNotes.md index 3f8e3ffdd..244df3849 100644 --- a/src/main/java/edu/rpi/legup/model/GoalNotes.md +++ b/src/main/java/edu/rpi/legup/model/GoalNotes.md @@ -24,23 +24,17 @@ been closed by a contradiction rule, verus an "open" one that has not. A "comple one whose board holds a valid, proven solution to the puzzle, versus an "incomplete" leaf that has not. -Any goal type that refers to "assuming a solution exists" can have an additional field specified -in the xml goal element (assumeSolution="true"). This will allow for the proof to be shortened, and -change the text of the goal to "Prove that if there is a solution, then...". This defaults to false -if the field is not present. It is not accounted for in other goalTypes, where it either wouldn't -make a difference (i.e. PROVE_MULTIPLE_CELL_VALUE) or would make no sense (i.e. PROVE_NO_SOLUTION) - -| **GoalType** | **Goal** | **Conditions of proof tree** | -|---------------------------------|--------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------| -| **DEFAULT** | Prove all possible solutions, or prove none exist | Every open leaf is a complete one | -| **PROVE_ANY_SOLUTION** | Prove any solution | There is a complete leaf | -| **PROVE_NO_SOLUTION** | Prove that there is no solution to the puzzle | There are no open leaves | -| **PROVE_CELL_MUST_BE** | Prove that the given cell locations are forced into the given set of values | All open leaves are proven to match the set, and one solution is proven / assumed to exist | -| **PROVE_CELL_MIGHT_NOT_BE** | Prove that the given cell locations are not forced into have the given set of values | Either:
Any complete leaf has a different set of values
Every open leaf has a different set of values | -| **PROVE_SINGLE_CELL_VALUE** | Prove that the given cell locations are forced into one set of values | The set of values at the goal locations are proven to match in every open branch, and one solution is proven / assumed to exist | -| **PROVE_MULTIPLE_CELL_VALUE** | Prove that the given cell locations are not forced into one set of values | The set of values at the goal locations are proven to match in at least two complete leaves | -| **PROVE_VALUES_ARE_POSSIBLE** | Prove that the given cell locations are able to have the given set of values | Either:
Any complete leaf matches the set
Every open leaf matches the set and a solution is assumed to exist | -| **PROVE_VALUES_ARE_IMPOSSIBLE** | Prove that the given cell locations are not able to have the given set of values | Every open leaf has a different set of values | +| **GoalType** | **Goal** | **Conditions of proof tree** | +|---------------------------------|--------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------| +| **DEFAULT** | Prove all possible solutions, or prove none exist | Every open leaf is a complete one | +| **PROVE_ANY_SOLUTION** | Prove any solution | There is a complete leaf | +| **PROVE_NO_SOLUTION** | Prove that there is no solution to the puzzle | There are no open leaves | +| **PROVE_CELL_MUST_BE** | Prove that the given cell locations are forced into the given set of values | All open leaves are proven to match the set | +| **PROVE_CELL_MIGHT_NOT_BE** | Prove that the given cell locations are not forced into have the given set of values | Either:
Any complete leaf has a different set of values
Every open leaf has a different set of values | +| **PROVE_SINGLE_CELL_VALUE** | Prove that the given cell locations are forced into one set of values | The set of values at the goal locations are proven to match in every open branch | +| **PROVE_MULTIPLE_CELL_VALUE** | Prove that the given cell locations are not forced into one set of values | The set of values at the goal locations are proven to match in at least two complete leaves | +| **PROVE_VALUES_ARE_POSSIBLE** | Prove that the given cell locations are able to have the given set of values | Either:
Any complete leaf matches the set
Every open leaf matches the set | +| **PROVE_VALUES_ARE_IMPOSSIBLE** | Prove that the given cell locations are not able to have the given set of values | Every open leaf has a different set of values | ## Extending to New Puzzles diff --git a/src/main/java/edu/rpi/legup/model/Puzzle.java b/src/main/java/edu/rpi/legup/model/Puzzle.java index fd7148f75..a28ab9980 100644 --- a/src/main/java/edu/rpi/legup/model/Puzzle.java +++ b/src/main/java/edu/rpi/legup/model/Puzzle.java @@ -380,8 +380,7 @@ public boolean isPuzzleComplete() { { if (countGoalMatches(node, true) != goal.getCells().size()) {yield false;} } - // There must be a proven solution - yield (goal.assumeSolution() || !getCompleteLeaves().isEmpty()); + yield true; } case PROVE_CELL_MIGHT_NOT_BE -> { // One solution differs from the given @@ -402,10 +401,7 @@ public boolean isPuzzleComplete() { { if (!goalCellsAreKnown(node)) {yield false;} } - if (!cellsMatchBetweenBoards(getOpenLeaves())) {yield false;} - - // There must be a proven solution - yield (goal.assumeSolution() || !getCompleteLeaves().isEmpty()); + yield cellsMatchBetweenBoards(getOpenLeaves()); } case PROVE_MULTIPLE_CELL_VALUE -> { // The following line yielding true vs false determines if 0 solutions counts @@ -428,15 +424,11 @@ public boolean isPuzzleComplete() { } // If there is a solution, it must have this set of values - if (goal.assumeSolution() && !getOpenLeaves().isEmpty()) + for (TreeNode node : getOpenLeaves()) { - for (TreeNode node : getOpenLeaves()) - { - if (countGoalMatches(node, true) != goal.getCells().size()) {yield false;} - } - yield true; + if (countGoalMatches(node, true) != goal.getCells().size()) {yield false;} } - yield false; + yield true; } case PROVE_VALUES_ARE_IMPOSSIBLE -> { // No open branch matches these values diff --git a/src/main/java/edu/rpi/legup/model/PuzzleExporter.java b/src/main/java/edu/rpi/legup/model/PuzzleExporter.java index 678ce64fe..39d6d5c2f 100644 --- a/src/main/java/edu/rpi/legup/model/PuzzleExporter.java +++ b/src/main/java/edu/rpi/legup/model/PuzzleExporter.java @@ -170,7 +170,6 @@ protected void appendGoalElement( Element goalElement = newDocument.createElement("goal"); goalElement.setAttribute("type", String.valueOf(goalType)); - goalElement.setAttribute("assumeSolution", String.valueOf(puzzle.getGoal().assumeSolution())); boolean hasGoalCells = false; @@ -187,7 +186,7 @@ protected void appendGoalElement( } } - if (!hasGoalCells && puzzle.getGoal().assumeSolution() && puzzle.getGoal() != null) { + if (!hasGoalCells && puzzle.getGoal() != null) { for (GridCell goalCell : puzzle.getGoal().getCells()) { Element cellElement = puzzle.getFactory().exportCell(newDocument, goalCell); goalElement.appendChild(cellElement); @@ -195,7 +194,7 @@ protected void appendGoalElement( } } - if (hasGoalCells || !puzzle.getGoal().assumeSolution()) { + if (hasGoalCells) { boardElement.appendChild(goalElement); } } diff --git a/src/main/java/edu/rpi/legup/model/gameboard/ElementFactory.java b/src/main/java/edu/rpi/legup/model/gameboard/ElementFactory.java index 304c0f5df..802a2ba7e 100644 --- a/src/main/java/edu/rpi/legup/model/gameboard/ElementFactory.java +++ b/src/main/java/edu/rpi/legup/model/gameboard/ElementFactory.java @@ -43,22 +43,7 @@ public Goal importGoal(Node node, Board board) throws InvalidFileFormatException String goalTypeString = attributeList.getNamedItem("type").getNodeValue(); GoalType goalType = goalTypeString == null ? GoalType.DEFAULT : GoalType.valueOf(goalTypeString.toUpperCase()); - try - { - String assumeSolution = attributeList.getNamedItem("assumeSolution").getNodeValue(); - if (!(assumeSolution.equalsIgnoreCase("true") - || assumeSolution.equalsIgnoreCase("false"))) - { - throw new InvalidFileFormatException( - "Field 'assumeSolution' must be null, true, or false."); - } - boolean assume = (assumeSolution.equalsIgnoreCase("true")); - return new Goal(goalType, assume); - } - catch(NullPointerException e) - { - return new Goal(goalType, false); - } + return new Goal(goalType); } catch (NumberFormatException e) { throw new InvalidFileFormatException( diff --git a/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementFrame.java b/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementFrame.java index 192c007da..a4a5eb7a2 100644 --- a/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementFrame.java +++ b/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementFrame.java @@ -16,7 +16,6 @@ public class ElementFrame extends JPanel { private JTabbedPane tabbedPane; private JComboBox goalTypeComboBox; private JComboBox goalDataTypecomboBox; - private JCheckBox assumeSolutionCheckBox; private JScrollPane elements; private ButtonGroup buttonGroup; @@ -96,11 +95,6 @@ private JComponent createGoalConditionsPanel() { selectorPanel2.add(goalDataTypecomboBox, BorderLayout.CENTER); topPanel.add(selectorPanel2, BorderLayout.SOUTH); - assumeSolutionCheckBox = new JCheckBox("Assume solution"); - assumeSolutionCheckBox.addActionListener( - e -> controller.setAssumeSolution(assumeSolutionCheckBox.isSelected())); - topPanel.add(assumeSolutionCheckBox, BorderLayout.CENTER); - goalPanel.add(topPanel, BorderLayout.NORTH); return goalPanel; diff --git a/src/test/java/goalConditions/ProveCellMustBeTest.java b/src/test/java/goalConditions/ProveCellMustBeTest.java index fe33e810f..97d6bf543 100644 --- a/src/test/java/goalConditions/ProveCellMustBeTest.java +++ b/src/test/java/goalConditions/ProveCellMustBeTest.java @@ -35,16 +35,10 @@ public void TestInvalidRules() throws InvalidFileFormatException { @Test public void TestRootNode() throws InvalidFileFormatException { Assert.assertTrue(TestUtilities.verifyBoard( - "goalConditions/ProveCellMustBe/RootCompleteWithAssumption", puzzle)); - - Assert.assertTrue(TestUtilities.verifyBoard( - "goalConditions/ProveCellMustBe/RootCompleteNoAssumption", puzzle)); - - Assert.assertFalse(TestUtilities.verifyBoard( - "goalConditions/ProveCellMustBe/RootIncompleteWithAssumption", puzzle)); + "goalConditions/ProveCellMustBe/RootComplete", puzzle)); Assert.assertFalse(TestUtilities.verifyBoard( - "goalConditions/ProveCellMustBe/RootIncompleteNoAssumption", puzzle)); + "goalConditions/ProveCellMustBe/RootIncomplete", puzzle)); } @@ -52,7 +46,7 @@ public void TestRootNode() throws InvalidFileFormatException { @Test public void TestSinglePath() throws InvalidFileFormatException { Assert.assertTrue(TestUtilities.verifyBoard( - "goalConditions/ProveCellMustBe/CompleteLineWithAssumption", puzzle)); + "goalConditions/ProveCellMustBe/CompleteLine", puzzle)); Assert.assertTrue(TestUtilities.verifyBoard( "goalConditions/ProveCellMustBe/OvercompleteLine", puzzle)); @@ -60,12 +54,9 @@ public void TestSinglePath() throws InvalidFileFormatException { Assert.assertTrue(TestUtilities.verifyBoard( "goalConditions/ProveCellMustBe/SolvedLine", puzzle)); - Assert.assertFalse(TestUtilities.verifyBoard( + Assert.assertTrue(TestUtilities.verifyBoard( "goalConditions/ProveCellMustBe/ContradictoryLine", puzzle)); - Assert.assertFalse(TestUtilities.verifyBoard( - "goalConditions/ProveCellMustBe/CompleteLineNoAssumption", puzzle)); - Assert.assertFalse(TestUtilities.verifyBoard( "goalConditions/ProveCellMustBe/IncompleteLine", puzzle)); diff --git a/src/test/java/goalConditions/ProveSingleCellValueTest.java b/src/test/java/goalConditions/ProveSingleCellValueTest.java index bc17b38b1..4d7230959 100644 --- a/src/test/java/goalConditions/ProveSingleCellValueTest.java +++ b/src/test/java/goalConditions/ProveSingleCellValueTest.java @@ -35,16 +35,11 @@ public void TestInvalidRules() throws InvalidFileFormatException { @Test public void TestRootNode() throws InvalidFileFormatException { Assert.assertTrue(TestUtilities.verifyBoard( - "goalConditions/ProveSingleCellValue/RootCompleteWithAssumption", puzzle)); - - Assert.assertTrue(TestUtilities.verifyBoard( - "goalConditions/ProveSingleCellValue/RootCompleteNoAssumption", puzzle)); + "goalConditions/ProveSingleCellValue/RootComplete", puzzle)); Assert.assertFalse(TestUtilities.verifyBoard( - "goalConditions/ProveSingleCellValue/RootIncompleteWithAssumption", puzzle)); + "goalConditions/ProveSingleCellValue/RootIncomplete", puzzle)); - Assert.assertFalse(TestUtilities.verifyBoard( - "goalConditions/ProveSingleCellValue/RootIncompleteNoAssumption", puzzle)); } @@ -52,7 +47,7 @@ public void TestRootNode() throws InvalidFileFormatException { @Test public void TestSinglePath() throws InvalidFileFormatException { Assert.assertTrue(TestUtilities.verifyBoard( - "goalConditions/ProveSingleCellValue/CompleteLineWithAssumption", puzzle)); + "goalConditions/ProveSingleCellValue/CompleteLine", puzzle)); Assert.assertTrue(TestUtilities.verifyBoard( "goalConditions/ProveSingleCellValue/SolvedLine", puzzle)); @@ -60,14 +55,11 @@ public void TestSinglePath() throws InvalidFileFormatException { Assert.assertTrue(TestUtilities.verifyBoard( "goalConditions/ProveSingleCellValue/OvercompleteLine", puzzle)); - Assert.assertFalse(TestUtilities.verifyBoard( + Assert.assertTrue(TestUtilities.verifyBoard( "goalConditions/ProveSingleCellValue/ContradictoryLine", puzzle)); Assert.assertFalse(TestUtilities.verifyBoard( "goalConditions/ProveSingleCellValue/IncompleteLine", puzzle)); - - Assert.assertFalse(TestUtilities.verifyBoard( - "goalConditions/ProveSingleCellValue/CompleteLineNoAssumption", puzzle)); } diff --git a/src/test/java/goalConditions/ProveValuesArePossible.java b/src/test/java/goalConditions/ProveValuesArePossible.java index abfbc40e7..95843f71b 100644 --- a/src/test/java/goalConditions/ProveValuesArePossible.java +++ b/src/test/java/goalConditions/ProveValuesArePossible.java @@ -36,16 +36,10 @@ public void TestInvalidRules() throws InvalidFileFormatException { @Test public void TestRootNode() throws InvalidFileFormatException { Assert.assertTrue(TestUtilities.verifyBoard( - "goalConditions/ProveValuesArePossible/RootCompleteNoAssumption", puzzle)); - - Assert.assertTrue(TestUtilities.verifyBoard( - "goalConditions/ProveValuesArePossible/RootCompleteWithAssumption", puzzle)); + "goalConditions/ProveValuesArePossible/RootComplete", puzzle)); Assert.assertFalse(TestUtilities.verifyBoard( - "goalConditions/ProveValuesArePossible/RootIncompleteNoAssumption", puzzle)); - - Assert.assertFalse(TestUtilities.verifyBoard( - "goalConditions/ProveValuesArePossible/RootIncompleteWithAssumption", puzzle)); + "goalConditions/ProveValuesArePossible/RootIncomplete", puzzle)); } @@ -53,21 +47,15 @@ public void TestRootNode() throws InvalidFileFormatException { @Test public void TestSinglePath() throws InvalidFileFormatException { Assert.assertTrue(TestUtilities.verifyBoard( - "goalConditions/ProveValuesArePossible/CompleteLineWithAssumption", puzzle)); + "goalConditions/ProveValuesArePossible/CompleteLine", puzzle)); Assert.assertTrue(TestUtilities.verifyBoard( "goalConditions/ProveValuesArePossible/SolvedLine", puzzle)); Assert.assertTrue(TestUtilities.verifyBoard( - "goalConditions/ProveValuesArePossible/IncompleteLineWithMatchAndAssumption", puzzle)); - - Assert.assertFalse(TestUtilities.verifyBoard( - "goalConditions/ProveValuesArePossible/CompleteLineNoAssumption", puzzle)); - - Assert.assertFalse(TestUtilities.verifyBoard( "goalConditions/ProveValuesArePossible/IncompleteLineWithMatch", puzzle)); - Assert.assertFalse(TestUtilities.verifyBoard( + Assert.assertTrue(TestUtilities.verifyBoard( "goalConditions/ProveValuesArePossible/ContradictoryLine", puzzle)); Assert.assertFalse(TestUtilities.verifyBoard( diff --git a/src/test/resources/goalConditions/ProveCellMustBe/CompleteLineWithAssumption b/src/test/resources/goalConditions/ProveCellMustBe/CompleteLine similarity index 93% rename from src/test/resources/goalConditions/ProveCellMustBe/CompleteLineWithAssumption rename to src/test/resources/goalConditions/ProveCellMustBe/CompleteLine index 939c4e1f4..6f3b9dbc7 100644 --- a/src/test/resources/goalConditions/ProveCellMustBe/CompleteLineWithAssumption +++ b/src/test/resources/goalConditions/ProveCellMustBe/CompleteLine @@ -2,7 +2,7 @@ - + diff --git a/src/test/resources/goalConditions/ProveCellMustBe/CompleteLineNoAssumption b/src/test/resources/goalConditions/ProveCellMustBe/CompleteLineNoAssumption deleted file mode 100644 index 6a7c4fc35..000000000 --- a/src/test/resources/goalConditions/ProveCellMustBe/CompleteLineNoAssumption +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/test/resources/goalConditions/ProveCellMustBe/MergedSolutions b/src/test/resources/goalConditions/ProveCellMustBe/MergedSolutions index 0f24731a5..e40f0619f 100644 --- a/src/test/resources/goalConditions/ProveCellMustBe/MergedSolutions +++ b/src/test/resources/goalConditions/ProveCellMustBe/MergedSolutions @@ -2,7 +2,7 @@ - + diff --git a/src/test/resources/goalConditions/ProveCellMustBe/OvercompleteLine b/src/test/resources/goalConditions/ProveCellMustBe/OvercompleteLine index 5c729921a..d7d4da7d6 100644 --- a/src/test/resources/goalConditions/ProveCellMustBe/OvercompleteLine +++ b/src/test/resources/goalConditions/ProveCellMustBe/OvercompleteLine @@ -2,7 +2,7 @@ - + diff --git a/src/test/resources/goalConditions/ProveCellMustBe/RootIncompleteNoAssumption b/src/test/resources/goalConditions/ProveCellMustBe/RootComplete similarity index 100% rename from src/test/resources/goalConditions/ProveCellMustBe/RootIncompleteNoAssumption rename to src/test/resources/goalConditions/ProveCellMustBe/RootComplete diff --git a/src/test/resources/goalConditions/ProveCellMustBe/RootCompleteNoAssumption b/src/test/resources/goalConditions/ProveCellMustBe/RootCompleteNoAssumption deleted file mode 100644 index 998e71e53..000000000 --- a/src/test/resources/goalConditions/ProveCellMustBe/RootCompleteNoAssumption +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/resources/goalConditions/ProveCellMustBe/RootCompleteWithAssumption b/src/test/resources/goalConditions/ProveCellMustBe/RootCompleteWithAssumption deleted file mode 100644 index b497c5d41..000000000 --- a/src/test/resources/goalConditions/ProveCellMustBe/RootCompleteWithAssumption +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/resources/goalConditions/ProveCellMustBe/RootIncompleteWithAssumption b/src/test/resources/goalConditions/ProveCellMustBe/RootIncomplete similarity index 89% rename from src/test/resources/goalConditions/ProveCellMustBe/RootIncompleteWithAssumption rename to src/test/resources/goalConditions/ProveCellMustBe/RootIncomplete index 4d8b0695e..f07286b1a 100644 --- a/src/test/resources/goalConditions/ProveCellMustBe/RootIncompleteWithAssumption +++ b/src/test/resources/goalConditions/ProveCellMustBe/RootIncomplete @@ -1,7 +1,7 @@ - + diff --git a/src/test/resources/goalConditions/ProveCellMustBe/SimpleContradiction b/src/test/resources/goalConditions/ProveCellMustBe/SimpleContradiction index 3d950cc8a..e6f4c6f53 100644 --- a/src/test/resources/goalConditions/ProveCellMustBe/SimpleContradiction +++ b/src/test/resources/goalConditions/ProveCellMustBe/SimpleContradiction @@ -2,7 +2,7 @@ - + diff --git a/src/test/resources/goalConditions/ProveCellMustBe/SingleSolutionAndUnfinished b/src/test/resources/goalConditions/ProveCellMustBe/SingleSolutionAndUnfinished index 8123242ab..790c46a8a 100644 --- a/src/test/resources/goalConditions/ProveCellMustBe/SingleSolutionAndUnfinished +++ b/src/test/resources/goalConditions/ProveCellMustBe/SingleSolutionAndUnfinished @@ -2,7 +2,7 @@ - + diff --git a/src/test/resources/goalConditions/ProveCellMustBe/UnmergedSolutions b/src/test/resources/goalConditions/ProveCellMustBe/UnmergedSolutions index f90fe6452..23674c1e6 100644 --- a/src/test/resources/goalConditions/ProveCellMustBe/UnmergedSolutions +++ b/src/test/resources/goalConditions/ProveCellMustBe/UnmergedSolutions @@ -2,7 +2,7 @@ - + diff --git a/src/test/resources/goalConditions/ProveSingleCellValue/CompleteLineNoAssumption b/src/test/resources/goalConditions/ProveSingleCellValue/CompleteLine similarity index 100% rename from src/test/resources/goalConditions/ProveSingleCellValue/CompleteLineNoAssumption rename to src/test/resources/goalConditions/ProveSingleCellValue/CompleteLine diff --git a/src/test/resources/goalConditions/ProveSingleCellValue/CompleteLineWithAssumption b/src/test/resources/goalConditions/ProveSingleCellValue/CompleteLineWithAssumption deleted file mode 100644 index 427af77bc..000000000 --- a/src/test/resources/goalConditions/ProveSingleCellValue/CompleteLineWithAssumption +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/test/resources/goalConditions/ProveSingleCellValue/MergedSolutions b/src/test/resources/goalConditions/ProveSingleCellValue/MergedSolutions index b3694c4e5..cc97e6c64 100644 --- a/src/test/resources/goalConditions/ProveSingleCellValue/MergedSolutions +++ b/src/test/resources/goalConditions/ProveSingleCellValue/MergedSolutions @@ -2,7 +2,7 @@ - + diff --git a/src/test/resources/goalConditions/ProveSingleCellValue/OvercompleteLine b/src/test/resources/goalConditions/ProveSingleCellValue/OvercompleteLine index ba7e1eb3b..8b000d9d8 100644 --- a/src/test/resources/goalConditions/ProveSingleCellValue/OvercompleteLine +++ b/src/test/resources/goalConditions/ProveSingleCellValue/OvercompleteLine @@ -2,7 +2,7 @@ - + diff --git a/src/test/resources/goalConditions/ProveSingleCellValue/RootCompleteWithAssumption b/src/test/resources/goalConditions/ProveSingleCellValue/RootComplete similarity index 85% rename from src/test/resources/goalConditions/ProveSingleCellValue/RootCompleteWithAssumption rename to src/test/resources/goalConditions/ProveSingleCellValue/RootComplete index 4c0a866c7..321864fd5 100644 --- a/src/test/resources/goalConditions/ProveSingleCellValue/RootCompleteWithAssumption +++ b/src/test/resources/goalConditions/ProveSingleCellValue/RootComplete @@ -2,7 +2,7 @@ - + diff --git a/src/test/resources/goalConditions/ProveSingleCellValue/RootCompleteNoAssumption b/src/test/resources/goalConditions/ProveSingleCellValue/RootCompleteNoAssumption deleted file mode 100644 index d22397c59..000000000 --- a/src/test/resources/goalConditions/ProveSingleCellValue/RootCompleteNoAssumption +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/test/resources/goalConditions/ProveSingleCellValue/RootIncompleteWithAssumption b/src/test/resources/goalConditions/ProveSingleCellValue/RootIncomplete similarity index 85% rename from src/test/resources/goalConditions/ProveSingleCellValue/RootIncompleteWithAssumption rename to src/test/resources/goalConditions/ProveSingleCellValue/RootIncomplete index fb9126b16..f5b8826bf 100644 --- a/src/test/resources/goalConditions/ProveSingleCellValue/RootIncompleteWithAssumption +++ b/src/test/resources/goalConditions/ProveSingleCellValue/RootIncomplete @@ -2,7 +2,7 @@ - + diff --git a/src/test/resources/goalConditions/ProveSingleCellValue/RootIncompleteNoAssumption b/src/test/resources/goalConditions/ProveSingleCellValue/RootIncompleteNoAssumption deleted file mode 100644 index 74e976632..000000000 --- a/src/test/resources/goalConditions/ProveSingleCellValue/RootIncompleteNoAssumption +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/test/resources/goalConditions/ProveSingleCellValue/SimpleContradiction b/src/test/resources/goalConditions/ProveSingleCellValue/SimpleContradiction index 6e7cda489..4197a44d4 100644 --- a/src/test/resources/goalConditions/ProveSingleCellValue/SimpleContradiction +++ b/src/test/resources/goalConditions/ProveSingleCellValue/SimpleContradiction @@ -2,7 +2,7 @@ - + diff --git a/src/test/resources/goalConditions/ProveSingleCellValue/UnmergedSolutions b/src/test/resources/goalConditions/ProveSingleCellValue/UnmergedSolutions index ec6413dc9..7136b7d62 100644 --- a/src/test/resources/goalConditions/ProveSingleCellValue/UnmergedSolutions +++ b/src/test/resources/goalConditions/ProveSingleCellValue/UnmergedSolutions @@ -2,7 +2,7 @@ - + diff --git a/src/test/resources/goalConditions/ProveValuesArePossible/CompleteLineNoAssumption b/src/test/resources/goalConditions/ProveValuesArePossible/CompleteLine similarity index 100% rename from src/test/resources/goalConditions/ProveValuesArePossible/CompleteLineNoAssumption rename to src/test/resources/goalConditions/ProveValuesArePossible/CompleteLine diff --git a/src/test/resources/goalConditions/ProveValuesArePossible/CompleteLineWithAssumption b/src/test/resources/goalConditions/ProveValuesArePossible/CompleteLineWithAssumption deleted file mode 100644 index 40075da08..000000000 --- a/src/test/resources/goalConditions/ProveValuesArePossible/CompleteLineWithAssumption +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/test/resources/goalConditions/ProveValuesArePossible/IncompleteLineWithMatchAndAssumption b/src/test/resources/goalConditions/ProveValuesArePossible/IncompleteLineWithMatchAndAssumption deleted file mode 100644 index c77d773b5..000000000 --- a/src/test/resources/goalConditions/ProveValuesArePossible/IncompleteLineWithMatchAndAssumption +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/test/resources/goalConditions/ProveValuesArePossible/RootIncompleteNoAssumption b/src/test/resources/goalConditions/ProveValuesArePossible/RootComplete similarity index 100% rename from src/test/resources/goalConditions/ProveValuesArePossible/RootIncompleteNoAssumption rename to src/test/resources/goalConditions/ProveValuesArePossible/RootComplete diff --git a/src/test/resources/goalConditions/ProveValuesArePossible/RootCompleteNoAssumption b/src/test/resources/goalConditions/ProveValuesArePossible/RootCompleteNoAssumption deleted file mode 100644 index 4a921df6d..000000000 --- a/src/test/resources/goalConditions/ProveValuesArePossible/RootCompleteNoAssumption +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/src/test/resources/goalConditions/ProveValuesArePossible/RootCompleteWithAssumption b/src/test/resources/goalConditions/ProveValuesArePossible/RootCompleteWithAssumption deleted file mode 100644 index 2633a524a..000000000 --- a/src/test/resources/goalConditions/ProveValuesArePossible/RootCompleteWithAssumption +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/test/resources/goalConditions/ProveValuesArePossible/RootIncompleteWithAssumption b/src/test/resources/goalConditions/ProveValuesArePossible/RootIncomplete similarity index 85% rename from src/test/resources/goalConditions/ProveValuesArePossible/RootIncompleteWithAssumption rename to src/test/resources/goalConditions/ProveValuesArePossible/RootIncomplete index 50ef07256..a4962a671 100644 --- a/src/test/resources/goalConditions/ProveValuesArePossible/RootIncompleteWithAssumption +++ b/src/test/resources/goalConditions/ProveValuesArePossible/RootIncomplete @@ -2,7 +2,7 @@ - + From 00e52af1cc892a4cfe2a159e19ea695a437fb356 Mon Sep 17 00:00:00 2001 From: Jayden Carlson Date: Fri, 2 Oct 2026 16:50:36 -0400 Subject: [PATCH 2/4] Explicitly write that a proof that closes all branches is a valid solution --- src/main/java/edu/rpi/legup/model/Puzzle.java | 3 +++ src/test/java/goalConditions/ProveAnySolutionTest.java | 2 +- src/test/java/goalConditions/ProveMultipleCellValueTest.java | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/rpi/legup/model/Puzzle.java b/src/main/java/edu/rpi/legup/model/Puzzle.java index a28ab9980..f3fc634c3 100644 --- a/src/main/java/edu/rpi/legup/model/Puzzle.java +++ b/src/main/java/edu/rpi/legup/model/Puzzle.java @@ -371,6 +371,9 @@ public boolean isPuzzleComplete() { return false; } + // If the puzzle has no solution, this is a logical contradiction from which every + // claim can be derived + if (getOpenLeaves().isEmpty()) {return true;} // The goal determines what state the leaves must be in. return switch (this.goal.getType()) { diff --git a/src/test/java/goalConditions/ProveAnySolutionTest.java b/src/test/java/goalConditions/ProveAnySolutionTest.java index 889b532a6..a23a07a4f 100644 --- a/src/test/java/goalConditions/ProveAnySolutionTest.java +++ b/src/test/java/goalConditions/ProveAnySolutionTest.java @@ -48,7 +48,7 @@ public void TestSinglePath() throws InvalidFileFormatException { Assert.assertTrue(TestUtilities.verifyBoard( "goalConditions/ProveAnySolution/CompleteLine", puzzle)); - Assert.assertFalse(TestUtilities.verifyBoard( + Assert.assertTrue(TestUtilities.verifyBoard( "goalConditions/ProveAnySolution/ContradictoryLine", puzzle)); Assert.assertFalse(TestUtilities.verifyBoard( diff --git a/src/test/java/goalConditions/ProveMultipleCellValueTest.java b/src/test/java/goalConditions/ProveMultipleCellValueTest.java index 7a187fb01..9d9dcc0a3 100644 --- a/src/test/java/goalConditions/ProveMultipleCellValueTest.java +++ b/src/test/java/goalConditions/ProveMultipleCellValueTest.java @@ -42,7 +42,7 @@ public void TestRootNode() throws InvalidFileFormatException { /** Tests puzzle completion with a single path down the tree*/ @Test public void TestSinglePath() throws InvalidFileFormatException { - Assert.assertFalse(TestUtilities.verifyBoard( + Assert.assertTrue(TestUtilities.verifyBoard( "goalConditions/ProveMultipleCellValue/ContradictoryLine", puzzle)); Assert.assertFalse(TestUtilities.verifyBoard( From e160d75de00305acbb100a5ad46d0905edd32af0 Mon Sep 17 00:00:00 2001 From: Jayden Carlson Date: Fri, 2 Oct 2026 17:14:10 -0400 Subject: [PATCH 3/4] Fix merge mistakes --- .../ui/puzzleeditorui/elementsview/ElementFrame.java | 10 +--------- src/test/java/goalConditions/ProveCellMustBeTest.java | 2 +- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementFrame.java b/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementFrame.java index 651e3dc98..33a751748 100644 --- a/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementFrame.java +++ b/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementFrame.java @@ -7,15 +7,7 @@ import edu.rpi.legup.ui.JitterlessScrollPane; import java.awt.Dimension; import java.awt.BorderLayout; -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JTabbedPane; -import javax.swing.SwingConstants; +import javax.swing.*; import javax.swing.border.EmptyBorder; import javax.swing.border.TitledBorder; diff --git a/src/test/java/goalConditions/ProveCellMustBeTest.java b/src/test/java/goalConditions/ProveCellMustBeTest.java index fee0f63ba..33a816304 100644 --- a/src/test/java/goalConditions/ProveCellMustBeTest.java +++ b/src/test/java/goalConditions/ProveCellMustBeTest.java @@ -48,7 +48,7 @@ public void TestSinglePath() throws InvalidFileFormatException { "goalConditions/ProveCellMustBe/CompleteLine", puzzle)); Assert.assertTrue(TestUtilities.verifyBoard( - "goalConditions/ProveCellMustBe/OvercompleteLine", puzzle)); + "goalConditions/ProveCellMustBe/SolvedLine", puzzle)); Assert.assertTrue( TestUtilities.verifyBoard( From c5383c699bae4353083a7670b957b5fc1f308d47 Mon Sep 17 00:00:00 2001 From: Jayden Carlson Date: Tue, 6 Oct 2026 16:23:27 -0400 Subject: [PATCH 4/4] Remove unused JScrollPane --- .../rpi/legup/ui/puzzleeditorui/elementsview/ElementFrame.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementFrame.java b/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementFrame.java index 33a751748..fdf46b659 100644 --- a/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementFrame.java +++ b/src/main/java/edu/rpi/legup/ui/puzzleeditorui/elementsview/ElementFrame.java @@ -17,7 +17,6 @@ public class ElementFrame extends JPanel { private JTabbedPane tabbedPane; private JComboBox goalTypeComboBox; private JComboBox goalDataTypecomboBox; - private JScrollPane elements; private ButtonGroup buttonGroup; private EditorElementController controller;