Skip to content

Commit

Permalink
Merge branch 'Bram-Hub:Skyscrapers_Contradiction_Tests' into Skyscrap…
Browse files Browse the repository at this point in the history
…ers_Contradiction_Tests
  • Loading branch information
ThisMatt authored Oct 3, 2023
2 parents 86df4d8 + bcb8629 commit da98374
Show file tree
Hide file tree
Showing 45 changed files with 720 additions and 74 deletions.
2 changes: 1 addition & 1 deletion bin/main/edu/rpi/legup/legup/config
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<puzzle name="ShortTruthTable"
qualifiedClassName="edu.rpi.legup.puzzle.shorttruthtable.ShortTruthTable"
fileType=".xml"
fileCreationDisabled="true"/>
fileCreationDisabled="false"/>
<puzzle name="Sudoku" qualifiedClassName="edu.rpi.legup.puzzle.sudoku.Sudoku"
fileType=".xml"
fileCreationDisabled="true"/>
Expand Down
14 changes: 14 additions & 0 deletions puzzles files/shorttruthtable/empty_test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Legup version="2.0.0">
<puzzle name="ShortTruthTable">
<board>
<data>
<statement representation="A>(B^C)" row_index="0"/>
<statement representation="C-B" row_index="1"/>
<statement representation="~C" row_index="2"/>
<statement representation="~A" row_index="3"/>
</data>
</board>
</puzzle>
<Solved isSolved="false"/>
</Legup>
84 changes: 76 additions & 8 deletions src/main/java/edu/rpi/legup/app/GameBoardFacade.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
package edu.rpi.legup.app;

import edu.rpi.legup.history.History;
import edu.rpi.legup.history.IHistoryListener;
import edu.rpi.legup.history.IHistorySubject;
import edu.rpi.legup.model.Puzzle;
import edu.rpi.legup.model.PuzzleImporter;
import edu.rpi.legup.model.gameboard.Board;
import edu.rpi.legup.model.Puzzle;
import edu.rpi.legup.model.tree.Tree;
import edu.rpi.legup.save.InvalidFileFormatException;
import edu.rpi.legup.ui.LegupUI;
import edu.rpi.legup.ui.ProofEditorPanel;
import edu.rpi.legup.ui.PuzzleEditorPanel;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import edu.rpi.legup.save.InvalidFileFormatException;
import edu.rpi.legup.ui.LegupUI;
import edu.rpi.legup.history.History;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
Expand Down Expand Up @@ -144,6 +143,30 @@ public boolean validateDimensions(String game, int rows, int columns) throws Run
}
}

/**
* Validates the given text input for the given puzzle
*
* @param game the name of the puzzle
* @param statements an array of statements
* @return true if it is possible to create a board for the given game with the given statements,
* false otherwise
* @throws RuntimeException if any of the input is invalid
*/
public boolean validateTextInput(String game, String[] statements) throws RuntimeException {
String qualifiedClassName = config.getPuzzleClassForName(game);
try {
Class<?> c = Class.forName(qualifiedClassName);
Constructor<?> constructor = c.getConstructor();
Puzzle puzzle = (Puzzle) constructor.newInstance();
return puzzle.isValidTextInput(statements);
}
catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException |
InstantiationException e) {
LOGGER.error(e);
throw new RuntimeException("Error validating puzzle text input");
}
}

