+
+
@@ -38,5 +39,5 @@
-
+
diff --git a/src/main/java/edu/rpi/legup/model/PuzzleImporter.java b/src/main/java/edu/rpi/legup/model/PuzzleImporter.java
index 0cc163200..c22831c8d 100644
--- a/src/main/java/edu/rpi/legup/model/PuzzleImporter.java
+++ b/src/main/java/edu/rpi/legup/model/PuzzleImporter.java
@@ -6,6 +6,8 @@
import edu.rpi.legup.model.rules.Rule;
import edu.rpi.legup.model.tree.*;
import edu.rpi.legup.save.InvalidFileFormatException;
+
+import java.lang.reflect.Array;
import java.util.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -130,6 +132,19 @@ public void initializePuzzle(Node node) throws InvalidFileFormatException {
public abstract void initializeBoard(String[] statements)
throws UnsupportedOperationException, IllegalArgumentException;
+ /**
+ * Used to check that elements in the proof tree are saved properly.
+ * Make sure the list elements are lowercase
+ *
+ * @return A list of elements that will change when solving the puzzle
+ * * e.g. {"cell"}, {"cell", "line"}
+ */
+ public List getImporterElements() {
+ List elements = new ArrayList<>();
+ elements.add("cell");
+ return elements;
+ }
+
/**
* Creates the proof for building
*
@@ -379,7 +394,8 @@ protected void makeTransitionChanges(TreeTransition transition, Node transElemen
NodeList cellList = transElement.getChildNodes();
for (int i = 0; i < cellList.getLength(); i++) {
Node node = cellList.item(i);
- if (node.getNodeName().equalsIgnoreCase("cell")) {
+ List elements = getImporterElements();
+ if (elements.contains(node.getNodeName().toLowerCase())) {
Board board = transition.getBoard();
PuzzleElement cell = puzzle.getFactory().importCell(node, board);
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/Binary.java b/src/main/java/edu/rpi/legup/puzzle/binary/Binary.java
new file mode 100644
index 000000000..773513cda
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/Binary.java
@@ -0,0 +1,71 @@
+package edu.rpi.legup.puzzle.binary;
+
+import edu.rpi.legup.model.Puzzle;
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.ContradictionRule;
+
+public class Binary extends Puzzle {
+ public Binary() {
+ super();
+
+ this.name = "Binary";
+
+ this.importer = new BinaryImporter(this);
+ this.exporter = new BinaryExporter(this);
+
+ this.factory = new BinaryCellFactory();
+ }
+
+ /** Initializes the game board. Called by the invoker of the class */
+ @Override
+ public void initializeView() {
+ boardView = new BinaryView((BinaryBoard) currentBoard);
+ boardView.setBoard(currentBoard);
+ addBoardListener(boardView);
+ }
+
+ /**
+ * Generates a random edu.rpi.legup.puzzle based on the difficulty
+ *
+ * @param difficulty level of difficulty (1-10)
+ * @return board of the random edu.rpi.legup.puzzle
+ */
+ @Override
+ public Board generatePuzzle(int difficulty) {
+ return null;
+ }
+
+ // /**
+ // * Determines if the given dimensions are valid for Binary
+ // *
+ // * @param rows the number of rows
+ // * @param columns the number of columns
+ // * @return true if the given dimensions are valid for Binary, false otherwise
+ // */
+ // @Override
+ // public boolean isValidDimensions(int rows, int columns){
+ // return rows >= 2 && rows % 2 == 0 && columns >= 2 && columns % 2 == 0;
+ // }
+
+ @Override
+ public boolean isBoardComplete(Board board) {
+ BinaryBoard binaryBoard = (BinaryBoard) board;
+
+ for (ContradictionRule rule : contradictionRules) {
+ if (rule.checkContradiction(binaryBoard) == null) {
+ return false;
+ }
+ }
+ for (PuzzleElement data : binaryBoard.getPuzzleElements()) {
+ BinaryCell cell = (BinaryCell) data;
+ if (cell.getType() == BinaryType.UNKNOWN) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public void onBoardChange(Board board) {}
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryBoard.java b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryBoard.java
new file mode 100644
index 000000000..35c37b1a1
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryBoard.java
@@ -0,0 +1,84 @@
+package edu.rpi.legup.puzzle.binary;
+
+import edu.rpi.legup.model.gameboard.GridBoard;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+public class BinaryBoard extends GridBoard {
+ private int size;
+
+ public BinaryBoard(int width, int height) {
+ super(width, height);
+ this.size = width;
+ }
+
+ public BinaryBoard(int size) {
+ super(size, size);
+ this.size = size;
+ }
+
+ @Override
+ public BinaryCell getCell(int x, int y) {
+ if (y * dimension.width + x >= puzzleElements.size()
+ || x >= dimension.width
+ || y >= dimension.height
+ || x < 0
+ || y < 0) {
+ return null;
+ }
+ return (BinaryCell) super.getCell(x, y);
+ }
+
+ public Set getRowCells(int rowNum) {
+ Set row = new HashSet<>();
+ for (int i = 0; i < size; i++) {
+ BinaryCell cell = getCell(i, rowNum);
+ row.add(cell);
+ }
+ return row;
+ }
+
+ public ArrayList getRowTypes(int rowNum) {
+ ArrayList row = new ArrayList();
+ for (int i = 0; i < size; i++) {
+ BinaryCell cell = getCell(i, rowNum);
+ row.add(cell.getType());
+ }
+ return row;
+ }
+
+ public ArrayList getColTypes(int colNum) {
+ ArrayList col = new ArrayList();
+ for (int i = 0; i < size; i++) {
+ BinaryCell cell = getCell(colNum, i);
+ col.add(cell.getType());
+ }
+ return col;
+ }
+
+ public Set getCol(int colNum) {
+ Set col = new HashSet<>();
+ for (int i = 0; i < size; i++) {
+ col.add(getCell(colNum, i));
+ }
+ return col;
+ }
+
+ @Override
+ public BinaryBoard copy() {
+ System.out.println("BinaryBoard copy()");
+ BinaryBoard copy = new BinaryBoard(dimension.width, dimension.height);
+ for (int x = 0; x < this.dimension.width; x++) {
+ for (int y = 0; y < this.dimension.height; y++) {
+ copy.setCell(x, y, getCell(x, y).copy());
+ }
+ }
+ for (PuzzleElement e : modifiedData) {
+ copy.getPuzzleElement(e).setModifiable(false);
+ }
+ return copy;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCell.java b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCell.java
new file mode 100644
index 000000000..9007215ad
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCell.java
@@ -0,0 +1,35 @@
+package edu.rpi.legup.puzzle.binary;
+
+import edu.rpi.legup.model.gameboard.GridCell;
+import java.awt.Point;
+
+public class BinaryCell extends GridCell {
+ public BinaryCell(int valueInt, Point location) {
+ super(valueInt, location);
+ }
+
+ public BinaryType getType() {
+ switch (data) {
+ case 0:
+ return BinaryType.ZERO;
+ case 1:
+ return BinaryType.ONE;
+ case 2:
+ return BinaryType.UNKNOWN;
+ default:
+ if (data > 1) {
+ return BinaryType.UNKNOWN;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public BinaryCell copy() {
+ BinaryCell copy = new BinaryCell(data, (Point) location.clone());
+ copy.setIndex(index);
+ copy.setModifiable(isModifiable);
+ copy.setGiven(isGiven);
+ return copy;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCellFactory.java b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCellFactory.java
new file mode 100644
index 000000000..890c26656
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCellFactory.java
@@ -0,0 +1,59 @@
+package edu.rpi.legup.puzzle.binary;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.ElementFactory;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.save.InvalidFileFormatException;
+import java.awt.*;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+public class BinaryCellFactory extends ElementFactory {
+
+ public BinaryCell importCell(Node node, Board board) throws InvalidFileFormatException {
+ try {
+ if (!node.getNodeName().equalsIgnoreCase("cell")) {
+ throw new InvalidFileFormatException(
+ "binary Factory: unknown puzzleElement puzzleElement");
+ }
+
+ BinaryBoard binaryBoard = (BinaryBoard) board;
+ int width = binaryBoard.getWidth();
+ int height = binaryBoard.getHeight();
+
+ NamedNodeMap attributeList = node.getAttributes();
+ int value = Integer.valueOf(attributeList.getNamedItem("value").getNodeValue());
+ int x = Integer.valueOf(attributeList.getNamedItem("x").getNodeValue());
+ int y = Integer.valueOf(attributeList.getNamedItem("y").getNodeValue());
+
+ if (x >= width || y >= height) {
+ throw new InvalidFileFormatException("binary Factory: cell location out of bounds");
+ }
+ if (value < -2) {
+ throw new InvalidFileFormatException("binary Factory: cell unknown value");
+ }
+
+ BinaryCell cell = new BinaryCell(value, new Point(x, y));
+ cell.setIndex(y * height + x);
+ return cell;
+ } catch (NumberFormatException e) {
+ throw new InvalidFileFormatException(
+ "binary Factory: unknown value where integer expected");
+ } catch (NullPointerException e) {
+ throw new InvalidFileFormatException("binary Factory: could not find attribute(s)");
+ }
+ }
+
+ public org.w3c.dom.Element exportCell(Document document, PuzzleElement puzzleElement) {
+ org.w3c.dom.Element cellElement = document.createElement("cell");
+
+ BinaryCell cell = (BinaryCell) puzzleElement;
+ Point loc = cell.getLocation();
+ cellElement.setAttribute("value", String.valueOf(cell.getData()));
+ cellElement.setAttribute("x", String.valueOf(loc.x));
+ cellElement.setAttribute("y", String.valueOf(loc.y));
+
+ return cellElement;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryController.java b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryController.java
new file mode 100644
index 000000000..0bad559d9
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryController.java
@@ -0,0 +1,45 @@
+package edu.rpi.legup.puzzle.binary;
+
+import edu.rpi.legup.controller.ElementController;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import java.awt.event.MouseEvent;
+
+public class BinaryController extends ElementController {
+
+ @Override
+ public void changeCell(MouseEvent e, PuzzleElement data) {
+ BinaryCell cell = (BinaryCell) data;
+ if (e.getButton() == MouseEvent.BUTTON1) {
+ if (e.isControlDown()) {
+ this.boardView
+ .getSelectionPopupMenu()
+ .show(
+ boardView,
+ this.boardView.getCanvas().getX() + e.getX(),
+ this.boardView.getCanvas().getY() + e.getY());
+ } else {
+ if (cell.getData() == 0) {
+ data.setData(1);
+ } else {
+ if (cell.getData() == 1) {
+ data.setData(2);
+ } else {
+ data.setData(0);
+ }
+ }
+ }
+ } else {
+ if (e.getButton() == MouseEvent.BUTTON3) {
+ if (cell.getData() == 0) {
+ data.setData(1);
+ } else {
+ if (cell.getData() == 1) {
+ data.setData(2);
+ } else {
+ data.setData(0);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryElementView.java b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryElementView.java
new file mode 100644
index 000000000..9ac99c958
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryElementView.java
@@ -0,0 +1,120 @@
+package edu.rpi.legup.puzzle.binary;
+
+import edu.rpi.legup.ui.boardview.GridElementView;
+import java.awt.*;
+
+public class BinaryElementView extends GridElementView {
+
+ private static final Font FONT = new Font("TimesRoman", Font.BOLD, 17);
+ private static final Color FONT_COLOR = Color.BLACK;
+
+ public BinaryElementView(BinaryCell cell) {
+ super(cell);
+ }
+
+ /**
+ * Gets the PuzzleElement associated with this view
+ *
+ * @return PuzzleElement associated with this view
+ */
+ @Override
+ public BinaryCell getPuzzleElement() {
+ return (BinaryCell) super.getPuzzleElement();
+ }
+
+ @Override
+ public void drawGiven(Graphics2D graphics2D) {
+ BinaryCell cell = (BinaryCell) puzzleElement;
+ BinaryType type = cell.getType();
+ if (type == BinaryType.ZERO) {
+ graphics2D.setStroke(new BasicStroke(1));
+ graphics2D.setColor(Color.LIGHT_GRAY);
+ graphics2D.fillRect(location.x, location.y, size.width, size.height);
+ graphics2D.setColor(Color.BLACK);
+ graphics2D.drawRect(location.x, location.y, size.width, size.height);
+ graphics2D.setColor(FONT_COLOR);
+ graphics2D.setFont(FONT);
+ FontMetrics metrics = graphics2D.getFontMetrics(FONT);
+ String value = String.valueOf(puzzleElement.getData());
+ int xText = location.x + (size.width - metrics.stringWidth(value)) / 2;
+ int yText =
+ location.y + ((size.height - metrics.getHeight()) / 2) + metrics.getAscent();
+ graphics2D.drawString(String.valueOf(puzzleElement.getData()), xText, yText);
+ } else {
+ if (type == BinaryType.ONE) {
+ graphics2D.setStroke(new BasicStroke(1));
+ graphics2D.setColor(Color.LIGHT_GRAY);
+ graphics2D.fillRect(location.x, location.y, size.width, size.height);
+ graphics2D.setColor(Color.BLACK);
+ graphics2D.drawRect(location.x, location.y, size.width, size.height);
+ graphics2D.setColor(FONT_COLOR);
+ graphics2D.setFont(FONT);
+ FontMetrics metrics = graphics2D.getFontMetrics(FONT);
+ String value = String.valueOf(puzzleElement.getData());
+ int xText = location.x + (size.width - metrics.stringWidth(value)) / 2;
+ int yText =
+ location.y
+ + ((size.height - metrics.getHeight()) / 2)
+ + metrics.getAscent();
+ graphics2D.drawString(String.valueOf(puzzleElement.getData()), xText, yText);
+
+ } else {
+ if (type == BinaryType.UNKNOWN) {
+ graphics2D.setStroke(new BasicStroke(0));
+ graphics2D.setColor(Color.WHITE);
+ graphics2D.fillRect(location.x, location.y, size.width, size.height);
+ graphics2D.setColor(Color.BLACK);
+ graphics2D.drawRect(location.x, location.y, size.width, size.height);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void drawElement(Graphics2D graphics2D) {
+ BinaryCell cell = (BinaryCell) puzzleElement;
+ BinaryType type = cell.getType();
+ if (type == BinaryType.ZERO) {
+ graphics2D.setStroke(new BasicStroke(1));
+ graphics2D.setColor(Color.WHITE);
+ graphics2D.fillRect(location.x, location.y, size.width, size.height);
+ graphics2D.setColor(Color.BLACK);
+ graphics2D.drawRect(location.x, location.y, size.width, size.height);
+ graphics2D.setColor(FONT_COLOR);
+ graphics2D.setFont(FONT);
+ FontMetrics metrics = graphics2D.getFontMetrics(FONT);
+ String value = String.valueOf(puzzleElement.getData());
+ int xText = location.x + (size.width - metrics.stringWidth(value)) / 2;
+ int yText =
+ location.y + ((size.height - metrics.getHeight()) / 2) + metrics.getAscent();
+ graphics2D.drawString(String.valueOf(puzzleElement.getData()), xText, yText);
+ } else {
+ if (type == BinaryType.ONE) {
+ graphics2D.setStroke(new BasicStroke(1));
+ graphics2D.setColor(Color.WHITE);
+ graphics2D.fillRect(location.x, location.y, size.width, size.height);
+ graphics2D.setColor(Color.BLACK);
+ graphics2D.drawRect(location.x, location.y, size.width, size.height);
+ graphics2D.setColor(FONT_COLOR);
+ graphics2D.setFont(FONT);
+ FontMetrics metrics = graphics2D.getFontMetrics(FONT);
+ String value = String.valueOf(puzzleElement.getData());
+ int xText = location.x + (size.width - metrics.stringWidth(value)) / 2;
+ int yText =
+ location.y
+ + ((size.height - metrics.getHeight()) / 2)
+ + metrics.getAscent();
+ graphics2D.drawString(String.valueOf(puzzleElement.getData()), xText, yText);
+
+ } else {
+ if (type == BinaryType.UNKNOWN) {
+ graphics2D.setStroke(new BasicStroke(0));
+ graphics2D.setColor(Color.WHITE);
+ graphics2D.fillRect(location.x, location.y, size.width, size.height);
+ graphics2D.setColor(Color.BLACK);
+ graphics2D.drawRect(location.x, location.y, size.width, size.height);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryExporter.java b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryExporter.java
new file mode 100644
index 000000000..cd58314b6
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryExporter.java
@@ -0,0 +1,39 @@
+package edu.rpi.legup.puzzle.binary;
+
+import edu.rpi.legup.model.PuzzleExporter;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import org.w3c.dom.Document;
+
+public class BinaryExporter extends PuzzleExporter {
+
+ public BinaryExporter(Binary binary) {
+ super(binary);
+ }
+
+ @Override
+ protected org.w3c.dom.Element createBoardElement(Document newDocument) {
+ BinaryBoard board;
+ if (puzzle.getTree() != null) {
+ board = (BinaryBoard) puzzle.getTree().getRootNode().getBoard();
+ } else {
+ board = (BinaryBoard) puzzle.getBoardView().getBoard();
+ }
+
+ org.w3c.dom.Element boardElement = newDocument.createElement("board");
+ boardElement.setAttribute("width", String.valueOf(board.getWidth()));
+ boardElement.setAttribute("height", String.valueOf(board.getHeight()));
+
+ org.w3c.dom.Element cellsElement = newDocument.createElement("cells");
+ for (PuzzleElement puzzleElement : board.getPuzzleElements()) {
+ BinaryCell cell = (BinaryCell) puzzleElement;
+ if (cell.getData() != -2) {
+ org.w3c.dom.Element cellElement =
+ puzzle.getFactory().exportCell(newDocument, puzzleElement);
+ cellsElement.appendChild(cellElement);
+ }
+ }
+
+ boardElement.appendChild(cellsElement);
+ return boardElement;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryImporter.java b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryImporter.java
new file mode 100644
index 000000000..2fc5b09ef
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryImporter.java
@@ -0,0 +1,117 @@
+package edu.rpi.legup.puzzle.binary;
+
+import edu.rpi.legup.model.PuzzleImporter;
+import edu.rpi.legup.save.InvalidFileFormatException;
+import java.awt.*;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class BinaryImporter extends PuzzleImporter {
+ public BinaryImporter(Binary binary) {
+ super(binary);
+ }
+
+ @Override
+ public boolean acceptsRowsAndColumnsInput() {
+ return true;
+ }
+
+ @Override
+ public boolean acceptsTextInput() {
+ return false;
+ }
+
+ @Override
+ public void initializeBoard(int rows, int columns) {
+ BinaryBoard binaryBoard = new BinaryBoard(columns, rows);
+
+ for (int y = 0; y < rows; y++) {
+ for (int x = 0; x < columns; x++) {
+ BinaryCell cell = new BinaryCell(BinaryType.UNKNOWN.toValue(), new Point(x, y));
+ cell.setIndex(y * columns + x);
+ cell.setModifiable(true);
+ binaryBoard.setCell(x, y, cell);
+ }
+ }
+ puzzle.setCurrentBoard(binaryBoard);
+ }
+
+ /**
+ * Creates the board for building
+ *
+ * @param node xml document node
+ * @throws InvalidFileFormatException if file is invalid
+ */
+ @Override
+ public void initializeBoard(Node node) throws InvalidFileFormatException {
+ try {
+ if (!node.getNodeName().equalsIgnoreCase("board")) {
+ throw new InvalidFileFormatException(
+ "binary Importer: cannot find board puzzleElement");
+ }
+ Element boardElement = (Element) node;
+ if (boardElement.getElementsByTagName("cells").getLength() == 0) {
+ throw new InvalidFileFormatException(
+ "binary Importer: no puzzleElement found for board");
+ }
+
+ Element dataElement = (Element) boardElement.getElementsByTagName("cells").item(0);
+ NodeList elementDataList = dataElement.getElementsByTagName("cell");
+
+ BinaryBoard binaryBoard = null;
+ if (!boardElement.getAttribute("size").isEmpty()) {
+ int size = Integer.valueOf(boardElement.getAttribute("size"));
+ binaryBoard = new BinaryBoard(size);
+ } else {
+ if (!boardElement.getAttribute("width").isEmpty()
+ && !boardElement.getAttribute("height").isEmpty()) {
+ int width = Integer.valueOf(boardElement.getAttribute("width"));
+ int height = Integer.valueOf(boardElement.getAttribute("height"));
+ binaryBoard = new BinaryBoard(width, height);
+ }
+ }
+
+ int width = binaryBoard.getWidth();
+ int height = binaryBoard.getHeight();
+
+ if (binaryBoard == null || width % 2 != 0 || height % 2 != 0) {
+ throw new InvalidFileFormatException("binary Importer: invalid board dimensions");
+ }
+
+ for (int i = 0; i < elementDataList.getLength(); i++) {
+ BinaryCell cell =
+ (BinaryCell)
+ puzzle.getFactory()
+ .importCell(elementDataList.item(i), binaryBoard);
+ Point loc = cell.getLocation();
+ if (cell.getData() != BinaryType.UNKNOWN.toValue()) {
+ cell.setModifiable(false);
+ cell.setGiven(true);
+ }
+ binaryBoard.setCell(loc.x, loc.y, cell);
+ }
+
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ if (binaryBoard.getCell(x, y) == null) {
+ BinaryCell cell =
+ new BinaryCell(BinaryType.UNKNOWN.toValue(), new Point(x, y));
+ cell.setIndex(y * height + x);
+ cell.setModifiable(true);
+ binaryBoard.setCell(x, y, cell);
+ }
+ }
+ }
+ puzzle.setCurrentBoard(binaryBoard);
+ } catch (NumberFormatException e) {
+ throw new InvalidFileFormatException(
+ "binary Importer: unknown value where integer expected");
+ }
+ }
+
+ @Override
+ public void initializeBoard(String[] statements) throws UnsupportedOperationException {
+ throw new UnsupportedOperationException("Binary cannot accept text input");
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryType.java b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryType.java
new file mode 100644
index 000000000..6e3413d7a
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryType.java
@@ -0,0 +1,11 @@
+package edu.rpi.legup.puzzle.binary;
+
+public enum BinaryType {
+ ZERO,
+ ONE,
+ UNKNOWN;
+
+ public int toValue() {
+ return this.ordinal();
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/BinaryView.java b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryView.java
new file mode 100644
index 000000000..b11554f28
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryView.java
@@ -0,0 +1,24 @@
+package edu.rpi.legup.puzzle.binary;
+
+import edu.rpi.legup.controller.BoardController;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.ui.boardview.GridBoardView;
+import java.awt.*;
+
+public class BinaryView extends GridBoardView {
+
+ public BinaryView(BinaryBoard board) {
+ super(new BoardController(), new BinaryController(), board.getDimension());
+
+ for (PuzzleElement puzzleElement : board.getPuzzleElements()) {
+ BinaryCell cell = (BinaryCell) puzzleElement;
+ Point loc = cell.getLocation();
+ BinaryElementView elementView = new BinaryElementView(cell);
+ elementView.setIndex(cell.getIndex());
+ elementView.setSize(elementSize);
+ elementView.setLocation(
+ new Point(loc.x * elementSize.width, loc.y * elementSize.height));
+ elementViews.add(elementView);
+ }
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/elements/BlankTile.java b/src/main/java/edu/rpi/legup/puzzle/binary/elements/BlankTile.java
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/elements/BlankTile.java
@@ -0,0 +1 @@
+
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/elements/NumberTile.java b/src/main/java/edu/rpi/legup/puzzle/binary/elements/NumberTile.java
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/elements/NumberTile.java
@@ -0,0 +1 @@
+
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/CompleteRowColumnDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/CompleteRowColumnDirectRule.java
new file mode 100644
index 000000000..e38c6b78d
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/CompleteRowColumnDirectRule.java
@@ -0,0 +1,55 @@
+package edu.rpi.legup.puzzle.binary.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.ContradictionRule;
+import edu.rpi.legup.model.rules.DirectRule;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.binary.BinaryBoard;
+import edu.rpi.legup.puzzle.binary.BinaryCell;
+
+public class CompleteRowColumnDirectRule extends DirectRule {
+
+ public CompleteRowColumnDirectRule() {
+ super(
+ "BINA-BASC-0003",
+ "Complete Row Column",
+ "If a row/column of length n contains n/2 of a single value, the remaining cells must contain the other value",
+ "edu/rpi/legup/images/binary/rules/CompleteRowColumnDirectRule.png");
+ }
+
+ /**
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule
+ *
+ * @param transition transition to check
+ * @param puzzleElement equivalent puzzleElement
+ * @return null if the child node logically follow from the parent node at the specified
+ * puzzleElement, otherwise error message
+ */
+ @Override
+ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ BinaryBoard origBoard = (BinaryBoard) transition.getParents().get(0).getBoard();
+ ContradictionRule contraRule = new UnbalancedRowOrColumnContradictionRule();
+ BinaryCell binaryCell = (BinaryCell) puzzleElement;
+ BinaryBoard modified = origBoard.copy();
+ BinaryCell c = (BinaryCell) modified.getPuzzleElement(puzzleElement);
+
+ // System.out.println("ORIG" + binaryCell.getData());
+ // System.out.println("AFTER" + Math.abs(binaryCell.getData() - 1));
+ modified.getPuzzleElement(puzzleElement).setData(binaryCell.getData());
+ System.out.println(contraRule.checkContradictionAt(modified, puzzleElement));
+
+ if (contraRule.checkContradictionAt(modified, puzzleElement) != null) {
+ return null;
+ }
+
+ return "Grouping of Three Ones or Zeros not found";
+ }
+
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ return null;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/DuplicateRowsOrColumnsContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/DuplicateRowsOrColumnsContradictionRule.java
new file mode 100644
index 000000000..8b0d88ae4
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/DuplicateRowsOrColumnsContradictionRule.java
@@ -0,0 +1,55 @@
+package edu.rpi.legup.puzzle.binary.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.ContradictionRule;
+import edu.rpi.legup.puzzle.binary.BinaryBoard;
+import edu.rpi.legup.puzzle.binary.BinaryCell;
+import edu.rpi.legup.puzzle.binary.BinaryType;
+import java.util.ArrayList;
+
+public class DuplicateRowsOrColumnsContradictionRule extends ContradictionRule {
+ private final String NO_CONTRADICTION_MESSAGE =
+ "Does not contain a contradiction at this index";
+ private final String INVALID_USE_MESSAGE = "Row or column must have a value in each cell";
+
+ public DuplicateRowsOrColumnsContradictionRule() {
+ super(
+ "BINA-CONT-0003",
+ "Duplicate Rows Or Columns",
+ "There must not be two rows or two columns that are duplicates",
+ "edu/rpi/legup/images/binary/rules/DuplicateRowOrColumnContradictionRule.png");
+ }
+
+ @Override
+ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
+ BinaryBoard binaryBoard = (BinaryBoard) board;
+ BinaryCell cell = (BinaryCell) binaryBoard.getPuzzleElement(puzzleElement);
+
+ ArrayList row = binaryBoard.getRowTypes(cell.getLocation().y);
+
+ int size = row.size();
+
+ for (int i = 0; i < size; i++) {
+ if (i > cell.getLocation().y) {
+ ArrayList currRow = binaryBoard.getRowTypes(i);
+ if (currRow.equals(row)) {
+ return null;
+ }
+ }
+ }
+
+ ArrayList col = binaryBoard.getColTypes(cell.getLocation().x);
+
+ for (int i = 0; i < size; i++) {
+ if (i > cell.getLocation().x) {
+ ArrayList currCol = binaryBoard.getColTypes(i);
+ if (currCol.equals(col)) {
+ return null;
+ }
+ }
+ }
+
+ return super.getNoContradictionMessage() + ": " + this.NO_CONTRADICTION_MESSAGE;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/OneOrZeroCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/OneOrZeroCaseRule.java
new file mode 100644
index 000000000..70549cd72
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/OneOrZeroCaseRule.java
@@ -0,0 +1,90 @@
+package edu.rpi.legup.puzzle.binary.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.CaseBoard;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.CaseRule;
+import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.binary.BinaryBoard;
+import edu.rpi.legup.puzzle.binary.BinaryCell;
+import edu.rpi.legup.puzzle.binary.BinaryType;
+import java.util.ArrayList;
+import java.util.List;
+
+public class OneOrZeroCaseRule extends CaseRule {
+
+ public OneOrZeroCaseRule() {
+ super(
+ "BINA-CASE-0001",
+ "One or Zero",
+ "Each blank cell is either a one or a zero.",
+ "edu/rpi/legup/images/binary/rules/OneOrZeroCaseRule.png");
+ }
+
+ @Override
+ public String checkRuleRaw(TreeTransition transition) {
+ List childTransitions = transition.getParents().get(0).getChildren();
+ if (childTransitions.size() != 2) {
+ return super.getInvalidUseOfRuleMessage() + ": This case rule must have 2 children.";
+ }
+
+ TreeTransition case1 = childTransitions.get(0);
+ TreeTransition case2 = childTransitions.get(1);
+ if (case1.getBoard().getModifiedData().size() != 1
+ || case2.getBoard().getModifiedData().size() != 1) {
+ return super.getInvalidUseOfRuleMessage()
+ + ": This case rule must have 1 modified cell for each case.";
+ }
+
+ BinaryCell mod1 = (BinaryCell) case1.getBoard().getModifiedData().iterator().next();
+ BinaryCell mod2 = (BinaryCell) case2.getBoard().getModifiedData().iterator().next();
+ if (!mod1.getLocation().equals(mod2.getLocation())) {
+ return super.getInvalidUseOfRuleMessage()
+ + ": This case rule must modify the same cell for each case.";
+ }
+
+ if (!((mod1.getType() == BinaryType.ZERO && mod2.getType() == BinaryType.ONE)
+ || (mod2.getType() == BinaryType.ZERO && mod1.getType() == BinaryType.ONE))) {
+ return super.getInvalidUseOfRuleMessage()
+ + ": This case rule must an empty white and black cell.";
+ }
+
+ return null;
+ }
+
+ @Override
+ public CaseBoard getCaseBoard(Board board) {
+ BinaryBoard binaryBoard = (BinaryBoard) board.copy();
+ CaseBoard caseBoard = new CaseBoard(binaryBoard, this);
+ binaryBoard.setModifiable(false);
+ for (PuzzleElement element : binaryBoard.getPuzzleElements()) {
+ if (((BinaryCell) element).getType() == BinaryType.UNKNOWN) {
+ caseBoard.addPickableElement(element);
+ }
+ }
+ return caseBoard;
+ }
+
+ @Override
+ public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
+ ArrayList cases = new ArrayList<>();
+ Board case1 = board.copy();
+ PuzzleElement data1 = case1.getPuzzleElement(puzzleElement);
+ data1.setData(BinaryType.ZERO.toValue());
+ case1.addModifiedData(data1);
+ cases.add(case1);
+
+ Board case2 = board.copy();
+ PuzzleElement data2 = case2.getPuzzleElement(puzzleElement);
+ data2.setData(BinaryType.ONE.toValue());
+ case2.addModifiedData(data2);
+ cases.add(case2);
+
+ return cases;
+ }
+
+ @Override
+ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ return null;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/OneTileGapDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/OneTileGapDirectRule.java
new file mode 100644
index 000000000..2e1e96fa5
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/OneTileGapDirectRule.java
@@ -0,0 +1,64 @@
+package edu.rpi.legup.puzzle.binary.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.ContradictionRule;
+import edu.rpi.legup.model.rules.DirectRule;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.binary.BinaryBoard;
+import edu.rpi.legup.puzzle.binary.BinaryCell;
+
+public class OneTileGapDirectRule extends DirectRule {
+ private final String INVALID_USE_MESSAGE = "Number at cell is incorrect";
+
+ public OneTileGapDirectRule() {
+ super(
+ "BINA-BASC-0002",
+ "One Tile Gap",
+ "If an empty tile is in between the same value, fill the gap with the other value.",
+ "edu/rpi/legup/images/binary/rules/OneTileGapDirectRule.png");
+ }
+
+ boolean checkLeftRight(BinaryCell c, BinaryBoard board) {
+ int x = c.getLocation().x;
+ int y = c.getLocation().y;
+ return board.getCell(x - 1, y).getType() != c.getType()
+ || board.getCell(x + 1, y).getType() != c.getType();
+ }
+
+ boolean checkUpDown(BinaryCell c, BinaryBoard board) {
+ int x = c.getLocation().x;
+ int y = c.getLocation().y;
+ return board.getCell(x, y - 1).getType() != c.getType()
+ || board.getCell(x, y + 1).getType() != c.getType();
+ }
+
+ @Override
+ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ BinaryBoard origBoard = (BinaryBoard) transition.getParents().get(0).getBoard();
+ ContradictionRule contraRule = new ThreeAdjacentContradictionRule();
+ BinaryCell binaryCell = (BinaryCell) puzzleElement;
+ BinaryBoard modified = origBoard.copy();
+
+ // System.out.println("ORIG" + binaryCell.getData());
+ // System.out.println("AFTER" + Math.abs(binaryCell.getData() - 1));
+ modified.getPuzzleElement(puzzleElement).setData(Math.abs(binaryCell.getData() - 1));
+
+ PuzzleElement newP = binaryCell;
+
+ System.out.println(contraRule.checkContradictionAt(modified, newP));
+
+ if (contraRule.checkContradictionAt(modified, newP) == null) {
+ return null;
+ }
+ modified.getPuzzleElement(puzzleElement).setData(Math.abs(binaryCell.getData() - 1));
+
+ return "Grouping of Three Ones or Zeros not found";
+ }
+
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ return null;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/SurroundPairDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/SurroundPairDirectRule.java
new file mode 100644
index 000000000..dc2f07c8b
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/SurroundPairDirectRule.java
@@ -0,0 +1,48 @@
+package edu.rpi.legup.puzzle.binary.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.ContradictionRule;
+import edu.rpi.legup.model.rules.DirectRule;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.binary.BinaryBoard;
+import edu.rpi.legup.puzzle.binary.BinaryCell;
+
+public class SurroundPairDirectRule extends DirectRule {
+
+ public SurroundPairDirectRule() {
+ super(
+ "BINA-BASC-0001",
+ "Surround Pair",
+ "If two adjacent tiles have the same value, surround the tiles with the other value.",
+ "edu/rpi/legup/images/binary/rules/SurroundPairDirectRule.png");
+ }
+
+ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ BinaryBoard origBoard = (BinaryBoard) transition.getParents().get(0).getBoard();
+ ContradictionRule contraRule = new ThreeAdjacentContradictionRule();
+ BinaryCell binaryCell = (BinaryCell) puzzleElement;
+ BinaryBoard modified = origBoard.copy();
+
+ // System.out.println("ORIG" + binaryCell.getData());
+ // System.out.println("AFTER" + Math.abs(binaryCell.getData() - 1));
+ modified.getPuzzleElement(puzzleElement).setData(Math.abs(binaryCell.getData() - 1));
+
+ PuzzleElement newP = binaryCell;
+
+ System.out.println(contraRule.checkContradictionAt(modified, newP));
+
+ if (contraRule.checkContradictionAt(modified, newP) == null) {
+ return null;
+ }
+ modified.getPuzzleElement(puzzleElement).setData(Math.abs(binaryCell.getData() - 1));
+
+ return "Grouping of Three Ones or Zeros not found";
+ }
+
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ return null;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/ThreeAdjacentContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/ThreeAdjacentContradictionRule.java
new file mode 100644
index 000000000..075642246
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/ThreeAdjacentContradictionRule.java
@@ -0,0 +1,127 @@
+package edu.rpi.legup.puzzle.binary.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.ContradictionRule;
+import edu.rpi.legup.puzzle.binary.BinaryBoard;
+import edu.rpi.legup.puzzle.binary.BinaryCell;
+import edu.rpi.legup.puzzle.binary.BinaryType;
+
+public class ThreeAdjacentContradictionRule extends ContradictionRule {
+ private final String NO_CONTRADICTION_MESSAGE =
+ "Does not contain a contradiction at this index";
+ private final String INVALID_USE_MESSAGE = "Contradiction must be a zero or one";
+
+ public ThreeAdjacentContradictionRule() {
+ super(
+ "BINA-CONT-0001",
+ "Three Adjacent",
+ "There must not be three adjacent zeros or three adjacent ones in a row or column",
+ "edu/rpi/legup/images/binary/rules/ThreeAdjacentContradictionRule.png");
+ }
+
+ @Override
+ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
+ BinaryBoard binaryBoard = (BinaryBoard) board;
+ int height = binaryBoard.getHeight();
+ int width = binaryBoard.getWidth();
+
+ BinaryCell cell = (BinaryCell) binaryBoard.getPuzzleElement(puzzleElement);
+ System.out.println("THE CELL IS : " + cell.getType());
+ int cellX = cell.getLocation().x;
+ int cellY = cell.getLocation().y;
+ BinaryCell oneUp = null;
+ BinaryCell oneDown = null;
+ BinaryCell oneForward = null;
+ BinaryCell oneBackward = null;
+ BinaryCell twoUp = null;
+ BinaryCell twoDown = null;
+ BinaryCell twoForward = null;
+ BinaryCell twoBackward = null;
+ if (binaryBoard.getCell(cellX, cellY + 1) != null) {
+ oneUp = binaryBoard.getCell(cellX, cellY + 1);
+ }
+ if (binaryBoard.getCell(cellX, cellY - 1) != null) {
+ oneDown = binaryBoard.getCell(cellX, cellY - 1);
+ }
+ if (binaryBoard.getCell(cellX + 1, cellY) != null) {
+ oneForward = binaryBoard.getCell(cellX + 1, cellY);
+ }
+ if (binaryBoard.getCell(cellX - 1, cellY) != null) {
+ oneBackward = binaryBoard.getCell(cellX - 1, cellY);
+ }
+ if (binaryBoard.getCell(cellX, cellY + 2) != null) {
+ twoUp = binaryBoard.getCell(cellX, cellY + 2);
+ }
+ if (binaryBoard.getCell(cellX, cellY - 2) != null) {
+ twoDown = binaryBoard.getCell(cellX, cellY - 2);
+ }
+ if (binaryBoard.getCell(cellX + 2, cellY) != null) {
+ twoForward = binaryBoard.getCell(cellX + 2, cellY);
+ }
+ if (binaryBoard.getCell(cellX - 2, cellY) != null) {
+ twoBackward = binaryBoard.getCell(cellX - 2, cellY);
+ }
+
+ if (cell.getType() == BinaryType.ONE || cell.getType() == BinaryType.ZERO) {
+ if (twoBackward != null
+ && oneBackward != null
+ && twoBackward.getType() != BinaryType.UNKNOWN
+ && oneBackward.getType() != BinaryType.UNKNOWN) {
+ if (twoBackward.getType() == cell.getType()
+ && oneBackward.getType() == cell.getType()) {
+ System.out.println("1");
+ return null;
+ }
+ }
+ if (twoForward != null
+ && oneForward != null
+ && twoForward.getType() != BinaryType.UNKNOWN
+ && oneForward.getType() != BinaryType.UNKNOWN) {
+ if (twoForward.getType() == cell.getType()
+ && oneForward.getType() == cell.getType()) {
+ System.out.println("2");
+ return null;
+ }
+ }
+ if (twoDown != null
+ && oneDown != null
+ && twoDown.getType() != BinaryType.UNKNOWN
+ && oneDown.getType() != BinaryType.UNKNOWN) {
+ if (twoDown.getType() == cell.getType() && oneDown.getType() == cell.getType()) {
+ System.out.println("3");
+ return null;
+ }
+ }
+ if (twoUp != null
+ && oneUp != null
+ && twoUp.getType() != BinaryType.UNKNOWN
+ && oneUp.getType() != BinaryType.UNKNOWN) {
+ if (twoUp.getType() == cell.getType() && oneUp.getType() == cell.getType()) {
+ System.out.println("4");
+ return null;
+ }
+ }
+ if (oneBackward != null
+ && oneForward != null
+ && oneBackward.getType() != BinaryType.UNKNOWN
+ && oneForward.getType() != BinaryType.UNKNOWN) {
+ if (oneBackward.getType() == cell.getType()
+ && oneForward.getType() == cell.getType()) {
+ System.out.println("5");
+ return null;
+ }
+ }
+ if (oneUp != null
+ && oneDown != null
+ && oneUp.getType() != BinaryType.UNKNOWN
+ && oneDown.getType() != BinaryType.UNKNOWN) {
+ if (oneUp.getType() == cell.getType() && oneDown.getType() == cell.getType()) {
+ System.out.println("6");
+ return null;
+ }
+ }
+ }
+ return super.getNoContradictionMessage() + ": " + this.NO_CONTRADICTION_MESSAGE;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/UnbalancedRowOrColumnContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/UnbalancedRowOrColumnContradictionRule.java
new file mode 100644
index 000000000..5089b3b5f
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/UnbalancedRowOrColumnContradictionRule.java
@@ -0,0 +1,68 @@
+package edu.rpi.legup.puzzle.binary.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.ContradictionRule;
+import edu.rpi.legup.puzzle.binary.BinaryBoard;
+import edu.rpi.legup.puzzle.binary.BinaryCell;
+import edu.rpi.legup.puzzle.binary.BinaryType;
+import java.util.Set;
+
+public class UnbalancedRowOrColumnContradictionRule extends ContradictionRule {
+
+ private final String NO_CONTRADICTION_MESSAGE =
+ "Does not contain a contradiction at this index";
+ private final String INVALID_USE_MESSAGE = "Row or column must have a value in each cell";
+
+ public UnbalancedRowOrColumnContradictionRule() {
+ super(
+ "BINA-CONT-0002",
+ "Unbalanced Row Or Column",
+ "Each row or column must contain an equal number of zeros and ones",
+ "edu/rpi/legup/images/binary/rules/UnbalancedRowColumnContradictionRule.png");
+ }
+
+ @Override
+ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
+ BinaryBoard binaryBoard = (BinaryBoard) board;
+
+ BinaryCell cell = (BinaryCell) binaryBoard.getPuzzleElement(puzzleElement);
+ Set row = binaryBoard.getRowCells(cell.getLocation().y);
+
+ int size = row.size();
+ int rowNumZeros = 0;
+ int rowNumOnes = 0;
+
+ for (BinaryCell item : row) {
+ if (item.getType() == BinaryType.ZERO) {
+ rowNumZeros++;
+ } else if (item.getType() == BinaryType.ONE) {
+ rowNumOnes++;
+ }
+ }
+
+ if (rowNumZeros == size / 2 && rowNumOnes == size / 2) {
+ return super.getNoContradictionMessage() + ": " + this.NO_CONTRADICTION_MESSAGE;
+ }
+
+ Set col = binaryBoard.getCol(cell.getLocation().x);
+
+ size = col.size();
+ int colNumZeros = 0;
+ int colNumOnes = 0;
+
+ for (BinaryCell item : col) {
+ if (item.getType() == BinaryType.ZERO) {
+ colNumZeros++;
+ } else if (item.getType() == BinaryType.ONE) {
+ colNumOnes++;
+ }
+ }
+
+ if (colNumZeros == size / 2 && colNumOnes == size / 2) {
+ return super.getNoContradictionMessage() + ": " + this.NO_CONTRADICTION_MESSAGE;
+ }
+
+ return null;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/binary_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/binary/rules/binary_reference_sheet.txt
new file mode 100644
index 000000000..c8cb0d1b9
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/binary_reference_sheet.txt
@@ -0,0 +1,9 @@
+BINA-BASC-0001 : SurroundPairDirectRule
+BINA-BASC-0002 : OneTileGapDirectRule
+BINA-BASC-0003 : CompleteRowColumnDirectRule
+
+BINA-CONT-0001 : ThreeAdjacentContradictionRule
+BINA-CONT-0002 : UnbalancedRowOrColumnContradictionRule
+BINA-CONT-0003 : DuplicateRowsOrColumnsContradictionRule
+
+BINA-CASE-0001 : OneOrZeroCaseRule
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentBoard.java b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentBoard.java
index 09706f92a..6ded23a18 100644
--- a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentBoard.java
+++ b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentBoard.java
@@ -3,6 +3,8 @@
import edu.rpi.legup.model.gameboard.Board;
import edu.rpi.legup.model.gameboard.GridBoard;
import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.tree.Tree;
+
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
@@ -53,21 +55,29 @@ public TreeTentCell getCell(int x, int y) {
@Override
public PuzzleElement getPuzzleElement(PuzzleElement element) {
- switch (element.getIndex()) {
- case -2:
- return element;
- case -1:
- TreeTentLine line = (TreeTentLine) element;
- TreeTentLine thisLine = null;
- for (TreeTentLine l : lines) {
- if (line.compare(l)) {
- thisLine = l;
- break;
- }
- }
- return thisLine;
- default:
- return super.getPuzzleElement(element);
+ return switch (element.getIndex()) {
+ case -2 -> element;
+ case -1 -> element;
+ default -> super.getPuzzleElement(element);
+ };
+ }
+
+ @Override
+ public void setPuzzleElement(int index, PuzzleElement puzzleElement) {
+ if (index == -1) {
+ lines.add((TreeTentLine) puzzleElement);
+ } else if (index < puzzleElements.size()) {
+ puzzleElements.set(index, puzzleElement);
+ }
+ }
+
+ @Override
+ public void notifyChange(PuzzleElement puzzleElement) {
+ int index = puzzleElement.getIndex();
+ if (index == -1) {
+ lines.add((TreeTentLine) puzzleElement);
+ } else if (index < puzzleElements.size()) {
+ puzzleElements.set(index, puzzleElement);
}
}
@@ -168,20 +178,20 @@ public List getDiagonals(TreeTentCell cell, TreeTentType type) {
*
* @param index the row or column number
* @param type type of TreeTent element
- * @param isRow boolean value beased on whether a row of column is being checked
+ * @param isRow boolean value based on whether a row of column is being checked
* @return List of TreeTentCells that match the given TreeTentType
*/
public List getRowCol(int index, TreeTentType type, boolean isRow) {
List list = new ArrayList<>();
if (isRow) {
- for (int i = 0; i < dimension.height; i++) {
+ for (int i = 0; i < dimension.width; i++) {
TreeTentCell cell = getCell(i, index);
if (cell.getType() == type) {
list.add(cell);
}
}
} else {
- for (int i = 0; i < dimension.width; i++) {
+ for (int i = 0; i < dimension.height; i++) {
TreeTentCell cell = getCell(index, i);
if (cell.getType() == type) {
list.add(cell);
diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentCellFactory.java b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentCellFactory.java
index 1697b8bd5..a3553940d 100644
--- a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentCellFactory.java
+++ b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentCellFactory.java
@@ -39,7 +39,7 @@ public PuzzleElement importCell(Node node, Board board) throws InvalidFileFormat
}
TreeTentCell cell = new TreeTentCell(TreeTentType.valueOf(value), new Point(x, y));
- cell.setIndex(y * height + x);
+ cell.setIndex(y * width + x);
return cell;
} else {
if (node.getNodeName().equalsIgnoreCase("line")) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentClue.java b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentClue.java
index bcba7dc94..7b93f1301 100644
--- a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentClue.java
+++ b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentClue.java
@@ -50,6 +50,6 @@ public void setType(TreeTentType type) {
}
public TreeTentClue copy() {
- return null;
+ return new TreeTentClue(data, clueIndex, type);
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentController.java b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentController.java
index 79e074657..667c2ba7d 100644
--- a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentController.java
+++ b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentController.java
@@ -32,8 +32,10 @@ public TreeTentController() {
public void mousePressed(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON2) {
BoardView boardView = getInstance().getLegupUI().getBoardView();
- dragStart = boardView.getElement(e.getPoint());
- lastCellPressed = boardView.getElement(e.getPoint());
+ if (boardView != null) {
+ dragStart = boardView.getElement(e.getPoint());
+ lastCellPressed = boardView.getElement(e.getPoint());
+ }
}
}
@@ -105,6 +107,8 @@ public void mouseReleased(MouseEvent e) {
}
dragStart = null;
lastCellPressed = null;
+ } else {
+ super.mouseReleased(e);
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentExporter.java b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentExporter.java
index 475aaab1e..82c1b373d 100644
--- a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentExporter.java
+++ b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentExporter.java
@@ -52,7 +52,7 @@ protected org.w3c.dom.Element createBoardElement(Document newDocument) {
org.w3c.dom.Element axisSouth = newDocument.createElement("axis");
axisSouth.setAttribute("side", "south");
- for (TreeTentClue clue : board.getRowClues()) {
+ for (TreeTentClue clue : board.getColClues()) {
org.w3c.dom.Element clueElement = newDocument.createElement("clue");
clueElement.setAttribute("value", String.valueOf(clue.getData()));
clueElement.setAttribute("index", String.valueOf(clue.getClueIndex()));
diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentImporter.java b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentImporter.java
index 0117f41ce..c791617ce 100644
--- a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentImporter.java
+++ b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentImporter.java
@@ -3,6 +3,9 @@
import edu.rpi.legup.model.PuzzleImporter;
import edu.rpi.legup.save.InvalidFileFormatException;
import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
+
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@@ -113,7 +116,7 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
for (int x = 0; x < width; x++) {
if (treeTentBoard.getCell(x, y) == null) {
TreeTentCell cell = new TreeTentCell(TreeTentType.UNKNOWN, new Point(x, y));
- cell.setIndex(y * height + x);
+ cell.setIndex(y * width + x);
cell.setModifiable(true);
treeTentBoard.setCell(x, y, cell);
}
@@ -216,4 +219,12 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
public void initializeBoard(String[] statements) throws UnsupportedOperationException {
throw new UnsupportedOperationException("Tree Tent cannot accept text input");
}
+
+ @Override
+ public List getImporterElements() {
+ List elements = new ArrayList<>();
+ elements.add("cell");
+ elements.add("line");
+ return elements;
+ }
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/rules/FillinRowCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/treetent/rules/FillinRowCaseRule.java
index 0116c0dcd..a796c992a 100644
--- a/src/main/java/edu/rpi/legup/puzzle/treetent/rules/FillinRowCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/treetent/rules/FillinRowCaseRule.java
@@ -1,9 +1,11 @@
package edu.rpi.legup.puzzle.treetent.rules;
+import edu.rpi.legup.model.Puzzle;
import edu.rpi.legup.model.gameboard.Board;
import edu.rpi.legup.model.gameboard.CaseBoard;
import edu.rpi.legup.model.gameboard.PuzzleElement;
import edu.rpi.legup.model.rules.CaseRule;
+import edu.rpi.legup.model.tree.Tree;
import edu.rpi.legup.model.tree.TreeTransition;
import edu.rpi.legup.puzzle.treetent.TreeTentBoard;
import edu.rpi.legup.puzzle.treetent.TreeTentCell;
@@ -11,7 +13,9 @@
import edu.rpi.legup.puzzle.treetent.TreeTentType;
import java.awt.*;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
+import java.util.ListIterator;
public class FillinRowCaseRule extends CaseRule {
@@ -61,7 +65,7 @@ public CaseBoard getCaseBoard(Board board) {
*/
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
- ArrayList cases = new ArrayList();
+ ArrayList cases;
List group;
int tentsLeft;
TreeTentClue clue = ((TreeTentClue) puzzleElement);
@@ -70,7 +74,7 @@ public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
if (clue.getType() == TreeTentType.CLUE_SOUTH) {
group = tBoard.getRowCol(clueIndex, TreeTentType.UNKNOWN, false);
tentsLeft =
- tBoard.getRowClues().get(clueIndex).getData()
+ tBoard.getColClues().get(clueIndex).getData()
- tBoard.getRowCol(clueIndex, TreeTentType.TENT, false).size();
cases = genCombinations(tBoard, group, tentsLeft, clueIndex, false);
} else {
@@ -83,60 +87,100 @@ public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
// generate every combination (nCr)
// call goodBoard for each generated combination
- // alternitive would be to implement collision avoidance while generating instead of after
+ // alternative would be to implement collision avoidance while generating instead of after
if (cases.size() > 0) {
return cases;
}
return null;
}
+ /**
+ *
+ * @param iBoard the board to place tents onto
+ * @param tiles the locations where tents can be placed
+ * @param target the target number of tents to place
+ * @param index the index of tiles which is trying to be placed
+ * @param isRow Used to check validity of board
+ * @return the list of boards created
+ */
private ArrayList genCombinations(
TreeTentBoard iBoard,
List tiles,
int target,
Integer index,
boolean isRow) {
- return genCombRecursive(
- iBoard, tiles, tiles, target, 0, new ArrayList(), index, isRow);
+ ArrayList generatedBoards = new ArrayList<>();
+ genCombRecursive(
+ iBoard, tiles, target, 0, new ArrayList(), 0, index, generatedBoards, isRow);
+ return generatedBoards;
}
- private ArrayList genCombRecursive(
+ /**
+ *
+ * Recursive function to generate all ways of placing the target number of tents
+ * from the list of tiles to fill.
+ *
+ * @param iBoard The board
+ * @param tiles Unknown Tiles to fill
+ * @param target number of tents to place
+ * @param current number of tents already placed
+ * @param currentTile index of the next tile to add
+ * @param selected the cells which have tents
+ * @param index The index of the clue
+ * @param isRow Used for checking if the board is good
+ *
+ * The generated boards are placed into generatedBoards (passed by reference)
+ */
+
+ private void genCombRecursive(
TreeTentBoard iBoard,
- List original,
List tiles,
int target,
int current,
List selected,
+ int currentTile,
Integer index,
+ ArrayList generatedBoards,
boolean isRow) {
- ArrayList b = new ArrayList<>();
+ // Base Case: Enough tents have been placed
if (target == current) {
- TreeTentBoard temp = iBoard.copy();
- for (TreeTentCell c : original) {
- if (selected.contains(c)) {
- PuzzleElement change = temp.getPuzzleElement(c);
- change.setData(TreeTentType.TENT);
- temp.addModifiedData(change);
- } else {
- PuzzleElement change = temp.getPuzzleElement(c);
- change.setData(TreeTentType.GRASS);
- temp.addModifiedData(change);
+ TreeTentBoard boardCopy = iBoard.copy();
+ // Selected Tiles should already be filled
+ // Fill in other tiles with Grass
+ for (TreeTentCell tile : tiles) {
+ if (!selected.contains(tile)) {
+ PuzzleElement element = boardCopy.getPuzzleElement(tile);
+ element.setData(TreeTentType.GRASS);
+ boardCopy.addModifiedData(element);
}
}
- if (goodBoard(temp, index, isRow)) {
- b.add(temp);
- }
- return b;
+ // board validity is checked after placing every tent
+ // because the base case doesn't place any tents, the board
+ // should still be valid
+ generatedBoards.add(boardCopy);
+ return;
}
- for (int i = 0; i < tiles.size(); ++i) {
- List sub = tiles.subList(i + 1, tiles.size());
- List next = new ArrayList(selected);
- next.add(tiles.get(i));
- b.addAll(
- genCombRecursive(
- iBoard, original, sub, target, current + 1, next, index, isRow));
+
+ // Recursive Case:
+ // Looking at the group of possible tiles, save one of the tiles into selected,
+ // Place it on the board,
+ // Check if the board is good and recurse
+ //
+ // Backtracking:
+ // Remove the placed tent from the board and selected
+ for (int i = currentTile; i < tiles.size(); ++i){
+ TreeTentCell tile = tiles.get(i);
+ selected.add(tile);
+ PuzzleElement element = iBoard.getPuzzleElement(tile);
+ element.setData(TreeTentType.TENT);
+ iBoard.addModifiedData(element);
+ if (goodBoard(iBoard, index, isRow)) {
+ genCombRecursive(iBoard, tiles, target, current + 1, selected, i + 1, index, generatedBoards, isRow);
+ }
+ element.setData(TreeTentType.UNKNOWN);
+ iBoard.addModifiedData(element);
+ selected.remove(tile);
}
- return b;
}
// Effectively runs TouchingTents check on all the added tents to make sure that the proposed
@@ -153,7 +197,7 @@ private boolean goodBoard(TreeTentBoard board, Integer index, boolean isRow) {
for (TreeTentCell t : tents) {
List adj = board.getAdjacent(t, TreeTentType.TENT);
List diag = board.getDiagonals(t, TreeTentType.TENT);
- if (adj.size() > 0 || diag.size() > 0) {
+ if (!adj.isEmpty() || !diag.isEmpty()) {
return false;
}
}
diff --git a/src/main/java/edu/rpi/legup/ui/ProofEditorPanel.java b/src/main/java/edu/rpi/legup/ui/ProofEditorPanel.java
index 956f83ba4..8401e19f2 100644
--- a/src/main/java/edu/rpi/legup/ui/ProofEditorPanel.java
+++ b/src/main/java/edu/rpi/legup/ui/ProofEditorPanel.java
@@ -580,31 +580,31 @@ private void saveProofAs() {
if (puzzle == null) {
return;
}
-
- fileDialog.setMode(FileDialog.SAVE);
- fileDialog.setTitle("Save As");
- String curFileName = GameBoardFacade.getInstance().getCurFileName();
- if (curFileName == null) {
- fileDialog.setDirectory(
- LegupPreferences.getInstance().getUserPref(LegupPreferences.WORK_DIRECTORY));
- } else {
- File curFile = new File(curFileName);
- fileDialog.setDirectory(curFile.getParent());
+
+ LegupPreferences preferences = LegupPreferences.getInstance();
+ File preferredDirectory =
+ new File(preferences.getUserPref(LegupPreferences.WORK_DIRECTORY));
+ if (preferences.getSavedPath() != "") {
+ preferredDirectory = new File(preferences.getSavedPath());
}
- fileDialog.setVisible(true);
+ folderBrowser = new JFileChooser(preferredDirectory);
- String fileName = null;
- if (fileDialog.getDirectory() != null && fileDialog.getFile() != null) {
- fileName = fileDialog.getDirectory() + File.separator + fileDialog.getFile();
- }
+ folderBrowser.showSaveDialog(this);
+ folderBrowser.setVisible(true);
+ folderBrowser.setCurrentDirectory(new File(LegupPreferences.WORK_DIRECTORY));
+ folderBrowser.setDialogTitle("Select Directory");
+ folderBrowser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ folderBrowser.setAcceptAllFileFilterUsed(false);
- if (fileName != null) {
+ String path = folderBrowser.getSelectedFile().getAbsolutePath();
+
+ if (path != null) {
try {
PuzzleExporter exporter = puzzle.getExporter();
if (exporter == null) {
throw new ExportFileException("Puzzle exporter null");
}
- exporter.exportPuzzle(fileName);
+ exporter.exportPuzzle(path);
} catch (ExportFileException e) {
e.printStackTrace();
}
diff --git a/src/main/java/edu/rpi/legup/ui/PuzzleEditorPanel.java b/src/main/java/edu/rpi/legup/ui/PuzzleEditorPanel.java
index b3cd30ffb..f50c8d6fc 100644
--- a/src/main/java/edu/rpi/legup/ui/PuzzleEditorPanel.java
+++ b/src/main/java/edu/rpi/legup/ui/PuzzleEditorPanel.java
@@ -35,6 +35,7 @@ public class PuzzleEditorPanel extends LegupPanel implements IHistoryListener {
private JMenuItem helpLegup, aboutLegup;
private JMenuBar menuBar;
private JToolBar toolBar;
+ private JFileChooser folderBrowser;
private JFrame frame;
private JButton[] buttons;
JSplitPane splitPanel;
@@ -380,25 +381,37 @@ public void loadPuzzleFromHome(String game, String[] statements) {
public Object[] promptPuzzle() {
GameBoardFacade facade = GameBoardFacade.getInstance();
if (facade.getBoard() != null) {
- if (noQuit("Opening a new puzzle to edit?")) {
+ if (noQuit("Opening a new puzzle?")) {
return new Object[0];
}
}
- if (fileDialog == null) {
- fileDialog = new FileDialog(this.frame);
- }
+
LegupPreferences preferences = LegupPreferences.getInstance();
String preferredDirectory = preferences.getUserPref(LegupPreferences.WORK_DIRECTORY);
+ if (preferences.getSavedPath() != "") {
+ preferredDirectory = preferences.getSavedPath();
+ }
- fileDialog.setMode(FileDialog.LOAD);
- fileDialog.setTitle("Select Puzzle");
- fileDialog.setDirectory(preferredDirectory);
- fileDialog.setVisible(true);
+ File preferredDirectoryFile = new File(preferredDirectory);
+ JFileChooser fileBrowser = new JFileChooser(preferredDirectoryFile);
String fileName = null;
File puzzleFile = null;
- if (fileDialog.getDirectory() != null && fileDialog.getFile() != null) {
- fileName = fileDialog.getDirectory() + File.separator + fileDialog.getFile();
- puzzleFile = new File(fileName);
+
+ fileBrowser.showOpenDialog(this);
+ fileBrowser.setVisible(true);
+ fileBrowser.setCurrentDirectory(new File(preferredDirectory));
+ fileBrowser.setDialogTitle("Select Proof File");
+ fileBrowser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ fileBrowser.setAcceptAllFileFilterUsed(false);
+
+ File puzzlePath = fileBrowser.getSelectedFile();
+ System.out.println(puzzlePath.getAbsolutePath());
+
+ if (puzzlePath != null) {
+ fileName = puzzlePath.getAbsolutePath();
+ String lastDirectoryPath = fileName.substring(0, fileName.lastIndexOf(File.separator));
+ preferences.setSavedPath(lastDirectoryPath);
+ puzzleFile = puzzlePath;
} else {
// The attempt to prompt a puzzle ended gracefully (cancel)
return null;
@@ -538,39 +551,35 @@ private String savePuzzle() {
}
}
- if (fileDialog == null) {
- fileDialog = new FileDialog(this.frame);
+ LegupPreferences preferences = LegupPreferences.getInstance();
+ File preferredDirectory =
+ new File(preferences.getUserPref(LegupPreferences.WORK_DIRECTORY));
+ if (preferences.getSavedPath() != "") {
+ preferredDirectory = new File(preferences.getSavedPath());
}
+ folderBrowser = new JFileChooser(preferredDirectory);
- fileDialog.setMode(FileDialog.SAVE);
- fileDialog.setTitle("Save Proof");
- String curFileName = GameBoardFacade.getInstance().getCurFileName();
- if (curFileName == null) {
- fileDialog.setDirectory(
- LegupPreferences.getInstance().getUserPref(LegupPreferences.WORK_DIRECTORY));
- } else {
- File curFile = new File(curFileName);
- fileDialog.setDirectory(curFile.getParent());
- }
- fileDialog.setVisible(true);
+ folderBrowser.showSaveDialog(this);
+ folderBrowser.setVisible(true);
+ folderBrowser.setCurrentDirectory(new File(LegupPreferences.WORK_DIRECTORY));
+ folderBrowser.setDialogTitle("Select Directory");
+ folderBrowser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ folderBrowser.setAcceptAllFileFilterUsed(false);
- String fileName = null;
- if (fileDialog.getDirectory() != null && fileDialog.getFile() != null) {
- fileName = fileDialog.getDirectory() + File.separator + fileDialog.getFile();
- }
+ String path = folderBrowser.getSelectedFile().getAbsolutePath();
- if (fileName != null) {
+ if (path != null) {
try {
PuzzleExporter exporter = puzzle.getExporter();
if (exporter == null) {
throw new ExportFileException("Puzzle exporter null");
}
- exporter.exportPuzzle(fileName);
+ exporter.exportPuzzle(path);
} catch (ExportFileException e) {
e.printStackTrace();
}
}
- return fileName;
+ return path;
}
public DynamicView getDynamicBoardView() {
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/CompleteRowColumnDirectRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/CompleteRowColumnDirectRule.png
new file mode 100644
index 000000000..a74654d43
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/CompleteRowColumnDirectRule.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/DuplicateRowOrColumnContradictionRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/DuplicateRowOrColumnContradictionRule.png
new file mode 100644
index 000000000..214aa5348
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/DuplicateRowOrColumnContradictionRule.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/OneOrZeroCaseRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/OneOrZeroCaseRule.png
new file mode 100644
index 000000000..73072f2ce
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/OneOrZeroCaseRule.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/OneTileGapDirectRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/OneTileGapDirectRule.png
new file mode 100644
index 000000000..b68f67e44
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/OneTileGapDirectRule.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/SurroundPairDirectRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/SurroundPairDirectRule.png
new file mode 100644
index 000000000..67a4e47f3
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/SurroundPairDirectRule.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/ThreeAdjacentContradictionRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/ThreeAdjacentContradictionRule.png
new file mode 100644
index 000000000..862408b63
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/ThreeAdjacentContradictionRule.png differ
diff --git a/src/main/resources/edu/rpi/legup/images/binary/rules/UnbalancedRowColumnContradictionRule.png b/src/main/resources/edu/rpi/legup/images/binary/rules/UnbalancedRowColumnContradictionRule.png
new file mode 100644
index 000000000..029bd12ac
Binary files /dev/null and b/src/main/resources/edu/rpi/legup/images/binary/rules/UnbalancedRowColumnContradictionRule.png differ
diff --git a/src/main/resources/edu/rpi/legup/legup/config b/src/main/resources/edu/rpi/legup/legup/config
index 160e4093e..a6e2fad7d 100644
--- a/src/main/resources/edu/rpi/legup/legup/config
+++ b/src/main/resources/edu/rpi/legup/legup/config
@@ -4,6 +4,10 @@
qualifiedClassName="edu.rpi.legup.puzzle.battleship.Battleship"
fileType=".xml"
fileCreationDisabled="true"/>
+
Empty
+ * XXX
+ * XGX
+ * XXX
+ * Makes the (1, 1) tile GRASS
+ * Checks if the rule correctly detects no trees around the grass tile
+ */
+ @Test
+ public void EmptyFieldTest() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/EmptyFieldDirectRule/EmptyField", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
@@ -64,12 +70,17 @@ public void EmptyFieldTest() throws InvalidFileFormatException {
}
}
- // creates a 3x3 puzzle with 4 trees
- // trees are at (0,0), (2,0), (0,2), and (2,2)
- // make the (1,1) tile GRASS.
- // checks if tiles logically follow the EmptyFieldDirectRule
- @Test
- public void DiagonalTreeTest() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests EmptyFieldDirectRule
+ *
Trees are at (0, 0), (2, 0), (0, 2), and (2, 2)
+ * RXR
+ * XGX
+ * RXR
+ *
Makes the (1, 1) tile GRASS
+ * Checks if the rule correctly ignores the trees on the diagonals
+ */
+ @Test
+ public void DiagonalTreeTest() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/EmptyFieldDirectRule/DiagonalTree", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
@@ -103,12 +114,17 @@ public void DiagonalTreeTest() throws InvalidFileFormatException {
}
}
- // creates a 3x3 puzzle with 4 trees
- // trees are at (0,1), (1,0), (1,2), and (2,1)
- // make the (1,1) tile GRASS.
- // checks if tiles don't logically follow the EmptyFieldDirectRule
- @Test
- public void EmptyFieldTestFail() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests EmptyFieldDirectRule
+ *
Trees are at (0, 1), (1, 0), (1, 2), and (2, 1)
+ * XRX
+ * RGR
+ * XRX
+ *
Makes the (1, 1) tile GRASS
+ * Checks if the rule is not valid when there are adjacent trees
+ */
+ @Test
+ public void EmptyFieldTestFail() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFail", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
@@ -137,12 +153,17 @@ public void EmptyFieldTestFail() throws InvalidFileFormatException {
}
}
- // creates a 3x3 puzzle with 1 tree
- // tree is at (1,0)
- // make the (1,1) tile GRASS.
- // checks if tiles don't logically follow the EmptyFieldDirectRule
- @Test
- public void EmptyFieldTestFailTop() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests EmptyFieldDirectRule
+ *
Tree at (1, 0)
+ * XRX
+ * XGX
+ * XXX
+ *
Makes the (1, 1) tile GRASS
+ * Checks if the rule is not valid when there is one adjacent tree
+ */
+ @Test
+ public void EmptyFieldTestFailTop() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailTop", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
@@ -170,106 +191,4 @@ public void EmptyFieldTestFailTop() throws InvalidFileFormatException {
}
}
}
-
- // creates a 3x3 puzzle with 1 tree
- // tree is at (1,2)
- // make the (1,1) tile GRASS.
- // checks if tiles don't logically follow the EmptyFieldDirectRule
- @Test
- public void EmptyFieldTestFailTopBottom() throws InvalidFileFormatException {
- TestUtilities.importTestBoard(
- "puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailBottom", treetent);
- TreeNode rootNode = treetent.getTree().getRootNode();
- TreeTransition transition = rootNode.getChildren().get(0);
- transition.setRule(RULE);
-
- // get board state
- TreeTentBoard board = (TreeTentBoard) transition.getBoard();
-
- // change the board's cells considering breaking the EmptyField rule
- TreeTentCell cell1 = board.getCell(1, 1);
- cell1.setData(TreeTentType.GRASS);
- board.addModifiedData(cell1);
-
- // confirm there is not a logical following of the EmptyField rule
- Assert.assertNotNull(RULE.checkRule(transition));
-
- // the cells should not follow the rule
- TreeTentCell c;
- for (int i = 0; i < board.getWidth(); i++) {
- for (int j = 0; j < board.getHeight(); j++) {
- c = board.getCell(j, i);
- // does not use the rule to logically follow
- Assert.assertNotNull(RULE.checkRuleAt(transition, c));
- }
- }
- }
-
- // creates a 3x3 puzzle with 1 tree
- // tree is at (0,1)
- // make the (1,1) tile GRASS.
- // checks if tiles don't logically follow the EmptyFieldDirectRule
- @Test
- public void EmptyFieldTestFailLeft() throws InvalidFileFormatException {
- TestUtilities.importTestBoard(
- "puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailLeft", treetent);
- TreeNode rootNode = treetent.getTree().getRootNode();
- TreeTransition transition = rootNode.getChildren().get(0);
- transition.setRule(RULE);
-
- // get board state
- TreeTentBoard board = (TreeTentBoard) transition.getBoard();
-
- // change the board's cells considering breaking the EmptyField rule
- TreeTentCell cell1 = board.getCell(1, 1);
- cell1.setData(TreeTentType.GRASS);
- board.addModifiedData(cell1);
-
- // confirm there is not a logical following of the EmptyField rule
- Assert.assertNotNull(RULE.checkRule(transition));
-
- // the cells should not follow the rule
- TreeTentCell c;
- for (int i = 0; i < board.getWidth(); i++) {
- for (int j = 0; j < board.getHeight(); j++) {
- c = board.getCell(j, i);
- // does not use the rule to logically follow
- Assert.assertNotNull(RULE.checkRuleAt(transition, c));
- }
- }
- }
-
- // creates a 3x3 puzzle with 1 tree
- // tree is at (2,1)
- // make the (1,1) tile GRASS.
- // checks if tiles don't logically follow the EmptyFieldDirectRule
- @Test
- public void EmptyFieldTestFailRight() throws InvalidFileFormatException {
- TestUtilities.importTestBoard(
- "puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailRight", treetent);
- TreeNode rootNode = treetent.getTree().getRootNode();
- TreeTransition transition = rootNode.getChildren().get(0);
- transition.setRule(RULE);
-
- // get board state
- TreeTentBoard board = (TreeTentBoard) transition.getBoard();
-
- // change the board's cells considering breaking the EmptyField rule
- TreeTentCell cell1 = board.getCell(1, 1);
- cell1.setData(TreeTentType.GRASS);
- board.addModifiedData(cell1);
-
- // confirm there is not a logical following of the EmptyField rule
- Assert.assertNotNull(RULE.checkRule(transition));
-
- // the cells should not follow the rule
- TreeTentCell c;
- for (int i = 0; i < board.getWidth(); i++) {
- for (int j = 0; j < board.getHeight(); j++) {
- c = board.getCell(j, i);
- // does not use the rule to logically follow
- Assert.assertNotNull(RULE.checkRuleAt(transition, c));
- }
- }
- }
}
diff --git a/src/test/java/puzzles/treetent/rules/FillinRowCaseRuleTest.java b/src/test/java/puzzles/treetent/rules/FillinRowCaseRuleTest.java
new file mode 100644
index 000000000..71b478e7a
--- /dev/null
+++ b/src/test/java/puzzles/treetent/rules/FillinRowCaseRuleTest.java
@@ -0,0 +1,464 @@
+package puzzles.treetent.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.treetent.*;
+import edu.rpi.legup.puzzle.treetent.rules.FillinRowCaseRule;
+import edu.rpi.legup.save.InvalidFileFormatException;
+import legup.MockGameBoardFacade;
+import legup.TestUtilities;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+
+public class FillinRowCaseRuleTest {
+ private static final FillinRowCaseRule RULE = new FillinRowCaseRule();
+ private static TreeTent treetent;
+
+ @BeforeClass
+ public static void setUp() {
+ MockGameBoardFacade.getInstance();
+ treetent = new TreeTent();
+ }
+
+ /**
+ * empty 3x3 TreeTent puzzle Tests FillinRowCaseRule on row with 3 UNKNOWN tiles
+ * and a clue of 0 tents in the row.
+ *
+ *
checks that 1 case is created and that it is equivalent to FinishWithGrass rule
+ * May need to change checks due to issue #777
+ *
+ * @throws InvalidFileFormatException
+ */
+ @Test
+ public void TentOrTreeTestZeroTentClue() throws InvalidFileFormatException {
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3ZeroTent", treetent);
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+
+ /* Test the Row */
+ TreeTentClue testing_row = board.getClue(3, 1);
+ ArrayList cases = RULE.getCases(board, testing_row);
+
+ // assert that one case was found
+ Assert.assertEquals(1, cases.size());
+
+ // assert the case filled the row with grass
+ TreeTentBoard testCase = (TreeTentBoard) cases.getFirst();
+ Assert.assertEquals(3, testCase.getRowCol(1, TreeTentType.GRASS, true).size());
+
+ // checks other cells have not been modified
+ TreeTentCell original_cell;
+ TreeTentCell case_cell;
+
+ for (int w = 0; w < board.getWidth(); w++) {
+ for (int h = 0; h < board.getHeight(); h++) {
+ if (h == 1) {
+ continue;
+ }
+
+ original_cell = board.getCell(w, h);
+ case_cell = testCase.getCell(w, h);
+ Assert.assertEquals(original_cell.getType(), case_cell.getType());
+ }
+ }
+
+ /* Test the Column */
+ TreeTentClue testing_col = board.getClue(1, 3);
+ cases = RULE.getCases(board, testing_col);
+
+ // assert one case was created
+ Assert.assertEquals(1, cases.size());
+
+ // assert the case filled the column with grass
+ testCase = (TreeTentBoard) cases.getFirst();
+ Assert.assertEquals(3, testCase.getRowCol(1, TreeTentType.GRASS, false).size());
+
+ // checks other cells have not been modified
+ for (int w = 0; w < board.getWidth(); w++) {
+ for (int h = 0; h < board.getHeight(); h++) {
+ if (w == 1) {
+ continue;
+ }
+
+ original_cell = board.getCell(w, h);
+
+ case_cell = testCase.getCell(w, h);
+ Assert.assertEquals(original_cell.getType(), case_cell.getType());
+ }
+ }
+ }
+
+ /**
+ * empty 3x3 TreeTent puzzle Tests FillinRowCaseRule on row with 3 UNKNOWN tiles
+ * and a clue of 1 tent in the row. The column rules make the board impossible, but
+ * they are not checked here.
+ *
+ * checks 3 cases are created checks;
+ * first case is TENT tile at x=0,
+ * second case is TENT tile at x=1,
+ * and a third case is TENT tile at x=2.
+ * The cases can be in any order.
+ * Then, it checks that other cells have not been modified
+ *
+ * @throws InvalidFileFormatException
+ */
+ @Test
+ public void FillInRowEmptyOneTentClue() throws InvalidFileFormatException {
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3OneTent", treetent);
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+
+ /* Test the Row */
+ TreeTentClue testing_row = board.getClue(3, 1);
+ ArrayList cases = RULE.getCases(board, testing_row);
+
+ // assert correct number of cases created
+ Assert.assertEquals(3, cases.size());
+
+ for (Board testCaseBoard : cases) {
+ TreeTentBoard testCase = (TreeTentBoard) testCaseBoard;
+
+ // Each case must have 1 tent in the row
+ Assert.assertEquals(1, testCase.getRowCol(1, TreeTentType.TENT, true).size());
+
+ // and they must have 2 grass tiles in the row
+ Assert.assertEquals(2, testCase.getRowCol(1, TreeTentType.GRASS, true).size());
+ }
+
+ // checks other cells have not been modified
+ TreeTentCell original_cell;
+ TreeTentCell case_cell;
+
+ for (int w = 0; w < board.getWidth(); w++) {
+ for (int h = 0; h < board.getHeight(); h++) {
+ if (h == 1) {
+ continue;
+ }
+
+ original_cell = board.getCell(w, h);
+
+ for (Board testCaseBoard : cases) {
+ TreeTentBoard testCase = (TreeTentBoard) testCaseBoard;
+
+ case_cell = testCase.getCell(w, h);
+ Assert.assertEquals(original_cell.getType(), case_cell.getType());
+
+ }
+ }
+ }
+
+ /* Test the Column */
+ TreeTentClue testing_col = board.getClue(1, 3);
+ cases = RULE.getCases(board, testing_col);
+
+ // assert correct number of cases created
+ Assert.assertEquals(3, cases.size());
+ // Only one arrangement is possible when taking into account the
+ // touching tents contradiction rule.
+
+ for (Board testCaseBoard : cases) {
+ TreeTentBoard testCase = (TreeTentBoard) testCaseBoard;
+
+ // Each case must have 1 tent in the column
+ Assert.assertEquals(1, testCase.getRowCol(1, TreeTentType.TENT, false).size());
+
+ // and they must have 2 grass tiles in the column
+ Assert.assertEquals(2, testCase.getRowCol(1, TreeTentType.GRASS, false).size());
+ }
+
+ // checks other cells have not been modified
+ for (int w = 0; w < board.getWidth(); w++) {
+ for (int h = 0; h < board.getHeight(); h++) {
+ if (w == 1) {
+ continue;
+ }
+
+ original_cell = board.getCell(w, h);
+
+ for (Board testCaseBoard : cases) {
+ TreeTentBoard testCase = (TreeTentBoard) testCaseBoard;
+
+ case_cell = testCase.getCell(w, h);
+ Assert.assertEquals(original_cell.getType(), case_cell.getType());
+ }
+ }
+ }
+ }
+
+ /**
+ * empty 3x3 TreeTent puzzle Tests FillinRowCaseRule on row with 3 UNKNOWN tiles
+ * and a clue of 2 tent in the row. The column rules make the board impossible, but
+ * they are not checked here.
+ *
+ * checks 1 case is created. Checks that the case is when
+ * there are TENT tiles at x=0 and x=2.
+ * Then, it checks that other cells have not been modified
+ *
+ * @throws InvalidFileFormatException
+ */
+ @Test
+ public void FillInRowEmptyTwoTentClue() throws InvalidFileFormatException {
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3TwoTent", treetent);
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+ /* Test the Row */
+ TreeTentClue testing_row = board.getClue(3, 1);
+ ArrayList cases = RULE.getCases(board, testing_row);
+
+ // assert correct number of cases created
+ Assert.assertEquals(1, cases.size());
+ // Only one arrangement is possible when taking into account the
+ // touching tents contradiction rule.
+
+ TreeTentBoard testCase = (TreeTentBoard) cases.getFirst();
+
+ // The two side tiles are tents,
+ Assert.assertEquals(TreeTentType.TENT, testCase.getCell(0, 1).getType());
+ Assert.assertEquals(TreeTentType.TENT, testCase.getCell(2, 1).getType());
+
+ // and the center tile is grass.
+ Assert.assertEquals(TreeTentType.GRASS, testCase.getCell(1, 1).getType());
+
+ // checks other cells have not been modified
+ TreeTentCell original_cell;
+ TreeTentCell case_cell;
+
+ for (int w = 0; w < board.getWidth(); w++) {
+ for (int h = 0; h < board.getHeight(); h++) {
+ if (h == 1) {
+ continue;
+ }
+
+ original_cell = board.getCell(w, h);
+
+ case_cell = testCase.getCell(w, h);
+ Assert.assertEquals(original_cell.getType(), case_cell.getType());
+ }
+ }
+
+ /* Test the Column */
+ TreeTentClue testing_col = board.getClue(1, 3);
+ cases = RULE.getCases(board, testing_col);
+
+ // assert correct number of cases created
+ Assert.assertEquals(1, cases.size());
+ // Only one arrangement is possible when taking into account the
+ // touching tents contradiction rule.
+
+ testCase = (TreeTentBoard) cases.getFirst();
+
+ // The two side tiles are tents,
+ Assert.assertEquals(TreeTentType.TENT, testCase.getCell(1, 0).getType());
+ Assert.assertEquals(TreeTentType.TENT, testCase.getCell(1, 2).getType());
+
+ // and the center tile is grass.
+ Assert.assertEquals(TreeTentType.GRASS, testCase.getCell(1, 1).getType());
+
+ // checks other cells have not been modified
+ for (int w = 0; w < board.getWidth(); w++) {
+ for (int h = 0; h < board.getHeight(); h++) {
+ if (w == 1) {
+ continue;
+ }
+
+ original_cell = board.getCell(w, h);
+
+ case_cell = testCase.getCell(w, h);
+ Assert.assertEquals(original_cell.getType(), case_cell.getType());
+ }
+ }
+ }
+
+ /**
+ * empty 3x3 TreeTent puzzle Tests FillinRowCaseRule on row with 3 UNKNOWN tiles
+ * and a clue of 3 tent in the row.
+ *
+ * checks that 0 cases are created
+ *
+ * @throws InvalidFileFormatException
+ */
+ @Test
+ public void FillInRowEmptyThreeTentClue() throws InvalidFileFormatException {
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3ThreeTent", treetent);
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+
+ /* Test the Row */
+ TreeTentClue testing_row = board.getClue(3, 1);
+ ArrayList cases = RULE.getCases(board, testing_row);
+
+ // assert there were no cases found, as filling in all tiles causes the tents to touch
+ Assert.assertNull(cases);
+
+ /* Test the Column */
+ TreeTentClue testing_col = board.getClue(1, 3);
+ cases = RULE.getCases(board, testing_row);
+
+ Assert.assertNull(cases);
+ }
+
+ /**
+ * empty 5x5 TreeTent puzzle Tests FillinRowCaseRule on row with 5 UNKNOWN tiles
+ * and a clue of 2 tents in the row.
+ *
+ * checks that 6 cases are created and each case has the right number of tents
+ *
+ * @throws InvalidFileFormatException
+ */
+ @Test
+ public void FillInRowEmpty5x5TwoTentClue() throws InvalidFileFormatException {
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/FillinRowCaseRule/EmptyRow5x5TwoTent", treetent);
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+
+ // Test the Row
+ TreeTentClue testing_row = board.getClue(5, 2);
+ ArrayList cases = RULE.getCases(board, testing_row);
+
+ // assert correct number of cases created
+ Assert.assertEquals(6, cases.size());
+ // Only one arrangement is possible when taking into account the
+ // touching tents contradiction rule.
+
+ for (Board testCaseBoard : cases) {
+ TreeTentBoard testCase = (TreeTentBoard) testCaseBoard;
+
+ // Each case must have 2 tens in the row
+ Assert.assertEquals(2, testCase.getRowCol(2, TreeTentType.TENT, true).size());
+
+ // and they must have 3 grass tiles in the row
+ Assert.assertEquals(3, testCase.getRowCol(2, TreeTentType.GRASS, true).size());
+ }
+
+ TreeTentCell original_cell;
+ TreeTentCell case_cell;
+
+ // checks other cells have not been modified
+ for (int w = 0; w < board.getWidth(); w++) {
+ for (int h = 0; h < board.getHeight(); h++) {
+ if (h == 2) {
+ continue;
+ }
+
+ original_cell = board.getCell(w, h);
+
+ for (Board testCaseBoard : cases) {
+ TreeTentBoard testCase = (TreeTentBoard) testCaseBoard;
+
+ case_cell = testCase.getCell(w, h);
+ Assert.assertEquals(original_cell.getType(), case_cell.getType());
+ }
+ }
+ }
+
+ // Test the Column
+ TreeTentClue testing_col = board.getClue(2, 5);
+ cases = RULE.getCases(board, testing_col);
+
+ // assert correct number of cases created
+ Assert.assertEquals(6, cases.size());
+ // Only one arrangement is possible when taking into account the
+ // touching tents contradiction rule.
+
+ for (Board testCaseBoard : cases) {
+ TreeTentBoard testCase = (TreeTentBoard) testCaseBoard;
+
+ // Each case must have 2 tents in the column
+ Assert.assertEquals(2, testCase.getRowCol(2, TreeTentType.TENT, false).size());
+
+ // and they must have 4 grass tiles in the column
+ Assert.assertEquals(3, testCase.getRowCol(2, TreeTentType.GRASS, false).size());
+ }
+
+ // checks other cells have not been modified
+ for (int w = 0; w < board.getWidth(); w++) {
+ for (int h = 0; h < board.getHeight(); h++) {
+ if (w == 2) {
+ continue;
+ }
+
+ original_cell = board.getCell(w, h);
+
+ for (Board testCaseBoard : cases) {
+ TreeTentBoard testCase = (TreeTentBoard) testCaseBoard;
+
+ case_cell = testCase.getCell(w, h);
+ Assert.assertEquals(original_cell.getType(), case_cell.getType());
+ }
+ }
+ }
+ }
+
+ /**
+ * 7x3 TreeTent puzzle Tests FillinRowCaseRule on col with 3 UNKNOWN tiles separated by grass
+ * tiles and a clue of 3 tents in the col.
+ *
+ * checks that 1 case is created and that all three UNKNOWN tiles have become tents
+ *
+ * @throws InvalidFileFormatException
+ */
+ @Test
+ public void FillInRowPartialFillThreeTent() throws InvalidFileFormatException {
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/FillinRowCaseRule/PartialFillOneTent", treetent);
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+ TreeTentClue testing_col = board.getClue(1, 7);
+ ArrayList cases = RULE.getCases(board, testing_col);
+
+ // assert that one case was found
+ Assert.assertEquals(1, cases.size());
+
+ // assert the case has three tents in the column
+ TreeTentBoard testCase = (TreeTentBoard) cases.getFirst();
+ Assert.assertEquals(3, testCase.getRowCol(1, TreeTentType.TENT, false).size());
+
+ Assert.assertEquals(TreeTentType.TENT, testCase.getCell(1, 1).getType());
+ Assert.assertEquals(TreeTentType.TENT, testCase.getCell(1, 3).getType());
+ Assert.assertEquals(TreeTentType.TENT, testCase.getCell(1, 5).getType());
+
+ // checks other cells have not been modified
+ TreeTentCell original_cell;
+ TreeTentCell case_cell;
+
+ for (int w = 0; w < board.getWidth(); w++) {
+ if (w == 1) {
+ continue;
+ }
+ for (int h = 0; h < board.getHeight(); h++) {
+
+ original_cell = board.getCell(w, h);
+ case_cell = testCase.getCell(w, h);
+ Assert.assertEquals(original_cell.getType(), case_cell.getType());
+ }
+ }
+ }
+}
diff --git a/src/test/java/puzzles/treetent/rules/FinishWithGrassDirectRuleTest.java b/src/test/java/puzzles/treetent/rules/FinishWithGrassDirectRuleTest.java
index 0783ab8b8..f37761e26 100644
--- a/src/test/java/puzzles/treetent/rules/FinishWithGrassDirectRuleTest.java
+++ b/src/test/java/puzzles/treetent/rules/FinishWithGrassDirectRuleTest.java
@@ -28,14 +28,18 @@ public static void setUp() {
treetent = new TreeTent();
}
- /**
- * 3x3 TreeTent puzzle with a tent at (0,0) Tests FinishWithGrassDirectRule on GRASS tiles
- * horizontal of the tent at (1,0) and (2,0)
- *
- * @throws InvalidFileFormatException
- */
- @Test
- public void FinishWithGrassHorizontalTest() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests FinishWithGrassDirectRule
+ * Tent at (1, 1)
+ * XXX x
+ * GTG 1
+ * XXX x
+ * xxx
+ *
Makes (0, 1) and (2, 1) GRASS
+ * Checks if the rule detects the middle row to be filled in correctly
+ */
+ @Test
+ public void FinishWithGrassHorizontalTest() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/FinishWithGrassDirectRule/CornerTent", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
@@ -74,14 +78,18 @@ public void FinishWithGrassHorizontalTest() throws InvalidFileFormatException {
}
}
- /**
- * 3x3 TreeTent puzzle with a tent at (0,0) Tests FinishWithGrassDirectRule on GRASS tiles
- * vertical of the tent at (0,1) and (0,2)
- *
- * @throws InvalidFileFormatException
- */
- @Test
- public void FinishWithGrassVerticalTest() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests FinishWithGrassDirectRule
+ *
Tent at (0, 0)
+ * TXX x
+ * GXX x
+ * GXX x
+ * 1xx
+ *
Makes (0, 1) and (0, 2) GRASS
+ * Checks if the rule detects the leftmost column to be filled in correctly
+ */
+ @Test
+ public void FinishWithGrassVerticalTest() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/FinishWithGrassDirectRule/CornerTent", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
@@ -121,10 +129,14 @@ public void FinishWithGrassVerticalTest() throws InvalidFileFormatException {
}
/**
- * 3x3 TreeTent puzzle with a tent at (0,0) Tests FinishWithGrassDirectRule on GRASS tiles at
- * (1,0), (2,0), (0,1), and (0,2)
- *
- * @throws InvalidFileFormatException
+ * 3x3 TreeTent puzzle Tests FinishWithGrassDirectRule
+ *
Tent at (0, 0)
+ * TGG 1
+ * GXX x
+ * GXX x
+ * 1xx
+ *
Makes (0, 1), (0, 2), (1, 0), and (2, 0) GRASS
+ * Checks if the rule detects the top row and leftmost column to be filled in correctly
*/
@Test
public void FinishWithGrassTest() throws InvalidFileFormatException {
@@ -174,14 +186,18 @@ public void FinishWithGrassTest() throws InvalidFileFormatException {
}
}
- /**
- * 3x3 TreeTent puzzle with no tents Tests FinishWithGrassDirectRule on GRASS tiles GRASS tiles
- * fill entire board
- *
- * @throws InvalidFileFormatException
- */
- @Test
- public void NoTentTest() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests FinishWithGrassDirectRule
+ *
Empty
+ * GGG 0
+ * GGG 0
+ * GGG 0
+ * 000
+ *
Fill Board with GRASS
+ * Checks if the rule allows all cells to be filled when the clue for all rows and columns is zero.
+ */
+ @Test
+ public void NoTentTest() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/FinishWithGrassDirectRule/NoTent", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
@@ -215,14 +231,18 @@ public void NoTentTest() throws InvalidFileFormatException {
}
}
- /**
- * 3x3 TreeTent puzzle with a tent at (1,1) Tests FinishWithGrassDirectRule on GRASS tiles
- * surrounding the tent at (1,0), (0,1), (2,1), and (1,2)
- *
- * @throws InvalidFileFormatException
- */
- @Test
- public void MiddleTentTest() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests FinishWithGrassDirectRule
+ *
Tent at (1, 1)
+ * XGX x
+ * GTG 1
+ * XGX x
+ * x1x
+ *
Makes (1, 0), (0, 1), (2, 1), and (1, 2) GRASS
+ * Checks if the rule correctly allows the central row and column to be filled with grass.
+ */
+ @Test
+ public void MiddleTentTest() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/FinishWithGrassDirectRule/MiddleTent", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
@@ -270,14 +290,18 @@ public void MiddleTentTest() throws InvalidFileFormatException {
}
}
- /**
- * 3x3 TreeTent puzzle with missing tents Tests FinishWithGrassDirectRule on GRASS tiles filling
- * the puzzle all GRASS tiles should fail the FinishWithGrassDirectRule
- *
- * @throws InvalidFileFormatException
- */
- @Test
- public void FailTentTest() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests FinishWithGrassDirectRule
+ *
Empty
+ * GGG 1
+ * GGG 1
+ * GGG 1
+ * 111
+ *
Fill Board with GRASS
+ * Checks if the rule is not valid when a row or column does not have the required number of tents but is filled with grass
+ */
+ @Test
+ public void FailTentTest() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/FinishWithGrassDirectRule/FailTent", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
@@ -311,14 +335,22 @@ public void FailTentTest() throws InvalidFileFormatException {
}
}
- /**
- * 7x7 TreeTent puzzle with multiple tents spaced out Tests FinishWithGrassDirectRule on GRASS
- * tiles between the tents at (0,3), (2,3), (4,3), and (6,3)
- *
- * @throws InvalidFileFormatException
- */
- @Test
- public void SpacedOutTentTest() throws InvalidFileFormatException {
+ /**
+ * 7x7 TreeTent puzzle Tests FinishWithGrassDirectRule
+ *
Tents at (1, 3), (3, 3), and (5, 3)
+ * XXXXXXX x
+ * XXXXXXX x
+ * XXXXXXX x
+ * TGTGTGT 4
+ * XXXXXXX x
+ * XXXXXXX x
+ * XXXXXXX x
+ * xxxxxxx
+ *
Makes (0, 3), (2, 3), (4, 3), and (6, 3) GRASS
+ * Checks if applying the rule on row 3 is valid
+ */
+ @Test
+ public void SpacedOutTentTest() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/FinishWithGrassDirectRule/SpacedOutTent", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
diff --git a/src/test/java/puzzles/treetent/rules/FinishWithTentsDirectRuleTest.java b/src/test/java/puzzles/treetent/rules/FinishWithTentsDirectRuleTest.java
index 652af615f..d82be3f87 100644
--- a/src/test/java/puzzles/treetent/rules/FinishWithTentsDirectRuleTest.java
+++ b/src/test/java/puzzles/treetent/rules/FinishWithTentsDirectRuleTest.java
@@ -27,14 +27,18 @@ public static void setUp() {
treetent = new TreeTent();
}
- /**
- * 3x3 TreeTent puzzle with a GRASS tile at (0,0) Tests FinishWithTentsDirectRule on TENT tiles
- * horizontal of the GRASS tile at (1,0) and (2,0)
- *
- * @throws InvalidFileFormatException
- */
- @Test
- public void FinishWithHorizontalTentsTest() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests FinishWithTentsDirectRule
+ *
Grass at (0, 0)
+ * GTT 2
+ * XXX x
+ * XXX x
+ * xxx
+ *
Makes (1, 0) and (2, 0) TENT
+ * Checks that the rule correctly fills in the first row
+ */
+ @Test
+ public void FinishWithHorizontalTentsTest() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/FinishWithTentsDirectRule/FinishWithHorizontalTents",
treetent);
@@ -67,14 +71,18 @@ public void FinishWithHorizontalTentsTest() throws InvalidFileFormatException {
}
}
- /**
- * 3x3 TreeTent puzzle with a GRASS tile at (0,0) Tests FinishWithTentsDirectRule on TENT tiles
- * vertical of the GRASS tile at (0,1) and (0,2)
- *
- * @throws InvalidFileFormatException
- */
- @Test
- public void FinishWithVerticalTentsTest() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests FinishWithTentsDirectRule
+ *
Grass at (0, 0)
+ * GXX x
+ * TXX x
+ * TXX x
+ * 2xx
+ *
Makes (0, 1) and (0, 2) TENT
+ * Checks that the rule correctly fills in the first column
+ */
+ @Test
+ public void FinishWithVerticalTentsTest() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/FinishWithTentsDirectRule/FinishWithVerticalTents",
treetent);
@@ -107,14 +115,18 @@ public void FinishWithVerticalTentsTest() throws InvalidFileFormatException {
}
}
- /**
- * 3x3 TreeTent puzzle with a GRASS tile at (1,1) Tests FinishWithTentsDirectRule on TENT tiles
- * around the GRASS tile at (1,0), (1,2), (0,1), and (2,1)
- *
- * @throws InvalidFileFormatException
- */
- @Test
- public void FinishWithTentsTest() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests FinishWithTentsDirectRule
+ *
Grass at (0, 0)
+ * GTT 2
+ * TXX x
+ * TXX x
+ * 2xx
+ *
Makes (1, 0), (2, 0), (0, 1) and (0, 2) TENT
+ * Checks that the rule correctly fills both the first row and first column
+ */
+ @Test
+ public void FinishWithTentsTest() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/FinishWithTentsDirectRule/FinishWithTents", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
@@ -155,14 +167,18 @@ public void FinishWithTentsTest() throws InvalidFileFormatException {
}
}
- /**
- * 3x3 TreeTent puzzle with a TENT tile at (1,1) Tests FinishWithTentsDirectRule on TENT tiles
- * around the TENT tile at (1,0), (1,2), (0,1), and (2,1)
- *
- * @throws InvalidFileFormatException
- */
- @Test
- public void AdditionalTentsTest() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests FinishWithTentsDirectRule
+ *
Tent at (1, 1)
+ * XTX x
+ * TTT 3
+ * XTX x
+ * x3x
+ *
Makes (1, 0), (0, 1), (2, 1), and (1, 2) TENT
+ * Checks that the rule correctly fills in the middle row and column when a tent starts at (1, 1)
+ */
+ @Test
+ public void AdditionalTentsTest() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/FinishWithTentsDirectRule/AdditionalTents", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
@@ -203,14 +219,18 @@ public void AdditionalTentsTest() throws InvalidFileFormatException {
}
}
- /**
- * Empty 3x3 TreeTent puzzle Tests FinishWithTentsDirectRule on TENT tiles of entire puzzle all
- * TENT tiles should fail FinishWithTentsDirectRule as no TENT tiles should be there
- *
- * @throws InvalidFileFormatException
- */
- @Test
- public void FinishWithTentsFailTest() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests FinishWithTentsDirectRule
+ *
Empty
+ * TTT 0
+ * TTT 0
+ * TTT 0
+ * 000
+ *
Fills the board with tents
+ * Checks that the rule does not allow for more tents in any of the rows or columns
+ */
+ @Test
+ public void FinishWithTentsFailTest() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/FinishWithTentsDirectRule/FinishWithTentsFail", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
@@ -239,15 +259,18 @@ public void FinishWithTentsFailTest() throws InvalidFileFormatException {
}
}
- /**
- * 3x3 TreeTent puzzle with a TENT tile at (1,1) Tests FinishWithTentsDirectRule on TENT tiles
- * around the TENT tile at (1,0), (1,2), (0,1), and (2,1) all TENT tiles should fail
- * FinishWithTentsDirectRule as there were already sufficient number of TENT tiles
- *
- * @throws InvalidFileFormatException
- */
- @Test
- public void TooManyTentsTest() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests FinishWithTentsDirectRule
+ *
Tent at (1, 1)
+ * XTX x
+ * TTT 1
+ * XTX x
+ * x1x
+ *
Makes (1, 0), (0, 1), (2, 1) and (1, 2) Tent
+ * Checks that the rule does not allow for more tents in the central row or central column
+ */
+ @Test
+ public void TooManyTentsTest() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/FinishWithTentsDirectRule/TooManyTents", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
@@ -279,16 +302,18 @@ public void TooManyTentsTest() throws InvalidFileFormatException {
}
}
- /**
- * 3x3 TreeTent puzzle with a TENT tile at (1,1) Tests FinishWithTentsDirectRule on TENT tiles
- * around the TENT tile at (1,0), (1,2), (0,1), and (2,1) all TENT tiles should fail
- * FinishWithTentsDirectRule as there are multiple configurations of the placement of the TENT
- * tiles
- *
- * @throws InvalidFileFormatException
- */
- @Test
- public void AmbiguousTentsTest() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests FinishWithTentsDirectRule
+ *
Tent at (1, 1)
+ * XTX x
+ * TTT 2
+ * XTX x
+ * x2x
+ *
Makes (1, 0), (0, 1), (2, 1) and (1, 2) Tent
+ * Checks that the rule is not satisfied because there are multiple configurations of tents for the central row and central column
+ */
+ @Test
+ public void AmbiguousTentsTest() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/FinishWithTentsDirectRule/AmbiguousTents", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
diff --git a/src/test/java/puzzles/treetent/rules/LastCampingSpotDirectRuleTest.java b/src/test/java/puzzles/treetent/rules/LastCampingSpotDirectRuleTest.java
index 92d6e4a59..ad4559922 100644
--- a/src/test/java/puzzles/treetent/rules/LastCampingSpotDirectRuleTest.java
+++ b/src/test/java/puzzles/treetent/rules/LastCampingSpotDirectRuleTest.java
@@ -26,13 +26,17 @@ public static void setUp() {
treetent = new TreeTent();
}
- /**
- * @throws InvalidFileFormatException
- *
Checks if a test works for an empty square above a tree which is surrounded on all
- * other sides.
- */
- @Test
- public void EmptyFieldTest_Up() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests LastCampingSpotDirectRule
+ *
TREE at (1, 1) and (0, 1); GRASS at (1, 2) and (2, 1)
+ * XTX
+ * RRG
+ * XGX
+ *
Makes (1, 0) TENT
+ * Checks that a tent must be placed above the central tree
+ */
+ @Test
+ public void EmptyFieldTest_Up() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/LastCampingSpotDirectRule/LastCampingSpotUp", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
@@ -60,13 +64,17 @@ public void EmptyFieldTest_Up() throws InvalidFileFormatException {
}
}
- /**
- * @throws InvalidFileFormatException
- *
Checks if a test works for an empty square below a tree which is surrounded on all
- * other sides.
- */
- @Test
- public void EmptyFieldTest_Down() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests LastCampingSpotDirectRule
+ *
TREE at (1, 1) and (0, 1); GRASS at (1, 0) and (1, 2)
+ * XGX
+ * RRG
+ * XTX
+ *
Makes (1, 2) TENT
+ * Checks that a tent must be placed below the central tree
+ */
+ @Test
+ public void EmptyFieldTest_Down() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/LastCampingSpotDirectRule/LastCampingSpotDown", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
@@ -94,13 +102,17 @@ public void EmptyFieldTest_Down() throws InvalidFileFormatException {
}
}
- /**
- * @throws InvalidFileFormatException
- *
Checks if a test works for an empty square to the left of a tree which is surrounded
- * on all other sides.
- */
- @Test
- public void EmptyFieldTest_Left() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests LastCampingSpotDirectRule
+ *
TREE at (1, 1) and (2, 1); GRASS at (1, 0) and (1, 2)
+ * XGX
+ * TRR
+ * XGX
+ *
Makes (0, 1) TENT
+ * Checks that a tent must be placed on the left of the central tree
+ */
+ @Test
+ public void EmptyFieldTest_Left() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/LastCampingSpotDirectRule/LastCampingSpotLeft", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
@@ -128,13 +140,17 @@ public void EmptyFieldTest_Left() throws InvalidFileFormatException {
}
}
- /**
- * @throws InvalidFileFormatException
- *
Checks if a test works for an empty square to the right of a tree which is surrounded
- * on all other sides.
- */
- @Test
- public void EmptyFieldTest_Right() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests LastCampingSpotDirectRule
+ *
TREE at (1, 1) and (1, 2); GRASS at (0, 1) and (1, 0)
+ * XGX
+ * GRT
+ * XRX
+ *
Makes (2, 1) TENT
+ * Checks that a tent must be placed to the right of the central tree
+ */
+ @Test
+ public void EmptyFieldTest_Right() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/LastCampingSpotDirectRule/LastCampingSpotRight", treetent);
TreeNode rootNode = treetent.getTree().getRootNode();
diff --git a/src/test/java/puzzles/treetent/rules/LinkTentCaseRuleTest.java b/src/test/java/puzzles/treetent/rules/LinkTentCaseRuleTest.java
new file mode 100644
index 000000000..3ed1fd79e
--- /dev/null
+++ b/src/test/java/puzzles/treetent/rules/LinkTentCaseRuleTest.java
@@ -0,0 +1,191 @@
+package puzzles.treetent.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.tree.Tree;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.treetent.*;
+import edu.rpi.legup.puzzle.treetent.rules.LinkTentCaseRule;
+import edu.rpi.legup.save.InvalidFileFormatException;
+import legup.MockGameBoardFacade;
+import legup.TestUtilities;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.LinkedList;
+
+public class LinkTentCaseRuleTest {
+ private static final LinkTentCaseRule RULE = new LinkTentCaseRule();
+ private static TreeTent treetent;
+
+ @BeforeClass
+ public static void setUp() {
+ MockGameBoardFacade.getInstance();
+ treetent = new TreeTent();
+ }
+
+ /**
+ * empty 3x3 TreeTent puzzle Tests LinkTentCaseRule on a central tent
+ * with one tree surrounding it.
+ *
+ *
checks that 1 cases is with the line connecting the central tent and the tree
+ *
+ * @throws InvalidFileFormatException
+ */
+ @Test
+ public void LinkTentOneTreeTest() throws InvalidFileFormatException {
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/LinkTentCaseRule/OneTreeOneTent", treetent);
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+ TreeTentCell test_location = board.getCell(1, 1);
+ ArrayList cases = RULE.getCases(board, test_location);
+
+ // assert that one cases was found
+ Assert.assertEquals(1, cases.size());
+ TreeTentBoard testCase = (TreeTentBoard) cases.getFirst();
+
+ TreeTentLine expectedLine = new TreeTentLine(board.getCell(1, 1), board.getCell(1, 0));
+
+ ArrayList lines = testCase.getLines();
+
+ // One line connecting the tree to the tent
+ Assert.assertEquals(1, lines.size());
+ TreeTentLine line = lines.getFirst();
+
+ // Expected line
+ Assert.assertTrue(line.compare(expectedLine));
+
+ // checks other cells have not been modified
+ TreeTentCell original_cell;
+ TreeTentCell case_cell;
+
+ for (int w = 0; w < board.getWidth(); w++) {
+ for (int h = 0; h < board.getHeight(); h++) {
+ original_cell = board.getCell(w, h);
+ case_cell = testCase.getCell(w, h);
+ Assert.assertEquals(original_cell.getType(), case_cell.getType());
+ }
+ }
+ }
+
+ /**
+ * empty 3x3 TreeTent puzzle Tests LinkTentCaseRule on a central tent
+ * with four trees surrounding it.
+ *
+ * checks that 4 cases are created, each of which create a line
+ * connecting the tent to one of the four trees without repeat.
+ *
+ * @throws InvalidFileFormatException
+ */
+ @Test
+ public void LinkTentFourTreesTest() throws InvalidFileFormatException {
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/LinkTentCaseRule/FourTreesOneTent", treetent);
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+ TreeTentCell test_location = board.getCell(1, 1);
+ ArrayList cases = RULE.getCases(board, test_location);
+
+ // assert that four cases were found
+ Assert.assertEquals(4, cases.size());
+
+ ArrayList expectedLines = new ArrayList<>();
+ expectedLines.addFirst(new TreeTentLine(board.getCell(1, 1), board.getCell(1, 0)));
+ expectedLines.addFirst(new TreeTentLine(board.getCell(1, 1), board.getCell(0, 1)));
+ expectedLines.addFirst(new TreeTentLine(board.getCell(1, 1), board.getCell(2, 1)));
+ expectedLines.addFirst(new TreeTentLine(board.getCell(1, 1), board.getCell(1, 2)));
+
+ for (Board testCaseBoard : cases) {
+ TreeTentBoard testCase = (TreeTentBoard) testCaseBoard ;
+ ArrayList lines = testCase.getLines();
+
+ // Each case should connect one line from the tent to
+ // one of the four trees next to it
+ Assert.assertEquals(1, lines.size());
+ TreeTentLine line = lines.getFirst();
+
+ // Check to make sure that cases do not repeat
+ // and cover all four possibilities
+ boolean exists = false;
+ for (TreeTentLine expectedLine : expectedLines) {
+ if (line.compare(expectedLine)) {
+ expectedLines.remove(expectedLine);
+ exists = true;
+ break;
+ }
+ }
+
+ Assert.assertTrue(exists);
+
+ // checks other cells have not been modified
+ TreeTentCell original_cell;
+ TreeTentCell case_cell;
+
+ for (int w = 0; w < board.getWidth(); w++) {
+ for (int h = 0; h < board.getHeight(); h++) {
+ original_cell = board.getCell(w, h);
+ case_cell = testCase.getCell(w, h);
+ Assert.assertEquals(original_cell.getType(), case_cell.getType());
+ }
+ }
+ }
+ }
+
+ /**
+ * empty 3x3 TreeTent puzzle Tests LinkTentCaseRule on a central tent
+ * with zero trees around it.
+ *
+ * Ensures no cases are created
+ *
+ * @throws InvalidFileFormatException
+ */
+ @Test
+ public void LinkTentNoTreesTest() throws InvalidFileFormatException {
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/LinkTentCaseRule/NoTrees", treetent);
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+ TreeTentCell test_location = board.getCell(1, 1);
+ ArrayList cases = RULE.getCases(board, test_location);
+
+ // assert that no cases were found
+ Assert.assertEquals(0, cases.size());
+ }
+
+ /**
+ * empty 3x3 TreeTent puzzle Tests LinkTentCaseRule on a central tent
+ * with trees on a diagonal.
+ *
+ * Ensures no cases are created
+ *
+ * @throws InvalidFileFormatException
+ */
+ @Test
+ public void LinkTentDiagTreesTest() throws InvalidFileFormatException {
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/LinkTentCaseRule/DiagTrees", treetent);
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+ TreeTentCell test_location = board.getCell(1, 1);
+ ArrayList cases = RULE.getCases(board, test_location);
+
+ // assert that no cases were found
+ Assert.assertEquals(0, cases.size());
+ }
+}
diff --git a/src/test/java/puzzles/treetent/rules/LinkTreeCaseRuleTest.java b/src/test/java/puzzles/treetent/rules/LinkTreeCaseRuleTest.java
new file mode 100644
index 000000000..fffde14b1
--- /dev/null
+++ b/src/test/java/puzzles/treetent/rules/LinkTreeCaseRuleTest.java
@@ -0,0 +1,192 @@
+package puzzles.treetent.rules;
+
+import com.sun.source.doctree.LinkTree;
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.treetent.TreeTent;
+import edu.rpi.legup.puzzle.treetent.TreeTentBoard;
+import edu.rpi.legup.puzzle.treetent.TreeTentCell;
+import edu.rpi.legup.puzzle.treetent.TreeTentLine;
+import edu.rpi.legup.puzzle.treetent.rules.LinkTreeCaseRule;
+import edu.rpi.legup.save.InvalidFileFormatException;
+import legup.MockGameBoardFacade;
+import legup.TestUtilities;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.ArrayList;
+
+public class LinkTreeCaseRuleTest {
+ private static final LinkTreeCaseRule RULE = new LinkTreeCaseRule();
+ private static TreeTent treetent;
+
+ @BeforeClass
+ public static void setUp() {
+ MockGameBoardFacade.getInstance();
+ treetent = new TreeTent();
+ }
+
+ /**
+ * empty 3x3 TreeTent puzzle Tests LinkTentCaseRule on a central tree
+ * with one tent above
+ *
+ * Ensures one case is created that connects the tree to the tent.
+ *
+ * @throws InvalidFileFormatException
+ */
+ @Test
+ public void LinkTentOneTentTest() throws InvalidFileFormatException {
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/LinkTreeCaseRule/OneTent", treetent);
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+ TreeTentCell test_location = board.getCell(1, 1);
+ ArrayList cases = RULE.getCases(board, test_location);
+
+ // assert that no cases were found
+ Assert.assertEquals(1, cases.size());
+ TreeTentBoard testCase = (TreeTentBoard) cases.getFirst();
+
+ TreeTentLine expectedLine = new TreeTentLine(board.getCell(1, 1), board.getCell(1, 0));
+
+ ArrayList lines = testCase.getLines();
+
+ // One line connecting the tree to the tent
+ Assert.assertEquals(1, lines.size());
+ TreeTentLine line = lines.getFirst();
+
+ // Expected line
+ Assert.assertTrue(line.compare(expectedLine));
+
+ // checks other cells have not been modified
+ TreeTentCell original_cell;
+ TreeTentCell case_cell;
+
+ for (int w = 0; w < board.getWidth(); w++) {
+ for (int h = 0; h < board.getHeight(); h++) {
+ original_cell = board.getCell(w, h);
+ case_cell = testCase.getCell(w, h);
+ Assert.assertEquals(original_cell.getType(), case_cell.getType());
+ }
+ }
+ }
+
+ /**
+ * empty 3x3 TreeTent puzzle Tests LinkTentCaseRule on a central tree
+ * with two tents, one on the left and one on the right.
+ *
+ * Ensures two cases are created, one connecting the tree and the
+ * left tent, and one connecting the tree and the right tent.
+ * Because tents must be surrounded by grass, there can be at most
+ * two tents around a given tree.
+ *
+ * @throws InvalidFileFormatException
+ */
+ @Test
+ public void LinkTentTwoTentsTest() throws InvalidFileFormatException {
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/LinkTreeCaseRule/TwoTents", treetent);
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+ TreeTentCell test_location = board.getCell(1, 1);
+ ArrayList cases = RULE.getCases(board, test_location);
+
+ // assert that no cases were found
+ Assert.assertEquals(2, cases.size());
+
+ ArrayList expectedLines = new ArrayList<>();
+ expectedLines.addFirst(new TreeTentLine(board.getCell(1, 1), board.getCell(0, 1)));
+ expectedLines.addFirst(new TreeTentLine(board.getCell(1, 1), board.getCell(2, 1)));
+
+ for (Board testCaseBoard : cases) {
+ TreeTentBoard testCase = (TreeTentBoard) testCaseBoard ;
+ ArrayList lines = testCase.getLines();
+
+ // Each case should connect one line from the tent to
+ // either the left or right tree
+ Assert.assertEquals(1, lines.size());
+ TreeTentLine line = lines.getFirst();
+
+ // Check to make sure that cases do not repeat
+ // and cover both possibilities
+ boolean exists = false;
+ for (TreeTentLine expectedLine : expectedLines) {
+ if (line.compare(expectedLine)) {
+ expectedLines.remove(expectedLine);
+ exists = true;
+ break;
+ }
+ }
+
+ Assert.assertTrue(exists);
+
+ // checks other cells have not been modified
+ TreeTentCell original_cell;
+ TreeTentCell case_cell;
+
+ for (int w = 0; w < board.getWidth(); w++) {
+ for (int h = 0; h < board.getHeight(); h++) {
+ original_cell = board.getCell(w, h);
+ case_cell = testCase.getCell(w, h);
+ Assert.assertEquals(original_cell.getType(), case_cell.getType());
+ }
+ }
+ }
+ }
+
+ /**
+ * empty 3x3 TreeTent puzzle Tests LinkTentCaseRule on a central tree
+ * with zero tents around it.
+ *
+ * Ensures no cases are created
+ *
+ * @throws InvalidFileFormatException
+ */
+ @Test
+ public void LinkTentNoTreesTest() throws InvalidFileFormatException {
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/LinkTreeCaseRule/NoTents", treetent);
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+ TreeTentCell test_location = board.getCell(1, 1);
+ ArrayList cases = RULE.getCases(board, test_location);
+
+ // assert that no cases were found
+ Assert.assertEquals(0, cases.size());
+ }
+
+ /**
+ * empty 3x3 TreeTent puzzle Tests LinkTentCaseRule on a central tree
+ * with tents on a diagonal.
+ *
+ * Ensures no cases are created
+ *
+ * @throws InvalidFileFormatException
+ */
+ @Test
+ public void LinkTentDiagTentsTest() throws InvalidFileFormatException {
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/LinkTreeCaseRule/NoTents", treetent);
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+ TreeTentCell test_location = board.getCell(1, 1);
+ ArrayList cases = RULE.getCases(board, test_location);
+
+ // assert that no cases were found
+ Assert.assertEquals(0, cases.size());
+ }
+}
diff --git a/src/test/java/puzzles/treetent/rules/SurroundTentWithGrassDirectRuleTest.java b/src/test/java/puzzles/treetent/rules/SurroundTentWithGrassDirectRuleTest.java
index 7ff57a052..6177bb64c 100644
--- a/src/test/java/puzzles/treetent/rules/SurroundTentWithGrassDirectRuleTest.java
+++ b/src/test/java/puzzles/treetent/rules/SurroundTentWithGrassDirectRuleTest.java
@@ -27,12 +27,17 @@ public static void setUp() {
treetent = new TreeTent();
}
- /**
- * @throws InvalidFileFormatException Test to check if all adjacent and diagonals not filled
- * with a tree are filled with grass
- */
- @Test
- public void SurroundTentWithGrassBasicRuleTest() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests SurroundTentWithGrassDirectRule
+ * TREE at (0, 0), (2, 0), (0, 1), (2, 1), (1, 2), and (2, 2); TENT at (1, 1)
+ * RGR
+ * RTR
+ * GRR
+ *
Makes (1, 0) and (0, 2) GRASS
+ * Checks that the rule detects unknown adjacent and diagonal tiles correctly
+ */
+ @Test
+ public void SurroundTentWithGrassBasicRuleTest() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/SurroundTentWithGrassDirectRule/SurroundTentWithGrass",
treetent);
@@ -64,14 +69,17 @@ public void SurroundTentWithGrassBasicRuleTest() throws InvalidFileFormatExcepti
}
}
- /**
- * @throws InvalidFileFormatException
- *
Test with a 3x3 board with an absolutely empty area aside from a tent in the middle
- * While such a situation is an illegal treetent setup, this direct rule doesn't consider
- * that aspect, so its ok in this context
- */
- @Test
- public void SurroundTentWithGrassBasicRuleTest_BadBoard() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests SurroundTentWithGrassDirectRule
+ *
TENT at (1, 1)
+ * GGG
+ * GTG
+ * GGG
+ *
Makes all cells adjacent and diagonal to the tent GRASS
+ * Checks that the rule detects all adjacent and diagonal tiles correctly
+ */
+ @Test
+ public void SurroundTentWithGrassBasicRuleTest_BadBoard() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/SurroundTentWithGrassDirectRule/SurroundTentWithGrassBad",
treetent);
@@ -129,13 +137,17 @@ public void SurroundTentWithGrassBasicRuleTest_BadBoard() throws InvalidFileForm
}
}
- /**
- * @throws InvalidFileFormatException
- *
Test to see if the rule passes even if no grass was able to be placed due to the
- * presence of trees.
- */
- @Test
- public void SurroundTentWithGrassBasicRuleTest_FullBoard() throws InvalidFileFormatException {
+ /**
+ * 3x3 TreeTent puzzle Tests SurroundTentWithGrassDirectRule
+ *
TENT at (1, 1); TREE on all adjacent and diagonal tiles
+ * RRR
+ * RTR
+ * RRR
+ *
Null
+ * Checks that the rule correctly detects no missing tiles
+ */
+ @Test
+ public void SurroundTentWithGrassBasicRuleTest_FullBoard() throws InvalidFileFormatException {
TestUtilities.importTestBoard(
"puzzles/treetent/rules/SurroundTentWithGrassDirectRule/SurroundTentWithGrassTrees",
treetent);
diff --git a/src/test/java/puzzles/treetent/rules/TentForTreeDirectRuleTest.java b/src/test/java/puzzles/treetent/rules/TentForTreeDirectRuleTest.java
index 68dbeaf48..e55704ec2 100644
--- a/src/test/java/puzzles/treetent/rules/TentForTreeDirectRuleTest.java
+++ b/src/test/java/puzzles/treetent/rules/TentForTreeDirectRuleTest.java
@@ -1,14 +1,167 @@
package puzzles.treetent.rules;
-// This feature is no longer supported
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.treetent.*;
+import edu.rpi.legup.puzzle.treetent.rules.TentForTreeDirectRule;
+import edu.rpi.legup.save.InvalidFileFormatException;
+import legup.MockGameBoardFacade;
+import legup.TestUtilities;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.ArrayList;
+
public class TentForTreeDirectRuleTest {
- // private static final TentForTreeBasicRule RULE = new TentForTreeBasicRule();
- // private static TreeTent treetent;
- //
- // @BeforeClass
- // public static void setUp() {
- // MockGameBoardFacade.getInstance();
- // treetent = new TreeTent();
- // }
+ private static final TentForTreeDirectRule RULE = new TentForTreeDirectRule();
+ private static TreeTent treetent;
+
+ @BeforeClass
+ public static void setUp() {
+ MockGameBoardFacade.getInstance();
+ treetent = new TreeTent();
+ }
+
+ /**
+ * 3x3 TreeTent puzzle Tests TentForTreeDirectRule
+ *
TREE at (1, 0); TENT at (1, 1)
+ * XRX
+ * XTX
+ * XXX
+ *
Makes a line between (1, 0) and (1, 1)
+ * Checks that the rule correctly detects the central tent as the only possible connection
+ */
+ @Test
+ public void TentForTreeTestOneTreeOneTentTest() throws InvalidFileFormatException {
+
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/TentForTreeDirectRule/OneTreeOneTent",
+ treetent);
+
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+
+ TreeTentCell cell1 = board.getCell(1, 0);
+ TreeTentCell cell2 = board.getCell(1, 1);
+ TreeTentLine line = new TreeTentLine(cell1, cell2);
+
+ board.addModifiedData(line);
+ board.getLines().add(line);
+
+ Assert.assertNull(RULE.checkRule(transition));
+
+ ArrayList lines = board.getLines();
+ for (TreeTentLine l : lines) {
+ if (l.compare((line))) {
+ Assert.assertNull(RULE.checkRuleAt(transition, l));
+ } else {
+ Assert.assertNotNull(RULE.checkRuleAt(transition, l));
+ }
+ }
+ }
+
+ /**
+ * 3x3 TreeTent puzzle Tests TentForTreeDirectRule
+ * TREE at (1, 0) and (1, 2); TENT at (1, 1)
+ * XRX
+ * XTX
+ * XRX
+ *
Makes a line between (1, 0) and (1, 1)
+ * Checks that the rule works when connecting a line between the tree at (1, 0) and tent at (1, 1)
+ */
+ @Test
+ public void TentForTreeArbitraryTreeTest() throws InvalidFileFormatException {
+
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/TentForTreeDirectRule/ArbitraryTree",
+ treetent);
+
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+
+ TreeTentCell cell1 = board.getCell(1, 0);
+ TreeTentCell cell2 = board.getCell(1, 1);
+ TreeTentLine line = new TreeTentLine(cell1, cell2);
+
+ board.addModifiedData(line);
+ board.getLines().add(line);
+
+ Assert.assertNull(RULE.checkRule(transition));
+ }
+
+ /**
+ * 3x3 TreeTent puzzle Tests TentForTreeDirectRule
+ *
TREE at (1, 0) and (1, 2); TENT at (1, 1); LINE between (1, 0) and (1, 1)
+ * XRX
+ * XTX
+ * XRX
+ *
Makes a line between (1, 1) and (1, 2)
+ * Checks that the rule fails for the tree at (1, 2) because there are no valid tents to connect to
+ */
+ @Test
+ public void TentForTreeConnectedTent() throws InvalidFileFormatException {
+
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/TentForTreeDirectRule/ArbitraryTree",
+ treetent);
+
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+
+ TreeTentCell cell1 = board.getCell(1, 2);
+ TreeTentCell cell2 = board.getCell(1, 1);
+ TreeTentLine line = new TreeTentLine(cell1, cell2);
+
+ board.addModifiedData(line);
+ board.getLines().add(line);
+
+ Assert.assertNull(RULE.checkRule(transition));
+
+ ArrayList lines = board.getLines();
+ for (TreeTentLine l : lines) {
+ Assert.assertNotNull(RULE.checkRuleAt(transition, l));
+ }
+ }
+
+ /**
+ * 3x3 TreeTent puzzle Tests TentForTreeDirectRule
+ * TREE at (1, 1); TENT at (1, 0) and (1, 2)
+ * XTX
+ * XRX
+ * XTX
+ *
Makes a line between (1, 1) and (1, 2)
+ * Checks that the rule fails for the tree at (1, 1) because there are two valid tents to connect to
+ */
+ @Test
+ public void TentForTreeOneTreeTwoAdjacentTent() throws InvalidFileFormatException {
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/TentForTreeDirectRule/OneTreeTwoAdjacentTent",
+ treetent);
+
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+
+ TreeTentCell cell1 = board.getCell(1, 2);
+ TreeTentCell cell2 = board.getCell(1, 1);
+ TreeTentLine line = new TreeTentLine(cell1, cell2);
+
+ board.addModifiedData(line);
+ board.getLines().add(line);
+
+ Assert.assertNotNull(RULE.checkRule(transition));
+ }
}
diff --git a/src/test/java/puzzles/treetent/rules/TooManyTentsContradictionRuleTest.java b/src/test/java/puzzles/treetent/rules/TooManyTentsContradictionRuleTest.java
index 2e542b3d2..c1dc6380a 100644
--- a/src/test/java/puzzles/treetent/rules/TooManyTentsContradictionRuleTest.java
+++ b/src/test/java/puzzles/treetent/rules/TooManyTentsContradictionRuleTest.java
@@ -29,7 +29,7 @@ public static void setUp() {
TESTING BASIS:
All test in this Rule use a 3x3 table.
There is a Tree at (1,1)
- There are tents at (0,1) and (2,2)
+ There are tents at (1,0) and (2,2)
All Tent Counts are listed left to right or top to bottom
*/
diff --git a/src/test/java/puzzles/treetent/rules/TouchingTentsContradictionRuleTest.java b/src/test/java/puzzles/treetent/rules/TouchingTentsContradictionRuleTest.java
index 9f5455a92..e44543ab6 100644
--- a/src/test/java/puzzles/treetent/rules/TouchingTentsContradictionRuleTest.java
+++ b/src/test/java/puzzles/treetent/rules/TouchingTentsContradictionRuleTest.java
@@ -135,90 +135,6 @@ public void TouchingTentsContradictionRule_2By2Square() throws InvalidFileFormat
Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(1, 1)));
}
- /**
- * @throws InvalidFileFormatException Tests a tent of orientation TT T
- */
- @Test
- public void TouchingTentsContradictionRule_UpLeft() throws InvalidFileFormatException {
- TestUtilities.importTestBoard(
- "puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedUpLeft",
- treetent);
- TreeNode rootNode = treetent.getTree().getRootNode();
- TreeTransition transition = rootNode.getChildren().get(0);
- transition.setRule(RULE);
-
- TreeTentBoard board = (TreeTentBoard) transition.getBoard();
-
- Assert.assertNull(RULE.checkContradiction(board));
- Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(0, 0)));
- Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(0, 1)));
- Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(1, 0)));
- Assert.assertNotNull(RULE.checkRuleAt(transition, board.getCell(1, 1)));
- }
-
- /**
- * @throws InvalidFileFormatException Tests a tent of orientation TT T
- */
- @Test
- public void TouchingTentsContradictionRule_UpRight() throws InvalidFileFormatException {
- TestUtilities.importTestBoard(
- "puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedUpRight",
- treetent);
- TreeNode rootNode = treetent.getTree().getRootNode();
- TreeTransition transition = rootNode.getChildren().get(0);
- transition.setRule(RULE);
-
- TreeTentBoard board = (TreeTentBoard) transition.getBoard();
-
- Assert.assertNull(RULE.checkContradiction(board));
- Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(0, 0)));
- Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(0, 1)));
- Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(1, 1)));
- Assert.assertNotNull(RULE.checkRuleAt(transition, board.getCell(1, 0)));
- }
-
- /**
- * @throws InvalidFileFormatException Tests a tent of orientation T TT
- */
- @Test
- public void TouchingTentsContradictionRule_DownLeft() throws InvalidFileFormatException {
- TestUtilities.importTestBoard(
- "puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedDownLeft",
- treetent);
- TreeNode rootNode = treetent.getTree().getRootNode();
- TreeTransition transition = rootNode.getChildren().get(0);
- transition.setRule(RULE);
-
- TreeTentBoard board = (TreeTentBoard) transition.getBoard();
-
- Assert.assertNull(RULE.checkContradiction(board));
- Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(0, 0)));
- Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(1, 0)));
- Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(1, 1)));
- Assert.assertNotNull(RULE.checkRuleAt(transition, board.getCell(0, 1)));
- }
-
- /**
- * @throws InvalidFileFormatException Tests a tent of orientation T TT
- */
- @Test
- public void TouchingTentsContradictionRule_DownRight() throws InvalidFileFormatException {
- TestUtilities.importTestBoard(
- "puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedDownRight",
- treetent);
- TreeNode rootNode = treetent.getTree().getRootNode();
- TreeTransition transition = rootNode.getChildren().get(0);
- transition.setRule(RULE);
-
- TreeTentBoard board = (TreeTentBoard) transition.getBoard();
-
- Assert.assertNull(RULE.checkContradiction(board));
- Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(0, 1)));
- Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(1, 0)));
- Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(1, 1)));
- Assert.assertNotNull(RULE.checkRuleAt(transition, board.getCell(0, 0)));
- }
-
/**
* @throws InvalidFileFormatException Tests if tree adjacent triggers a null
*/
@@ -254,6 +170,6 @@ public void TouchingTentsContradictionRule_TreeDiagonal() throws InvalidFileForm
Assert.assertNotNull(RULE.checkContradiction(board));
Assert.assertNotNull(RULE.checkRuleAt(transition, board.getCell(0, 0)));
- Assert.assertNotNull(RULE.checkRuleAt(transition, board.getCell(1, 0)));
+ Assert.assertNotNull(RULE.checkRuleAt(transition, board.getCell(1, 1)));
}
}
diff --git a/src/test/java/puzzles/treetent/rules/TreeForTentDirectRuleTest.java b/src/test/java/puzzles/treetent/rules/TreeForTentDirectRuleTest.java
index f4ea6703b..ba1b49b8c 100644
--- a/src/test/java/puzzles/treetent/rules/TreeForTentDirectRuleTest.java
+++ b/src/test/java/puzzles/treetent/rules/TreeForTentDirectRuleTest.java
@@ -1,14 +1,161 @@
package puzzles.treetent.rules;
-// This feature is no longer supported
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.treetent.TreeTent;
+import edu.rpi.legup.puzzle.treetent.TreeTentBoard;
+import edu.rpi.legup.puzzle.treetent.TreeTentCell;
+import edu.rpi.legup.puzzle.treetent.TreeTentLine;
+import edu.rpi.legup.puzzle.treetent.rules.TreeForTentDirectRule;
+import edu.rpi.legup.save.InvalidFileFormatException;
+import legup.MockGameBoardFacade;
+import legup.TestUtilities;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.ArrayList;
+
public class TreeForTentDirectRuleTest {
- // private static final TreeForTentBasicRule RULE = new TreeForTentBasicRule();
- // private static TreeTent treetent;
+ private static final TreeForTentDirectRule RULE = new TreeForTentDirectRule();
+ private static TreeTent treetent;
+
+ @BeforeClass
+ public static void setUp() {
+ MockGameBoardFacade.getInstance();
+ treetent = new TreeTent();
+ }
+
+ /**
+ * 3x3 TreeTent puzzle Tests TreeForTentDirectRule
+ *
TENT at (1, 0); TREE at (1, 1)
+ * XTX
+ * XRX
+ * XXX
+ *
Makes a line between (1, 0) and (1, 1)
+ * Checks that the rule correctly detects the central tree as the only possible connection
+ */
+ @Test
+ public void TreeForTentTestOneTreeOneTentTest() throws InvalidFileFormatException {
+
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/TreeForTentDirectRule/OneTentOneTree",
+ treetent);
+
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+
+ TreeTentCell cell1 = board.getCell(1, 0);
+ TreeTentCell cell2 = board.getCell(1, 1);
+ TreeTentLine line = new TreeTentLine(cell1, cell2);
+
+ board.addModifiedData(line);
+ board.getLines().add(line);
+
+ Assert.assertNull(RULE.checkRule(transition));
+ }
+
+ /**
+ * 3x3 TreeTent puzzle Tests TreeForTentDirectRule
+ *
TENT at (1, 0) and (1, 2); TREE at (1, 1)
+ * XTX
+ * XRX
+ * XTX
+ *
Makes a line between (1, 0) and (1, 1)
+ * Checks that the rule works when connecting a line between the tent at (1, 0) and the tree at (1, 1)
+ */
+ @Test
+ public void TentForTreeWithArbitraryTreeTest() throws InvalidFileFormatException {
+
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/TreeForTentDirectRule/ArbitraryTent",
+ treetent);
+
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+
+ TreeTentCell cell1 = board.getCell(1, 0);
+ TreeTentCell cell2 = board.getCell(1, 1);
+ TreeTentLine line = new TreeTentLine(cell1, cell2);
+
+ board.addModifiedData(line);
+ board.getLines().add(line);
+
+ Assert.assertNull(RULE.checkRule(transition));
+ }
+
+ /**
+ * 3x3 TreeTent puzzle Tests TreeForTentDirectRule
+ *
TENT at (1, 0) and (1, 2); TREE at (1, 1); LINE between (1, 0) and (1, 1)
+ * XTX
+ * XRX
+ * XTX
+ *
Makes a line between (1, 1) and (1, 2)
+ * Checks that the rule fails for the tent at (1, 2) because there are no valid trees to connect to
+ */
+ @Test
+ public void TentForTreeConnectedTent() throws InvalidFileFormatException {
+
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/TreeForTentDirectRule/ConnectedTree",
+ treetent);
+
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+
+ TreeTentCell cell1 = board.getCell(1, 2);
+ TreeTentCell cell2 = board.getCell(1, 1);
+ TreeTentLine line = new TreeTentLine(cell1, cell2);
+
+ board.addModifiedData(line);
+ board.getLines().add(line);
+
+ Assert.assertNull(RULE.checkRule(transition));
+
+ ArrayList lines = board.getLines();
+ for (TreeTentLine l : lines) {
+ Assert.assertNotNull(RULE.checkRuleAt(transition, l));
+ }
+ }
+
+ /**
+ * 3x3 TreeTent puzzle Tests TreeForTentDirectRule
+ * TENT at (1, 1); TREE at (1, 0) and (1, 2)
+ * XRX
+ * XTX
+ * XRX
+ *
Makes a line between (1, 1) and (1, 2)
+ * Checks that the rule fails for the tree at (1, 1) because there are two valid trees to connect to
+ */
+ @Test
+ public void TentForTreeOneTreeTwoAdjacentTent() throws InvalidFileFormatException {
+ TestUtilities.importTestBoard(
+ "puzzles/treetent/rules/TreeForTentDirectRule/OneTentTwoAdjacentTrees",
+ treetent);
+
+ TreeNode rootNode = treetent.getTree().getRootNode();
+ TreeTransition transition = rootNode.getChildren().get(0);
+ transition.setRule(RULE);
+
+ TreeTentBoard board = (TreeTentBoard) transition.getBoard();
+
+ TreeTentCell cell1 = board.getCell(1, 2);
+ TreeTentCell cell2 = board.getCell(1, 1);
+ TreeTentLine line = new TreeTentLine(cell1, cell2);
+
+ board.addModifiedData(line);
+ board.getLines().add(line);
- // @BeforeClass
- // public static void setUp() {
- // MockGameBoardFacade.getInstance();
- // treetent = new TreeTent();
- // }
+ Assert.assertNotNull(RULE.checkRule(transition));
+ }
}
diff --git a/src/test/resources/puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailLeft b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3OneTent
similarity index 78%
rename from src/test/resources/puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailLeft
rename to src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3OneTent
index d19e01daf..1e1259a44 100644
--- a/src/test/resources/puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailLeft
+++ b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3OneTent
@@ -2,16 +2,15 @@
- |
-
+
-
+
diff --git a/src/test/resources/puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailRight b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3ThreeTent
similarity index 78%
rename from src/test/resources/puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailRight
rename to src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3ThreeTent
index bf3954964..7c352347d 100644
--- a/src/test/resources/puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailRight
+++ b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3ThreeTent
@@ -2,16 +2,15 @@
- |
-
+
-
+
diff --git a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedDownLeft b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3TwoTent
similarity index 57%
rename from src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedDownLeft
rename to src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3TwoTent
index af4ca0831..1f4a907eb 100644
--- a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedDownLeft
+++ b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3TwoTent
@@ -1,18 +1,17 @@
-
+
- |
- |
- |
-
+
+
-
+
+
diff --git a/src/test/resources/puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailBottom b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3ZeroTent
similarity index 92%
rename from src/test/resources/puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailBottom
rename to src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3ZeroTent
index 80deadaea..a13c7cc55 100644
--- a/src/test/resources/puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailBottom
+++ b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3ZeroTent
@@ -2,7 +2,6 @@
- |
diff --git a/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow5x5TwoTent b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow5x5TwoTent
new file mode 100644
index 000000000..ddfcf44db
--- /dev/null
+++ b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow5x5TwoTent
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/PartialFillOneTent b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/PartialFillOneTent
new file mode 100644
index 000000000..47d06d5b9
--- /dev/null
+++ b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/PartialFillOneTent
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/DiagTrees b/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/DiagTrees
new file mode 100644
index 000000000..4a10b61f2
--- /dev/null
+++ b/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/DiagTrees
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/FourTreesOneTent b/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/FourTreesOneTent
new file mode 100644
index 000000000..96a06de3b
--- /dev/null
+++ b/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/FourTreesOneTent
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/NoTrees b/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/NoTrees
new file mode 100644
index 000000000..c781cfde9
--- /dev/null
+++ b/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/NoTrees
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/OneTreeOneTent b/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/OneTreeOneTent
new file mode 100644
index 000000000..103c1ce3e
--- /dev/null
+++ b/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/OneTreeOneTent
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/DiagTents b/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/DiagTents
new file mode 100644
index 000000000..e50bef8c1
--- /dev/null
+++ b/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/DiagTents
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/NoTents b/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/NoTents
new file mode 100644
index 000000000..3bab63f75
--- /dev/null
+++ b/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/NoTents
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/OneTent b/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/OneTent
new file mode 100644
index 000000000..69eb680de
--- /dev/null
+++ b/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/OneTent
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/TwoTents b/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/TwoTents
new file mode 100644
index 000000000..7fb4b6e46
--- /dev/null
+++ b/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/TwoTents
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/ArbitraryTree b/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/ArbitraryTree
new file mode 100644
index 000000000..258ebec21
--- /dev/null
+++ b/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/ArbitraryTree
@@ -0,0 +1,28 @@
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/ConnectedTent b/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/ConnectedTent
new file mode 100644
index 000000000..031bca068
--- /dev/null
+++ b/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/ConnectedTent
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/OneTreeOneTent b/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/OneTreeOneTent
new file mode 100644
index 000000000..dcc428c8b
--- /dev/null
+++ b/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/OneTreeOneTent
@@ -0,0 +1,28 @@
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/OneTreeTwoAdjacentTent b/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/OneTreeTwoAdjacentTent
new file mode 100644
index 000000000..508cda0a8
--- /dev/null
+++ b/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/OneTreeTwoAdjacentTent
@@ -0,0 +1,28 @@
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedDownRight b/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedDownRight
deleted file mode 100644
index 05b7a7667..000000000
--- a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedDownRight
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
- |
- |
- |
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedUpLeft b/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedUpLeft
deleted file mode 100644
index b8b81c7b4..000000000
--- a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedUpLeft
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
- |
- |
- |
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedUpRight b/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedUpRight
deleted file mode 100644
index af7fb5df2..000000000
--- a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedUpRight
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
- |
- |
- |
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsTreeDiagonal b/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsTreeDiagonal
index b2f54aef3..b25eb6c4c 100644
--- a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsTreeDiagonal
+++ b/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsTreeDiagonal
@@ -3,7 +3,7 @@
|
- |
+ |
diff --git a/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/ArbitraryTent b/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/ArbitraryTent
new file mode 100644
index 000000000..ce083cfc0
--- /dev/null
+++ b/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/ArbitraryTent
@@ -0,0 +1,28 @@
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/ConnectedTree b/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/ConnectedTree
new file mode 100644
index 000000000..6ebecc06f
--- /dev/null
+++ b/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/ConnectedTree
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/OneTentOneTree b/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/OneTentOneTree
new file mode 100644
index 000000000..fabfe06e2
--- /dev/null
+++ b/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/OneTentOneTree
@@ -0,0 +1,28 @@
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/OneTentTwoAdjacentTrees b/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/OneTentTwoAdjacentTrees
new file mode 100644
index 000000000..8218fb2f1
--- /dev/null
+++ b/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/OneTentTwoAdjacentTrees
@@ -0,0 +1,28 @@
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file