/**
* Loads an empty puzzle
*
Expand All @@ -159,14 +182,20 @@ public void loadPuzzle(String game, int rows, int columns) throws RuntimeExcepti
Class<?> c = Class.forName(qualifiedClassName);
Constructor<?> cons = c.getConstructor();
Puzzle puzzle = (Puzzle) cons.newInstance();
setWindowTitle(puzzle.getName(), "New " + puzzle.getName() + " Puzzle");

PuzzleImporter importer = puzzle.getImporter();
if (importer == null) {
LOGGER.error("Puzzle importer is null");
throw new RuntimeException("Puzzle importer null");
}

// Theoretically, this exception should never be thrown, since LEGUP should not be
// allowing the user to give row/column input for a puzzle that doesn't support it
if (!importer.acceptsRowsAndColumnsInput()) {
throw new IllegalArgumentException(puzzle.getName() + " does not accept rows and columns input");
}

setWindowTitle(puzzle.getName(), "New " + puzzle.getName() + " Puzzle");
importer.initializePuzzle(rows, columns);

puzzle.initializeView();
Expand All @@ -183,6 +212,45 @@ public void loadPuzzle(String game, int rows, int columns) throws RuntimeExcepti
}
}

public void loadPuzzle(String game, String[] statements) {
String qualifiedClassName = config.getPuzzleClassForName(game);
LOGGER.debug("Loading " + qualifiedClassName);

try {
Class<?> c = Class.forName(qualifiedClassName);
Constructor<?> cons = c.getConstructor();
Puzzle puzzle = (Puzzle) cons.newInstance();

PuzzleImporter importer = puzzle.getImporter();
if (importer == null) {
LOGGER.error("Puzzle importer is null");
throw new RuntimeException("Puzzle importer null");
}

// Theoretically, this exception should never be thrown, since LEGUP should not be
// allowing the user to give text input for a puzzle that doesn't support it
if (!importer.acceptsTextInput()) {
throw new IllegalArgumentException(puzzle.getName() + " does not accept text input");
}

setWindowTitle(puzzle.getName(), "New " + puzzle.getName() + " Puzzle");
importer.initializePuzzle(statements);

puzzle.initializeView();
// puzzle.getBoardView().onTreeElementChanged(puzzle.getTree().getRootNode());
setPuzzleEditor(puzzle);
}
catch (IllegalArgumentException exception) {
throw new IllegalArgumentException(exception.getMessage());
}
catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException |
IllegalAccessException | InstantiationException e) {
LOGGER.error(e);
throw new RuntimeException("Puzzle creation error");
}

}

/**
* Loads a puzzle file
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,17 @@ public void executeCommand() {
}
else {
TreeTransitionView transitionView = (TreeTransitionView) firstSelectedView;
finalTreeElement = transitionView.getChildView().getTreeElement();
if (transitionView.getChildView() != null) {
finalTreeElement = transitionView.getChildView().getTreeElement();
}
else {
finalTreeElement = null;
}
}

if (finalTreeElement != null) {
puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(finalTreeElement));
}
puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(finalTreeElement));
puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(newSelection));
}

Expand Down
14 changes: 14 additions & 0 deletions src/main/java/edu/rpi/legup/model/Puzzle.java
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,26 @@ public boolean isValidDimensions(int rows, int columns) {
return rows > 0 && columns > 0;
}

/**
* Checks if the given array of statements is valid text input for the given puzzle
*
* @param statements
* @return
*/
public boolean isValidTextInput(String[] statements) {
return statements.length > 0;
}

/**
* Determines if the edu.rpi.legup.puzzle was solves correctly
*
* @return true if the board was solved correctly, false otherwise
*/
public boolean isPuzzleComplete() {
if (tree == null) {
return false;
}

boolean isComplete = tree.isValid();
if (isComplete) {
for (TreeElement leaf : tree.getLeafTreeElements()) {
Expand Down
1 change: 1 addition & 0 deletions src/main/java/edu/rpi/legup/model/PuzzleExporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public abstract class PuzzleExporter {

/**
* PuzzleExporter Constructor exports the puzzle object to a file
*
* @param puzzle puzzle that is to be exported
*/
public PuzzleExporter(Puzzle puzzle) {
Expand Down
19 changes: 15 additions & 4 deletions src/main/java/edu/rpi/legup/model/PuzzleImporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

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

public abstract class PuzzleImporter {
private static final Logger LOGGER = LogManager.getLogger(PuzzleImporter.class.getName());
Expand All @@ -24,12 +21,17 @@ public abstract class PuzzleImporter {

/**
* PuzzleImporter Constructor creates the puzzle object
*
* @param puzzle puzzle that is imported
*/
public PuzzleImporter(Puzzle puzzle) {
this.puzzle = puzzle;
}

public abstract boolean acceptsRowsAndColumnsInput();

public abstract boolean acceptsTextInput();

/**
* Initializes an empty puzzle
*
Expand All @@ -46,6 +48,13 @@ public void initializePuzzle(int rows, int columns) throws RuntimeException {
}
}

public void initializePuzzle(String[] statements) throws InputMismatchException, IllegalArgumentException {
// Note: Error checking for the statements will be left up to the puzzles that support
// text input. For example, some puzzles may be okay with "blank" statements (Strings with
// length = 0) while others may not.
initializeBoard(statements);
}

/**
* Initializes the puzzle attributes
*
Expand Down Expand Up @@ -116,6 +125,8 @@ public void initializePuzzle(Node node) throws InvalidFileFormatException {
*/
public abstract void initializeBoard(Node node) throws InvalidFileFormatException;

public abstract void initializeBoard(String[] statements) throws UnsupportedOperationException, IllegalArgumentException;

/**
* Creates the proof for building
*
Expand Down
14 changes: 4 additions & 10 deletions src/main/java/edu/rpi/legup/model/rules/DirectRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,12 @@ public DirectRule(String ruleID, String ruleName, String description, String ima
*/
public String checkRule(TreeTransition transition) {
Board finalBoard = transition.getBoard();

if (!finalBoard.isModified()) {
return "State must be modified";
if (transition.getParents().size() != 1 ||
transition.getParents().get(0).getChildren().size() != 1) {
return "State must have only 1 parent and 1 child";
}
else {
if (transition.getParents().size() != 1 ||
transition.getParents().get(0).getChildren().size() != 1) {
return "State must have only 1 parent and 1 child";
}
else {
return checkRuleRaw(transition);
}
return checkRuleRaw(transition);
}
}

Expand Down
1 change: 1 addition & 0 deletions src/main/java/edu/rpi/legup/model/tree/Tree.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ public Set<TreeElement> getLeafTreeElements() {

/**
* Gets a Set of TreeNodes that are leaf nodes from the sub tree rooted at the specified node
*
* @param node node that is input
* @return Set of TreeNodes that are leaf nodes from the sub tree
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ public BattleshipImporter(Battleship battleShip) {
super(battleShip);
}

@Override
public boolean acceptsRowsAndColumnsInput() {
return true;
}

@Override
public boolean acceptsTextInput() {
return false;
}

/**
* Creates an empty board for building
*
Expand Down Expand Up @@ -177,4 +187,9 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
"unknown value where integer expected");
}
}

@Override
public void initializeBoard(String[] statements) throws UnsupportedOperationException {
throw new UnsupportedOperationException("Battleship cannot accept text input");
}
}
15 changes: 15 additions & 0 deletions src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixImporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ public FillapixImporter(Fillapix fillapix) {
super(fillapix);
}

@Override
public boolean acceptsRowsAndColumnsInput() {
return true;
}

@Override
public boolean acceptsTextInput() {
return false;
}

/**
* Creates an empty board for building
*
Expand Down Expand Up @@ -88,4 +98,9 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
throw new InvalidFileFormatException("Fillapix Importer: unknown value where integer expected");
}
}

@Override
public void initializeBoard(String[] statements) throws UnsupportedOperationException {
throw new UnsupportedOperationException("Fillapix cannot accept text input");
}
}
15 changes: 15 additions & 0 deletions src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeImporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ public HeyawakeImporter(Heyawake heyawake) {
super(heyawake);
}

@Override
public boolean acceptsRowsAndColumnsInput() {
return true;
}

@Override
public boolean acceptsTextInput() {
return false;
}

/**
* Creates an empty board for building
*
Expand Down Expand Up @@ -91,4 +101,9 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
throw new InvalidFileFormatException("Heyawake Importer: unknown value where integer expected");
}
}

@Override
public void initializeBoard(String[] statements) throws UnsupportedOperationException {
throw new UnsupportedOperationException("Hey Awake cannot accept text input");
}
}
15 changes: 15 additions & 0 deletions src/main/java/edu/rpi/legup/puzzle/lightup/LightUpImporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ public LightUpImporter(LightUp lightUp) {
super(lightUp);
}

@Override
public boolean acceptsRowsAndColumnsInput() {
return true;
}

@Override
public boolean acceptsTextInput() {
return false;
}

/**
* Creates an empty board for building
*
Expand Down Expand Up @@ -102,4 +112,9 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
throw new InvalidFileFormatException("lightup Importer: unknown value where integer expected");
}
}

@Override
public void initializeBoard(String[] statements) throws UnsupportedOperationException {
throw new UnsupportedOperationException("Light Up cannot accept text input");
}
}
Loading

0 comments on commit da98374

Please sign in to comment.