defaultPreferencesMap = new HashMap<>();
@@ -26,7 +31,6 @@ public class LegupPreferences {
public static final String IMMEDIATE_FEEDBACK = "immediate-feedback";
public static final String COLOR_BLIND = "color-blind";
-
static {
defaultPreferencesMap.put(WORK_DIRECTORY, System.getProperty("user.home"));
defaultPreferencesMap.put(START_FULL_SCREEN, Boolean.toString(false));
@@ -41,22 +45,42 @@ public class LegupPreferences {
}
static {
- preferencesMap.put(WORK_DIRECTORY, preferences.get(WORK_DIRECTORY, defaultPreferencesMap.get(WORK_DIRECTORY)));
- preferencesMap.put(START_FULL_SCREEN, preferences.get(START_FULL_SCREEN, defaultPreferencesMap.get(START_FULL_SCREEN)));
- preferencesMap.put(AUTO_UPDATE, preferences.get(AUTO_UPDATE, defaultPreferencesMap.get(AUTO_UPDATE)));
- preferencesMap.put(DARK_MODE, preferences.get(DARK_MODE, defaultPreferencesMap.get(DARK_MODE)));
- preferencesMap.put(SHOW_MISTAKES, preferences.get(SHOW_MISTAKES, defaultPreferencesMap.get(SHOW_MISTAKES)));
- preferencesMap.put(SHOW_ANNOTATIONS, preferences.get(SHOW_ANNOTATIONS, defaultPreferencesMap.get(SHOW_ANNOTATIONS)));
- preferencesMap.put(ALLOW_DEFAULT_RULES, preferences.get(ALLOW_DEFAULT_RULES, defaultPreferencesMap.get(ALLOW_DEFAULT_RULES)));
- preferencesMap.put(AUTO_GENERATE_CASES, preferences.get(AUTO_GENERATE_CASES, defaultPreferencesMap.get(AUTO_GENERATE_CASES)));
- preferencesMap.put(IMMEDIATE_FEEDBACK, preferences.get(IMMEDIATE_FEEDBACK, defaultPreferencesMap.get(IMMEDIATE_FEEDBACK)));
- preferencesMap.put(COLOR_BLIND, preferences.get(COLOR_BLIND, defaultPreferencesMap.get(COLOR_BLIND)));
+ preferencesMap.put(
+ WORK_DIRECTORY,
+ preferences.get(WORK_DIRECTORY, defaultPreferencesMap.get(WORK_DIRECTORY)));
+ preferencesMap.put(
+ START_FULL_SCREEN,
+ preferences.get(START_FULL_SCREEN, defaultPreferencesMap.get(START_FULL_SCREEN)));
+ preferencesMap.put(
+ AUTO_UPDATE, preferences.get(AUTO_UPDATE, defaultPreferencesMap.get(AUTO_UPDATE)));
+ preferencesMap.put(
+ DARK_MODE, preferences.get(DARK_MODE, defaultPreferencesMap.get(DARK_MODE)));
+ preferencesMap.put(
+ SHOW_MISTAKES,
+ preferences.get(SHOW_MISTAKES, defaultPreferencesMap.get(SHOW_MISTAKES)));
+ preferencesMap.put(
+ SHOW_ANNOTATIONS,
+ preferences.get(SHOW_ANNOTATIONS, defaultPreferencesMap.get(SHOW_ANNOTATIONS)));
+ preferencesMap.put(
+ ALLOW_DEFAULT_RULES,
+ preferences.get(
+ ALLOW_DEFAULT_RULES, defaultPreferencesMap.get(ALLOW_DEFAULT_RULES)));
+ preferencesMap.put(
+ AUTO_GENERATE_CASES,
+ preferences.get(
+ AUTO_GENERATE_CASES, defaultPreferencesMap.get(AUTO_GENERATE_CASES)));
+ preferencesMap.put(
+ IMMEDIATE_FEEDBACK,
+ preferences.get(IMMEDIATE_FEEDBACK, defaultPreferencesMap.get(IMMEDIATE_FEEDBACK)));
+ preferencesMap.put(
+ COLOR_BLIND, preferences.get(COLOR_BLIND, defaultPreferencesMap.get(COLOR_BLIND)));
}
/**
- * Gets the legup preferences singleton instance.
+ * Gets the legup preferences singleton instance
+ * This method ensures that only one instance of LegupPreferences exists
*
- * @return legup preferences
+ * @return the singleton instance of LegupPreferences
*/
public static LegupPreferences getInstance() {
if (instance == null) {
@@ -66,52 +90,65 @@ public static LegupPreferences getInstance() {
}
/**
- * Private LegupPreferences Singleton Constructor
+ * Private constructor to prevent instantiation from outside the class
+ * Use {@link #getInstance()} to access the singleton instance
*/
- private LegupPreferences() {
-
- }
+ private LegupPreferences() {}
/**
* Gets the user preference by the string key
*
* @param key key name of the preference
- * @return value of the preference
+ * @return value of the preference or {@code null} if the preference does not exist
*/
public String getUserPref(String key) {
return preferencesMap.get(key);
}
/**
- * Gets the user preference by the string key, value pair
+ * Sets the user preference for the specified key to the provided value
*
- * @param key key name of the preference
- * @param value value of the preference
+ * @param key key to set for the preference
+ * @param value value to set for the preference
*/
public void setUserPref(String key, String value) {
preferences.put(key, value);
preferencesMap.put(key, value);
}
+ /**
+ * Retrieves the user preference associated with the specified key as a boolean
+ *
+ * @param key the key for the preference to retrieve
+ * @return the boolean value of the preference
+ * @throws RuntimeException if the preference value cannot be interpreted as a boolean
+ */
public boolean getUserPrefAsBool(String key) {
if (preferencesMap.get(key).equalsIgnoreCase(Boolean.toString(true))) {
return true;
- }
- else {
+ } else {
if (preferencesMap.get(key).equalsIgnoreCase(Boolean.toString(false))) {
return false;
- }
- else {
+ } else {
throw new RuntimeException("Cannot get user preference - " + key);
}
}
}
-
+ /**
+ * Gets the saved path
+ *
+ * @return the saved path as a String
+ */
public String getSavedPath() {
return SAVED_PATH;
}
+ /**
+ * Sets the saved path to the specified value
+ *
+ * @param path the new saved path
+ */
public void setSavedPath(String path) {
SAVED_PATH = path;
}
diff --git a/src/main/java/edu/rpi/legup/app/PuzzleKeyAccelerator.java b/src/main/java/edu/rpi/legup/app/PuzzleKeyAccelerator.java
index 36ffb08aa..f3945be22 100644
--- a/src/main/java/edu/rpi/legup/app/PuzzleKeyAccelerator.java
+++ b/src/main/java/edu/rpi/legup/app/PuzzleKeyAccelerator.java
@@ -1,22 +1,21 @@
package edu.rpi.legup.app;
+import static edu.rpi.legup.app.GameBoardFacade.getInstance;
+
import edu.rpi.legup.history.ICommand;
-import edu.rpi.legup.history.ValidateDirectRuleCommand;
import edu.rpi.legup.history.ValidateContradictionRuleCommand;
-import edu.rpi.legup.model.rules.DirectRule;
+import edu.rpi.legup.history.ValidateDirectRuleCommand;
import edu.rpi.legup.model.rules.ContradictionRule;
+import edu.rpi.legup.model.rules.DirectRule;
import edu.rpi.legup.model.rules.Rule;
import edu.rpi.legup.model.rules.RuleType;
import edu.rpi.legup.ui.proofeditorui.treeview.TreeView;
import edu.rpi.legup.ui.proofeditorui.treeview.TreeViewSelection;
-
-import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.HashMap;
import java.util.Map;
-
-import static edu.rpi.legup.app.GameBoardFacade.getInstance;
+import javax.swing.*;
public class PuzzleKeyAccelerator implements KeyListener {
@@ -39,21 +38,17 @@ public void clearKeyMap() {
}
/**
- * Invoked when a key has been typed.
- * See the class description for {@link KeyEvent} for a definition of
- * a key typed event.
+ * Invoked when a key has been typed. See the class description for {@link KeyEvent} for a
+ * definition of a key typed event.
*
* @param e the event to be processed
*/
@Override
- public void keyTyped(KeyEvent e) {
-
- }
+ public void keyTyped(KeyEvent e) {}
/**
- * Invoked when a key has been pressed.
- * See the class description for {@link KeyEvent} for a definition of
- * a key pressed event.
+ * Invoked when a key has been pressed. See the class description for {@link KeyEvent} for a
+ * definition of a key pressed event.
*
* @param e the event to be processed
*/
@@ -62,35 +57,35 @@ public void keyPressed(KeyEvent e) {
KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(e);
Rule rule = keyStrokeMap.get(keyStroke);
if (rule != null) {
- TreeView treeView = GameBoardFacade.getInstance().getLegupUI().getTreePanel().getTreeView();
+ TreeView treeView =
+ GameBoardFacade.getInstance().getLegupUI().getTreePanel().getTreeView();
String update = "";
if (rule.getRuleType() == RuleType.CASE) {
- // TODO: review this line of code and figure out what it's supposed to do (remove if necessary)
-// handleCaseRule((CaseRule)rule);
- }
- else {
+ // TODO: review this line of code and figure out what it's supposed to do (remove if
+ // necessary)
+ // handleCaseRule((CaseRule)rule);
+ } else {
if (rule.getRuleType() == RuleType.CONTRADICTION) {
TreeViewSelection selection = treeView.getSelection();
- ICommand validate = new ValidateContradictionRuleCommand(selection, (ContradictionRule) rule);
+ ICommand validate =
+ new ValidateContradictionRuleCommand(
+ selection, (ContradictionRule) rule);
if (validate.canExecute()) {
getInstance().getHistory().pushChange(validate);
validate.execute();
- }
- else {
+ } else {
update = validate.getError();
}
- }
- else {
+ } else {
TreeViewSelection selection = treeView.getSelection();
ICommand validate = new ValidateDirectRuleCommand(selection, (DirectRule) rule);
if (validate.canExecute()) {
getInstance().getHistory().pushChange(validate);
validate.execute();
- }
- else {
+ } else {
update = validate.getError();
}
}
@@ -100,14 +95,11 @@ public void keyPressed(KeyEvent e) {
}
/**
- * Invoked when a key has been released.
- * See the class description for {@link KeyEvent} for a definition of
- * a key released event.
+ * Invoked when a key has been released. See the class description for {@link KeyEvent} for a
+ * definition of a key released event.
*
* @param e the event to be processed
*/
@Override
- public void keyReleased(KeyEvent e) {
-
- }
+ public void keyReleased(KeyEvent e) {}
}
diff --git a/src/main/java/edu/rpi/legup/controller/BoardController.java b/src/main/java/edu/rpi/legup/controller/BoardController.java
index f9c328a99..eaae3851d 100644
--- a/src/main/java/edu/rpi/legup/controller/BoardController.java
+++ b/src/main/java/edu/rpi/legup/controller/BoardController.java
@@ -3,16 +3,13 @@
import java.awt.*;
import java.awt.event.*;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
public class BoardController extends Controller {
protected Point lastLeftMousePoint;
protected Point lastRightMousePoint;
/**
- * BoardController Constructor creates a controller object to listen
- * to ui events from a ScrollView
+ * BoardController Constructor creates a controller object to listen to ui events from a
+ * ScrollView
*/
public BoardController() {
super();
@@ -26,13 +23,10 @@ public BoardController() {
* @param e MouseEvent object
*/
@Override
- public void mouseClicked(MouseEvent e) {
-
- }
+ public void mouseClicked(MouseEvent e) {}
/**
- * Mouse Pressed event - sets the cursor to the move cursor and stores
- * info for possible panning
+ * Mouse Pressed event - sets the cursor to the move cursor and stores info for possible panning
*
* @param e MouseEvent object
*/
@@ -42,8 +36,7 @@ public void mousePressed(MouseEvent e) {
}
/**
- * Mouse Released event - sets the cursor back to the default cursor and reset
- * info for panning
+ * Mouse Released event - sets the cursor back to the default cursor and reset info for panning
*
* @param e MouseEvent object
*/
@@ -58,9 +51,7 @@ public void mouseReleased(MouseEvent e) {
* @param e MouseEvent object
*/
@Override
- public void mouseEntered(MouseEvent e) {
-
- }
+ public void mouseEntered(MouseEvent e) {}
/**
* Mouse Exited event - no default action
@@ -68,9 +59,7 @@ public void mouseEntered(MouseEvent e) {
* @param e MouseEvent object
*/
@Override
- public void mouseExited(MouseEvent e) {
-
- }
+ public void mouseExited(MouseEvent e) {}
/**
* Mouse Dragged event - adjusts the viewport
@@ -88,9 +77,7 @@ public void mouseDragged(MouseEvent e) {
* @param e MouseEvent object
*/
@Override
- public void mouseMoved(MouseEvent e) {
-
- }
+ public void mouseMoved(MouseEvent e) {}
/**
* Mouse Wheel Moved event - zooms in on the viewport
diff --git a/src/main/java/edu/rpi/legup/controller/Controller.java b/src/main/java/edu/rpi/legup/controller/Controller.java
index 5eef8cc17..47ef70e17 100644
--- a/src/main/java/edu/rpi/legup/controller/Controller.java
+++ b/src/main/java/edu/rpi/legup/controller/Controller.java
@@ -1,24 +1,33 @@
package edu.rpi.legup.controller;
import edu.rpi.legup.ui.ScrollView;
-
-import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
+import javax.swing.*;
+/**
+ * {@code Controller} is an abstract class designed to handle various mouse events and provide control functionality for a {@code ScrollView}.
+ * It implements several mouse event interfaces to manage interactions such as panning and zooming within a {@code ScrollView}
+ */
public abstract class Controller implements MouseMotionListener, MouseListener, MouseWheelListener {
protected ScrollView viewer;
private int x, y;
private boolean pan;
/**
- * Controller Constructor creates a controller object to listen to ui events from a {@link ScrollView}
+ * Controller Constructor creates a controller object to listen to ui events from a {@link
+ * ScrollView}
*/
public Controller() {
x = y = -1;
pan = false;
}
+ /**
+ * Sets the ScrollView instance that this controller manages
+ *
+ * @param viewer The ScrollView instance to be set
+ */
public void setViewer(ScrollView viewer) {
this.viewer = viewer;
}
@@ -29,13 +38,10 @@ public void setViewer(ScrollView viewer) {
* @param e MouseEvent object
*/
@Override
- public void mouseClicked(MouseEvent e) {
-
- }
+ public void mouseClicked(MouseEvent e) {}
/**
- * Mouse Pressed event sets the cursor to the move cursor and stores
- * info for possible panning
+ * Mouse Pressed event sets the cursor to the move cursor and stores info for possible panning
*
* @param e MouseEvent object
*/
@@ -50,8 +56,7 @@ public void mousePressed(MouseEvent e) {
}
/**
- * Mouse Released event sets the cursor back to the default cursor and reset
- * info for panning
+ * Mouse Released event sets the cursor back to the default cursor and reset info for panning
*
* @param e MouseEvent object
*/
@@ -69,9 +74,7 @@ public void mouseReleased(MouseEvent e) {
* @param e MouseEvent object
*/
@Override
- public void mouseEntered(MouseEvent e) {
-
- }
+ public void mouseEntered(MouseEvent e) {}
/**
* Mouse Exited event no default action
@@ -79,9 +82,7 @@ public void mouseEntered(MouseEvent e) {
* @param e MouseEvent object
*/
@Override
- public void mouseExited(MouseEvent e) {
-
- }
+ public void mouseExited(MouseEvent e) {}
/**
* Mouse Dragged event adjusts the viewport
@@ -106,9 +107,7 @@ public void mouseDragged(MouseEvent e) {
* @param e MouseEvent object
*/
@Override
- public void mouseMoved(MouseEvent e) {
-
- }
+ public void mouseMoved(MouseEvent e) {}
/**
* Mouse Wheel Moved event zooms in on the viewport
@@ -122,11 +121,10 @@ public void mouseWheelMoved(MouseWheelEvent e) {
if (e.getWheelRotation() != 0) {
viewer.zoom(e.getWheelRotation() * 2, e.getPoint());
}
- }
- else {
+ } else {
if (e.getWheelRotation() != 0) {
viewer.zoom(e.getWheelRotation(), e.getPoint());
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/controller/CursorController.java b/src/main/java/edu/rpi/legup/controller/CursorController.java
index 0c9a644ed..6a3ab018d 100644
--- a/src/main/java/edu/rpi/legup/controller/CursorController.java
+++ b/src/main/java/edu/rpi/legup/controller/CursorController.java
@@ -2,15 +2,18 @@
import java.awt.Component;
import java.awt.Cursor;
-import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Timer;
import java.util.TimerTask;
+/**
+ * {@code CursorController} provides functionality for managing the cursor appearance during actions that take a certain amount of time.
+ * It allows for the display of a busy cursor while an action is being processed and reverts to the default cursor afterward
+ */
public class CursorController {
public static final Cursor BUSY_CURSOR = new Cursor(Cursor.WAIT_CURSOR);
public static final Cursor DEFAULT_CURSOR = new Cursor(Cursor.DEFAULT_CURSOR);
- public static final int DELAY = 200; // in milliseconds
+ public static final int DELAY = 200; // in milliseconds
private CursorController() {
// Intentionally left empty
@@ -18,36 +21,38 @@ private CursorController() {
/**
* Creates an ActionListener that will still do the same action processing as the given
- * ActionListener while also displaying a loading cursor if the time it takes to execute
- * the given process exceeds the time (in milliseconds) specified in this.DELAY
- *
- * Sources consulted: http://www.catalysoft.com/articles/busycursor.html
+ * ActionListener while also displaying a loading cursor if the time it takes to execute the
+ * given process exceeds the time (in milliseconds) specified in this.DELAY
*
- * @param component The component you want to set the cursor for
+ *
Sources consulted: http://www.catalysoft.com/articles/busycursor.html
+ *
+ * @param component The component you want to set the cursor for
* @param mainActionListener The ActionListener that does the intended action processing
- * @return An ActionListener object that does the same action processing
- * as mainActionListener while also modifying the cursor if needed
+ * @return An ActionListener object that does the same action processing as mainActionListener
+ * while also modifying the cursor if needed
*/
- public static ActionListener createListener(final Component component, final ActionListener mainActionListener) {
- ActionListener actionListener = e -> {
- TimerTask timerTask = new TimerTask() {
- @Override
- public void run() {
- component.setCursor(BUSY_CURSOR);
- }
- };
+ public static ActionListener createListener(
+ final Component component, final ActionListener mainActionListener) {
+ ActionListener actionListener =
+ e -> {
+ TimerTask timerTask =
+ new TimerTask() {
+ @Override
+ public void run() {
+ component.setCursor(BUSY_CURSOR);
+ }
+ };
- Timer timer = new Timer();
- try {
- timer.schedule(timerTask, DELAY);
- mainActionListener.actionPerformed(e);
- }
- finally {
- timer.cancel();
- component.setCursor(DEFAULT_CURSOR);
- }
- };
+ Timer timer = new Timer();
+ try {
+ timer.schedule(timerTask, DELAY);
+ mainActionListener.actionPerformed(e);
+ } finally {
+ timer.cancel();
+ component.setCursor(DEFAULT_CURSOR);
+ }
+ };
return actionListener;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/controller/EditorElementController.java b/src/main/java/edu/rpi/legup/controller/EditorElementController.java
index 80e7dd35a..040610137 100644
--- a/src/main/java/edu/rpi/legup/controller/EditorElementController.java
+++ b/src/main/java/edu/rpi/legup/controller/EditorElementController.java
@@ -1,32 +1,18 @@
package edu.rpi.legup.controller;
-import edu.rpi.legup.app.GameBoardFacade;
-import edu.rpi.legup.app.LegupPreferences;
import edu.rpi.legup.history.*;
-import edu.rpi.legup.model.Puzzle;
import edu.rpi.legup.model.elements.Element;
-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.*;
-import edu.rpi.legup.model.tree.TreeElement;
-import edu.rpi.legup.model.tree.TreeElementType;
-import edu.rpi.legup.ui.proofeditorui.rulesview.RuleButton;
-import edu.rpi.legup.ui.proofeditorui.treeview.TreeElementView;
-import edu.rpi.legup.ui.proofeditorui.treeview.TreePanel;
-import edu.rpi.legup.ui.proofeditorui.treeview.TreeView;
-import edu.rpi.legup.ui.proofeditorui.treeview.TreeViewSelection;
import edu.rpi.legup.ui.puzzleeditorui.elementsview.ElementButton;
-
-import javax.swing.*;
-import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.util.List;
-
-import static edu.rpi.legup.app.GameBoardFacade.getInstance;
+import javax.swing.*;
+/**
+ * {@code EditorElementController} manages actions related to UI elements within the puzzle editor environment.
+ * It handles button presses, updates element selection, and manages visual states of buttons
+ */
public class EditorElementController implements ActionListener {
protected Object lastSource;
protected ElementController elementController;
@@ -38,19 +24,33 @@ public EditorElementController() {
prevButton = null;
}
+ /**
+ * Sets the ElementController instance for this controller
+ *
+ * @param elementController the ElementController instance to be set
+ */
public void setElementController(ElementController elementController) {
this.elementController = elementController;
}
+ /**
+ * Handles the event when a button associated with an Element is pressed
+ *
+ * @param element the Element associated with the button that was pressed
+ */
public void buttonPressed(Element element) {
// TODO: implement what happens when element is pressed
- System.out.printf("%s button pressed!\n", element.getElementName());
if (elementController != null) {
elementController.setSelectedElement(element);
}
}
+ /**
+ * Handles action events triggered by buttons
+ *
+ * @param e the event to be processed
+ */
@Override
public void actionPerformed(ActionEvent e) {
lastSource = e.getSource();
@@ -66,6 +66,5 @@ public void actionPerformed(ActionEvent e) {
button.setBorderToSelected();
this.prevButton = button;
-
}
}
diff --git a/src/main/java/edu/rpi/legup/controller/ElementController.java b/src/main/java/edu/rpi/legup/controller/ElementController.java
index 50fa7d1b9..436b078b9 100644
--- a/src/main/java/edu/rpi/legup/controller/ElementController.java
+++ b/src/main/java/edu/rpi/legup/controller/ElementController.java
@@ -1,10 +1,12 @@
package edu.rpi.legup.controller;
-import edu.rpi.legup.puzzle.treetent.TreeTentBoard;
-import edu.rpi.legup.ui.ScrollView;
+import static edu.rpi.legup.app.GameBoardFacade.*;
+
import edu.rpi.legup.app.GameBoardFacade;
import edu.rpi.legup.app.LegupPreferences;
import edu.rpi.legup.history.AutoCaseRuleCommand;
+import edu.rpi.legup.history.EditDataCommand;
+import edu.rpi.legup.history.ICommand;
import edu.rpi.legup.model.Puzzle;
import edu.rpi.legup.model.elements.Element;
import edu.rpi.legup.model.gameboard.Board;
@@ -14,26 +16,28 @@
import edu.rpi.legup.model.tree.TreeElement;
import edu.rpi.legup.model.tree.TreeElementType;
import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.treetent.TreeTentBoard;
import edu.rpi.legup.ui.DynamicView;
import edu.rpi.legup.ui.boardview.BoardView;
import edu.rpi.legup.ui.boardview.ElementSelection;
import edu.rpi.legup.ui.boardview.ElementView;
import edu.rpi.legup.ui.boardview.SelectionItemView;
import edu.rpi.legup.ui.proofeditorui.treeview.*;
-import edu.rpi.legup.history.ICommand;
-import edu.rpi.legup.history.EditDataCommand;
-
import java.awt.*;
import java.awt.event.*;
-import static edu.rpi.legup.app.GameBoardFacade.*;
-
-public class ElementController implements MouseListener, MouseMotionListener, ActionListener, KeyListener {
+/**
+ * The ElementController class manages UI interactions related to elements in a {@link BoardView}.
+ * It handles mouse events, key events, and actions related to element selection and manipulation
+ */
+public class ElementController
+ implements MouseListener, MouseMotionListener, ActionListener, KeyListener {
protected BoardView boardView;
private Element selectedElement;
/**
- * ElementController Constructor controller to handles ui events associated interacting with a {@link BoardView}
+ * ElementController Constructor controller to handle ui events associated interacting with a
+ * {@link BoardView}
*/
public ElementController() {
this.boardView = null;
@@ -59,9 +63,7 @@ public void setBoardView(BoardView boardView) {
* @param e the event to be processed
*/
@Override
- public void mouseClicked(MouseEvent e) {
-
- }
+ public void mouseClicked(MouseEvent e) {}
/**
* Invoked when a mouse button has been pressed on a component.
@@ -69,9 +71,7 @@ public void mouseClicked(MouseEvent e) {
* @param e the event to be processed
*/
@Override
- public void mousePressed(MouseEvent e) {
-
- }
+ public void mousePressed(MouseEvent e) {}
/**
* Invoked when a mouse button has been released on a component.
@@ -90,6 +90,7 @@ public void mouseReleased(MouseEvent e) {
if (boardView == null) {
boardView = getInstance().getLegupUI().getEditorBoardView();
}
+
Board board = boardView.getBoard();
ElementView elementView = boardView.getElement(e.getPoint());
TreeViewSelection selection = null;
@@ -100,21 +101,21 @@ public void mouseReleased(MouseEvent e) {
if (elementView != null) {
if (board instanceof CaseBoard) {
CaseBoard caseBoard = (CaseBoard) board;
- AutoCaseRuleCommand autoCaseRuleCommand = new AutoCaseRuleCommand(elementView, selection, caseBoard.getCaseRule(), caseBoard, e);
+ AutoCaseRuleCommand autoCaseRuleCommand =
+ new AutoCaseRuleCommand(
+ elementView, selection, caseBoard.getCaseRule(), caseBoard, e);
if (autoCaseRuleCommand.canExecute()) {
autoCaseRuleCommand.execute();
getInstance().getHistory().pushChange(autoCaseRuleCommand);
if (treePanel != null) {
treePanel.updateError("");
}
- }
- else {
+ } else {
if (treePanel != null) {
treePanel.updateError(autoCaseRuleCommand.getError());
}
}
- }
- else {
+ } else {
if (selection != null) {
ICommand edit = new EditDataCommand(elementView, selection, e);
if (edit.canExecute()) {
@@ -123,8 +124,7 @@ public void mouseReleased(MouseEvent e) {
if (treePanel != null) {
treePanel.updateError("");
}
- }
- else {
+ } else {
if (treePanel != null) {
treePanel.updateError(edit.getError());
}
@@ -132,20 +132,18 @@ public void mouseReleased(MouseEvent e) {
}
}
}
-// if (selectedElement != null) {
+ // if (selectedElement != null) {
GridBoard b = (GridBoard) this.boardView.getBoard();
Point point = e.getPoint();
- Point scaledPoint = new Point((int) Math.floor(point.x / (30 * this.boardView.getScale())), (int) Math.floor(point.y / (30 * this.boardView.getScale())));
+ Point scaledPoint =
+ new Point(
+ (int) Math.floor(point.x / (30 * this.boardView.getScale())),
+ (int) Math.floor(point.y / (30 * this.boardView.getScale())));
if (this.boardView.getBoard() instanceof TreeTentBoard) {
scaledPoint.setLocation(scaledPoint.getX() - 1, scaledPoint.getY() - 1);
}
- System.out.printf("selected Element is NOT null, attempting to change board at (%d, %d)\n", scaledPoint.x, scaledPoint.y);
-// System.out.println("Before: " + b.getCell(scaledPoint.x, scaledPoint.y).getData());
+
b.setCell(scaledPoint.x, scaledPoint.y, this.selectedElement, e);
-// System.out.println("After: " + b.getCell(scaledPoint.x, scaledPoint.y).getData());
-// } else {
-// System.out.println("selected Element is null!");
-// }
boardView.repaint();
}
@@ -175,7 +173,9 @@ public void mouseEntered(MouseEvent e) {
selection.newHover(elementView);
if (LegupPreferences.getInstance().getUserPrefAsBool(LegupPreferences.SHOW_MISTAKES)) {
PuzzleElement element = elementView.getPuzzleElement();
- if (treeElement != null && treeElement.getType() == TreeElementType.TRANSITION && board.getModifiedData().contains(element)) {
+ if (treeElement != null
+ && treeElement.getType() == TreeElementType.TRANSITION
+ && board.getModifiedData().contains(element)) {
TreeTransition transition = (TreeTransition) treeElement;
if (transition.isJustified() && !transition.isCorrect()) {
error = transition.getRule().checkRuleAt(transition, element);
@@ -183,8 +183,7 @@ public void mouseEntered(MouseEvent e) {
}
if (error != null) {
dynamicView.updateError(error);
- }
- else {
+ } else {
dynamicView.resetStatus();
}
}
@@ -222,9 +221,7 @@ public void mouseExited(MouseEvent e) {
* @param e the event to be processed
*/
@Override
- public void mouseDragged(MouseEvent e) {
-
- }
+ public void mouseDragged(MouseEvent e) {}
/**
* Invoked when the mouse moved
@@ -250,7 +247,9 @@ public void mouseMoved(MouseEvent e) {
selection.newHover(elementView);
if (LegupPreferences.getInstance().getUserPrefAsBool(LegupPreferences.SHOW_MISTAKES)) {
PuzzleElement element = elementView.getPuzzleElement();
- if (treeElement != null && treeElement.getType() == TreeElementType.TRANSITION && board.getModifiedData().contains(element)) {
+ if (treeElement != null
+ && treeElement.getType() == TreeElementType.TRANSITION
+ && board.getModifiedData().contains(element)) {
TreeTransition transition = (TreeTransition) treeElement;
if (transition.isJustified() && !transition.isCorrect()) {
error = transition.getRule().checkRuleAt(transition, element);
@@ -258,8 +257,7 @@ public void mouseMoved(MouseEvent e) {
}
if (error != null) {
dynamicView.updateError(error);
- }
- else {
+ } else {
dynamicView.resetStatus();
}
}
@@ -267,9 +265,7 @@ public void mouseMoved(MouseEvent e) {
}
}
- public void changeCell(MouseEvent e, PuzzleElement data) {
-
- }
+ public void changeCell(MouseEvent e, PuzzleElement data) {}
/**
* Invoked when an action occurs.
@@ -299,8 +295,7 @@ public void actionPerformed(ActionEvent e) {
if (puzzleElement.equalsData(prevBord.getPuzzleElement(puzzleElement))) {
puzzleElement.setModified(false);
- }
- else {
+ } else {
puzzleElement.setModified(true);
}
@@ -311,33 +306,26 @@ public void actionPerformed(ActionEvent e) {
}
/**
- * Invoked when a key has been typed.
- * See the class description for {@link KeyEvent} for a definition of
- * a key typed event.
+ * Invoked when a key has been typed. See the class description for {@link KeyEvent} for a
+ * definition of a key typed event.
*
* @param e the event to be processed
*/
@Override
- public void keyTyped(KeyEvent e) {
-
- }
+ public void keyTyped(KeyEvent e) {}
/**
- * Invoked when a key has been pressed.
- * See the class description for {@link KeyEvent} for a definition of
- * a key pressed event.
+ * Invoked when a key has been pressed. See the class description for {@link KeyEvent} for a
+ * definition of a key pressed event.
*
* @param e the event to be processed
*/
@Override
- public void keyPressed(KeyEvent e) {
-
- }
+ public void keyPressed(KeyEvent e) {}
/**
- * Invoked when a key has been released.
- * See the class description for {@link KeyEvent} for a definition of
- * a key released event.
+ * Invoked when a key has been released. See the class description for {@link KeyEvent} for a
+ * definition of a key released event.
*
* @param e the event to be processed
*/
diff --git a/src/main/java/edu/rpi/legup/controller/RuleController.java b/src/main/java/edu/rpi/legup/controller/RuleController.java
index fef6fca45..491e02f74 100644
--- a/src/main/java/edu/rpi/legup/controller/RuleController.java
+++ b/src/main/java/edu/rpi/legup/controller/RuleController.java
@@ -1,5 +1,7 @@
package edu.rpi.legup.controller;
+import static edu.rpi.legup.app.GameBoardFacade.getInstance;
+
import edu.rpi.legup.app.GameBoardFacade;
import edu.rpi.legup.app.LegupPreferences;
import edu.rpi.legup.history.*;
@@ -10,19 +12,21 @@
import edu.rpi.legup.ui.proofeditorui.rulesview.RuleButton;
import edu.rpi.legup.ui.proofeditorui.rulesview.RulePanel;
import edu.rpi.legup.ui.proofeditorui.treeview.*;
-
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
-import static edu.rpi.legup.app.GameBoardFacade.getInstance;
-
+/**
+ * The RuleController class is responsible for handling UI events related to rule buttons
+ * in the RulePanel of the Legup application. It implements ActionListener to process action
+ * events triggered by rule buttons and applies rules to the puzzle accordingly
+ */
public class RuleController implements ActionListener {
protected Object lastSource;
/**
- * RuleController Constructor creates a controller object to listen
- * to ui events from a {@link RulePanel}
+ * RuleController Constructor creates a controller object to listen to ui events from a {@link
+ * RulePanel}
*/
public RuleController() {
super();
@@ -51,56 +55,56 @@ public void buttonPressed(Rule rule) {
if (caseRuleCommand.canExecute()) {
caseRuleCommand.execute();
getInstance().getHistory().pushChange(caseRuleCommand);
- }
- else {
+ } else {
updateErrorString = caseRuleCommand.getError();
}
- }
- else {
- if (LegupPreferences.getInstance().getUserPref(LegupPreferences.AUTO_GENERATE_CASES).equalsIgnoreCase(Boolean.toString(true))) {
+ } else {
+ if (LegupPreferences.getInstance()
+ .getUserPref(LegupPreferences.AUTO_GENERATE_CASES)
+ .equalsIgnoreCase(Boolean.toString(true))) {
CaseBoard caseBoard = caseRule.getCaseBoard(element.getBoard());
if (caseBoard != null && caseBoard.getCount() > 0) {
- puzzle.notifyBoardListeners(listener -> listener.onCaseBoardAdded(caseBoard));
- }
- else {
+ puzzle.notifyBoardListeners(
+ listener -> listener.onCaseBoardAdded(caseBoard));
+ } else {
updateErrorString = "This board cannot be applied with this case rule.";
}
- }
- else {
- updateErrorString = "Auto generated case rules are turned off in preferences.";
+ } else {
+ updateErrorString =
+ "Auto generated case rules are turned off in preferences.";
}
}
- }
- else {
+ } else {
ICommand caseRuleCommand = new ValidateCaseRuleCommand(selection, caseRule);
if (caseRuleCommand.canExecute()) {
caseRuleCommand.execute();
getInstance().getHistory().pushChange(caseRuleCommand);
- }
- else {
+ } else {
updateErrorString = caseRuleCommand.getError();
}
}
- }
- else {
+ } else {
if (rule.getRuleType() == RuleType.CONTRADICTION) {
- ICommand validate = new ValidateContradictionRuleCommand(selection, (ContradictionRule) rule);
+ ICommand validate =
+ new ValidateContradictionRuleCommand(selection, (ContradictionRule) rule);
if (validate.canExecute()) {
getInstance().getHistory().pushChange(validate);
validate.execute();
- }
- else {
+ } else {
updateErrorString = validate.getError();
}
- }
- else {
- boolean def = LegupPreferences.getInstance().getUserPrefAsBool(LegupPreferences.ALLOW_DEFAULT_RULES);
- ICommand validate = def ? new ApplyDefaultDirectRuleCommand(selection, (DirectRule) rule) : new ValidateDirectRuleCommand(selection, (DirectRule) rule);
+ } else {
+ boolean def =
+ LegupPreferences.getInstance()
+ .getUserPrefAsBool(LegupPreferences.ALLOW_DEFAULT_RULES);
+ ICommand validate =
+ def
+ ? new ApplyDefaultDirectRuleCommand(selection, (DirectRule) rule)
+ : new ValidateDirectRuleCommand(selection, (DirectRule) rule);
if (validate.canExecute()) {
getInstance().getHistory().pushChange(validate);
validate.execute();
- }
- else {
+ } else {
updateErrorString = validate.getError();
}
}
diff --git a/src/main/java/edu/rpi/legup/controller/ToolbarController.java b/src/main/java/edu/rpi/legup/controller/ToolbarController.java
index 2ee4ee25e..6cbb5ee60 100644
--- a/src/main/java/edu/rpi/legup/controller/ToolbarController.java
+++ b/src/main/java/edu/rpi/legup/controller/ToolbarController.java
@@ -1,19 +1,15 @@
package edu.rpi.legup.controller;
import edu.rpi.legup.ui.LegupUI;
-
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
public class ToolbarController implements ActionListener {
private LegupUI legupUI;
/**
- * ToolbarController Constructor - creates a new {@link ToolbarController} to listen
- * for button pressed from the tool mBar
+ * ToolbarController Constructor - creates a new {@link ToolbarController} to listen for button
+ * pressed from the tool mBar
*
* @param legupUI legupUI
*/
@@ -27,7 +23,5 @@ public ToolbarController(LegupUI legupUI) {
* @param e action event
*/
@Override
- public void actionPerformed(ActionEvent e) {
-
- }
+ public void actionPerformed(ActionEvent e) {}
}
diff --git a/src/main/java/edu/rpi/legup/controller/TreeController.java b/src/main/java/edu/rpi/legup/controller/TreeController.java
index 6eae4ac3b..2b12268ac 100644
--- a/src/main/java/edu/rpi/legup/controller/TreeController.java
+++ b/src/main/java/edu/rpi/legup/controller/TreeController.java
@@ -1,25 +1,26 @@
package edu.rpi.legup.controller;
+import static edu.rpi.legup.app.GameBoardFacade.getInstance;
+
import edu.rpi.legup.model.Puzzle;
import edu.rpi.legup.model.tree.Tree;
-import edu.rpi.legup.model.tree.TreeElementType;
import edu.rpi.legup.ui.boardview.BoardView;
import edu.rpi.legup.ui.proofeditorui.treeview.*;
-
-import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
+import javax.swing.*;
-import static edu.rpi.legup.app.GameBoardFacade.getInstance;
-
+/**
+ * The TreeController class handles UI events from a TreePanel.
+ * It extends the Controller class to provide specific behavior for tree interactions
+ */
public class TreeController extends Controller {
/**
- * TreeController Constructor creates a controller object to listen to ui events from a {@link TreePanel}
+ * TreeController Constructor creates a controller object to listen to ui events from a {@link
+ * TreePanel}
*/
- public TreeController() {
-
- }
+ public TreeController() {}
/**
* Mouse Clicked event no default action
@@ -27,9 +28,7 @@ public TreeController() {
* @param e MouseEvent object
*/
@Override
- public void mouseClicked(MouseEvent e) {
-
- }
+ public void mouseClicked(MouseEvent e) {}
/**
* Mouse Pressed event sets the cursor to the move cursor and stores info for possible panning
@@ -44,6 +43,7 @@ public void mousePressed(MouseEvent e) {
/**
* Mouse Released event sets the cursor back to the default cursor and reset info for panning
* Set board modifiability
+ *
* @param e MouseEvent object
*/
@Override
@@ -58,19 +58,19 @@ public void mouseReleased(MouseEvent e) {
if (treeElementView != null) {
if (e.isShiftDown()) {
selection.addToSelection(treeElementView);
- }
- else {
+ } else {
if (e.isControlDown()) {
- if (!(selection.getSelectedViews().size() == 1 && treeElementView == selection.getFirstSelection())) {
+ if (!(selection.getSelectedViews().size() == 1
+ && treeElementView == selection.getFirstSelection())) {
selection.toggleSelection(treeElementView);
}
- }
- else {
+ } else {
selection.newSelection(treeElementView);
}
}
puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(selection));
- puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(treeElementView.getTreeElement()));
+ puzzle.notifyBoardListeners(
+ listener -> listener.onTreeElementChanged(treeElementView.getTreeElement()));
}
}
@@ -88,7 +88,8 @@ public void mouseEntered(MouseEvent e) {
TreeElementView treeElementView = treeView.getTreeElementView(point);
Puzzle puzzle = getInstance().getPuzzleModule();
if (treeElementView != null) {
- puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(treeElementView.getTreeElement()));
+ puzzle.notifyBoardListeners(
+ listener -> listener.onTreeElementChanged(treeElementView.getTreeElement()));
}
}
@@ -108,7 +109,8 @@ public void mouseExited(MouseEvent e) {
selection.setMousePoint(null);
if (elementView != null) {
TreeElementView selectedView = selection.getFirstSelection();
- puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(selectedView.getTreeElement()));
+ puzzle.notifyBoardListeners(
+ listener -> listener.onTreeElementChanged(selectedView.getTreeElement()));
}
}
@@ -137,15 +139,20 @@ public void mouseMoved(MouseEvent e) {
TreeViewSelection selection = treeView.getSelection();
selection.setMousePoint(treeView.getActualPoint(e.getPoint()));
if (treeElementView != null && treeElementView != selection.getHover()) {
- puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(treeElementView.getTreeElement()));
+ puzzle.notifyBoardListeners(
+ listener ->
+ listener.onTreeElementChanged(treeElementView.getTreeElement()));
selection.newHover(treeElementView);
puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(selection));
- }
- else {
+ } else {
if (treeElementView == null && selection.getHover() != null) {
- puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(selection.getFirstSelection().getTreeElement()));
+ puzzle.notifyBoardListeners(
+ listener ->
+ listener.onTreeElementChanged(
+ selection.getFirstSelection().getTreeElement()));
selection.clearHover();
- puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(selection));
+ puzzle.notifyTreeListeners(
+ listener -> listener.onTreeSelectionChanged(selection));
}
}
}
diff --git a/src/main/java/edu/rpi/legup/history/AddTreeElementCommand.java b/src/main/java/edu/rpi/legup/history/AddTreeElementCommand.java
index 0aa6f416d..92a887f71 100644
--- a/src/main/java/edu/rpi/legup/history/AddTreeElementCommand.java
+++ b/src/main/java/edu/rpi/legup/history/AddTreeElementCommand.java
@@ -6,11 +6,15 @@
import edu.rpi.legup.ui.proofeditorui.treeview.TreeElementView;
import edu.rpi.legup.ui.proofeditorui.treeview.TreeView;
import edu.rpi.legup.ui.proofeditorui.treeview.TreeViewSelection;
-
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+
+/**
+ * The AddTreeElementCommand class represents a command to add tree elements to the proof tree.
+ * It extends the PuzzleCommand class to handle the addition of tree elements and undo operation.
+ */
public class AddTreeElementCommand extends PuzzleCommand {
private TreeViewSelection selection;
@@ -18,7 +22,8 @@ public class AddTreeElementCommand extends PuzzleCommand {
private Map addChild;
/**
- * AddTreeElementCommand Constructor creates a command for adding a tree element to the proof tree
+ * AddTreeElementCommand Constructor creates a command for adding a tree element to the proof
+ * tree
*
* @param selection selection of tree elements views
*/
@@ -28,7 +33,8 @@ public AddTreeElementCommand(TreeViewSelection selection) {
}
/**
- * Executes an command
+ * Executes the command to add selected tree elements to the tree.
+ * Updates the puzzle and tree view accordingly
*/
@Override
public void executeCommand() {
@@ -43,12 +49,11 @@ public void executeCommand() {
TreeElement child = addChild.get(treeElement);
if (child == null) {
child = tree.addTreeElement(treeElement);
- }
- else {
+ } else {
+
if (treeElement.getType() == TreeElementType.NODE) {
child = tree.addTreeElement((TreeNode) treeElement, (TreeTransition) child);
- }
- else {
+ } else {
child = tree.addTreeElement((TreeTransition) treeElement, (TreeNode) child);
}
}
@@ -69,15 +74,14 @@ public void executeCommand() {
* Gets the reason why the command cannot be executed
*
* @return if command cannot be executed, returns reason for why the command cannot be executed,
- * otherwise null if command can be executed
+ * otherwise null if command can be executed
*/
@Override
public String getErrorString() {
List selectedViews = selection.getSelectedViews();
if (selectedViews.isEmpty()) {
return CommandError.NO_SELECTED_VIEWS.toString();
- }
- else {
+ } else {
for (TreeElementView view : selectedViews) {
TreeElement element = view.getTreeElement();
if (element.getType() == TreeElementType.TRANSITION) {
@@ -85,8 +89,7 @@ public String getErrorString() {
if (transition.getChildNode() != null) {
return CommandError.ADD_WITH_CHILD.toString();
}
- }
- else {
+ } else {
TreeNode node = (TreeNode) element;
if (!node.getChildren().isEmpty()) {
TreeTransition transition = node.getChildren().get(0);
@@ -101,7 +104,8 @@ public String getErrorString() {
}
/**
- * Undoes an command
+ * Undoes the command by removing the added tree elements.
+ * Updates the puzzle and tree view accordingly
*/
@Override
public void undoCommand() {
@@ -119,4 +123,4 @@ public void undoCommand() {
}
puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(newSelection));
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/history/ApplyDefaultDirectRuleCommand.java b/src/main/java/edu/rpi/legup/history/ApplyDefaultDirectRuleCommand.java
index bc4c89741..ad89ab636 100644
--- a/src/main/java/edu/rpi/legup/history/ApplyDefaultDirectRuleCommand.java
+++ b/src/main/java/edu/rpi/legup/history/ApplyDefaultDirectRuleCommand.java
@@ -1,128 +1,140 @@
-package edu.rpi.legup.history;
-
-import edu.rpi.legup.app.GameBoardFacade;
-import edu.rpi.legup.model.Puzzle;
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.rules.DirectRule;
-import edu.rpi.legup.model.tree.*;
-import edu.rpi.legup.ui.proofeditorui.treeview.*;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class ApplyDefaultDirectRuleCommand extends PuzzleCommand {
-
- private TreeViewSelection selection;
- private DirectRule rule;
- private Map addMap;
-
- /**
- * ApplyDefaultDirectRuleCommand Constructor creates a command for applying the default of a basic rule
- *
- * @param selection selection of tree element views
- * @param rule basic rule for the command
- */
- public ApplyDefaultDirectRuleCommand(TreeViewSelection selection, DirectRule rule) {
- this.selection = selection.copy();
- this.rule = rule;
- this.addMap = new HashMap<>();
- }
-
- /**
- * Gets the reason why the command cannot be executed
- *
- * @return if command cannot be executed, returns reason for why the command cannot be executed,
- * otherwise null if command can be executed
- */
- @Override
- public String getErrorString() {
- List selectedViews = selection.getSelectedViews();
- if (selectedViews.isEmpty()) {
- return CommandError.DEFAULT_APPLICATION + " - " + CommandError.NO_SELECTED_VIEWS.toString();
- }
- else {
- for (TreeElementView view : selectedViews) {
- TreeElement element = view.getTreeElement();
- if (element.getType() == TreeElementType.NODE) {
- TreeNode node = (TreeNode) element;
- if (!node.getChildren().isEmpty()) {
- return CommandError.DEFAULT_APPLICATION + " - " + CommandError.NO_CHILDREN.toString();
- }
- else {
- if (rule.getDefaultBoard(node) == null) {
- return CommandError.DEFAULT_APPLICATION + " - " + "This selection contains a tree element that this rule cannot be applied to.";
- }
- }
- }
- else {
- return CommandError.DEFAULT_APPLICATION + " - " + CommandError.SELECTION_CONTAINS_TRANSITION.toString();
- }
- }
- }
- return null;
- }
-
- /**
- * Executes an command
- */
- @Override
- public void executeCommand() {
- Tree tree = GameBoardFacade.getInstance().getTree();
- TreeView treeView = GameBoardFacade.getInstance().getLegupUI().getTreePanel().getTreeView();
- Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule();
- final TreeViewSelection newSelection = new TreeViewSelection();
-
- for (TreeElementView selectedView : selection.getSelectedViews()) {
- TreeNodeView nodeView = (TreeNodeView) selectedView;
- TreeNode node = nodeView.getTreeElement();
- TreeTransition transition = addMap.get(node);
- TreeNode childNode;
- if (transition == null) {
- transition = (TreeTransition) tree.addTreeElement(node);
- childNode = (TreeNode) tree.addTreeElement(transition);
- addMap.put(node, transition);
- }
- else {
- tree.addTreeElement(node, transition);
- childNode = transition.getChildNode();
- }
-
- transition.setRule(rule);
- Board defaultBoard = rule.getDefaultBoard(node);
- transition.setBoard(defaultBoard);
- Board copyBoard = defaultBoard.copy();
- copyBoard.setModifiable(false);
- childNode.setBoard(copyBoard);
-
- final TreeTransition finalTran = transition;
- puzzle.notifyTreeListeners(listener -> listener.onTreeElementAdded(finalTran));
-
- newSelection.addToSelection(treeView.getElementView(childNode));
- }
-
- final TreeElement finalTreeElement = newSelection.getFirstSelection().getTreeElement();
- puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(finalTreeElement));
- puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(newSelection));
- }
-
- /**
- * Undoes an command
- */
- @Override
- public void undoCommand() {
- Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule();
-
- for (TreeElementView selectedView : selection.getSelectedViews()) {
- TreeNodeView nodeView = (TreeNodeView) selectedView;
- TreeNode node = nodeView.getTreeElement();
- final TreeTransition transition = addMap.get(node);
-
- puzzle.notifyTreeListeners(listener -> listener.onTreeElementRemoved(transition));
- }
-
- final TreeElement finalTreeElement = selection.getFirstSelection().getTreeElement();
- puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(finalTreeElement));
- puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(selection));
- }
-}
+package edu.rpi.legup.history;
+
+import edu.rpi.legup.app.GameBoardFacade;
+import edu.rpi.legup.model.Puzzle;
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.rules.DirectRule;
+import edu.rpi.legup.model.tree.*;
+import edu.rpi.legup.ui.proofeditorui.treeview.*;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The ApplyDefaultDirectRuleCommand class represents a command to apply a default direct rule
+ * to selected tree nodes in the proof tree.
+ * It extends the PuzzleCommand class to handle rule application and undo operation.
+ */
+public class ApplyDefaultDirectRuleCommand extends PuzzleCommand {
+
+ private TreeViewSelection selection;
+ private DirectRule rule;
+ private Map addMap;
+
+ /**
+ * ApplyDefaultDirectRuleCommand Constructor creates a command for applying the default of a
+ * basic rule
+ *
+ * @param selection selection of tree element views
+ * @param rule basic rule for the command
+ */
+ public ApplyDefaultDirectRuleCommand(TreeViewSelection selection, DirectRule rule) {
+ this.selection = selection.copy();
+ this.rule = rule;
+ this.addMap = new HashMap<>();
+ }
+
+ /**
+ * Gets the reason why the command cannot be executed
+ *
+ * @return if command cannot be executed, returns reason for why the command cannot be executed,
+ * otherwise null if command can be executed
+ */
+ @Override
+ public String getErrorString() {
+ List selectedViews = selection.getSelectedViews();
+ if (selectedViews.isEmpty()) {
+ return CommandError.DEFAULT_APPLICATION
+ + " - "
+ + CommandError.NO_SELECTED_VIEWS.toString();
+ } else {
+ for (TreeElementView view : selectedViews) {
+ TreeElement element = view.getTreeElement();
+ if (element.getType() == TreeElementType.NODE) {
+ TreeNode node = (TreeNode) element;
+ if (!node.getChildren().isEmpty()) {
+
+ return CommandError.DEFAULT_APPLICATION
+ + " - "
+ + CommandError.NO_CHILDREN.toString();
+ } else {
+ if (rule.getDefaultBoard(node) == null) {
+ return CommandError.DEFAULT_APPLICATION
+ + " - This selection contains a tree element that this rule"
+ + " cannot be applied to.";
+ }
+ }
+ } else {
+ return CommandError.DEFAULT_APPLICATION
+ + " - "
+ + CommandError.SELECTION_CONTAINS_TRANSITION.toString();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Executes the command to apply the default rule to the selected tree nodes.
+ * Updates the puzzle and tree view accordingly.
+ */
+ @Override
+ public void executeCommand() {
+ Tree tree = GameBoardFacade.getInstance().getTree();
+ TreeView treeView = GameBoardFacade.getInstance().getLegupUI().getTreePanel().getTreeView();
+ Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule();
+ final TreeViewSelection newSelection = new TreeViewSelection();
+
+ for (TreeElementView selectedView : selection.getSelectedViews()) {
+ TreeNodeView nodeView = (TreeNodeView) selectedView;
+ TreeNode node = nodeView.getTreeElement();
+ TreeTransition transition = addMap.get(node);
+ TreeNode childNode;
+ if (transition == null) {
+ transition = (TreeTransition) tree.addTreeElement(node);
+ childNode = (TreeNode) tree.addTreeElement(transition);
+ addMap.put(node, transition);
+ } else {
+ tree.addTreeElement(node, transition);
+ childNode = transition.getChildNode();
+ }
+
+ transition.setRule(rule);
+ Board defaultBoard = rule.getDefaultBoard(node);
+ transition.setBoard(defaultBoard);
+ Board copyBoard = defaultBoard.copy();
+ copyBoard.setModifiable(false);
+ childNode.setBoard(copyBoard);
+
+ final TreeTransition finalTran = transition;
+ puzzle.notifyTreeListeners(listener -> listener.onTreeElementAdded(finalTran));
+
+ newSelection.addToSelection(treeView.getElementView(childNode));
+ }
+
+ final TreeElement finalTreeElement = newSelection.getFirstSelection().getTreeElement();
+ puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(finalTreeElement));
+ puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(newSelection));
+ }
+
+ /**
+ * Undoes the command by removing the applied default rule from the tree nodes.
+ * Updates the puzzle and tree view accordingly.
+ */
+ @Override
+ public void undoCommand() {
+ Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule();
+
+ for (TreeElementView selectedView : selection.getSelectedViews()) {
+ TreeNodeView nodeView = (TreeNodeView) selectedView;
+ TreeNode node = nodeView.getTreeElement();
+ final TreeTransition transition = addMap.get(node);
+
+ puzzle.notifyTreeListeners(listener -> listener.onTreeElementRemoved(transition));
+ }
+
+ final TreeElement finalTreeElement = selection.getFirstSelection().getTreeElement();
+ puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(finalTreeElement));
+ puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(selection));
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/history/AutoCaseRuleCommand.java b/src/main/java/edu/rpi/legup/history/AutoCaseRuleCommand.java
index a4c157c77..b86cda6ea 100644
--- a/src/main/java/edu/rpi/legup/history/AutoCaseRuleCommand.java
+++ b/src/main/java/edu/rpi/legup/history/AutoCaseRuleCommand.java
@@ -1,5 +1,7 @@
package edu.rpi.legup.history;
+import static edu.rpi.legup.app.GameBoardFacade.getInstance;
+
import edu.rpi.legup.app.GameBoardFacade;
import edu.rpi.legup.model.Puzzle;
import edu.rpi.legup.model.gameboard.Board;
@@ -8,12 +10,14 @@
import edu.rpi.legup.model.tree.*;
import edu.rpi.legup.ui.boardview.ElementView;
import edu.rpi.legup.ui.proofeditorui.treeview.*;
-
import java.awt.event.MouseEvent;
import java.util.*;
-import static edu.rpi.legup.app.GameBoardFacade.getInstance;
-
+/**
+ * The AutoCaseRuleCommand class represents a command to automatically apply a case rule to a
+ * selected tree node in the proof tree.
+ * It extends the PuzzleCommand class to handle case rule application and undo operation.
+ */
public class AutoCaseRuleCommand extends PuzzleCommand {
private ElementView elementView;
@@ -24,18 +28,21 @@ public class AutoCaseRuleCommand extends PuzzleCommand {
private List caseTrans;
- private static final int MAX_CASES = 10;
-
/**
* AutoCaseRuleCommand Constructor creates a command for validating a case rule
*
* @param elementView currently selected puzzle puzzleElement view that is being edited
- * @param selection currently selected tree puzzleElement views that is being edited
+ * @param selection currently selected tree puzzleElement views that is being edited
* @param caseRule currently selected caseRule puzzleElement view that is being edited
* @param caseBoard currently selected caseBoard puzzleElement view that is being edited
* @param mouseEvent currently selected mouseEvent puzzleElement view that is being edited
*/
- public AutoCaseRuleCommand(ElementView elementView, TreeViewSelection selection, CaseRule caseRule, CaseBoard caseBoard, MouseEvent mouseEvent) {
+ public AutoCaseRuleCommand(
+ ElementView elementView,
+ TreeViewSelection selection,
+ CaseRule caseRule,
+ CaseBoard caseBoard,
+ MouseEvent mouseEvent) {
this.elementView = elementView;
this.selection = selection.copy();
this.caseRule = caseRule;
@@ -45,7 +52,8 @@ public AutoCaseRuleCommand(ElementView elementView, TreeViewSelection selection,
}
/**
- * Executes an command
+ * Executes the command to apply the case rule to the selected tree node.
+ * Updates the puzzle and tree view accordingly.
*/
@Override
public void executeCommand() {
@@ -59,7 +67,7 @@ public void executeCommand() {
List cases = caseRule.getCases(caseBoard.getBaseBoard(), elementView.getPuzzleElement());
for (Board board : cases) {
final TreeTransition transition = (TreeTransition) tree.addTreeElement(node);
- board.setModifiable(false);
+ //board.setModifiable(false);
transition.setBoard(board);
transition.setRule(caseRule);
transition.setSelection(elementView.getPuzzleElement().copy());
@@ -70,8 +78,7 @@ public void executeCommand() {
puzzle.notifyTreeListeners(listener -> listener.onTreeElementAdded(transition));
newSelection.addToSelection(treeView.getElementView(childNode));
}
- }
- else {
+ } else {
for (final TreeTransition transition : caseTrans) {
tree.addTreeElement(node, transition);
TreeNode childNode = transition.getChildNode();
@@ -89,7 +96,7 @@ public void executeCommand() {
* Gets the reason why the command cannot be executed
*
* @return if command cannot be executed, returns reason for why the command cannot be executed,
- * otherwise null if command can be executed
+ * otherwise null if command can be executed
*/
@Override
public String getErrorString() {
@@ -115,15 +122,21 @@ public String getErrorString() {
return "The selection must produce at least one case";
}
- if (caseRule.getCases(caseBoard.getBaseBoard(), elementView.getPuzzleElement()).size() > MAX_CASES) {
- return "The selection can produce a max of " + MAX_CASES + " cases";
+ int numberOfCaseRules = caseRule.getCases(caseBoard.getBaseBoard(), elementView.getPuzzleElement()).size();
+ System.out.println("Number of cases:" + numberOfCaseRules);
+ if (numberOfCaseRules > caseRule.MAX_CASES) {
+ return "The selection can produce a max of " + caseRule.MAX_CASES + " cases";
+ }
+ if (numberOfCaseRules < caseRule.MIN_CASES) {
+ return "The selection must produce a minimum of " + caseRule.MIN_CASES + " cases";
}
return null;
}
/**
- * Undoes an command
+ * Undoes the command by removing the applied case rules from the tree node.
+ * Updates the puzzle and tree view accordingly
*/
@Override
public void undoCommand() {
diff --git a/src/main/java/edu/rpi/legup/history/CommandError.java b/src/main/java/edu/rpi/legup/history/CommandError.java
index 90c9db526..26959cccd 100644
--- a/src/main/java/edu/rpi/legup/history/CommandError.java
+++ b/src/main/java/edu/rpi/legup/history/CommandError.java
@@ -1,11 +1,16 @@
package edu.rpi.legup.history;
+/**
+ * The CommandError enum represents various error conditions that can occur when executing or
+ * validating commands related to tree elements in the proof tree.
+ * Each error condition is associated with a descriptive message.
+ */
public enum CommandError {
-
NO_SELECTED_VIEWS("The selection does not have any tree elements."),
ONE_SELECTED_VIEW("The selection must have exactly one tree element."),
UNMODIFIABLE_BOARD("The selection contains a board which is not modifiable."),
UNMODIFIABLE_DATA("The selection contains a board where the data element is not modifiable."),
+ UNMODIFIABLE_DATA_CASE_RULE("The proof tree contains a future case rule, causing previous transitions to become unmodifiable."),
CONTAINS_ROOT("The selection contains the root tree node."),
ONE_CHILD("The selection contains a tree node that does not have exactly one child."),
ADD_WITH_CHILD("The selection contains a tree transition that already has a child tree node."),
@@ -19,10 +24,20 @@ public enum CommandError {
private String value;
+ /**
+ * Constructs a CommandError with the specified error message
+ *
+ * @param value The error message associated with the command error
+ */
CommandError(String value) {
this.value = value;
}
+ /**
+ * Returns the error message associated with this CommandError
+ *
+ * @return The error message
+ */
@Override
public String toString() {
return value;
diff --git a/src/main/java/edu/rpi/legup/history/CommandState.java b/src/main/java/edu/rpi/legup/history/CommandState.java
index b7c2ff938..326490e28 100644
--- a/src/main/java/edu/rpi/legup/history/CommandState.java
+++ b/src/main/java/edu/rpi/legup/history/CommandState.java
@@ -1,14 +1,31 @@
package edu.rpi.legup.history;
+/**
+ * The CommandState enum represents the various states that a command can be in during its lifecycle.
+ * Each state is associated with a descriptive name.
+ */
public enum CommandState {
- CREATED("Created"), EXECUTED("Executed"), UNDOED("Undoed"), REDOED("Redoed");
+ CREATED("Created"),
+ EXECUTED("Executed"),
+ UNDOED("Undoed"),
+ REDOED("Redoed");
private String value;
+ /**
+ * Constructs a CommandState with the specified state name
+ *
+ * @param value The name associated with the command state
+ */
CommandState(String value) {
this.value = value;
}
+ /**
+ * Returns the name associated with this CommandState
+ *
+ * @return The state name
+ */
@Override
public String toString() {
return value;
diff --git a/src/main/java/edu/rpi/legup/history/DeleteTreeElementCommand.java b/src/main/java/edu/rpi/legup/history/DeleteTreeElementCommand.java
index 80cad9b24..e82197898 100644
--- a/src/main/java/edu/rpi/legup/history/DeleteTreeElementCommand.java
+++ b/src/main/java/edu/rpi/legup/history/DeleteTreeElementCommand.java
@@ -5,14 +5,19 @@
import edu.rpi.legup.model.observer.ITreeListener;
import edu.rpi.legup.model.tree.*;
import edu.rpi.legup.ui.proofeditorui.treeview.*;
-
import java.util.List;
+/**
+ * The DeleteTreeElementCommand class represents a command to delete tree elements from a proof tree.
+ * It extends PuzzleCommand and implements the functionality to remove selected tree elements and
+ * handle undo operations.
+ */
public class DeleteTreeElementCommand extends PuzzleCommand {
private TreeViewSelection selection;
/**
- * DeleteTreeElementCommand Constructor creates a PuzzleCommand for deleting a tree puzzleElement
+ * DeleteTreeElementCommand Constructor creates a PuzzleCommand for deleting a tree
+ * puzzleElement
*
* @param selection the currently selected tree elements before the command is executed
*/
@@ -21,7 +26,7 @@ public DeleteTreeElementCommand(TreeViewSelection selection) {
}
/**
- * Executes an command
+ * Executes the delete command, removing the selected tree elements from the tree.
*/
@Override
public void executeCommand() {
@@ -29,19 +34,24 @@ public void executeCommand() {
Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule();
List selectedViews = selection.getSelectedViews();
+ if (selectedViews.isEmpty()) {
+ return;
+ }
TreeElementView firstSelectedView = selectedViews.get(0);
TreeElementView newSelectedView;
if (firstSelectedView.getType() == TreeElementType.NODE) {
+ //System.out.println("FIRST SELECTION NODE, total selection views: " + selectedViews.size());
TreeNodeView nodeView = (TreeNodeView) firstSelectedView;
newSelectedView = nodeView.getParentView();
- }
- else {
+ } else {
+ //System.out.println("FIRST SELECTION TRANS, total selection views: " + selectedViews.size());
TreeTransitionView transitionView = (TreeTransitionView) firstSelectedView;
newSelectedView = transitionView.getParentViews().get(0);
}
for (TreeElementView selectedView : selectedViews) {
+ System.out.println("DELETED");
TreeElement element = selectedView.getTreeElement();
tree.removeTreeElement(element);
puzzle.notifyTreeListeners(listener -> listener.onTreeElementRemoved(element));
@@ -56,7 +66,7 @@ public void executeCommand() {
* Gets the reason why the command cannot be executed
*
* @return if command cannot be executed, returns reason for why the command cannot be executed,
- * otherwise null if command can be executed
+ * otherwise null if command can be executed
*/
@Override
public String getErrorString() {
@@ -75,7 +85,7 @@ public String getErrorString() {
}
/**
- * Undoes an command
+ * Undoes the delete command, re-adding the previously deleted tree elements.
*/
@Override
public void undoCommand() {
@@ -89,8 +99,7 @@ public void undoCommand() {
node.getParent().setChildNode(node);
puzzle.notifyTreeListeners(listener -> listener.onTreeElementAdded(node));
- }
- else {
+ } else {
TreeTransition transition = (TreeTransition) element;
transition.getParents().forEach(node -> node.addChild(transition));
transition.getParents().get(0).getChildren().forEach(TreeTransition::reverify);
@@ -99,7 +108,10 @@ public void undoCommand() {
}
}
- puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(selection.getFirstSelection().getTreeElement()));
+ puzzle.notifyBoardListeners(
+ listener ->
+ listener.onTreeElementChanged(
+ selection.getFirstSelection().getTreeElement()));
puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(selection));
}
}
diff --git a/src/main/java/edu/rpi/legup/history/EditDataCommand.java b/src/main/java/edu/rpi/legup/history/EditDataCommand.java
index 328cc050d..a629aa085 100644
--- a/src/main/java/edu/rpi/legup/history/EditDataCommand.java
+++ b/src/main/java/edu/rpi/legup/history/EditDataCommand.java
@@ -1,5 +1,7 @@
package edu.rpi.legup.history;
+import static edu.rpi.legup.app.GameBoardFacade.getInstance;
+
import edu.rpi.legup.model.Puzzle;
import edu.rpi.legup.model.gameboard.Board;
import edu.rpi.legup.model.gameboard.PuzzleElement;
@@ -7,13 +9,19 @@
import edu.rpi.legup.model.tree.*;
import edu.rpi.legup.ui.boardview.BoardView;
import edu.rpi.legup.ui.boardview.ElementView;
+import edu.rpi.legup.ui.lookandfeel.materialdesign.MaterialColors;
import edu.rpi.legup.ui.proofeditorui.treeview.*;
+import javax.swing.*;
+import java.awt.*;
import java.awt.event.MouseEvent;
import java.util.List;
-import static edu.rpi.legup.app.GameBoardFacade.getInstance;
-
+/**
+ * The EditDataCommand class represents a command to edit the data of a puzzle element within
+ * a tree transition. It extends PuzzleCommand and provides functionality to execute and undo
+ * changes made to puzzle elements.
+ */
public class EditDataCommand extends PuzzleCommand {
private TreeTransition transition;
private PuzzleElement savePuzzleElement;
@@ -27,8 +35,8 @@ public class EditDataCommand extends PuzzleCommand {
* EditDataCommand Constructor create a puzzle command for editing a board
*
* @param elementView currently selected puzzle puzzleElement view that is being edited
- * @param selection currently selected tree puzzleElement views that is being edited
- * @param event mouse event
+ * @param selection currently selected tree puzzleElement views that are being edited
+ * @param event mouse event
*/
public EditDataCommand(ElementView elementView, TreeViewSelection selection, MouseEvent event) {
this.elementView = elementView;
@@ -40,7 +48,7 @@ public EditDataCommand(ElementView elementView, TreeViewSelection selection, Mou
}
/**
- * Executes a command
+ * Executes the edit data command, modifying the puzzle element and propagating changes
*/
@SuppressWarnings("unchecked")
@Override
@@ -57,33 +65,27 @@ public void executeCommand() {
if (treeElement.getType() == TreeElementType.NODE) {
TreeNode treeNode = (TreeNode) treeElement;
-
if (treeNode.getChildren().isEmpty()) {
if (transition == null) {
transition = tree.addNewTransition(treeNode);
}
puzzle.notifyTreeListeners(listener -> listener.onTreeElementAdded(transition));
}
-
board = transition.getBoard();
-
puzzleElement = board.getPuzzleElement(selectedPuzzleElement);
savePuzzleElement = puzzleElement.copy();
- }
- else {
+ } else {
transition = (TreeTransition) treeElement;
puzzleElement = board.getPuzzleElement(selectedPuzzleElement);
savePuzzleElement = puzzleElement.copy();
}
Board prevBoard = transition.getParents().get(0).getBoard();
-
boardView.getElementController().changeCell(event, puzzleElement);
if (prevBoard.getPuzzleElement(selectedPuzzleElement).equalsData(puzzleElement)) {
board.removeModifiedData(puzzleElement);
- }
- else {
+ } else {
board.addModifiedData(puzzleElement);
}
transition.propagateChange(puzzleElement);
@@ -92,7 +94,8 @@ public void executeCommand() {
puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(finalTreeElement));
puzzle.notifyBoardListeners(listener -> listener.onBoardDataChanged(puzzleElement));
- final TreeViewSelection newSelection = new TreeViewSelection(treeView.getElementView(transition));
+ final TreeViewSelection newSelection =
+ new TreeViewSelection(treeView.getElementView(transition));
puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(newSelection));
}
@@ -100,37 +103,39 @@ public void executeCommand() {
* Gets the reason why the command cannot be executed
*
* @return if command cannot be executed, returns reason for why the command cannot be executed,
- * otherwise null if command can be executed
+ * otherwise null if command can be executed
*/
@Override
public String getErrorString() {
List selectedViews = selection.getSelectedViews();
if (selectedViews.size() != 1) {
+ flashTreeViewRed();
return CommandError.ONE_SELECTED_VIEW.toString();
}
TreeElementView selectedView = selection.getFirstSelection();
Board board = selectedView.getTreeElement().getBoard();
PuzzleElement selectedPuzzleElement = elementView.getPuzzleElement();
if (selectedView.getType() == TreeElementType.NODE) {
-
TreeNodeView nodeView = (TreeNodeView) selectedView;
if (!nodeView.getChildrenViews().isEmpty()) {
+ flashTreeViewRed();
return CommandError.UNMODIFIABLE_BOARD.toString();
+ } else if (!board.getPuzzleElement(selectedPuzzleElement).isModifiable()) {
+ flashTreeViewRed();
+ return CommandError.UNMODIFIABLE_DATA.toString();
}
- else {
- if (!board.getPuzzleElement(selectedPuzzleElement).isModifiable()) {
- return CommandError.UNMODIFIABLE_DATA.toString();
- }
- }
- }
- else {
+ } else {
TreeTransitionView transitionView = (TreeTransitionView) selectedView;
if (!transitionView.getTreeElement().getBoard().isModifiable()) {
+ flashTreeViewRed();
return CommandError.UNMODIFIABLE_BOARD.toString();
- }
- else {
+ } else {
if (!board.getPuzzleElement(selectedPuzzleElement).isModifiable()) {
+ flashTreeViewRed();
return CommandError.UNMODIFIABLE_DATA.toString();
+ } else if (!board.getPuzzleElement(selectedPuzzleElement).isModifiableCaseRule()) {
+ flashTreeViewRed();
+ return CommandError.UNMODIFIABLE_DATA_CASE_RULE.toString();
}
}
}
@@ -138,7 +143,19 @@ public String getErrorString() {
}
/**
- * Undoes an command
+ * Causes the TreeView background to flash red for a short duration when an error occurs.
+ */
+ private void flashTreeViewRed() {
+ TreeView treeView = getInstance().getLegupUI().getTreePanel().getTreeView();
+ Color originalColor = treeView.getBackground();
+ treeView.setBackground(MaterialColors.RED_700);
+ Timer timer = new Timer(400, e -> treeView.setBackground(originalColor));
+ timer.setRepeats(false);
+ timer.start();
+ }
+
+ /**
+ * Undoes the edit data command, restoring the previous state of the puzzle element.
*/
@SuppressWarnings("unchecked")
@Override
@@ -152,7 +169,8 @@ public void undoCommand() {
if (selectedView.getType() == TreeElementType.NODE) {
tree.removeTreeElement(transition);
- puzzle.notifyTreeListeners((ITreeListener listener) -> listener.onTreeElementRemoved(transition));
+ puzzle.notifyTreeListeners(
+ (ITreeListener listener) -> listener.onTreeElementRemoved(transition));
}
Board prevBoard = transition.getParents().get(0).getBoard();
@@ -162,8 +180,7 @@ public void undoCommand() {
if (prevBoard.getPuzzleElement(selectedPuzzleElement).equalsData(puzzleElement)) {
board.removeModifiedData(puzzleElement);
- }
- else {
+ } else {
board.addModifiedData(puzzleElement);
}
transition.propagateChange(puzzleElement);
diff --git a/src/main/java/edu/rpi/legup/history/History.java b/src/main/java/edu/rpi/legup/history/History.java
index 77e3fae94..b244e8f88 100644
--- a/src/main/java/edu/rpi/legup/history/History.java
+++ b/src/main/java/edu/rpi/legup/history/History.java
@@ -1,13 +1,15 @@
package edu.rpi.legup.history;
import edu.rpi.legup.app.GameBoardFacade;
-
import java.util.ArrayList;
import java.util.List;
-
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+/**
+ * The History class manages a stack of commands for undo and redo operations on the board and tree structure.
+ * It maintains a list of commands and a current index to track the position in the history stack.
+ */
public class History {
private static final Logger LOGGER = LogManager.getLogger(History.class.getName());
@@ -16,10 +18,8 @@ public class History {
private int curIndex;
/**
- * History Constructor this holds information about changes to the board
- * and Tree structure for undoing and redoing operations. Though history is
- * an List, it is implemented like a stack. The curIndex points to the
- * top of the stack (where the last change was made).
+ * Constructs a History object to keep track of changes and allow undo and redo operations.
+ * The history is implemented as a stack, with curIndex pointing to the top of the stack.
*/
public History() {
history = new ArrayList<>();
@@ -27,9 +27,9 @@ public History() {
}
/**
- * Pushes a change to the history list and increments the current index.
- * If the current index does not point to the top of the stack, then at least
- * 1 undo operation was called and that information will be lost by the next change
+ * Pushes a change to the history list and increments the current index. If the current index
+ * does not point to the top of the stack, then at least 1 undo operation was called and that
+ * information will be lost by the next change
*
* @param command command to be pushed onto the stack
*/
@@ -48,7 +48,8 @@ public void pushChange(ICommand command) {
}
/**
- * Undoes an action
+ * Undoes the last action by calling the undo method of the command at the current index.
+ * Updates the current index and notifies listeners.
*/
public void undo() {
synchronized (lock) {
@@ -56,13 +57,18 @@ public void undo() {
ICommand command = history.get(curIndex--);
command.undo();
LOGGER.info("Undoed " + command.getClass().getSimpleName());
- GameBoardFacade.getInstance().notifyHistoryListeners(l -> l.onUndo(curIndex < 0, curIndex == history.size() - 1));
+
+
+ GameBoardFacade.getInstance()
+ .notifyHistoryListeners(
+ l -> l.onUndo(curIndex < 0, curIndex == history.size() - 1));
}
}
}
/**
- * Redoes an action
+ * Redoes the next action by calling the redo method of the command at the current index.
+ * Updates the current index and notifies listeners.
*/
public void redo() {
synchronized (lock) {
@@ -70,13 +76,15 @@ public void redo() {
ICommand command = history.get(++curIndex);
command.redo();
LOGGER.info("Redoed " + command.getClass().getSimpleName());
- GameBoardFacade.getInstance().notifyHistoryListeners(l -> l.onRedo(curIndex < 0, curIndex == history.size() - 1));
+ GameBoardFacade.getInstance()
+ .notifyHistoryListeners(
+ l -> l.onRedo(curIndex < 0, curIndex == history.size() - 1));
}
}
}
/**
- * Clears all actions from the history stack
+ * Clears all actions from the history stack and resets the current index
*/
public void clear() {
history.clear();
diff --git a/src/main/java/edu/rpi/legup/history/ICommand.java b/src/main/java/edu/rpi/legup/history/ICommand.java
index bc82c4df5..4f867dbab 100644
--- a/src/main/java/edu/rpi/legup/history/ICommand.java
+++ b/src/main/java/edu/rpi/legup/history/ICommand.java
@@ -1,13 +1,18 @@
package edu.rpi.legup.history;
+/**
+ * The ICommand interface defines the structure for command objects in a command pattern.
+ * It provides methods to execute, undo, redo commands, and to check if a command can be executed.
+ */
public interface ICommand {
/**
- * Executes a command
+ * Executes the command. The specific behavior depends on the implementation
*/
void execute();
/**
* Determines whether this command can be executed
+ *
* @return true if can execute, false otherwise
*/
boolean canExecute();
@@ -16,17 +21,17 @@ public interface ICommand {
* Gets the reason why the command cannot be executed
*
* @return if command cannot be executed, returns reason for why the command cannot be executed,
- * otherwise null if command can be executed
+ * otherwise null if command can be executed
*/
String getError();
/**
- * Undoes a command
+ * Undoes the command. Reverts the changes made by the execute method
*/
void undo();
/**
- * Redoes a command
+ * Redoes the command. Re-applies the changes made by the execute method after undoing
*/
void redo();
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/history/IHistoryListener.java b/src/main/java/edu/rpi/legup/history/IHistoryListener.java
index 5201a09c5..48690168d 100644
--- a/src/main/java/edu/rpi/legup/history/IHistoryListener.java
+++ b/src/main/java/edu/rpi/legup/history/IHistoryListener.java
@@ -1,31 +1,37 @@
package edu.rpi.legup.history;
+/**
+ * The IHistoryListener interface defines methods for listening to changes in the history of commands.
+ * Implementations of this interface can respond to events related to command history such as pushing,
+ * undoing, redoing commands, and clearing the history.
+ */
public interface IHistoryListener {
+
/**
- * Called when a action is pushed onto the edu.rpi.legup.history stack
+ * Called when a command is pushed onto the history stack.
*
- * @param command action to push onto the stack
+ * @param command the command that was pushed onto the stack
*/
void onPushChange(ICommand command);
/**
- * Called when an action is undone
+ * Called when a command is undone.
*
* @param isBottom true if there are no more actions to undo, false otherwise
- * @param isTop true if there are no more changes to redo, false otherwise
+ * @param isTop true if there are no more changes to redo, false otherwise
*/
void onUndo(boolean isBottom, boolean isTop);
/**
- * Called when an action is redone
+ * Called when a command is redone.
*
* @param isBottom true if there are no more actions to undo, false otherwise
- * @param isTop true if there are no more changes to redo, false otherwise
+ * @param isTop true if there are no more changes to redo, false otherwise
*/
void onRedo(boolean isBottom, boolean isTop);
/**
- * Called when the edu.rpi.legup.history is cleared
+ * Called when the history stack is cleared.
*/
void onClearHistory();
}
diff --git a/src/main/java/edu/rpi/legup/history/IHistorySubject.java b/src/main/java/edu/rpi/legup/history/IHistorySubject.java
index 78fefff00..431adbb93 100644
--- a/src/main/java/edu/rpi/legup/history/IHistorySubject.java
+++ b/src/main/java/edu/rpi/legup/history/IHistorySubject.java
@@ -2,25 +2,31 @@
import java.util.function.Consumer;
+/**
+ * The IHistorySubject interface defines methods for managing and notifying listeners
+ * about changes in the command history. Implementations of this interface can add, remove,
+ * and notify history listeners.
+ */
public interface IHistorySubject {
+
/**
- * Adds a history listener
+ * Adds a history listener to receive updates about changes in the command history.
*
- * @param listener listener to add
+ * @param listener the listener to add
*/
void addHistoryListener(IHistoryListener listener);
/**
- * Removes a history listener
+ * Removes a history listener, so it no longer receives updates about changes in the command history.
*
- * @param listener listener to remove
+ * @param listener the listener to remove
*/
void removeHistoryListener(IHistoryListener listener);
/**
- * Notifies listeners
+ * Notifies all registered listeners about a change in the command history.
*
- * @param algorithm algorithm to notify the listeners with
+ * @param algorithm a Consumer function that takes an IHistoryListener and performs some action with it
*/
void notifyHistoryListeners(Consumer super IHistoryListener> algorithm);
}
diff --git a/src/main/java/edu/rpi/legup/history/InvalidCommandStateTransition.java b/src/main/java/edu/rpi/legup/history/InvalidCommandStateTransition.java
index 7e79814a6..201babb9e 100644
--- a/src/main/java/edu/rpi/legup/history/InvalidCommandStateTransition.java
+++ b/src/main/java/edu/rpi/legup/history/InvalidCommandStateTransition.java
@@ -1,8 +1,26 @@
package edu.rpi.legup.history;
+/**
+ * The InvalidCommandStateTransition exception is thrown when an invalid state transition
+ * is attempted on a PuzzleCommand
+ */
public class InvalidCommandStateTransition extends RuntimeException {
- public InvalidCommandStateTransition(PuzzleCommand puzzleCommand, CommandState from, CommandState to) {
- super("PuzzleCommand - " + puzzleCommand.getClass().getSimpleName() + " - Attempted invalid command state transition from " + from + " to " + to);
+ /**
+ * Constructs a new InvalidCommandStateTransition exception with a detailed message
+ *
+ * @param puzzleCommand the PuzzleCommand involved in the invalid transition
+ * @param from the state from which the transition was attempted
+ * @param to the state to which the transition was attempted
+ */
+ public InvalidCommandStateTransition(
+ PuzzleCommand puzzleCommand, CommandState from, CommandState to) {
+ super(
+ "PuzzleCommand - "
+ + puzzleCommand.getClass().getSimpleName()
+ + " - Attempted invalid command state transition from "
+ + from
+ + " to "
+ + to);
}
}
diff --git a/src/main/java/edu/rpi/legup/history/MergeCommand.java b/src/main/java/edu/rpi/legup/history/MergeCommand.java
index 2091ecf0a..c2851bced 100644
--- a/src/main/java/edu/rpi/legup/history/MergeCommand.java
+++ b/src/main/java/edu/rpi/legup/history/MergeCommand.java
@@ -6,11 +6,14 @@
import edu.rpi.legup.model.rules.MergeRule;
import edu.rpi.legup.model.tree.*;
import edu.rpi.legup.ui.proofeditorui.treeview.*;
-
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
+/**
+ * The MergeCommand class represents a command to merge selected tree nodes into a single node
+ * and create a transition to represent the merge
+ */
public class MergeCommand extends PuzzleCommand {
private TreeViewSelection selection;
private TreeTransition transition;
@@ -26,7 +29,7 @@ public MergeCommand(TreeViewSelection selection) {
}
/**
- * Executes an command
+ * Executes the merge command
*/
@Override
public void executeCommand() {
@@ -55,8 +58,7 @@ public void executeCommand() {
transition.setRule(new MergeRule());
transition.setChildNode(mergedNode);
mergedNode.setParent(transition);
- }
- else {
+ } else {
mergedNode = transition.getChildNode();
}
@@ -76,14 +78,15 @@ public void executeCommand() {
}
/**
- * Undoes an command
+ * Undoes the merge command
*/
@Override
public void undoCommand() {
Tree tree = GameBoardFacade.getInstance().getTree();
Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule();
- TreeTransition transition = ((TreeNode) selection.getFirstSelection().getTreeElement()).getChildren().get(0);
+ TreeTransition transition =
+ ((TreeNode) selection.getFirstSelection().getTreeElement()).getChildren().get(0);
tree.removeTreeElement(transition);
puzzle.notifyTreeListeners(listener -> listener.onTreeElementRemoved(transition));
@@ -94,7 +97,7 @@ public void undoCommand() {
* Gets the reason why the command cannot be executed
*
* @return if command cannot be executed, returns reason for why the command cannot be executed,
- * otherwise null if command can be executed
+ * otherwise null if command can be executed
*/
@Override
public String getErrorString() {
@@ -112,8 +115,7 @@ public String getErrorString() {
return CommandError.NO_CHILDREN.toString();
}
nodeList.add(nodeView.getTreeElement());
- }
- else {
+ } else {
return CommandError.SELECTION_CONTAINS_TRANSITION.toString();
}
}
@@ -130,12 +132,12 @@ public String getErrorString() {
}
Set leafNodes = tree.getLeafTreeElements(lca);
if (leafNodes.size() != mergingNodes.size()) {
-// return "Unable to merge tree elements.";
+ // return "Unable to merge tree elements.";
}
for (TreeNode node : mergingNodes) {
if (!leafNodes.contains(node)) {
-// return "Unable to merge tree elements.";
+ // return "Unable to merge tree elements.";
}
}
diff --git a/src/main/java/edu/rpi/legup/history/PuzzleCommand.java b/src/main/java/edu/rpi/legup/history/PuzzleCommand.java
index 0c96b16f5..d4385b3e8 100644
--- a/src/main/java/edu/rpi/legup/history/PuzzleCommand.java
+++ b/src/main/java/edu/rpi/legup/history/PuzzleCommand.java
@@ -1,15 +1,17 @@
package edu.rpi.legup.history;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
+/**
+ * The PuzzleCommand class is an abstract base class for commands that can be executed, undone, and redone
+ * within the puzzle model. It implements the ICommand interface and maintains the state and error handling
+ * for the command.
+ */
public abstract class PuzzleCommand implements ICommand {
private CommandState state;
private boolean isCached;
private String cachedError;
/**
- * Puzzle Command Constructor for creating an undoable and redoable change to the model.
+ * Puzzle Command Constructor for creating an undoable and redoable change to the model
*/
protected PuzzleCommand() {
this.state = CommandState.CREATED;
@@ -18,7 +20,7 @@ protected PuzzleCommand() {
}
/**
- * Executes an command
+ * Executes the command if it can be executed
*/
@Override
public final void execute() {
@@ -29,7 +31,7 @@ public final void execute() {
}
/**
- * Determines whether this command can be executed
+ * Determines whether the command can be executed by checking the error state
*/
@Override
public final boolean canExecute() {
@@ -42,14 +44,13 @@ public final boolean canExecute() {
* Gets the reason why the command cannot be executed
*
* @return if command cannot be executed, returns reason for why the command cannot be executed,
- * otherwise null if command can be executed
+ * otherwise null if command can be executed
*/
@Override
public final String getError() {
if (isCached) {
return cachedError;
- }
- else {
+ } else {
return getErrorString();
}
}
@@ -58,57 +59,56 @@ public final String getError() {
* Gets the reason why the command cannot be executed
*
* @return if command cannot be executed, returns reason for why the command cannot be executed,
- * otherwise null if command can be executed
+ * otherwise null if command can be executed
*/
public abstract String getErrorString();
/**
- * Executes an command
+ * Executes the command.
+ * This method must be implemented by subclasses to define the command's execution behavior.
*/
public abstract void executeCommand();
/**
- * Undoes an command
+ * Undoes the command.
+ * This method must be implemented by subclasses to define the command's undo behavior.
*/
public abstract void undoCommand();
/**
- * Redoes an command
+ * Redoes the command. This method is called if the command was previously undone.
*/
public void redoCommand() {
if (state == CommandState.UNDOED) {
executeCommand();
state = CommandState.REDOED;
- }
- else {
+ } else {
throw new InvalidCommandStateTransition(this, state, CommandState.REDOED);
}
}
/**
- * Undoes an command
+ * Undoes the command if it was executed or redone
*/
@Override
public final void undo() {
if (state == CommandState.EXECUTED || state == CommandState.REDOED) {
undoCommand();
state = CommandState.UNDOED;
- }
- else {
+ } else {
throw new InvalidCommandStateTransition(this, state, CommandState.UNDOED);
}
}
/**
- * Redoes an command
+ * Redoes the command if it was previously undone.
*/
public final void redo() {
if (state == CommandState.UNDOED) {
redoCommand();
state = CommandState.REDOED;
- }
- else {
+ } else {
throw new InvalidCommandStateTransition(this, state, CommandState.REDOED);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/history/ValidateCaseRuleCommand.java b/src/main/java/edu/rpi/legup/history/ValidateCaseRuleCommand.java
index 398f17478..6827436e8 100644
--- a/src/main/java/edu/rpi/legup/history/ValidateCaseRuleCommand.java
+++ b/src/main/java/edu/rpi/legup/history/ValidateCaseRuleCommand.java
@@ -1,18 +1,21 @@
package edu.rpi.legup.history;
+import static edu.rpi.legup.app.GameBoardFacade.getInstance;
+
import edu.rpi.legup.app.GameBoardFacade;
import edu.rpi.legup.model.Puzzle;
import edu.rpi.legup.model.rules.CaseRule;
import edu.rpi.legup.model.rules.Rule;
import edu.rpi.legup.model.tree.*;
import edu.rpi.legup.ui.proofeditorui.treeview.*;
-
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import static edu.rpi.legup.app.GameBoardFacade.getInstance;
-
+/**
+ * The ValidateCaseRuleCommand class represents a command for validating a CaseRule in the tree structure.
+ * It extends the PuzzleCommand class and implements the ICommand interface.
+ */
public class ValidateCaseRuleCommand extends PuzzleCommand {
private TreeViewSelection selection;
@@ -35,7 +38,7 @@ public ValidateCaseRuleCommand(TreeViewSelection selection, CaseRule caseRule) {
}
/**
- * Executes an command
+ * Executes the command to validate the CaseRule
*/
@Override
public void executeCommand() {
@@ -58,8 +61,7 @@ public void executeCommand() {
if (childNode == null) {
childNode = (TreeNode) tree.addTreeElement(transition);
addNode.put(transition, childNode);
- }
- else {
+ } else {
childNode = (TreeNode) tree.addTreeElement(transition, childNode);
}
@@ -75,8 +77,7 @@ public void executeCommand() {
if (firstSelectedView.getType() == TreeElementType.NODE) {
TreeNodeView nodeView = (TreeNodeView) firstSelectedView;
finalTreeElement = nodeView.getChildrenViews().get(0).getTreeElement();
- }
- else {
+ } else {
TreeTransitionView transitionView = (TreeTransitionView) firstSelectedView;
finalTreeElement = transitionView.getChildView().getTreeElement();
}
@@ -88,7 +89,7 @@ public void executeCommand() {
* Gets the reason why the command cannot be executed
*
* @return if command cannot be executed, returns reason for why the command cannot be executed,
- * otherwise null if command can be executed
+ * otherwise null if command can be executed
*/
@Override
public String getErrorString() {
@@ -100,8 +101,7 @@ public String getErrorString() {
for (TreeElementView view : selectedViews) {
if (view.getType() == TreeElementType.NODE) {
return CommandError.SELECTION_CONTAINS_NODE.toString();
- }
- else {
+ } else {
TreeTransitionView transView = (TreeTransitionView) view;
if (transView.getParentViews().size() > 1) {
return CommandError.CONTAINS_MERGE.toString();
@@ -111,8 +111,9 @@ public String getErrorString() {
return null;
}
+
/**
- * Undoes an command
+ * Undoes the validation command, restoring the previous state
*/
@Override
public void undoCommand() {
@@ -136,4 +137,4 @@ public void undoCommand() {
puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(finalTreeElement));
puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(selection));
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/history/ValidateContradictionRuleCommand.java b/src/main/java/edu/rpi/legup/history/ValidateContradictionRuleCommand.java
index 23f8dce21..b106a6072 100644
--- a/src/main/java/edu/rpi/legup/history/ValidateContradictionRuleCommand.java
+++ b/src/main/java/edu/rpi/legup/history/ValidateContradictionRuleCommand.java
@@ -5,12 +5,15 @@
import edu.rpi.legup.model.rules.ContradictionRule;
import edu.rpi.legup.model.tree.*;
import edu.rpi.legup.ui.proofeditorui.treeview.*;
-
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+/**
+ * The ValidateContradictionRuleCommand class represents a command for validating and applying a ContradictionRule
+ * within a tree structure. It extends the PuzzleCommand class and implements the ICommand interface.
+ */
public class ValidateContradictionRuleCommand extends PuzzleCommand {
private TreeViewSelection selection;
@@ -19,10 +22,11 @@ public class ValidateContradictionRuleCommand extends PuzzleCommand {
private Map addTran;
/**
- * ValidateContradictionRuleCommand Constructor creates a puzzle command for verifying a contradiction rule
+ * ValidateContradictionRuleCommand Constructor creates a puzzle command for verifying a
+ * contradiction rule
*
* @param selection currently selected tree puzzleElement views
- * @param rule contradiction rule to be set to all the tree elements
+ * @param rule contradiction rule to be set to all the tree elements
*/
public ValidateContradictionRuleCommand(TreeViewSelection selection, ContradictionRule rule) {
this.selection = selection.copy();
@@ -32,7 +36,7 @@ public ValidateContradictionRuleCommand(TreeViewSelection selection, Contradicti
}
/**
- * Executes a command
+ * Executes the command to validate and apply the ContradictionRule.
*/
@Override
public void executeCommand() {
@@ -48,8 +52,7 @@ public void executeCommand() {
if (treeElement.getType() == TreeElementType.TRANSITION) {
TreeTransition transition = (TreeTransition) treeElement;
treeNode = transition.getParents().get(0);
- }
- else {
+ } else {
treeNode = (TreeNode) treeElement;
}
@@ -58,7 +61,11 @@ public void executeCommand() {
saveElements.put(treeNode, save);
}
- treeNode.getChildren().forEach(n -> puzzle.notifyTreeListeners(listener -> listener.onTreeElementRemoved(n)));
+ treeNode.getChildren()
+ .forEach(
+ n ->
+ puzzle.notifyTreeListeners(
+ listener -> listener.onTreeElementRemoved(n)));
treeNode.getChildren().clear();
@@ -68,8 +75,7 @@ public void executeCommand() {
transition.setRule(newRule);
transition.getBoard().setModifiable(false);
tree.addTreeElement(transition);
- }
- else {
+ } else {
transition.getBoard().setModifiable(false);
tree.addTreeElement(treeNode, transition);
}
@@ -84,20 +90,24 @@ public void executeCommand() {
final TreeElement finalTreeElement;
if (firstSelectedView.getType() == TreeElementType.NODE) {
TreeNodeView nodeView = (TreeNodeView) firstSelectedView;
- finalTreeElement = nodeView.getChildrenViews().get(0).getTreeElement();
- }
- else {
+ if (!nodeView.getChildrenViews().isEmpty()) {
+ finalTreeElement = nodeView.getChildrenViews().get(0).getTreeElement();
+ }
+ else {
+ finalTreeElement = null;
+ }
+ } else {
TreeTransitionView transitionView = (TreeTransitionView) firstSelectedView;
if (transitionView.getChildView() != null) {
finalTreeElement = transitionView.getChildView().getTreeElement();
- }
- else {
+ } else {
finalTreeElement = null;
}
}
if (finalTreeElement != null) {
- puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(finalTreeElement));
+ puzzle.notifyBoardListeners(
+ listener -> listener.onTreeElementChanged(finalTreeElement));
}
puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(newSelection));
}
@@ -106,7 +116,7 @@ public void executeCommand() {
* Gets the reason why the command cannot be executed
*
* @return if command cannot be executed, returns reason for why the command cannot be executed,
- * otherwise null if command can be executed
+ * otherwise null if command can be executed
*/
@Override
public String getErrorString() {
@@ -127,7 +137,7 @@ public String getErrorString() {
}
/**
- * Undoes a command
+ * Undoes the validation command, restoring the previous state.
*/
@Override
public void undoCommand() {
@@ -140,18 +150,25 @@ public void undoCommand() {
if (element.getType() == TreeElementType.TRANSITION) {
TreeTransition transition = (TreeTransition) element;
node = transition.getParents().get(0);
- }
- else {
+ } else {
node = (TreeNode) element;
}
- node.getChildren().forEach(n -> puzzle.notifyTreeListeners(listener -> listener.onTreeElementRemoved(n)));
+ node.getChildren()
+ .forEach(
+ n ->
+ puzzle.notifyTreeListeners(
+ listener -> listener.onTreeElementRemoved(n)));
node.getChildren().clear();
ArrayList save = saveElements.get(node);
if (save != null) {
node.getChildren().addAll(save);
- node.getChildren().forEach(n -> puzzle.notifyTreeListeners(listener -> listener.onTreeElementAdded(n)));
+ node.getChildren()
+ .forEach(
+ n ->
+ puzzle.notifyTreeListeners(
+ listener -> listener.onTreeElementAdded(n)));
}
}
diff --git a/src/main/java/edu/rpi/legup/history/ValidateDirectRuleCommand.java b/src/main/java/edu/rpi/legup/history/ValidateDirectRuleCommand.java
index 61babe883..f7694cc0a 100644
--- a/src/main/java/edu/rpi/legup/history/ValidateDirectRuleCommand.java
+++ b/src/main/java/edu/rpi/legup/history/ValidateDirectRuleCommand.java
@@ -1,152 +1,182 @@
-package edu.rpi.legup.history;
-
-import edu.rpi.legup.app.GameBoardFacade;
-import edu.rpi.legup.model.Puzzle;
-import edu.rpi.legup.model.rules.DirectRule;
-import edu.rpi.legup.model.rules.Rule;
-import edu.rpi.legup.model.tree.*;
-import edu.rpi.legup.ui.proofeditorui.treeview.*;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class ValidateDirectRuleCommand extends PuzzleCommand {
- private TreeViewSelection selection;
-
- private Map oldRules;
- private Map addNode;
- private DirectRule newRule;
-
- /**
- * ValidateDesireRuleCommand Constructor creates a command for verifying a basic rule
- *
- * @param selection selection of tree elements
- * @param rule basic rule
- */
- public ValidateDirectRuleCommand(TreeViewSelection selection, DirectRule rule) {
- this.selection = selection.copy();
- this.newRule = rule;
- this.oldRules = new HashMap<>();
- this.addNode = new HashMap<>();
- }
-
- /**
- * Executes an command
- */
- @Override
- public void executeCommand() {
- Tree tree = GameBoardFacade.getInstance().getTree();
- TreeView treeView = GameBoardFacade.getInstance().getLegupUI().getTreePanel().getTreeView();
- Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule();
- final TreeViewSelection newSelection = new TreeViewSelection();
-
- List selectedViews = selection.getSelectedViews();
- for (TreeElementView selectedView : selectedViews) {
- TreeElement element = selectedView.getTreeElement();
- TreeTransitionView transitionView;
- if (element.getType() == TreeElementType.NODE) {
- TreeNodeView nodeView = (TreeNodeView) selectedView;
- transitionView = nodeView.getChildrenViews().get(0);
- }
- else {
- transitionView = (TreeTransitionView) selectedView;
- }
- TreeTransition transition = transitionView.getTreeElement();
-
- oldRules.put(transition, transition.getRule());
- transition.setRule(newRule);
-
- TreeNode childNode = transition.getChildNode();
- if (childNode == null) {
- childNode = addNode.get(transition);
- if (childNode == null) {
- childNode = (TreeNode) tree.addTreeElement(transition);
- addNode.put(transition, childNode);
- }
- else {
- tree.addTreeElement(transition, childNode);
- }
-
- final TreeNode finalNode = childNode;
- puzzle.notifyTreeListeners(listener -> listener.onTreeElementAdded(finalNode));
- }
- newSelection.addToSelection(treeView.getElementView(childNode));
- }
- TreeElementView firstSelectedView = selection.getFirstSelection();
- final TreeElement finalTreeElement;
- if (firstSelectedView.getType() == TreeElementType.NODE) {
- TreeNodeView nodeView = (TreeNodeView) firstSelectedView;
- finalTreeElement = nodeView.getChildrenViews().get(0).getTreeElement();
- }
- else {
- TreeTransitionView transitionView = (TreeTransitionView) firstSelectedView;
- finalTreeElement = transitionView.getChildView().getTreeElement();
- }
- puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(finalTreeElement));
- puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(newSelection));
- }
-
- /**
- * Gets the reason why the command cannot be executed
- *
- * @return if command cannot be executed, returns reason for why the command cannot be executed,
- * otherwise null if command can be executed
- */
- @Override
- public String getErrorString() {
- List selectedViews = selection.getSelectedViews();
- if (selectedViews.isEmpty()) {
- return CommandError.NO_SELECTED_VIEWS.toString();
- }
-
- for (TreeElementView view : selectedViews) {
- if (view.getType() == TreeElementType.NODE) {
- TreeNodeView nodeView = (TreeNodeView) view;
- if (nodeView.getChildrenViews().size() != 1) {
- return CommandError.ONE_CHILD.toString();
- }
- }
- else {
- TreeTransitionView transView = (TreeTransitionView) view;
- if (transView.getParentViews().size() > 1) {
- return CommandError.CONTAINS_MERGE.toString();
- }
- }
- }
- return null;
- }
-
- /**
- * Undoes an command
- */
- @Override
- public void undoCommand() {
- Tree tree = GameBoardFacade.getInstance().getTree();
- Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule();
-
- for (TreeElementView selectedView : selection.getSelectedViews()) {
- TreeElement element = selectedView.getTreeElement();
- TreeTransitionView transitionView;
- if (element.getType() == TreeElementType.NODE) {
- TreeNodeView nodeView = (TreeNodeView) selectedView;
- transitionView = nodeView.getChildrenViews().get(0);
- }
- else {
- transitionView = (TreeTransitionView) selectedView;
- }
- TreeTransition transition = transitionView.getTreeElement();
- transition.setRule(oldRules.get(transition));
-
- if (addNode.get(transition) != null) {
- final TreeNode childNode = transition.getChildNode();
- tree.removeTreeElement(childNode);
- puzzle.notifyTreeListeners(listener -> listener.onTreeElementRemoved(childNode));
- }
- }
-
- final TreeElement finalTreeElement = selection.getFirstSelection().getTreeElement();
- puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(finalTreeElement));
- puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(selection));
- }
-}
+package edu.rpi.legup.history;
+
+import edu.rpi.legup.app.GameBoardFacade;
+import edu.rpi.legup.model.Puzzle;
+import edu.rpi.legup.model.rules.DirectRule;
+import edu.rpi.legup.model.rules.Rule;
+import edu.rpi.legup.model.tree.*;
+import edu.rpi.legup.ui.proofeditorui.treeview.*;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The ValidateDirectRuleCommand class represents a command for validating and applying a DirectRule
+ * to a set of selected tree elements. It extends the PuzzleCommand class and implements the ICommand interface.
+ */
+public class ValidateDirectRuleCommand extends PuzzleCommand {
+ private static final Logger LOGGER = LogManager.getLogger(History.class.getName());
+ private TreeViewSelection selection;
+
+ private Map oldRules;
+ private Map addNode;
+ private DirectRule newRule;
+
+ /**
+ * ValidateDesireRuleCommand Constructor creates a command for verifying a basic rule
+ *
+ * @param selection selection of tree elements
+ * @param rule basic rule
+ */
+ public ValidateDirectRuleCommand(TreeViewSelection selection, DirectRule rule) {
+ this.selection = selection.copy();
+ this.newRule = rule;
+ this.oldRules = new HashMap<>();
+ this.addNode = new HashMap<>();
+ }
+
+ /**
+ * Executes the command to validate and apply the DirectRule.
+ */
+ @Override
+ public void executeCommand() {
+ Tree tree = GameBoardFacade.getInstance().getTree();
+ TreeView treeView = GameBoardFacade.getInstance().getLegupUI().getTreePanel().getTreeView();
+ Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule();
+ final TreeViewSelection newSelection = new TreeViewSelection();
+
+ List selectedViews = selection.getSelectedViews();
+ for (TreeElementView selectedView : selectedViews) {
+ TreeElement element = selectedView.getTreeElement();
+ TreeTransitionView transitionView;
+
+ if (element.getType() == TreeElementType.NODE) {
+ TreeNodeView nodeView = (TreeNodeView) selectedView;
+ transitionView = nodeView.getChildrenViews().get(0);
+ } else {
+ transitionView = (TreeTransitionView) selectedView;
+ }
+
+ TreeTransition transition = transitionView.getTreeElement();
+ oldRules.put(transition, transition.getRule());
+ transition.setRule(newRule);
+
+ TreeNode childNode = transition.getChildNode();
+ if (childNode == null) {
+ childNode = addNode.get(transition);
+ if (childNode == null) {
+ childNode = (TreeNode) tree.addTreeElement(transition);
+ addNode.put(transition, childNode);
+ } else {
+ tree.addTreeElement(transition, childNode);
+ }
+
+ final TreeNode finalNode = childNode;
+ puzzle.notifyTreeListeners(listener -> listener.onTreeElementAdded(finalNode));
+ }
+
+ TreeElementView childView = treeView.getElementView(childNode);
+ if (childView == null) {
+ LOGGER.error("Child view is null for child node: " + childNode);
+ continue;
+ }
+ newSelection.addToSelection(childView);
+ }
+
+ TreeElementView firstSelectedView = selection.getFirstSelection();
+
+ final TreeElement finalTreeElement;
+ if (firstSelectedView.getType() == TreeElementType.NODE) {
+ TreeNodeView nodeView = (TreeNodeView) firstSelectedView;
+ if (nodeView.getChildrenViews().isEmpty()) {
+ LOGGER.error("NodeView has no children views");
+ return;
+ }
+ finalTreeElement = nodeView.getChildrenViews().get(0).getTreeElement();
+ } else {
+ TreeTransitionView transitionView = (TreeTransitionView) firstSelectedView;
+ TreeNodeView childView = transitionView.getChildView();
+ if (childView == null) {
+ LOGGER.error("Child view is null for transition view: " + transitionView);
+ TreeNode childNode = transitionView.getTreeElement().getChildNode();
+ childView = (TreeNodeView) treeView.getElementView(childNode);
+ transitionView.setChildView(childView);
+ }
+ TreeTransition transition = transitionView.getTreeElement();
+ if (transition.getParents().get(0).getChildren().isEmpty()) {
+ transition.getParents().get(0).addChild(transition);
+ }
+ finalTreeElement = transitionView.getChildView().getTreeElement();
+ }
+
+ puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(finalTreeElement));
+ puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(newSelection));
+ }
+
+
+ /**
+ * Gets the reason why the command cannot be executed
+ *
+ * @return if command cannot be executed, returns reason for why the command cannot be executed,
+ * otherwise null if command can be executed
+ */
+ @Override
+ public String getErrorString() {
+ List selectedViews = selection.getSelectedViews();
+ if (selectedViews.isEmpty()) {
+ return CommandError.NO_SELECTED_VIEWS.toString();
+ }
+
+ for (TreeElementView view : selectedViews) {
+ if (view.getType() == TreeElementType.NODE) {
+ TreeNodeView nodeView = (TreeNodeView) view;
+ if (nodeView.getChildrenViews().size() != 1) {
+ return CommandError.ONE_CHILD.toString();
+ }
+ } else {
+ TreeTransitionView transView = (TreeTransitionView) view;
+ if (transView.getParentViews().size() > 1) {
+ return CommandError.CONTAINS_MERGE.toString();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Undoes the validation command, restoring the previous state.
+ */
+ @Override
+ public void undoCommand() {
+ Tree tree = GameBoardFacade.getInstance().getTree();
+ Puzzle puzzle = GameBoardFacade.getInstance().getPuzzleModule();
+
+ for (TreeElementView selectedView : selection.getSelectedViews()) {
+ TreeElement element = selectedView.getTreeElement();
+ TreeTransitionView transitionView;
+ if (element.getType() == TreeElementType.NODE) {
+ TreeNodeView nodeView = (TreeNodeView) selectedView;
+ transitionView = nodeView.getChildrenViews().get(0);
+ } else {
+ transitionView = (TreeTransitionView) selectedView;
+
+ }
+ TreeTransition transition = transitionView.getTreeElement();
+
+ transition.setRule(oldRules.get(transition));
+
+ if (addNode.get(transition) != null) {
+ final TreeNode childNode = transition.getChildNode();
+ tree.removeTreeElement(childNode);
+ puzzle.notifyTreeListeners(listener -> listener.onTreeElementRemoved(childNode));
+ }
+ }
+
+ final TreeElement finalTreeElement = selection.getFirstSelection().getTreeElement();
+ puzzle.notifyBoardListeners(listener -> listener.onTreeElementChanged(finalTreeElement));
+ puzzle.notifyTreeListeners(listener -> listener.onTreeSelectionChanged(selection));
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/model/Puzzle.java b/src/main/java/edu/rpi/legup/model/Puzzle.java
index 18614131b..6cc92f347 100644
--- a/src/main/java/edu/rpi/legup/model/Puzzle.java
+++ b/src/main/java/edu/rpi/legup/model/Puzzle.java
@@ -1,6 +1,7 @@
package edu.rpi.legup.model;
import edu.rpi.legup.model.elements.*;
+import edu.rpi.legup.model.elements.Element;
import edu.rpi.legup.model.gameboard.Board;
import edu.rpi.legup.model.gameboard.ElementFactory;
import edu.rpi.legup.model.observer.IBoardListener;
@@ -12,33 +13,33 @@
import edu.rpi.legup.model.tree.TreeElement;
import edu.rpi.legup.model.tree.TreeElementType;
import edu.rpi.legup.model.tree.TreeNode;
-import edu.rpi.legup.puzzle.nurikabe.NurikabeType;
-import edu.rpi.legup.ui.puzzleeditorui.elementsview.NonPlaceableElementPanel;
-import edu.rpi.legup.utility.LegupUtils;
-import org.w3c.dom.Document;
-import edu.rpi.legup.model.elements.Element;
-import org.w3c.dom.Node;
import edu.rpi.legup.save.InvalidFileFormatException;
import edu.rpi.legup.ui.boardview.BoardView;
-import org.xml.sax.SAXException;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
+import edu.rpi.legup.utility.LegupUtils;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
-import java.lang.reflect.Modifier;
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
-
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+/**
+ * Abstract class representing a puzzle.
+ * The Puzzle class manages the core components of a puzzle game, including the board, rules, and elements.
+ * It also handles importing and exporting puzzle configurations and notifies listeners about changes.
+ */
public abstract class Puzzle implements IBoardSubject, ITreeSubject {
private static final Logger LOGGER = LogManager.getLogger(Puzzle.class.getName());
@@ -57,11 +58,8 @@ public abstract class Puzzle implements IBoardSubject, ITreeSubject {
protected List contradictionRules;
protected List caseRules;
protected List placeableElements;
- protected List nonPlaceableElements;
- /**
- * Puzzle Constructor - creates a new Puzzle
- */
+ /** Puzzle Constructor - creates a new Puzzle */
public Puzzle() {
this.boardListeners = new ArrayList<>();
this.treeListeners = new ArrayList<>();
@@ -71,12 +69,15 @@ public Puzzle() {
this.caseRules = new ArrayList<>();
this.placeableElements = new ArrayList<>();
- this.nonPlaceableElements = new ArrayList<>();
registerRules();
registerPuzzleElements();
}
+ /**
+ * Registers puzzle elements from the package of the derived class.
+ * Scans for classes annotated with {@link RegisterElement} and initializes them.
+ */
private void registerPuzzleElements() {
String packageName = this.getClass().getPackage().toString().replace("package ", "");
@@ -85,9 +86,13 @@ private void registerPuzzleElements() {
for (Class c : possElements) {
+ String classPackageName = c.getPackage().getName();
+ if (!classPackageName.startsWith("edu.rpi.legup.puzzle.") || !classPackageName.endsWith(".elements")) {
+ continue;
+ }
System.out.println("possible element: " + c.getName());
- //check that the element is not abstract
+ // check that the element is not abstract
if (Modifier.isAbstract(c.getModifiers())) continue;
for (Annotation a : c.getAnnotations()) {
@@ -101,31 +106,25 @@ private void registerPuzzleElements() {
case PLACEABLE:
this.addPlaceableElement((PlaceableElement) element);
break;
- case NONPLACEABLE:
- this.addNonPlaceableElement((NonPlaceableElement) element);
- break;
default:
break;
}
- }
- catch (InvocationTargetException e) {
+ } catch (InvocationTargetException e) {
System.out.println(" Failed ");
e.getTargetException().printStackTrace();
}
}
}
}
-
-// } catch (IOException | ClassNotFoundException | NoSuchMethodException |
-// InstantiationException | IllegalAccessException | InvocationTargetException e) {
-// LOGGER.error("Unable to find rules for " + this.getClass().getSimpleName(), e);
-// }
- }
- catch (Exception e) {
+ } catch (Exception e) {
LOGGER.error("Unable to find elements for " + this.getClass().getSimpleName(), e);
}
}
+ /**
+ * Registers rules from the package of the derived class.
+ * Scans for classes annotated with {@link RegisterRule} and initializes them.
+ */
private void registerRules() {
String packageName = this.getClass().getPackage().toString().replace("package ", "");
@@ -134,9 +133,13 @@ private void registerRules() {
for (Class c : possRules) {
+ String classPackageName = c.getPackage().getName();
+ if (!classPackageName.startsWith("edu.rpi.legup.puzzle.") || !classPackageName.endsWith(".rules")) {
+ continue;
+ }
System.out.println("possible rule: " + c.getName());
- //check that the rule is not abstract
+ // check that the rule is not abstract
if (Modifier.isAbstract(c.getModifiers())) continue;
for (Annotation a : c.getAnnotations()) {
@@ -161,21 +164,14 @@ private void registerRules() {
default:
break;
}
- }
- catch (InvocationTargetException e) {
+ } catch (InvocationTargetException e) {
System.out.println(" Failed ");
e.getTargetException().printStackTrace();
}
}
}
}
-
-// } catch (IOException | ClassNotFoundException | NoSuchMethodException |
-// InstantiationException | IllegalAccessException | InvocationTargetException e) {
-// LOGGER.error("Unable to find rules for " + this.getClass().getSimpleName(), e);
-// }
- }
- catch (Exception e) {
+ } catch (Exception e) {
LOGGER.error("Unable to find rules for " + this.getClass().getSimpleName(), e);
}
}
@@ -196,7 +192,7 @@ private void registerRules() {
/**
* Checks if the given height and width are valid board dimensions for the given puzzle
*
- * @param rows the number of rows on the board
+ * @param rows the number of rows on the board
* @param columns the number of columns on the board
* @return true if the given dimensions are valid for the given puzzle, false otherwise
*/
@@ -205,10 +201,10 @@ public boolean isValidDimensions(int rows, int columns) {
}
/**
- * Checks if the given array of statements is valid text input for the given puzzle
+ * Checks if the provided text input is valid for the puzzle.
*
- * @param statements
- * @return
+ * @param statements array of statements to check
+ * @return true if input is valid, false otherwise
*/
public boolean isValidTextInput(String[] statements) {
return statements.length > 0;
@@ -230,13 +226,13 @@ public boolean isPuzzleComplete() {
if (leaf.getType() == TreeElementType.NODE) {
TreeNode node = (TreeNode) leaf;
if (!node.isRoot()) {
- isComplete &= node.getParent().isContradictoryBranch() || isBoardComplete(node.getBoard());
- }
- else {
+ isComplete &=
+ node.getParent().isContradictoryBranch()
+ || isBoardComplete(node.getBoard());
+ } else {
isComplete &= isBoardComplete(node.getBoard());
}
- }
- else {
+ } else {
isComplete = false;
}
}
@@ -268,8 +264,7 @@ public boolean isPuzzleComplete() {
public void importPuzzle(String fileName) throws InvalidFileFormatException {
try {
importPuzzle(new FileInputStream(fileName));
- }
- catch (IOException e) {
+ } catch (IOException e) {
LOGGER.error("Importing puzzle error", e);
throw new InvalidFileFormatException("Could not find file");
}
@@ -287,8 +282,7 @@ public void importPuzzle(InputStream inputStream) throws InvalidFileFormatExcept
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse(inputStream);
- }
- catch (IOException | SAXException | ParserConfigurationException e) {
+ } catch (IOException | SAXException | ParserConfigurationException e) {
LOGGER.error("Importing puzzle error", e);
throw new InvalidFileFormatException("Could not find file");
}
@@ -300,8 +294,7 @@ public void importPuzzle(InputStream inputStream) throws InvalidFileFormatExcept
throw new InvalidFileFormatException("Puzzle importer null");
}
importer.initializePuzzle(node);
- }
- else {
+ } else {
LOGGER.error("Invalid file");
throw new InvalidFileFormatException("Invalid file: must be a Legup file");
}
@@ -343,15 +336,15 @@ public List getDirectRules() {
return directRules;
}
+ /**
+ * Gets the list of placeable elements.
+ *
+ * @return list of PlaceableElement instances
+ */
public List getPlaceableElements() {
return placeableElements;
}
- public List getNonPlaceableElements() {
- return nonPlaceableElements;
- }
-
-
/**
* Sets the list of direct rules
*
@@ -370,14 +363,15 @@ public void addDirectRule(DirectRule rule) {
directRules.add(rule);
}
+ /**
+ * Adds a placeable element to this puzzle.
+ *
+ * @param element PlaceableElement to add
+ */
public void addPlaceableElement(PlaceableElement element) {
placeableElements.add(element);
}
- public void addNonPlaceableElement(NonPlaceableElement element) {
- nonPlaceableElements.add(element);
- }
-
/**
* Remove a basic rule from this Puzzle
*
@@ -590,9 +584,10 @@ public void setFactory(ElementFactory factory) {
}
/**
- * Adds a board listener
+ * Adds a board listener to the list of listeners.
+ * This allows the puzzle to notify the listener about changes to the board.
*
- * @param listener listener to add
+ * @param listener The IBoardListener to be added to the list of listeners.
*/
@Override
public void addBoardListener(IBoardListener listener) {
@@ -600,9 +595,10 @@ public void addBoardListener(IBoardListener listener) {
}
/**
- * Removes a board listener
+ * Removes a board listener from the list of listeners.
+ * This prevents the puzzle from notifying the listener about future changes to the board.
*
- * @param listener listener to remove
+ * @param listener The IBoardListener to be removed from the list of listeners.
*/
@Override
public void removeBoardListener(IBoardListener listener) {
@@ -610,9 +606,10 @@ public void removeBoardListener(IBoardListener listener) {
}
/**
- * Notifies listeners
+ * Notifies all registered board listeners about changes.
+ * The provided algorithm is applied to each listener to process the notification.
*
- * @param algorithm algorithm to notify the listeners with
+ * @param algorithm A Consumer function that takes an IBoardListener and performs operations to notify the listener.
*/
@Override
public void notifyBoardListeners(Consumer super IBoardListener> algorithm) {
@@ -620,9 +617,10 @@ public void notifyBoardListeners(Consumer super IBoardListener> algorithm) {
}
/**
- * Adds a board listener
+ * Adds a tree listener to the list of listeners.
+ * This allows the puzzle to notify the listener about changes to the tree.
*
- * @param listener listener to add
+ * @param listener The ITreeListener to be added to the list of listeners.
*/
@Override
public void addTreeListener(ITreeListener listener) {
@@ -630,9 +628,10 @@ public void addTreeListener(ITreeListener listener) {
}
/**
- * Removes a tree listener
+ * Removes a tree listener from the list of listeners.
+ * This prevents the puzzle from notifying the listener about future changes to the tree.
*
- * @param listener listener to remove
+ * @param listener The ITreeListener to be removed from the list of listeners.
*/
@Override
public void removeTreeListener(ITreeListener listener) {
@@ -640,9 +639,10 @@ public void removeTreeListener(ITreeListener listener) {
}
/**
- * Notifies listeners
+ * Notifies all registered tree listeners about changes.
+ * The provided algorithm is applied to each listener to process the notification.
*
- * @param algorithm algorithm to notify the listeners with
+ * @param algorithm A Consumer function that takes an ITreeListener and performs operations to notify the listener.
*/
@Override
public void notifyTreeListeners(Consumer super ITreeListener> algorithm) {
@@ -650,9 +650,10 @@ public void notifyTreeListeners(Consumer super ITreeListener> algorithm) {
}
/**
- * Check if the puzzle is valid
+ * Checks if the puzzle is valid.
+ * The implementation of this method can vary based on the specific criteria for puzzle validity.
*
- * @return if the puzzle is valid
+ * @return true if the puzzle is valid, false otherwise.
*/
public boolean checkValidity() {
return true;
diff --git a/src/main/java/edu/rpi/legup/model/PuzzleExporter.java b/src/main/java/edu/rpi/legup/model/PuzzleExporter.java
index 613d2ed1c..234d0f25c 100644
--- a/src/main/java/edu/rpi/legup/model/PuzzleExporter.java
+++ b/src/main/java/edu/rpi/legup/model/PuzzleExporter.java
@@ -3,25 +3,28 @@
import edu.rpi.legup.model.gameboard.PuzzleElement;
import edu.rpi.legup.model.tree.TreeNode;
import edu.rpi.legup.model.tree.TreeTransition;
-import org.w3c.dom.Document;
import edu.rpi.legup.save.ExportFileException;
-
+import java.io.File;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
-import java.io.File;
-import java.util.*;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.time.ZoneId;
-
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.w3c.dom.Document;
import org.w3c.dom.Element;
+/**
+ * Abstract class for exporting puzzle data to XML format.
+ * This class provides functionality to export a puzzle object, including its board and tree structure, to an XML file.
+ * Subclasses must implement methods to create specific elements for the board and the tree.
+ */
public abstract class PuzzleExporter {
private static final Logger LOGGER = LogManager.getLogger(PuzzleExporter.class.getName());
@@ -60,7 +63,8 @@ public void exportPuzzle(String fileName) throws ExportFileException {
legupElement.appendChild(puzzleElement);
puzzleElement.appendChild(createBoardElement(newDocument));
- if (puzzle.getTree() != null && !puzzle.getTree().getRootNode().getChildren().isEmpty()) {
+ if (puzzle.getTree() != null
+ && !puzzle.getTree().getRootNode().getChildren().isEmpty()) {
puzzleElement.appendChild(createProofElement(newDocument));
}
@@ -84,18 +88,30 @@ public void exportPuzzle(String fileName) throws ExportFileException {
StreamResult result = new StreamResult(new File(fileName));
transformer.transform(source, result);
- }
- catch (ParserConfigurationException | TransformerException e) {
+ } catch (ParserConfigurationException | TransformerException e) {
throw new ExportFileException("Puzzle Exporter: parser configuration exception");
- }
- catch (Exception e) {
+ } catch (Exception e) {
throw e;
- //throw new ExportFileException(e.getMessage());
+ // throw new ExportFileException(e.getMessage());
}
}
+ /**
+ * Creates an XML element representing the board of the puzzle.
+ * Subclasses must implement this method to provide the XML structure for the board.
+ *
+ * @param newDocument The XML document to create elements within.
+ * @return An XML element representing the puzzle's board.
+ */
protected abstract Element createBoardElement(Document newDocument);
+ /**
+ * Creates an XML element representing the proof of the puzzle, including its tree structure.
+ * This method is used to generate the proof section of the XML, which contains the tree representation.
+ *
+ * @param newDocument The XML document to create elements within.
+ * @return An XML element representing the proof of the puzzle.
+ */
protected Element createProofElement(Document newDocument) {
org.w3c.dom.Element proofElement = newDocument.createElement("proof");
org.w3c.dom.Element treeElement = createTreeElement(newDocument);
@@ -103,6 +119,13 @@ protected Element createProofElement(Document newDocument) {
return proofElement;
}
+ /**
+ * Creates an XML element representing the tree structure of the puzzle.
+ * This method traverses the tree nodes and transitions, and creates XML elements for each.
+ *
+ * @param newDocument The XML document to create elements within.
+ * @return An XML element representing the puzzle's tree structure.
+ */
protected Element createTreeElement(Document newDocument) {
org.w3c.dom.Element treeElement = newDocument.createElement("tree");
diff --git a/src/main/java/edu/rpi/legup/model/PuzzleImporter.java b/src/main/java/edu/rpi/legup/model/PuzzleImporter.java
index 327a92773..b1e8a2dd9 100644
--- a/src/main/java/edu/rpi/legup/model/PuzzleImporter.java
+++ b/src/main/java/edu/rpi/legup/model/PuzzleImporter.java
@@ -6,14 +6,19 @@
import edu.rpi.legup.model.rules.Rule;
import edu.rpi.legup.model.tree.*;
import edu.rpi.legup.save.InvalidFileFormatException;
+import java.util.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-import java.util.*;
-
+/**
+ * Abstract class for importing puzzle data from various sources into a puzzle object.
+ * This class provides methods to initialize and set up a puzzle, including its board and proof structure,
+ * from different input formats such as dimensions, statements, or XML files.
+ * Subclasses must implement methods to handle specific formats for board initialization and proof creation.
+ */
public abstract class PuzzleImporter {
private static final Logger LOGGER = LogManager.getLogger(PuzzleImporter.class.getName());
@@ -35,20 +40,27 @@ public PuzzleImporter(Puzzle puzzle) {
/**
* Initializes an empty puzzle
*
- * @param rows number of rows on the puzzle
+ * @param rows number of rows on the puzzle
* @param columns number of columns on the puzzle
* @throws RuntimeException if puzzle can not be made
*/
public void initializePuzzle(int rows, int columns) throws RuntimeException {
if (this.puzzle.isValidDimensions(rows, columns)) {
initializeBoard(rows, columns);
- }
- else {
+ } else {
throw new IllegalArgumentException("Invalid dimensions provided");
}
}
- public void initializePuzzle(String[] statements) throws InputMismatchException, IllegalArgumentException {
+ /**
+ * Initializes the puzzle with the given array of statements
+ *
+ * @param statements the statements used to initialize the puzzle
+ * @throws InputMismatchException if the input statements are invalid
+ * @throws IllegalArgumentException if the statements are not suitable for initializing the puzzle
+ */
+ public void initializePuzzle(String[] statements)
+ throws InputMismatchException, IllegalArgumentException {
// Note: Error checking for the statements will be left up to the puzzles that support
// text input. For example, some puzzles may be okay with "blank" statements (Strings with
// length = 0) while others may not.
@@ -56,10 +68,10 @@ public void initializePuzzle(String[] statements) throws InputMismatchException,
}
/**
- * Initializes the puzzle attributes
+ * Initializes the puzzle attributes from the XML document node
*
- * @param node xml document node
- * @throws InvalidFileFormatException if file is invalid
+ * @param node the XML document node representing the puzzle
+ * @throws InvalidFileFormatException if the file format is invalid
*/
public void initializePuzzle(Node node) throws InvalidFileFormatException {
if (node.getNodeName().equalsIgnoreCase("puzzle")) {
@@ -72,60 +84,85 @@ public void initializePuzzle(Node node) throws InvalidFileFormatException {
Node n = childNodes.item(i);
if (n.getNodeName().equalsIgnoreCase("board")) {
if (initBoard) {
- throw new InvalidFileFormatException("Puzzle creation error: duplicate board puzzleElement found");
+ throw new InvalidFileFormatException(
+ "Puzzle creation error: duplicate board puzzleElement found");
}
initializeBoard(n);
initBoard = true;
- }
- else {
+ } else {
if (n.getNodeName().equalsIgnoreCase("proof")) {
if (initProof) {
- throw new InvalidFileFormatException("Puzzle creation error: duplicate proof puzzleElement found");
+ throw new InvalidFileFormatException(
+ "Puzzle creation error: duplicate proof puzzleElement found");
}
if (!initBoard) {
- throw new InvalidFileFormatException("Puzzle creation error: could not find board puzzleElement");
+ throw new InvalidFileFormatException(
+ "Puzzle creation error: could not find board puzzleElement");
}
initializeProof(n);
initProof = true;
- }
- else {
+ } else {
if (!n.getNodeName().equalsIgnoreCase("#text")) {
- throw new InvalidFileFormatException("Puzzle creation error: unknown node found in file");
+ throw new InvalidFileFormatException(
+ "Puzzle creation error: unknown node found in file");
}
}
}
}
if (!initBoard) {
- throw new InvalidFileFormatException("Puzzle creation error: could not find board puzzleElement");
+ throw new InvalidFileFormatException(
+ "Puzzle creation error: could not find board puzzleElement");
}
if (!initProof) {
createDefaultTree();
}
- }
- else {
- throw new InvalidFileFormatException("Invalid file format; does not contain \"puzzle\" node");
+ } else {
+ throw new InvalidFileFormatException(
+ "Invalid file format; does not contain \"puzzle\" node");
}
}
/**
- * Creates the board for building
+ * Initializes the board with the specified number of rows and columns.
*
- * @param rows number of rows on the puzzle
- * @param columns number of columns on the puzzle
- * @throws RuntimeException if board can not be created
+ * @param rows the number of rows on the puzzle
+ * @param columns the number of columns on the puzzle
+ * @throws RuntimeException if the board cannot be created with the provided dimensions
*/
public abstract void initializeBoard(int rows, int columns);
/**
- * Creates an empty board for building
+ * Initializes the board from the XML document node.
*
- * @param node xml document node
- * @throws InvalidFileFormatException if file is invalid
+ * @param node the XML document node representing the board
+ * @throws InvalidFileFormatException if the file format is invalid
*/
public abstract void initializeBoard(Node node) throws InvalidFileFormatException;
- public abstract void initializeBoard(String[] statements) throws UnsupportedOperationException, IllegalArgumentException;
+ /**
+ * Initializes the board using an array of statements.
+ *
+ * @param statements the statements used to initialize the board
+ * @throws UnsupportedOperationException if the operation is not supported
+ * @throws IllegalArgumentException if the statements are not suitable for initializing the board
+ */
+ 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
@@ -143,21 +180,22 @@ public void initializeProof(Node node) throws InvalidFileFormatException {
Node n = treeList.item(i);
if (n.getNodeName().equalsIgnoreCase("tree")) {
if (initTree) {
- throw new InvalidFileFormatException("Proof Tree construction error: duplicate tree puzzleElement");
+ throw new InvalidFileFormatException(
+ "Proof Tree construction error: duplicate tree puzzleElement");
}
createTree(n);
initTree = true;
- }
- else {
- throw new InvalidFileFormatException("Proof Tree construction error: unknown puzzleElement found");
+ } else {
+ throw new InvalidFileFormatException(
+ "Proof Tree construction error: unknown puzzleElement found");
}
}
if (!initTree) {
createDefaultTree();
}
- }
- else {
- throw new InvalidFileFormatException("Invalid file format; does not contain \"proof\" node");
+ } else {
+ throw new InvalidFileFormatException(
+ "Invalid file format; does not contain \"proof\" node");
}
}
@@ -171,7 +209,8 @@ protected void setCells(Node node) throws InvalidFileFormatException {
NodeList dataList = ((org.w3c.dom.Element) node).getElementsByTagName("cell");
Board board = puzzle.getCurrentBoard();
for (int i = 0; i < dataList.getLength(); i++) {
- PuzzleElement data = puzzle.getFactory().importCell(dataList.item(i), puzzle.getCurrentBoard());
+ PuzzleElement data =
+ puzzle.getFactory().importCell(dataList.item(i), puzzle.getCurrentBoard());
board.setPuzzleElement(data.getIndex(), data);
}
}
@@ -199,15 +238,18 @@ protected void createTree(Node node) throws InvalidFileFormatException {
String nodeId = treeNodeElement.getAttribute("id");
String isRoot = treeNodeElement.getAttribute("root");
if (nodeId.isEmpty()) {
- throw new InvalidFileFormatException("Proof Tree construction error: cannot find node ID");
+ throw new InvalidFileFormatException(
+ "Proof Tree construction error: cannot find node ID");
}
if (treeNodes.containsKey(nodeId)) {
- throw new InvalidFileFormatException("Proof Tree construction error: duplicate tree node ID found");
+ throw new InvalidFileFormatException(
+ "Proof Tree construction error: duplicate tree node ID found");
}
TreeNode treeNode = new TreeNode(puzzle.getCurrentBoard().copy());
if (isRoot.equalsIgnoreCase("true")) {
if (tree.getRootNode() != null) {
- throw new InvalidFileFormatException("Proof Tree construction error: multiple root nodes declared");
+ throw new InvalidFileFormatException(
+ "Proof Tree construction error: multiple root nodes declared");
}
treeNode.setRoot(true);
tree.setRootNode(treeNode);
@@ -215,7 +257,6 @@ protected void createTree(Node node) throws InvalidFileFormatException {
treeNodes.put(nodeId, treeNode);
}
-
for (int i = 0; i < nodeList.getLength(); i++) {
org.w3c.dom.Element treeNodeElement = (org.w3c.dom.Element) nodeList.item(i);
String nodeId = treeNodeElement.getAttribute("id");
@@ -231,11 +272,10 @@ protected void createTree(Node node) throws InvalidFileFormatException {
transition.addParent(treeNode);
treeNode.addChild(transition);
continue;
+ } else {
+ throw new InvalidFileFormatException(
+ "Proof Tree construction error: duplicate transition ID found");
}
- else {
- throw new InvalidFileFormatException("Proof Tree construction error: duplicate transition ID found");
- }
-
}
String childId = trans.getAttribute("child");
@@ -250,7 +290,8 @@ protected void createTree(Node node) throws InvalidFileFormatException {
if (!ruleName.isEmpty()) {
rule = puzzle.getRuleByID(ruleId);
if (rule == null) {
- throw new InvalidFileFormatException("Proof Tree construction error: could not find rule by ID");
+ throw new InvalidFileFormatException(
+ "Proof Tree construction error: could not find rule by ID");
}
transition.setRule(rule);
}
@@ -266,14 +307,17 @@ protected void createTree(Node node) throws InvalidFileFormatException {
}
}
- //validateTreeStructure(treeNodes, treeTransitions);
+ // validateTreeStructure(treeNodes, treeTransitions);
System.err.println("Tree Size: " + treeTransitions.size());
for (Map.Entry entry : nodeChanges.entrySet()) {
makeTransitionChanges(entry.getKey(), entry.getValue());
}
}
- protected void validateTreeStructure(HashMap nodes, HashMap transitions) throws InvalidFileFormatException {
+
+ protected void validateTreeStructure(
+ HashMap nodes, HashMap transitions)
+ throws InvalidFileFormatException {
Tree tree = puzzle.getTree();
if (tree == null) {
@@ -300,25 +344,27 @@ protected void validateTreeStructure(HashMap nodes, HashMap nodes, HashMap mergingNodes = transition.getParents();
List mergingBoards = new ArrayList<>();
@@ -349,7 +405,8 @@ protected void makeTransitionChanges(TreeTransition transition, Node transElemen
TreeNode lca = Tree.getLowestCommonAncestor(mergingNodes);
if (lca == null) {
- throw new InvalidFileFormatException("Proof Tree construction error: unable to find merge node");
+ throw new InvalidFileFormatException(
+ "Proof Tree construction error: unable to find merge node");
}
Board lcaBoard = lca.getBoard();
@@ -360,28 +417,32 @@ protected void makeTransitionChanges(TreeTransition transition, Node transElemen
if (childNode != null) {
childNode.setBoard(mergedBoard.copy());
}
- }
- else {
+ } else {
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);
board.setPuzzleElement(cell.getIndex(), cell);
board.addModifiedData(cell);
transition.propagateChange(cell);
- }
- else {
+ } else {
if (!node.getNodeName().equalsIgnoreCase("#text")) {
- throw new InvalidFileFormatException("Proof Tree construction error: unknown node in transition");
+ throw new InvalidFileFormatException(
+ "Proof Tree construction error: unknown node in transition");
}
}
}
}
}
+ /**
+ * Creates a default proof tree with a single root node. The root node is initialized with the current board state.
+ * The created tree is then set as the proof tree for the puzzle.
+ */
protected void createDefaultTree() {
TreeNode root = new TreeNode(puzzle.getCurrentBoard());
root.setRoot(true);
@@ -391,7 +452,7 @@ protected void createDefaultTree() {
}
/**
- * Gets the result of building the Puzzle
+ * Gets the result of building the Puzzle object.
*
* @return puzzle
*/
diff --git a/src/main/java/edu/rpi/legup/model/RegisterPuzzle.java b/src/main/java/edu/rpi/legup/model/RegisterPuzzle.java
index 32f01edbc..c473e0ecd 100644
--- a/src/main/java/edu/rpi/legup/model/RegisterPuzzle.java
+++ b/src/main/java/edu/rpi/legup/model/RegisterPuzzle.java
@@ -5,8 +5,9 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+/**
+ * Annotation for registering puzzle classes with the puzzle framework.
+ */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
-public @interface RegisterPuzzle {
-
-}
+public @interface RegisterPuzzle {}
diff --git a/src/main/java/edu/rpi/legup/model/elements/Element.java b/src/main/java/edu/rpi/legup/model/elements/Element.java
index 7ab502c63..0adbbaf91 100644
--- a/src/main/java/edu/rpi/legup/model/elements/Element.java
+++ b/src/main/java/edu/rpi/legup/model/elements/Element.java
@@ -1,11 +1,13 @@
package edu.rpi.legup.model.elements;
-import edu.rpi.legup.model.rules.RuleType;
-
-import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
+import javax.swing.*;
+/**
+ * The Element class serves as an abstract base class for various elements used in the system.
+ * It handles basic properties such as ID, name, description, and image associated with the element.
+ */
@RegisterElement
public abstract class Element {
protected String elementID;
@@ -19,6 +21,14 @@ public abstract class Element {
private final String INVALID_USE_MESSAGE;
+ /**
+ * Constructs an Element with the specified ID, name, description, and image name
+ *
+ * @param elementID Unique identifier for the element
+ * @param elementName Name of the element
+ * @param description Description of the element
+ * @param imageName File name of the image associated with the element
+ */
public Element(String elementID, String elementName, String description, String imageName) {
this.elementID = elementID;
this.elementName = elementName;
@@ -28,13 +38,17 @@ public Element(String elementID, String elementName, String description, String
loadImage();
}
+ /**
+ * Loads the image for the element and resizes it to a width of 100 pixels while maintaining aspect ratio
+ */
private void loadImage() {
if (imageName != null) {
this.image = new ImageIcon(ClassLoader.getSystemClassLoader().getResource(imageName));
- //Resize images to be 100px wide
+ // Resize images to be 100px wide
Image image = this.image.getImage();
if (this.image.getIconWidth() < 120) return;
- int height = (int) (100 * ((double) this.image.getIconHeight() / this.image.getIconWidth()));
+ int height =
+ (int) (100 * ((double) this.image.getIconHeight() / this.image.getIconWidth()));
if (height == 0) {
System.out.println("height is 0 error");
System.out.println("height: " + this.image.getIconHeight());
@@ -48,30 +62,65 @@ private void loadImage() {
}
}
+ /**
+ * Gets the name of the element
+ *
+ * @return The name of the element
+ */
public String getElementName() {
return elementName;
}
+ /**
+ * Sets the name of the element
+ *
+ * @param elementName The new name for the element
+ */
public void setElementName(String elementName) {
this.elementName = elementName;
}
+ /**
+ * Gets the unique identifier of the element
+ *
+ * @return The ID of the element
+ */
public String getElementID() {
return elementID;
}
+ /**
+ * Gets the description of the element
+ *
+ * @return The description of the element
+ */
public String getDescription() {
return description;
}
+ /**
+ * Gets the image icon associated with the element
+ *
+ * @return The ImageIcon for the element
+ */
public ImageIcon getImageIcon() {
return image;
}
+ /**
+ * Gets the type of the element
+ *
+ * @return The ElementType of the element
+ */
public ElementType getElementType() {
return elementType;
}
+ /**
+ * Gets the message for invalid use of the rule
+ *
+ * @return The invalid use message
+ */
public String getInvalidUseOfRuleMessage() {
return this.INVALID_USE_MESSAGE;
}
diff --git a/src/main/java/edu/rpi/legup/model/elements/ElementType.java b/src/main/java/edu/rpi/legup/model/elements/ElementType.java
index ea47ca0eb..4fee79d4f 100644
--- a/src/main/java/edu/rpi/legup/model/elements/ElementType.java
+++ b/src/main/java/edu/rpi/legup/model/elements/ElementType.java
@@ -1,5 +1,9 @@
package edu.rpi.legup.model.elements;
+/**
+ * Enum representing the different types of elements that can be used in the system
+ */
public enum ElementType {
- PLACEABLE, NONPLACEABLE
+ PLACEABLE
+ //NONPLACEABLE COMBINED ALL PLACEABLE AND NONPLACEABLE INTO JUST ONE CATEGORY
}
diff --git a/src/main/java/edu/rpi/legup/model/elements/NonPlaceableElement.java b/src/main/java/edu/rpi/legup/model/elements/NonPlaceableElement.java
index 87859991f..019001128 100644
--- a/src/main/java/edu/rpi/legup/model/elements/NonPlaceableElement.java
+++ b/src/main/java/edu/rpi/legup/model/elements/NonPlaceableElement.java
@@ -1,8 +1,9 @@
-package edu.rpi.legup.model.elements;
-
-public abstract class NonPlaceableElement extends Element {
- public NonPlaceableElement(String elementID, String elementName, String description, String imageName) {
- super(elementID, elementName, description, imageName);
- this.elementType = ElementType.NONPLACEABLE;
- }
-}
+//package edu.rpi.legup.model.elements;
+//
+//public abstract class NonPlaceableElement extends Element {
+// public NonPlaceableElement(
+// String elementID, String elementName, String description, String imageName) {
+// super(elementID, elementName, description, imageName);
+// this.elementType = ElementType.PLACEABLE;
+// }
+//}
diff --git a/src/main/java/edu/rpi/legup/model/elements/PlaceableElement.java b/src/main/java/edu/rpi/legup/model/elements/PlaceableElement.java
index 2d018ddbb..79a0dcff8 100644
--- a/src/main/java/edu/rpi/legup/model/elements/PlaceableElement.java
+++ b/src/main/java/edu/rpi/legup/model/elements/PlaceableElement.java
@@ -1,7 +1,21 @@
package edu.rpi.legup.model.elements;
+/**
+ * Abstract class representing elements that can be placed within the system.
+ * Inherits from the {@link Element} class and sets the {@link ElementType} to {@link ElementType#PLACEABLE}.
+ */
public abstract class PlaceableElement extends Element {
- public PlaceableElement(String elementID, String elementName, String description, String imageName) {
+
+ /**
+ * Constructs a PlaceableElement with the specified details
+ *
+ * @param elementID Unique identifier for the element
+ * @param elementName Name of the element
+ * @param description Description of the element
+ * @param imageName Name of the image file representing the element
+ */
+ public PlaceableElement(
+ String elementID, String elementName, String description, String imageName) {
super(elementID, elementName, description, imageName);
this.elementType = ElementType.PLACEABLE;
}
diff --git a/src/main/java/edu/rpi/legup/model/elements/RegisterElement.java b/src/main/java/edu/rpi/legup/model/elements/RegisterElement.java
index bda3f3070..5f59ad795 100644
--- a/src/main/java/edu/rpi/legup/model/elements/RegisterElement.java
+++ b/src/main/java/edu/rpi/legup/model/elements/RegisterElement.java
@@ -3,9 +3,12 @@
import java.lang.annotation.*;
import java.lang.annotation.ElementType;
+/**
+ * Annotation to mark classes as elements that should be registered.
+ * This annotation is used to indicate that a class is an element within the system and should be registered
+ * for use within the application.
+ */
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
-public @interface RegisterElement {
-
-}
+public @interface RegisterElement {}
diff --git a/src/main/java/edu/rpi/legup/model/gameboard/Board.java b/src/main/java/edu/rpi/legup/model/gameboard/Board.java
index 4bf2ff548..4544caa36 100644
--- a/src/main/java/edu/rpi/legup/model/gameboard/Board.java
+++ b/src/main/java/edu/rpi/legup/model/gameboard/Board.java
@@ -5,15 +5,18 @@
import java.util.List;
import java.util.Set;
+/**
+ * Abstract class representing a game board.
+ * This class provides functionality for managing puzzle elements, tracking modifications,
+ * and determining if the board is modifiable.
+ */
public abstract class Board {
protected List puzzleElements;
protected Set modifiedData;
protected boolean isModifiable;
- /**
- * Board Constructor creates an empty board.
- */
+ /** Board Constructor creates an empty board. */
public Board() {
this.puzzleElements = new ArrayList<>();
this.modifiedData = new HashSet<>();
@@ -33,21 +36,24 @@ public Board(int size) {
}
/**
- * Gets a specific {@link PuzzleElement} on this board.
+ * Gets a specific {@link PuzzleElement} from the board.
*
- * @param puzzleElement equivalent puzzleElement
- * @return equivalent puzzleElement on this board
+ * @param puzzleElement the puzzle element to retrieve
+ * @return the puzzle element at the corresponding index, or null if not found
*/
public PuzzleElement getPuzzleElement(PuzzleElement puzzleElement) {
+ if (puzzleElement == null) {
+ return null;
+ }
int index = puzzleElement.getIndex();
return index < puzzleElements.size() ? puzzleElements.get(index) : null;
}
/**
- * Sets a specific {@link PuzzleElement} on the board.
+ * Sets a specific {@link PuzzleElement} on the board
*
- * @param index index of the puzzleElement
- * @param puzzleElement new puzzleElement at the index
+ * @param index index of the puzzleElement
+ * @param puzzleElement the puzzleElement to set at the index
*/
public void setPuzzleElement(int index, PuzzleElement puzzleElement) {
if (index < puzzleElements.size()) {
@@ -56,7 +62,7 @@ public void setPuzzleElement(int index, PuzzleElement puzzleElement) {
}
/**
- * Gets the number of elements on the board.
+ * Gets the number of elements on the board
*
* @return number of elements on the board
*/
@@ -139,8 +145,8 @@ public void removeModifiedData(PuzzleElement data) {
}
/**
- * Called when a {@link PuzzleElement} data on this has changed and passes in the equivalent puzzle element with
- * the new data.
+ * Called when a {@link PuzzleElement} data on this has changed and passes in the equivalent
+ * puzzle element with the new data.
*
* @param puzzleElement equivalent puzzle element with the new data.
*/
@@ -150,22 +156,20 @@ public void notifyChange(PuzzleElement puzzleElement) {
}
/**
- * Called when a {@link PuzzleElement} has been added and passes in the equivalent puzzle element with the data.
+ * Called when a {@link PuzzleElement} has been added and passes in the equivalent puzzle
+ * element with the data.
*
* @param puzzleElement equivalent puzzle element with the data.
*/
- public void notifyAddition(PuzzleElement puzzleElement) {
-
- }
+ public void notifyAddition(PuzzleElement puzzleElement) {}
/**
- * Called when a {@link PuzzleElement} has been deleted and passes in the equivalent puzzle element with the data.
+ * Called when a {@link PuzzleElement} has been deleted and passes in the equivalent puzzle
+ * element with the data.
*
* @param puzzleElement equivalent puzzle element with the data.
*/
- public void notifyDeletion(PuzzleElement puzzleElement) {
-
- }
+ public void notifyDeletion(PuzzleElement puzzleElement) {}
@SuppressWarnings("unchecked")
public Board mergedBoard(Board lca, List boards) {
diff --git a/src/main/java/edu/rpi/legup/model/gameboard/CaseBoard.java b/src/main/java/edu/rpi/legup/model/gameboard/CaseBoard.java
index 799825025..14dcb8609 100644
--- a/src/main/java/edu/rpi/legup/model/gameboard/CaseBoard.java
+++ b/src/main/java/edu/rpi/legup/model/gameboard/CaseBoard.java
@@ -1,54 +1,112 @@
package edu.rpi.legup.model.gameboard;
import edu.rpi.legup.model.rules.CaseRule;
-
import java.awt.event.MouseEvent;
import java.util.HashSet;
import java.util.Set;
+/**
+ * Represents a game board with specific rules for selecting puzzle elements.
+ * Extends the abstract `Board` class and adds functionality for handling pickable elements and case rules.
+ */
public class CaseBoard extends Board {
protected Board baseBoard;
protected CaseRule caseRule;
protected Set pickablePuzzleElements;
+ /**
+ * Constructs a CaseBoard with a base board and a case rule.
+ *
+ * @param baseBoard the base board to use for this CaseBoard
+ * @param caseRule the case rule applied to this CaseBoard
+ */
public CaseBoard(Board baseBoard, CaseRule caseRule) {
this.baseBoard = baseBoard;
this.caseRule = caseRule;
this.pickablePuzzleElements = new HashSet<>();
}
+ /**
+ * Adds a puzzle element to the set of pickable elements.
+ *
+ * @param puzzleElement the puzzle element to add
+ */
public void addPickableElement(PuzzleElement puzzleElement) {
pickablePuzzleElements.add(puzzleElement);
}
+ /**
+ * Removes a puzzle element from the set of pickable elements.
+ *
+ * @param puzzleElement the puzzle element to remove
+ */
public void removePickableElement(PuzzleElement puzzleElement) {
pickablePuzzleElements.remove(puzzleElement);
}
+ /**
+ * Checks if a puzzle element is pickable based on the mouse event.
+ *
+ * @param puzzleElement the puzzle element to check
+ * @param e the mouse event
+ * @return true if the puzzle element is pickable, false otherwise
+ */
public boolean isPickable(PuzzleElement puzzleElement, MouseEvent e) {
return pickablePuzzleElements.contains(baseBoard.getPuzzleElement(puzzleElement));
}
+ /**
+ * Retrieves the base board for this CaseBoard.
+ *
+ * @return the base board
+ */
public Board getBaseBoard() {
return baseBoard;
}
+ /**
+ * Sets the base board for this CaseBoard.
+ *
+ * @param baseBoard the new base board
+ */
public void setBaseBoard(Board baseBoard) {
this.baseBoard = baseBoard;
}
+ /**
+ * Retrieves the case rule for this CaseBoard.
+ *
+ * @return the case rule
+ */
public CaseRule getCaseRule() {
return caseRule;
}
+ /**
+ * Sets the case rule for this CaseBoard.
+ *
+ * @param caseRule the new case rule
+ */
public void setCaseRule(CaseRule caseRule) {
this.caseRule = caseRule;
}
+ /**
+ * Gets the count of pickable puzzle elements.
+ *
+ * @return the number of pickable elements
+ */
public int getCount() {
return pickablePuzzleElements.size();
}
+
+ /**
+ * Performs a deep copy of this CaseBoard.
+ * CURRENTLY NOT IMPLEMENTED AND RETURNS NULL
+ *
+ * @return a new copy of the CaseBoard
+ */
public CaseBoard copy() {
return null;
}
diff --git a/src/main/java/edu/rpi/legup/model/gameboard/ElementFactory.java b/src/main/java/edu/rpi/legup/model/gameboard/ElementFactory.java
index 99e9bf65a..131feb122 100644
--- a/src/main/java/edu/rpi/legup/model/gameboard/ElementFactory.java
+++ b/src/main/java/edu/rpi/legup/model/gameboard/ElementFactory.java
@@ -1,28 +1,33 @@
package edu.rpi.legup.model.gameboard;
+import edu.rpi.legup.save.InvalidFileFormatException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
-import edu.rpi.legup.save.InvalidFileFormatException;
+/**
+ * ElementFactory is an abstract class for importing and exporting {@link PuzzleElement} instances.
+ */
public abstract class ElementFactory {
/**
* Creates a {@link PuzzleElement} based on the xml document Node and adds it to the board.
*
- * @param node node that represents the puzzleElement
+ * @param node node that represents the puzzleElement
* @param board board to add the newly created cell
* @return newly created cell from the xml document Node
- * @throws InvalidFileFormatException thrown if the xml node is invalid for the specific puzzle element
+ * @throws InvalidFileFormatException thrown if the xml node is invalid for the specific puzzle
+ * element
*/
- public abstract PuzzleElement importCell(Node node, Board board) throws InvalidFileFormatException;
+ public abstract PuzzleElement importCell(Node node, Board board)
+ throws InvalidFileFormatException;
/**
* Creates a xml document {@link PuzzleElement} from a cell for exporting.
*
- * @param document xml document
+ * @param document xml document
* @param puzzleElement PuzzleElement cell
* @return xml PuzzleElement
*/
public abstract Element exportCell(Document document, PuzzleElement puzzleElement);
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/model/gameboard/GridBoard.java b/src/main/java/edu/rpi/legup/model/gameboard/GridBoard.java
index d31e8185a..7338132f8 100644
--- a/src/main/java/edu/rpi/legup/model/gameboard/GridBoard.java
+++ b/src/main/java/edu/rpi/legup/model/gameboard/GridBoard.java
@@ -1,13 +1,16 @@
package edu.rpi.legup.model.gameboard;
import edu.rpi.legup.model.elements.Element;
-import edu.rpi.legup.puzzle.nurikabe.NurikabeCell;
import edu.rpi.legup.puzzle.treetent.TreeTentBoard;
import edu.rpi.legup.puzzle.treetent.TreeTentClue;
-
import java.awt.*;
import java.awt.event.MouseEvent;
+/**
+ * GridBoard represents a grid-based board where each cell can be manipulated based on its
+ * coordinates. The board supports operations such as getting and setting cells, and provides
+ * dimensions of the grid. It also supports deep copying of the board.
+ */
public class GridBoard extends Board {
protected Dimension dimension;
@@ -15,7 +18,7 @@ public class GridBoard extends Board {
/**
* GridBoard Constructor creates a board for grid using puzzles from a width and height.
*
- * @param width width of the board
+ * @param width width of the board
* @param height height of the board
*/
public GridBoard(int width, int height) {
@@ -43,83 +46,88 @@ public GridBoard(int size) {
* @return grid cell at location (x, y)
*/
public GridCell getCell(int x, int y) {
- if (y * dimension.width + x >= puzzleElements.size() || x >= dimension.width ||
- y >= dimension.height || x < 0 || y < 0) {
- System.err.printf("not in bounds, bounds are %dx%d\n", dimension.width, dimension.height);
+ if (y * dimension.width + x >= puzzleElements.size()
+ || x >= dimension.width
+ || y >= dimension.height
+ || x < 0
+ || y < 0) {
+ System.err.printf(
+ "not in bounds, bounds are %dx%d\n", dimension.width, dimension.height);
return null;
}
return (GridCell) puzzleElements.get(y * dimension.width + x);
}
/**
- * Sets the {@link GridCell} at the location (x,y). This method does not set the cell if the location specified is
- * out of bounds.
+ * Sets the {@link GridCell} at the location (x,y). This method does not set the cell if the
+ * location specified is out of bounds.
*
- * @param x x location of the cell
- * @param y y location of the cell
+ * @param x x location of the cell
+ * @param y y location of the cell
* @param cell grid cell to set at location (x,y)
*/
public void setCell(int x, int y, GridCell cell) {
- if (y * dimension.width + x >= puzzleElements.size() || x >= dimension.width ||
- y >= dimension.height || x < 0 || y < 0) {
+ if (y * dimension.width + x >= puzzleElements.size()
+ || x >= dimension.width
+ || y >= dimension.height
+ || x < 0
+ || y < 0) {
return;
}
puzzleElements.set(y * dimension.width + x, cell);
}
public void setCell(int x, int y, Element e, MouseEvent m) {
- if (this instanceof TreeTentBoard && ((y == dimension.height && 0 <= x && x < dimension.width) || (x == dimension.width && 0 <= y && y < dimension.height))) {
+ if (this instanceof TreeTentBoard
+ && ((y == dimension.height && 0 <= x && x < dimension.width)
+ || (x == dimension.width && 0 <= y && y < dimension.height))) {
TreeTentBoard treeTentBoard = ((TreeTentBoard) this);
TreeTentClue clue = treeTentBoard.getClue(x, y);
if (y == dimension.height) {
if (m.getButton() == MouseEvent.BUTTON1) {
if (clue.getData() < dimension.height) {
clue.setData(clue.getData() + 1);
- }
- else {
+ } else {
clue.setData(0);
}
- }
- else {
+ } else {
if (clue.getData() > 0) {
clue.setData(clue.getData() - 1);
- }
- else {
+ } else {
clue.setData(dimension.height);
}
}
- }
- else { //x == dimension.width
+ } else { // x == dimension.width
if (m.getButton() == MouseEvent.BUTTON1) {
if (clue.getData() < dimension.width) {
clue.setData(clue.getData() + 1);
- }
- else {
+ } else {
clue.setData(0);
}
- }
- else {
+ } else {
if (clue.getData() > 0) {
clue.setData(clue.getData() - 1);
- }
- else {
+ } else {
clue.setData(dimension.width);
}
}
}
- }
- else {
- if (e != null && y * dimension.width + x >= puzzleElements.size() || x >= dimension.width ||
- y >= dimension.height || x < 0 || y < 0) {
+ } else {
+ if (e != null && y * dimension.width + x >= puzzleElements.size()
+ || x >= dimension.width
+ || y >= dimension.height
+ || x < 0
+ || y < 0) {
return;
- }
- else {
+ } else {
if (e != null) {
puzzleElements.get(y * dimension.width + x).setType(e, m);
}
}
}
-// puzzleElements.set(y * dimension.width + x, puzzleElements.get(y * dimension.width + x));
+ // puzzleElements.set(y * dimension.width + x, puzzleElements.get(y * dimension.width
+ // +
+ // x));
}
/**
@@ -163,4 +171,4 @@ public GridBoard copy() {
}
return newGridBoard;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/model/gameboard/GridCell.java b/src/main/java/edu/rpi/legup/model/gameboard/GridCell.java
index 8209c0b6f..5d6fe1ff3 100644
--- a/src/main/java/edu/rpi/legup/model/gameboard/GridCell.java
+++ b/src/main/java/edu/rpi/legup/model/gameboard/GridCell.java
@@ -2,13 +2,20 @@
import java.awt.*;
+/**
+ * GridCell represents a cell within a grid-based board. It holds data of type T and tracks its location
+ * on the board using a {@link Point}. The class extends from PuzzleElement and supports deep copying of
+ * the grid cell.
+ *
+ * @param the type of data held by the GridCell
+ */
public class GridCell extends PuzzleElement {
protected Point location;
/**
* GridCell Constructor creates a grid cell at the specified location given as a {@link Point}
*
- * @param value data value that represents the grid cell
+ * @param value data value that represents the grid cell
* @param location location on the board
*/
public GridCell(T value, Point location) {
@@ -20,8 +27,8 @@ public GridCell(T value, Point location) {
* GridCell Constructor creates a grid cell at the specified location given as x,y pair
*
* @param value data value that represents the grid cell
- * @param x x location
- * @param y y location
+ * @param x x location
+ * @param y y location
*/
public GridCell(T value, int x, int y) {
this(value, new Point(x, y));
@@ -59,4 +66,3 @@ public GridCell copy() {
return copy;
}
}
-
diff --git a/src/main/java/edu/rpi/legup/model/gameboard/GridRegion.java b/src/main/java/edu/rpi/legup/model/gameboard/GridRegion.java
new file mode 100644
index 000000000..b2a10a153
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/model/gameboard/GridRegion.java
@@ -0,0 +1,56 @@
+package edu.rpi.legup.model.gameboard;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * GridRegion represents a collection of cells within a grid. It manages a list of cells and provides
+ * methods to add, remove, and retrieve cells from the region.
+ *
+ * @param the type of cell managed by the GridRegion
+ */
+public abstract class GridRegion {
+
+ protected List regionCells;
+
+ /** Region Constructor */
+ public GridRegion() {
+ this.regionCells = new ArrayList<>();
+ }
+
+ /**
+ * Adds the cell to the region
+ *
+ * @param cell cell to be added to the region
+ */
+ public void addCell(T cell) {
+ regionCells.add(cell);
+ }
+
+ /**
+ * Removes the cell from the region
+ *
+ * @param cell cell to be removed from the region
+ */
+ public void removeCell(T cell) {
+ regionCells.remove(cell);
+ }
+
+ /**
+ * Returns the list of cells in the region
+ *
+ * @return list of cells in region
+ */
+ public List getCells() {
+ return regionCells;
+ }
+
+ /**
+ * Returns the number of cells in the region
+ *
+ * @return number of cells in the region
+ */
+ public int getSize() {
+ return regionCells.size();
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/model/gameboard/PuzzleElement.java b/src/main/java/edu/rpi/legup/model/gameboard/PuzzleElement.java
index 3d84287e3..a92b3efb0 100644
--- a/src/main/java/edu/rpi/legup/model/gameboard/PuzzleElement.java
+++ b/src/main/java/edu/rpi/legup/model/gameboard/PuzzleElement.java
@@ -1,25 +1,30 @@
package edu.rpi.legup.model.gameboard;
import edu.rpi.legup.model.elements.Element;
-
import java.awt.event.MouseEvent;
+/**
+ * PuzzleElement represents a single element in a puzzle grid. It holds data and provides various
+ * methods to manage and retrieve its properties, including modifiability, modification status, and validity.
+ *
+ * @param the type of data held by the PuzzleElement
+ */
public abstract class PuzzleElement {
protected int index;
protected T data;
protected boolean isModifiable;
protected boolean isModified;
+ protected boolean isModifiableCaseRule;
protected boolean isGiven;
protected boolean isValid;
protected int casesDepended;
- /**
- * PuzzleElement Constructor creates a new puzzle element.
- */
+ /** PuzzleElement Constructor creates a new puzzle element. */
public PuzzleElement() {
this.index = -1;
this.data = null;
this.isModifiable = true;
+ this.isModifiableCaseRule = true;
this.isModified = false;
this.isGiven = false;
this.isValid = true;
@@ -76,6 +81,24 @@ public void setModifiable(boolean isModifiable) {
this.isModifiable = isModifiable;
}
+ /**
+ * Gets whether this puzzle element is modifiable as a result of a case rule.
+ *
+ * @return true if this puzzle element is modifiable, false otherwise
+ */
+ public boolean isModifiableCaseRule() {
+ return isModifiableCaseRule;
+ }
+
+ /**
+ * Sets whether this puzzle element is modifiable as a result of a case rule.
+ *
+ * @param isModifiableCaseRule true if this puzzle element is modifiable, false otherwise
+ */
+ public void setModifiableCaseRule(boolean isModifiableCaseRule) {
+ this.isModifiableCaseRule = isModifiableCaseRule;
+ }
+
/**
* Gets whether the puzzle element has been modified.
*
@@ -131,8 +154,8 @@ public void setGiven(boolean given) {
}
/**
- * Get whether this puzzle element data is a valid change according to the rule applied to the transition that
- * this puzzle element is contained in.
+ * Get whether this puzzle element data is a valid change according to the rule applied to the
+ * transition that this puzzle element is contained in.
*
* @return true if the puzzle element logically follows from the rule, otherwise false.
*/
@@ -141,8 +164,8 @@ public boolean isValid() {
}
/**
- * Sets whether this puzzle element data is a valid change according to the rule applied to the transition that
- * this puzzle element is contained in.
+ * Sets whether this puzzle element data is a valid change according to the rule applied to the
+ * transition that this puzzle element is contained in.
*
* @param isValid true if the puzzle element logically follows from the rule, otherwise false.
*/
diff --git a/src/main/java/edu/rpi/legup/model/observer/IBoardListener.java b/src/main/java/edu/rpi/legup/model/observer/IBoardListener.java
index 461128562..fa440369c 100644
--- a/src/main/java/edu/rpi/legup/model/observer/IBoardListener.java
+++ b/src/main/java/edu/rpi/legup/model/observer/IBoardListener.java
@@ -4,6 +4,10 @@
import edu.rpi.legup.model.gameboard.PuzzleElement;
import edu.rpi.legup.model.tree.TreeElement;
+/**
+ * IBoardListener defines methods for receiving notifications about changes to the board,
+ * including updates to tree elements, case boards, and puzzle elements.
+ */
public interface IBoardListener {
/**
* Called when the tree element has changed.
@@ -13,7 +17,7 @@ public interface IBoardListener {
void onTreeElementChanged(TreeElement treeElement);
/**
- * Called when the a case board has been added to the view.
+ * Called when a case board has been added to the view.
*
* @param caseBoard case board to be added
*/
diff --git a/src/main/java/edu/rpi/legup/model/observer/IBoardSubject.java b/src/main/java/edu/rpi/legup/model/observer/IBoardSubject.java
index c7bf13141..53bfe444b 100644
--- a/src/main/java/edu/rpi/legup/model/observer/IBoardSubject.java
+++ b/src/main/java/edu/rpi/legup/model/observer/IBoardSubject.java
@@ -2,6 +2,10 @@
import java.util.function.Consumer;
+/**
+ * IBoardSubject defines methods for managing and notifying board listeners.
+ * It allows for adding and removing listeners, and for notifying them using a specified algorithm.
+ */
public interface IBoardSubject {
/**
* Adds a board listener.
@@ -18,7 +22,7 @@ public interface IBoardSubject {
void removeBoardListener(IBoardListener listener);
/**
- * Notifies all of the listeners using the specified algorithm.
+ * Notifies all the listeners using the specified algorithm.
*
* @param algorithm algorithm used to notify the listeners
*/
diff --git a/src/main/java/edu/rpi/legup/model/observer/ITreeListener.java b/src/main/java/edu/rpi/legup/model/observer/ITreeListener.java
index d8fa24166..c5a0355ca 100644
--- a/src/main/java/edu/rpi/legup/model/observer/ITreeListener.java
+++ b/src/main/java/edu/rpi/legup/model/observer/ITreeListener.java
@@ -3,6 +3,10 @@
import edu.rpi.legup.model.tree.TreeElement;
import edu.rpi.legup.ui.proofeditorui.treeview.TreeViewSelection;
+/**
+ * ITreeListener defines methods for handling events related to changes in the tree.
+ * Implementations of this interface are notified of additions, removals, and selection changes in the tree.
+ */
public interface ITreeListener {
/**
* Called when a {@link TreeElement} is added to the tree.
@@ -25,8 +29,6 @@ public interface ITreeListener {
*/
void onTreeSelectionChanged(TreeViewSelection selection);
- /**
- * Called when the model has finished updating the tree.
- */
+ /** Called when the model has finished updating the tree. */
void onUpdateTree();
}
diff --git a/src/main/java/edu/rpi/legup/model/observer/ITreeSubject.java b/src/main/java/edu/rpi/legup/model/observer/ITreeSubject.java
index 66d5d9a5e..0b0aee348 100644
--- a/src/main/java/edu/rpi/legup/model/observer/ITreeSubject.java
+++ b/src/main/java/edu/rpi/legup/model/observer/ITreeSubject.java
@@ -2,9 +2,13 @@
import java.util.function.Consumer;
+/**
+ * ITreeSubject defines methods for managing and notifying listeners about changes to the tree model.
+ * Implementations of this interface handle adding, removing, and notifying listeners.
+ */
public interface ITreeSubject {
/**
- * Adds a board listener.
+ * Adds a tree listener.
*
* @param listener listener to add
*/
@@ -18,7 +22,7 @@ public interface ITreeSubject {
void removeTreeListener(ITreeListener listener);
/**
- * Notifies all of the listeners using the specified algorithm.
+ * Notifies all the tree listeners using the specified algorithm.
*
* @param algorithm algorithm used to notify the listeners
*/
diff --git a/src/main/java/edu/rpi/legup/model/rules/CaseRule.java b/src/main/java/edu/rpi/legup/model/rules/CaseRule.java
index a01db2b6d..ee5c91229 100644
--- a/src/main/java/edu/rpi/legup/model/rules/CaseRule.java
+++ b/src/main/java/edu/rpi/legup/model/rules/CaseRule.java
@@ -1,37 +1,45 @@
package edu.rpi.legup.model.rules;
+import static edu.rpi.legup.model.rules.RuleType.CASE;
+
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.tree.TreeNode;
import edu.rpi.legup.model.tree.TreeTransition;
-
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
-import static edu.rpi.legup.model.rules.RuleType.CASE;
-
+/**
+ * CaseRule is an abstract class representing a rule that can be applied with multiple cases in a puzzle board.
+ * It defines methods for applying and checking the rule, as well as retrieving the necessary elements.
+ */
public abstract class CaseRule extends Rule {
private final String INVALID_USE_MESSAGE;
+ public int MAX_CASES;
+ public int MIN_CASES;
/**
* CaseRule Constructor creates a new case rule.
*
- * @param ruleID ID of the rule
- * @param ruleName name of the rule
+ * @param ruleID ID of the rule
+ * @param ruleName name of the rule
* @param description description of the rule
- * @param imageName file name of the image
+ * @param imageName file name of the image
*/
public CaseRule(String ruleID, String ruleName, String description, String imageName) {
super(ruleID, ruleName, description, imageName);
this.ruleType = CASE;
this.INVALID_USE_MESSAGE = "Invalid use of the case rule " + this.ruleName;
+ this.MAX_CASES = 10;
+ this.MIN_CASES = 1; // By default, this will not actually have any effect
}
/**
- * Gets the case board that indicates where this case rule can be applied on the given {@link Board}.
+ * Gets the case board that indicates where this case rule can be applied on the given {@link
+ * Board}.
*
* @param board board to find locations where this case rule can be applied
* @return a case board
@@ -39,16 +47,18 @@ public CaseRule(String ruleID, String ruleName, String description, String image
public abstract CaseBoard getCaseBoard(Board board);
/**
- * Gets the possible cases for this {@link Board} at a specific {@link PuzzleElement} based on this case rule.
+ * Gets the possible cases for this {@link Board} at a specific {@link PuzzleElement} based on
+ * this case rule.
*
- * @param board the current board state
+ * @param board the current board state
* @param puzzleElement equivalent puzzleElement
* @return a list of elements the specified could be
*/
public abstract List getCases(Board board, PuzzleElement puzzleElement);
/**
- * Checks whether the {@link TreeTransition} logically follows from the parent node using this rule.
+ * Checks whether the {@link TreeTransition} logically follows from the parent node using this
+ * rule.
*
* @param transition transition to check
* @return null if the child node logically follow from the parent node, otherwise error message
@@ -61,11 +71,11 @@ public String checkRule(TreeTransition transition) {
}
for (TreeTransition childTrans : parentNodes.get(0).getChildren()) {
- if (childTrans.getRule() == null || !childTrans.getRule().getClass().equals(this.getClass())) {
+ if (childTrans.getRule() == null
+ || !childTrans.getRule().getClass().equals(this.getClass())) {
return "All children nodes must be justified with the same case rule.";
}
}
-
String check = checkRuleRaw(transition);
// Mark transition and new data as valid or not
@@ -81,8 +91,8 @@ public String checkRule(TreeTransition transition) {
}
/**
- * Checks whether the {@link TreeTransition} logically follows from the parent node using this rule. This method is
- * the one that should overridden in child classes.
+ * Checks whether the {@link TreeTransition} logically follows from the parent node using this
+ * rule. This method is the one that should overridden in child classes.
*
* @param transition transition to check
* @return null if the child node logically follow from the parent node, otherwise error message
@@ -91,13 +101,13 @@ public String checkRule(TreeTransition transition) {
public abstract String checkRuleRaw(TreeTransition transition);
/**
- * Checks whether the child node logically follows from the parent node at the specific puzzleElement index using
- * this rule.
+ * 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 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
+ * @return null if the child node logically follow from the parent node at the specified
+ * puzzleElement, otherwise error message
*/
@Override
public String checkRuleAt(TreeTransition transition, PuzzleElement puzzleElement) {
@@ -105,34 +115,35 @@ public String checkRuleAt(TreeTransition transition, PuzzleElement puzzleElement
}
/**
- * Checks whether the child node logically follows from the parent node at the specific puzzleElement index using
- * this rule. This method is the one that should overridden in child classes.
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule. This method is the one that should overridden in child
+ * classes.
*
- * @param transition transition to check
+ * @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
+ * @return null if the child node logically follow from the parent node at the specified
+ * puzzleElement, otherwise error message
*/
@Override
public abstract String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement);
/**
- * Returns the elements necessary for the cases returned by getCases(board,puzzleElement) to be valid
- * Overridden by case rules dependent on more than just the modified data
+ * Returns the elements necessary for the cases returned by getCases(board,puzzleElement) to be
+ * valid Overridden by case rules dependent on more than just the modified data
*
- * @param board board state at application
+ * @param board board state at application
* @param puzzleElement selected puzzleElement
- * @return List of puzzle elements (typically cells) this application of the case rule depends upon.
- * Defaults to any element modified by any case
+ * @return List of puzzle elements (typically cells) this application of the case rule depends
+ * upon. Defaults to any element modified by any case
*/
public List dependentElements(Board board, PuzzleElement puzzleElement) {
List elements = new ArrayList<>();
- List cases = getCases(board,puzzleElement);
+ List cases = getCases(board, puzzleElement);
for (Board caseBoard : cases) {
Set data = caseBoard.getModifiedData();
for (PuzzleElement element : data) {
- if(!elements.contains(board.getPuzzleElement(element))){
+ if (!elements.contains(board.getPuzzleElement(element))) {
elements.add(board.getPuzzleElement(element));
}
}
@@ -141,5 +152,3 @@ public List dependentElements(Board board, PuzzleElement puzzleEl
return elements;
}
}
-
-
diff --git a/src/main/java/edu/rpi/legup/model/rules/ContradictionRule.java b/src/main/java/edu/rpi/legup/model/rules/ContradictionRule.java
index 0d3a79a98..cd2e20081 100644
--- a/src/main/java/edu/rpi/legup/model/rules/ContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/model/rules/ContradictionRule.java
@@ -1,22 +1,27 @@
package edu.rpi.legup.model.rules;
+import static edu.rpi.legup.model.rules.RuleType.CONTRADICTION;
+
import edu.rpi.legup.model.gameboard.Board;
import edu.rpi.legup.model.gameboard.PuzzleElement;
import edu.rpi.legup.model.tree.TreeTransition;
-import static edu.rpi.legup.model.rules.RuleType.CONTRADICTION;
-
+/**
+ * ContradictionRule is an abstract class representing a rule that identifies contradictions in a puzzle.
+ * It provides methods to check for contradictions both globally and at specific puzzle elements.
+ */
public abstract class ContradictionRule extends Rule {
- private final String NO_CONTRADICTION_MESSAGE = "No instance of the contradiction " + this.ruleName + " here";
+ private final String NO_CONTRADICTION_MESSAGE =
+ "No instance of the contradiction " + this.ruleName + " here";
/**
* ContradictionRule Constructor creates a new contradiction rule
*
- * @param ruleID ID of the rule
- * @param ruleName name of the rule
+ * @param ruleID ID of the rule
+ * @param ruleName name of the rule
* @param description description of the rule
- * @param imageName file name of the image
+ * @param imageName file name of the image
*/
public ContradictionRule(String ruleID, String ruleName, String description, String imageName) {
super(ruleID, ruleName, description, imageName);
@@ -35,13 +40,13 @@ public String checkRule(TreeTransition transition) {
}
/**
- * Checks whether the child node logically follows from the parent node
- * at the specific puzzleElement index using this rule
+ * 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 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
+ * @return null if the child node logically follow from the parent node at the specified
+ * puzzleElement, otherwise error message
*/
@Override
public String checkRuleAt(TreeTransition transition, PuzzleElement puzzleElement) {
@@ -49,8 +54,8 @@ public String checkRuleAt(TreeTransition transition, PuzzleElement puzzleElement
}
/**
- * Checks whether the transition logically follows from the parent node using this rule.
- * This method is the one that should overridden in child classes
+ * Checks whether the transition logically follows from the parent node using this rule. This
+ * method is the one that should overridden in child classes
*
* @param transition transition to check
* @return null if the child node logically follow from the parent node, otherwise error message
@@ -61,14 +66,14 @@ public String checkRuleRaw(TreeTransition transition) {
}
/**
- * Checks whether the child node logically follows from the parent node
- * at the specific puzzleElement index using this rule
- * This method is the one that should overridden in child classes
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule This method is the one that should overridden in child
+ * classes
*
- * @param transition transition to check
+ * @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
+ * @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) {
@@ -96,13 +101,13 @@ public String getNoContradictionMessage() {
}
/**
- * Checks whether the transition has a contradiction at the specific puzzleElement index using this rule
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
*
- * @param board board to check contradiction
+ * @param board board to check contradiction
* @param puzzleElement equivalent puzzleElement
* @return null if the transition contains a contradiction at the specified puzzleElement,
- * otherwise error message
+ * otherwise error message
*/
public abstract String checkContradictionAt(Board board, PuzzleElement puzzleElement);
-
}
diff --git a/src/main/java/edu/rpi/legup/model/rules/DirectRule.java b/src/main/java/edu/rpi/legup/model/rules/DirectRule.java
index 847764b7b..613574989 100644
--- a/src/main/java/edu/rpi/legup/model/rules/DirectRule.java
+++ b/src/main/java/edu/rpi/legup/model/rules/DirectRule.java
@@ -1,105 +1,108 @@
-package edu.rpi.legup.model.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.model.tree.TreeNode;
-import edu.rpi.legup.model.tree.TreeTransition;
-
-import static edu.rpi.legup.model.rules.RuleType.BASIC;
-
-public abstract class DirectRule extends Rule {
- /**
- * DirectRule Constructor creates a new basic rule.
- *
- * @param ruleID ID of the rule
- * @param ruleName name of the rule
- * @param description description of the rule
- * @param imageName file name of the image
- */
- public DirectRule(String ruleID, String ruleName, String description, String imageName) {
- super(ruleID, ruleName, description, imageName);
- this.ruleType = BASIC;
- }
-
- /**
- * Checks whether the {@link TreeTransition} logically follows from the parent node using this rule.
- *
- * @param transition transition to check
- * @return null if the child node logically follow from the parent node, otherwise error message
- */
- public String checkRule(TreeTransition transition) {
- Board finalBoard = transition.getBoard();
- if (transition.getParents().size() != 1 ||
- transition.getParents().get(0).getChildren().size() != 1) {
- return "State must have only 1 parent and 1 child";
- }
- else if (finalBoard.getModifiedData().isEmpty()) {
- // null transition
- return null;
- }
- else {
- return checkRuleRaw(transition);
- }
- }
-
- /**
- * Checks whether the {@link TreeTransition} logically follows from the parent node using this rule. This method is
- * the one that should overridden in child classes.
- *
- * @param transition transition to check
- * @return null if the child node logically follow from the parent node, otherwise error message
- */
- public String checkRuleRaw(TreeTransition transition) {
- Board finalBoard = transition.getBoard();
- String checkStr = null;
-
- // Go directly to specific direct rule's judgement if no cell's are edited
- if (finalBoard.getModifiedData().size() == 0) {
- checkStr = checkRuleRawAt(transition, null);
- }
- for (PuzzleElement puzzleElement : finalBoard.getModifiedData()) {
- String tempStr = checkRuleAt(transition, puzzleElement);
- if (tempStr != null) {
- checkStr = tempStr;
- }
- }
- return checkStr;
- }
-
- /**
- * Checks whether the child node logically follows from the parent node at the specific {@link PuzzleElement} 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
- */
- public String checkRuleAt(TreeTransition transition, PuzzleElement puzzleElement) {
- Board finalBoard = transition.getBoard();
- puzzleElement = finalBoard.getPuzzleElement(puzzleElement);
- String checkStr;
- if (!puzzleElement.isModified()) {
- checkStr = "PuzzleElement must be modified";
- }
- else {
- if (transition.getParents().size() != 1 ||
- transition.getParents().get(0).getChildren().size() != 1) {
- checkStr = "State must have only 1 parent and 1 child";
- }
- else {
- checkStr = checkRuleRawAt(transition, puzzleElement);
- }
- }
- puzzleElement.setValid(checkStr == null);
- return checkStr;
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- public abstract Board getDefaultBoard(TreeNode node);
-}
+package edu.rpi.legup.model.rules;
+
+import static edu.rpi.legup.model.rules.RuleType.BASIC;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+
+/**
+ * DirectRule is an abstract class representing a direct rule for transitions in a puzzle.
+ * It provides methods for checking whether transitions and specific puzzle elements follow the rule.
+ */
+public abstract class DirectRule extends Rule {
+ /**
+ * DirectRule Constructor creates a new basic rule.
+ *
+ * @param ruleID ID of the rule
+ * @param ruleName name of the rule
+ * @param description description of the rule
+ * @param imageName file name of the image
+ */
+ public DirectRule(String ruleID, String ruleName, String description, String imageName) {
+ super(ruleID, ruleName, description, imageName);
+ this.ruleType = BASIC;
+ }
+
+ /**
+ * Checks whether the {@link TreeTransition} logically follows from the parent node using this
+ * rule.
+ *
+ * @param transition transition to check
+ * @return null if the child node logically follow from the parent node, otherwise error message
+ */
+ public String checkRule(TreeTransition transition) {
+ Board finalBoard = transition.getBoard();
+ // System.out.println(finalBoard.getModifiedData().size());
+ if (transition.getParents().size() != 1
+ || transition.getParents().get(0).getChildren().size() != 1) {
+ return "State must have only 1 parent and 1 child";
+ } else if (finalBoard.getModifiedData().isEmpty()) {
+ // null transition
+ return null;
+ } else {
+ return checkRuleRaw(transition);
+ }
+ }
+
+ /**
+ * Checks whether the {@link TreeTransition} logically follows from the parent node using this
+ * rule. This method is the one that should overridden in child classes.
+ *
+ * @param transition transition to check
+ * @return null if the child node logically follow from the parent node, otherwise error message
+ */
+ public String checkRuleRaw(TreeTransition transition) {
+ Board finalBoard = transition.getBoard();
+ String checkStr = null;
+
+ // Go directly to specific direct rule's judgement if no cell's are edited
+ if (finalBoard.getModifiedData().size() == 0) {
+ checkStr = checkRuleRawAt(transition, null);
+ }
+ for (PuzzleElement puzzleElement : finalBoard.getModifiedData()) {
+ String tempStr = checkRuleAt(transition, puzzleElement);
+ if (tempStr != null) {
+ checkStr = tempStr;
+ }
+ }
+ return checkStr;
+ }
+
+ /**
+ * Checks whether the child node logically follows from the parent node at the specific {@link
+ * PuzzleElement} 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
+ */
+ public String checkRuleAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ Board finalBoard = transition.getBoard();
+ puzzleElement = finalBoard.getPuzzleElement(puzzleElement);
+ String checkStr;
+ if (!puzzleElement.isModified()) {
+ checkStr = "PuzzleElement must be modified";
+ } else {
+ if (transition.getParents().size() != 1
+ || transition.getParents().get(0).getChildren().size() != 1) {
+ checkStr = "State must have only 1 parent and 1 child";
+ } else {
+ checkStr = checkRuleRawAt(transition, puzzleElement);
+ }
+ }
+ puzzleElement.setValid(checkStr == null);
+ return checkStr;
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ public abstract Board getDefaultBoard(TreeNode node);
+}
diff --git a/src/main/java/edu/rpi/legup/model/rules/MergeRule.java b/src/main/java/edu/rpi/legup/model/rules/MergeRule.java
index 9ae18648e..f7bd887f3 100644
--- a/src/main/java/edu/rpi/legup/model/rules/MergeRule.java
+++ b/src/main/java/edu/rpi/legup/model/rules/MergeRule.java
@@ -1,33 +1,33 @@
package edu.rpi.legup.model.rules;
+import static edu.rpi.legup.model.rules.RuleType.MERGE;
+
import edu.rpi.legup.model.gameboard.Board;
import edu.rpi.legup.model.gameboard.PuzzleElement;
import edu.rpi.legup.model.tree.Tree;
import edu.rpi.legup.model.tree.TreeNode;
import edu.rpi.legup.model.tree.TreeTransition;
-
import java.util.ArrayList;
import java.util.List;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import static edu.rpi.legup.model.rules.RuleType.MERGE;
-
+/**
+ * MergeRule is an implementation of a rule that merges multiple nodes into one.
+ * It validates if the merging of nodes is done correctly.
+ */
public class MergeRule extends Rule {
- /**
- * MergeRule Constructor merges to board states together
- */
+ /** MergeRule Constructor merges to board states together */
public MergeRule() {
- super("MERGE", "Merge Rule",
+ super(
+ "MERGE",
+ "Merge Rule",
"Merge any number of nodes into one",
"edu/rpi/legup/images/Legup/MergeRule.png");
this.ruleType = MERGE;
}
/**
- * Checks whether the transition logically follows from the parent node using this rule.
- * This method is the one that should overridden in child classes
+ * Checks whether the transition logically follows from the parent node using this rule. This
+ * method is the one that should have overridden in child classes
*
* @param transition transition to check
* @return null if the child node logically follow from the parent node, otherwise error message
@@ -61,14 +61,14 @@ public String checkRuleRaw(TreeTransition transition) {
}
/**
- * Checks whether the child node logically follows from the parent node
- * at the specific puzzleElement index using this rule
- * This method is the one that should overridden in child classes
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule This method is the one that should overridden in child
+ * classes
*
- * @param transition transition to check
+ * @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
+ * @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) {
@@ -87,13 +87,13 @@ public String checkRule(TreeTransition transition) {
}
/**
- * Checks whether the child node logically follows from the parent node
- * at the specific puzzleElement index using this rule
+ * 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 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
+ * @return null if the child node logically follow from the parent node at the specified
+ * puzzleElement, otherwise error message
*/
@Override
public String checkRuleAt(TreeTransition transition, PuzzleElement puzzleElement) {
diff --git a/src/main/java/edu/rpi/legup/model/rules/RegisterRule.java b/src/main/java/edu/rpi/legup/model/rules/RegisterRule.java
index 40def6edd..d357e0d86 100644
--- a/src/main/java/edu/rpi/legup/model/rules/RegisterRule.java
+++ b/src/main/java/edu/rpi/legup/model/rules/RegisterRule.java
@@ -2,9 +2,12 @@
import java.lang.annotation.*;
+/**
+ * Annotation to register a class as a rule in the system.
+ * This annotation can be applied to rule classes to indicate that they should be registered
+ * in the rule system.
+ */
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
-public @interface RegisterRule {
-
-}
+public @interface RegisterRule {}
diff --git a/src/main/java/edu/rpi/legup/model/rules/Rule.java b/src/main/java/edu/rpi/legup/model/rules/Rule.java
index 50f2cf962..107e72712 100644
--- a/src/main/java/edu/rpi/legup/model/rules/Rule.java
+++ b/src/main/java/edu/rpi/legup/model/rules/Rule.java
@@ -1,18 +1,19 @@
package edu.rpi.legup.model.rules;
+import edu.rpi.legup.app.LegupPreferences;
import edu.rpi.legup.model.gameboard.PuzzleElement;
import edu.rpi.legup.model.tree.TreeTransition;
-
-import edu.rpi.legup.app.LegupPreferences;
-
-import javax.swing.ImageIcon;
-import java.awt.image.BufferedImage;
-import java.awt.Image;
import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import javax.swing.ImageIcon;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
+/**
+ * Abstract base class for defining rules.
+ * This class encapsulates the common functionality and attributes of all rules,
+ * including rule identification, description, image handling, and validation logic.
+ * Subclasses must provide implementations for specific rule checking logic.
+ */
@RegisterRule
public abstract class Rule {
protected String ruleID;
@@ -27,10 +28,10 @@ public abstract class Rule {
/**
* Rule Constructor creates a new rule
*
- * @param ruleID ID of the rule
- * @param ruleName name of the rule
+ * @param ruleID ID of the rule
+ * @param ruleName name of the rule
* @param description description of the rule
- * @param imageName file name of the image
+ * @param imageName file name of the image
*/
public Rule(String ruleID, String ruleName, String description, String imageName) {
this.ruleID = ruleID;
@@ -50,8 +51,8 @@ public Rule(String ruleID, String ruleName, String description, String imageName
public abstract String checkRule(TreeTransition transition);
/**
- * Checks whether the transition logically follows from the parent node using this rule.
- * This method is the one that should overridden in child classes
+ * Checks whether the transition logically follows from the parent node using this rule. This
+ * method is the one that should overridden in child classes
*
* @param transition transition to check
* @return null if the child node logically follow from the parent node, otherwise error message
@@ -59,43 +60,44 @@ public Rule(String ruleID, String ruleName, String description, String imageName
protected abstract String checkRuleRaw(TreeTransition transition);
/**
- * Checks whether the child node logically follows from the parent node
- * at the specific puzzleElement index using this rule
+ * 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 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
+ * @return null if the child node logically follow from the parent node at the specified
+ * puzzleElement, otherwise error message
*/
public abstract String checkRuleAt(TreeTransition transition, PuzzleElement puzzleElement);
/**
- * Checks whether the child node logically follows from the parent node
- * at the specific puzzleElement index using this rule
- * This method is the one that should overridden in child classes
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule This method is the one that should overridden in child
+ * classes
*
- * @param transition transition to check
+ * @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
+ * @return null if the child node logically follow from the parent node at the specified
+ * puzzleElement, otherwise error message
*/
- protected abstract String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement);
+ protected abstract String checkRuleRawAt(
+ TreeTransition transition, PuzzleElement puzzleElement);
- /**
- * Loads the image file
- */
+ /** Loads the image file */
public void loadImage() {
if (imageName != null) {
String name = imageName;
LegupPreferences prefs = LegupPreferences.getInstance();
- if (name.contains("shorttruthtable") && prefs.getUserPref(LegupPreferences.COLOR_BLIND).equals("true")) {
+ if (name.contains("shorttruthtable")
+ && prefs.getUserPref(LegupPreferences.COLOR_BLIND).equals("true")) {
name = name.replace("ruleimages", "ruleimages_cb");
}
this.image = new ImageIcon(ClassLoader.getSystemClassLoader().getResource(name));
- //Resize images to be 100px wide
+ // Resize images to be 100px wide
Image image = this.image.getImage();
if (this.image.getIconWidth() < 120) return;
- int height = (int) (100 * ((double) this.image.getIconHeight() / this.image.getIconWidth()));
+ int height =
+ (int) (100 * ((double) this.image.getIconHeight() / this.image.getIconWidth()));
if (height == 0) {
System.out.println("height is 0 error");
System.out.println("height: " + this.image.getIconHeight());
@@ -163,7 +165,12 @@ public RuleType getRuleType() {
return ruleType;
}
+ /**
+ * Gets the message indicating an invalid use of the rule.
+ *
+ * @return the invalid use message
+ */
public String getInvalidUseOfRuleMessage() {
return this.INVALID_USE_MESSAGE;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/model/rules/RuleType.java b/src/main/java/edu/rpi/legup/model/rules/RuleType.java
index b7ce315cf..e72118e3c 100644
--- a/src/main/java/edu/rpi/legup/model/rules/RuleType.java
+++ b/src/main/java/edu/rpi/legup/model/rules/RuleType.java
@@ -1,5 +1,12 @@
package edu.rpi.legup.model.rules;
+/**
+ * Enumeration representing different types of rules in the rule-based system.
+ * This enum categorizes rules into various types based on their functionality and application.
+ */
public enum RuleType {
- BASIC, CASE, CONTRADICTION, MERGE
+ BASIC,
+ CASE,
+ CONTRADICTION,
+ MERGE
}
diff --git a/src/main/java/edu/rpi/legup/model/tree/Tree.java b/src/main/java/edu/rpi/legup/model/tree/Tree.java
index 79c0bcece..3e68015a1 100644
--- a/src/main/java/edu/rpi/legup/model/tree/Tree.java
+++ b/src/main/java/edu/rpi/legup/model/tree/Tree.java
@@ -1,12 +1,20 @@
package edu.rpi.legup.model.tree;
+import edu.rpi.legup.controller.TreeController;
import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.rules.CaseRule;
+import edu.rpi.legup.ui.proofeditorui.treeview.TreeView;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+/**
+ * Represents a tree structure in a puzzle.
+ * The tree consists of {@link TreeNode}s and {@link TreeTransition}s
+ * and allows adding, removing, and validating elements.
+ */
public class Tree {
private TreeNode rootNode;
@@ -20,13 +28,17 @@ public Tree(Board initBoard) {
this.rootNode.setRoot(true);
}
- /**
- * Tree Constructor creates the tree structure with null root node
- */
+ /** Tree Constructor creates the tree structure with null root node */
public Tree() {
this.rootNode = null;
}
+ /**
+ * Adds a new transition to the specified node.
+ *
+ * @param treeNode the node to add a transition to
+ * @return the created transition
+ */
public TreeTransition addNewTransition(TreeNode treeNode) {
TreeTransition transition = new TreeTransition(treeNode, treeNode.getBoard().copy());
treeNode.addChild(transition);
@@ -34,53 +46,76 @@ public TreeTransition addNewTransition(TreeNode treeNode) {
return transition;
}
- public TreeNode addNode(TreeTransition transition) {
- TreeNode treeNode = new TreeNode(transition.getBoard().copy());
- transition.setChildNode(treeNode);
- treeNode.setParent(transition);
- return treeNode;
- }
-
+ /**
+ * Adds a tree element (node or transition) to the tree.
+ *
+ * @param element the tree element to add
+ * @return the added tree element
+ */
public TreeElement addTreeElement(TreeElement element) {
if (element.getType() == TreeElementType.NODE) {
TreeNode treeNode = (TreeNode) element;
- return addTreeElement(treeNode, new TreeTransition(treeNode, treeNode.getBoard().copy()));
- }
- else {
+ return addTreeElement(
+ treeNode, new TreeTransition(treeNode, treeNode.getBoard().copy()));
+ } else {
TreeTransition transition = (TreeTransition) element;
Board copyBoard = transition.board.copy();
- copyBoard.setModifiable(false);
+ copyBoard.setModifiable(true);
return addTreeElement(transition, new TreeNode(copyBoard));
}
}
+ /**
+ * Adds a tree node and its associated transition to the tree.
+ *
+ * @param treeNode the tree node to add
+ * @param transition the transition to associate with the node
+ * @return the added transition
+ */
public TreeElement addTreeElement(TreeNode treeNode, TreeTransition transition) {
treeNode.addChild(transition);
treeNode.getChildren().forEach(TreeTransition::reverify);
return transition;
}
+ /**
+ * Adds a transition and its associated tree node to the tree.
+ *
+ * @param transition the transition to add
+ * @param treeNode the tree node to associate with the transition
+ * @return the added tree node
+ */
public TreeElement addTreeElement(TreeTransition transition, TreeNode treeNode) {
transition.setChildNode(treeNode);
treeNode.setParent(transition);
return treeNode;
}
+ /**
+ * Removes a tree element (node or transition) from the tree.
+ *
+ * @param element the tree element to remove
+ */
public void removeTreeElement(TreeElement element) {
if (element.getType() == TreeElementType.NODE) {
TreeNode node = (TreeNode) element;
+
+ node.getParent().removeChild(node);
node.getParent().setChildNode(null);
- }
- else {
+ } else {
TreeTransition transition = (TreeTransition) element;
+
transition.getParents().forEach(n -> n.removeChild(transition));
+ TreeController treeController = new TreeController();
+ TreeView treeView = new TreeView(treeController);
+ treeView.removeTreeTransition(transition);
transition.getParents().get(0).getChildren().forEach(TreeTransition::reverify);
}
}
/**
- * Determines if the tree is valid by checking whether this tree puzzleElement and
- * all descendants of this tree puzzleElement is justified and justified correctly
+ * Determines if the tree is valid by checking whether this tree puzzleElement and all
+ * descendants of this tree puzzleElement is justified and justified correctly
*
* @return true if tree is valid, false otherwise
*/
@@ -100,10 +135,10 @@ public Set getLeafTreeElements() {
}
/**
- * Gets a Set of TreeNodes that are leaf nodes from the sub tree rooted at the specified node
+ * Gets a Set of TreeNodes that are leaf nodes from the subtree rooted at the specified node
*
* @param node node that is input
- * @return Set of TreeNodes that are leaf nodes from the sub tree
+ * @return Set of TreeNodes that are leaf nodes from the subtree
*/
public Set getLeafTreeElements(TreeNode node) {
Set leafs = new HashSet<>();
@@ -114,7 +149,7 @@ public Set getLeafTreeElements(TreeNode node) {
/**
* Recursively gets a Set of TreeNodes that are leaf nodes
*
- * @param leafs Set of TreeNodes that are leaf nodes
+ * @param leafs Set of TreeNodes that are leaf nodes
* @param element current TreeNode being evaluated
*/
private void getLeafTreeElements(Set leafs, TreeElement element) {
@@ -123,41 +158,37 @@ private void getLeafTreeElements(Set leafs, TreeElement element) {
List childTrans = node.getChildren();
if (childTrans.isEmpty()) {
leafs.add(node);
- }
- else {
+ } else {
childTrans.forEach(t -> getLeafTreeElements(leafs, t));
}
- }
- else {
+ } else {
TreeTransition transition = (TreeTransition) element;
TreeNode childNode = transition.getChildNode();
if (childNode == null) {
leafs.add(transition);
- }
- else {
+ } else {
getLeafTreeElements(leafs, childNode);
}
}
}
/**
- * Gets the lowest common ancestor (LCA) among the list of {@link TreeNode} passed into
- * the function. This lowest common ancestor is the most immediate ancestor
- * node such that the list of tree nodes specified are descendants of the node.
- * This will return null if no such ancestor exists
+ * Gets the lowest common ancestor (LCA) among the list of {@link TreeNode} passed into the
+ * function. This lowest common ancestor is the most immediate ancestor node such that the list
+ * of tree nodes specified are descendants of the node. This will return null if no such
+ * ancestor exists
*
* @param nodes list of tree nodes to find the LCA
- * @return the first ancestor node that all tree nodes have in common, otherwise null if none exists
+ * @return the first ancestor node that all tree nodes have in common, otherwise null if none
+ * exists
*/
public static TreeNode getLowestCommonAncestor(List nodes) {
if (nodes.isEmpty()) {
return null;
- }
- else {
+ } else {
if (nodes.size() == 1) {
return nodes.get(0);
- }
- else {
+ } else {
List> ancestors = new ArrayList<>();
for (TreeNode node : nodes) {
ancestors.add(node.getAncestors());
diff --git a/src/main/java/edu/rpi/legup/model/tree/TreeElement.java b/src/main/java/edu/rpi/legup/model/tree/TreeElement.java
index 17168ac98..2f6f45e4d 100644
--- a/src/main/java/edu/rpi/legup/model/tree/TreeElement.java
+++ b/src/main/java/edu/rpi/legup/model/tree/TreeElement.java
@@ -2,6 +2,9 @@
import edu.rpi.legup.model.gameboard.Board;
+/**
+ * Represents an element in a tree structure, which can be either a {@link TreeNode} or a {@link TreeTransition}.
+ */
public abstract class TreeElement {
protected TreeElementType type;
protected Board board;
@@ -16,27 +19,28 @@ public TreeElement(TreeElementType type) {
}
/**
- * Determines if this tree node leads to a contradiction. Every path from this tree node
- * must lead to a contradiction including all of its children
+ * Determines if this tree node leads to a contradiction. Every path from this tree node must
+ * lead to a contradiction including all of its children
*
* @return true if this tree node leads to a contradiction, false otherwise
*/
public abstract boolean isContradictoryBranch();
/**
- * Recursively determines if the sub-tree rooted at this tree puzzleElement is valid by checking
+ * Recursively determines if the subtree rooted at this tree puzzleElement is valid by checking
* whether this tree puzzleElement and all descendants of this tree puzzleElement is justified
* and justified correctly
*
- * @return true if this tree puzzleElement and all descendants of this tree puzzleElement is valid,
- * false otherwise
+ * @return true if this tree puzzleElement and all descendants of this tree puzzleElement is
+ * valid, false otherwise
*/
public abstract boolean isValidBranch();
/**
* Gets the type of tree puzzleElement
*
- * @return NODE if this tree puzzleElement is a tree node, TRANSITION, if this tree puzzleElement is a transition
+ * @return NODE if this tree puzzleElement is a tree node, TRANSITION, if this tree
+ * puzzleElement is a transition
*/
public TreeElementType getType() {
return type;
diff --git a/src/main/java/edu/rpi/legup/model/tree/TreeElementType.java b/src/main/java/edu/rpi/legup/model/tree/TreeElementType.java
index ad93f16b6..3a6dbb124 100644
--- a/src/main/java/edu/rpi/legup/model/tree/TreeElementType.java
+++ b/src/main/java/edu/rpi/legup/model/tree/TreeElementType.java
@@ -1,5 +1,10 @@
package edu.rpi.legup.model.tree;
+/**
+ * Enum representing the type of a tree element.
+ * Tree elements can be either nodes or transitions in the tree structure.
+ */
public enum TreeElementType {
- NODE, TRANSITION
+ NODE,
+ TRANSITION
}
diff --git a/src/main/java/edu/rpi/legup/model/tree/TreeNode.java b/src/main/java/edu/rpi/legup/model/tree/TreeNode.java
index 59f6e736e..85a5e717b 100644
--- a/src/main/java/edu/rpi/legup/model/tree/TreeNode.java
+++ b/src/main/java/edu/rpi/legup/model/tree/TreeNode.java
@@ -2,9 +2,13 @@
import edu.rpi.legup.model.gameboard.Board;
import edu.rpi.legup.utility.DisjointSets;
-
import java.util.*;
+/**
+ * Represents a node in a tree structure. Extends {@link TreeElement}.
+ * A {@code TreeNode} contains a board, references to its parent and children transitions, and indicates
+ * if it is the root node of the tree.
+ */
public class TreeNode extends TreeElement {
private TreeTransition parent;
private List children;
@@ -24,8 +28,8 @@ public TreeNode(Board board) {
}
/**
- * Determines if this tree node leads to a contradiction. Every path from this tree node
- * must lead to a contradiction including all of its children
+ * Determines if this tree node leads to a contradiction. Every path from this tree node must
+ * lead to a contradiction including all of its children
*
* @return true if this tree node leads to a contradiction, false otherwise
*/
@@ -43,8 +47,8 @@ public boolean isContradictoryBranch() {
* whether this tree puzzleElement and all descendants of this tree puzzleElement is justified
* and justified correctly
*
- * @return true if this tree puzzleElement and all descendants of this tree puzzleElement is valid,
- * false otherwise
+ * @return true if this tree puzzleElement and all descendants of this tree puzzleElement is
+ * valid, false otherwise
*/
@Override
public boolean isValidBranch() {
@@ -57,9 +61,9 @@ public boolean isValidBranch() {
}
/**
- * Gets all of the ancestors of this node
+ * Gets a list of the ancestors of this node
*
- * @return list of all of the ancestors for this node
+ * @return list of all the ancestors for this node
*/
public List getAncestors() {
List ancestors = new ArrayList<>();
@@ -104,8 +108,7 @@ public List getDescendants() {
it.add(transition);
}
}
- }
- else {
+ } else {
TreeTransition trans = (TreeTransition) next;
TreeNode childNode = trans.getChildNode();
if (childNode != null && !descendants.contains(childNode)) {
@@ -118,9 +121,9 @@ public List getDescendants() {
}
/**
- * Gets a DisjointSets containing the children of this node such that the sets contained within the DisjointSets
- * are such that elements in the same set are branches of this tree node that will eventually merge. This could
- * mean that multiple merges take place before this happens.
+ * Gets a DisjointSets containing the children of this node such that the sets contained within
+ * the DisjointSets are such that elements in the same set are branches of this tree node that
+ * will eventually merge. This could mean that multiple merges take place before this happens.
*
* @return DisjointSets of tree transitions containing unique non-merging branches
*/
@@ -143,8 +146,7 @@ public DisjointSets findMergingBranches() {
if (element.getType() == TreeElementType.NODE) {
TreeNode node = (TreeNode) element;
nodes.addAll(node.getChildren());
- }
- else {
+ } else {
TreeTransition childTran = (TreeTransition) element;
if (childTran.getChildNode() != null) {
nodes.add(childTran.getChildNode());
@@ -169,8 +171,8 @@ public DisjointSets findMergingBranches() {
}
/**
- * Finds the point at which the set of tree elements passed in will merge. This must be a set gotten from
- * findMergingBranches method DisjointSets
+ * Finds the point at which the set of tree elements passed in will merge. This must be a set
+ * gotten from findMergingBranches method DisjointSets
*
* @param branches tree elements to find the merging point
* @return tree transition of the merging point or null if no such point exists
@@ -186,14 +188,15 @@ public static TreeTransition findMergingPoint(Set extends TreeElement> branche
mergeSet.createSet(element);
if (element.getType() == TreeElementType.NODE) {
TreeNode node = (TreeNode) element;
- node.getDescendants().forEach((TreeElement e) -> {
- if (!mergeSet.contains(e)) {
- mergeSet.createSet(e);
- }
- mergeSet.union(element, e);
- });
- }
- else {
+ node.getDescendants()
+ .forEach(
+ (TreeElement e) -> {
+ if (!mergeSet.contains(e)) {
+ mergeSet.createSet(e);
+ }
+ mergeSet.union(element, e);
+ });
+ } else {
TreeTransition transition = (TreeTransition) element;
TreeNode childNode = transition.getChildNode();
if (childNode != null) {
@@ -228,8 +231,7 @@ public static TreeTransition findMergingPoint(Set extends TreeElement> branche
if (element.getType() == TreeElementType.NODE) {
TreeNode node = (TreeNode) element;
next.addAll(node.getChildren());
- }
- else {
+ } else {
TreeTransition tran = (TreeTransition) element;
next.add(tran.getChildNode());
}
@@ -329,8 +331,11 @@ public void setRoot(boolean isRoot) {
this.isRoot = isRoot;
}
+ /**
+ * Clears all children transitions from this tree node.
+ * After calling this method, the node will have no child transitions.
+ */
public void clearChildren() {
this.children.clear();
}
-
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/model/tree/TreeTransition.java b/src/main/java/edu/rpi/legup/model/tree/TreeTransition.java
index 72572ac72..9e441ac55 100644
--- a/src/main/java/edu/rpi/legup/model/tree/TreeTransition.java
+++ b/src/main/java/edu/rpi/legup/model/tree/TreeTransition.java
@@ -5,10 +5,14 @@
import edu.rpi.legup.model.rules.CaseRule;
import edu.rpi.legup.model.rules.Rule;
import edu.rpi.legup.model.rules.RuleType;
-
import java.util.ArrayList;
import java.util.List;
+/**
+ * Represents a transition between two nodes in a tree structure within a game.
+ * A transition is responsible for propagating changes through the tree and managing
+ * and verifying the associated rules and puzzle elements.
+ */
public class TreeTransition extends TreeElement {
private ArrayList parents;
private TreeNode childNode;
@@ -38,7 +42,7 @@ public TreeTransition(Board board) {
* TreeTransition Constructor - create a transition from one node to another
*
* @param parent parent tree node associated with the transition
- * @param board board state of the transition
+ * @param board board state of the transition
*/
public TreeTransition(TreeNode parent, Board board) {
this(board);
@@ -71,8 +75,7 @@ public void propagateChange(PuzzleElement element) {
board.removeModifiedData(element);
board.notifyChange(element);
changed = true;
- }
- else {
+ } else {
if (!lcaElement.equalsData(element)) {
mergedData.setData(element.getData());
board.addModifiedData(mergedData);
@@ -89,8 +92,7 @@ public void propagateChange(PuzzleElement element) {
}
}
}
- }
- else {
+ } else {
// Overwrite previous modifications to this element
board.removeModifiedData(board.getPuzzleElement(element));
@@ -98,7 +100,8 @@ public void propagateChange(PuzzleElement element) {
board.notifyChange(element);
// mark first transition as modified
- if (!board.getPuzzleElement(element).equalsData(parents.get(0).getBoard().getPuzzleElement(element))) {
+ if (!board.getPuzzleElement(element)
+ .equalsData(parents.get(0).getBoard().getPuzzleElement(element))) {
board.addModifiedData(element);
}
@@ -116,8 +119,7 @@ public void propagateChange(PuzzleElement element) {
// Set as modifiable if reverted to starting value (and started modifiable)
if (headBoard.getPuzzleElement(element).equalsData(element)) {
copy.setModifiable(headBoard.getPuzzleElement(element).isModifiable());
- }
- else{
+ } else {
copy.setModifiable(false);
}
@@ -159,8 +161,7 @@ public void propagateAddition(PuzzleElement element) {
board.removeModifiedData(element);
board.notifyDeletion(element);
changed = true;
- }
- else {
+ } else {
if (!lcaElement.equalsData(element)) {
mergedData.setData(element.getData());
board.addModifiedData(mergedData);
@@ -175,8 +176,7 @@ public void propagateAddition(PuzzleElement element) {
}
}
}
- }
- else {
+ } else {
if (childNode != null) {
board.notifyAddition(element);
childNode.getBoard().notifyAddition(element.copy());
@@ -214,8 +214,7 @@ public void propagateDeletion(PuzzleElement element) {
board.removeModifiedData(element);
board.notifyDeletion(element);
changed = true;
- }
- else {
+ } else {
if (!lcaElement.equalsData(element)) {
mergedData.setData(element.getData());
board.addModifiedData(mergedData);
@@ -230,8 +229,7 @@ public void propagateDeletion(PuzzleElement element) {
}
}
}
- }
- else {
+ } else {
if (childNode != null) {
board.notifyDeletion(element);
childNode.getBoard().notifyDeletion(element.copy());
@@ -244,8 +242,8 @@ public void propagateDeletion(PuzzleElement element) {
}
/**
- * Determines if this tree node leads to a contradiction. Every path from this tree node
- * must lead to a contradiction including all of its children
+ * Determines if this tree node leads to a contradiction. Every path from this tree node must
+ * lead to a contradiction including all of its children
*
* @return true if this tree node leads to a contradiction, false otherwise
*/
@@ -253,12 +251,10 @@ public void propagateDeletion(PuzzleElement element) {
public boolean isContradictoryBranch() {
if (isJustified() && isCorrect() && rule.getRuleType() == RuleType.CONTRADICTION) {
return true;
- }
- else {
+ } else {
if (childNode == null) {
return false;
- }
- else {
+ } else {
return childNode.isContradictoryBranch() && isJustified() && isCorrect();
}
}
@@ -269,8 +265,8 @@ public boolean isContradictoryBranch() {
* whether this tree puzzleElement and all descendants of this tree puzzleElement is justified
* and justified correctly
*
- * @return true if this tree puzzleElement and all descendants of this tree puzzleElement is valid,
- * false otherwise
+ * @return true if this tree puzzleElement and all descendants of this tree puzzleElement is
+ * valid, false otherwise
*/
@Override
public boolean isValidBranch() {
@@ -341,6 +337,25 @@ public void setChildNode(TreeNode childNode) {
this.childNode = childNode;
}
+ /**
+ * Removes the child to this tree transition
+ *
+ * @param child child to remove
+ */
+ public void removeChild(TreeNode child) {
+ parents.remove(child);
+ }
+
+ /**
+ * Add the child to this tree transition
+ *
+ * @param child child to add
+ */
+ public void addChild(TreeNode child) {
+ parents.add(child);
+ }
+
+
/**
* Gets the rule associated with this transition
*
diff --git a/src/main/java/edu/rpi/legup/puzzle/PuzzleElementTypes.java b/src/main/java/edu/rpi/legup/puzzle/PuzzleElementTypes.java
index f2ddb056c..f0dd5a6e9 100644
--- a/src/main/java/edu/rpi/legup/puzzle/PuzzleElementTypes.java
+++ b/src/main/java/edu/rpi/legup/puzzle/PuzzleElementTypes.java
@@ -1,4 +1,3 @@
package edu.rpi.legup.puzzle;
-public enum PuzzleElementTypes {
-}
+public enum PuzzleElementTypes {}
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/Battleship.java b/src/main/java/edu/rpi/legup/puzzle/battleship/Battleship.java
index 22a980251..41af3f626 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/Battleship.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/Battleship.java
@@ -17,9 +17,7 @@ public Battleship() {
this.factory = new BattleshipCellFactory();
}
- /**
- * Initializes the game board. Called by the invoker of the class
- */
+ /** Initializes the game board. Called by the invoker of the class */
@Override
public void initializeView() {
boardView = new BattleshipView((BattleshipBoard) currentBoard);
@@ -35,8 +33,8 @@ public Board generatePuzzle(int difficulty) {
/**
* Determines if the given dimensions are valid for Battleship
*
- * @param rows the number of rows
- * @param columns the number of columns
+ * @param rows the number of rows
+ * @param columns the number of columns
* @return true if the given dimensions are valid for Battleship, false otherwise
*/
public boolean isValidDimensions(int rows, int columns) {
@@ -74,84 +72,98 @@ public boolean isBoardComplete(Board board) {
* @param board the board that has changed
*/
@Override
- public void onBoardChange(Board board) {
+ public void onBoardChange(Board board) {}
- }
-//
-// @Override
-// public void onTreeSelectionChange(ArrayList newSelection)
-// {
-//
-// }
+ //
+ // @Override
+ // public void onTreeSelectionChange(ArrayList newSelection)
+ // {
+ //
+ // }
@Override
public void importPuzzle(String fileName) {
-// if(fileName != null)
-// {
-// InputStream inputStream = new FileInputStream(fileName);
-// DocumentBuilder builder = null;//factory.newDocumentBuilder();
-// Document document = builder.parse(inputStream);
-//
-// BattleShipBoard battleShipBoard;
-//
-// PuzzleElement rootNode = document.getDocumentElement();
-// PuzzleElement puzzleElement = (PuzzleElement) rootNode.getElementsByTagName("edu.rpi.legup.puzzle").item(0);
-// PuzzleElement boardElement = (PuzzleElement) puzzleElement.getElementsByTagName("board").item(0);
-// PuzzleElement axesElement = (PuzzleElement) boardElement.getElementsByTagName("axes").item(0);
-// PuzzleElement shipElement = (PuzzleElement) boardElement.getElementsByTagName("ships").item(0);
-// PuzzleElement cellElement = (PuzzleElement) boardElement.getElementsByTagName("cells").item(0);
-// PuzzleElement rightElement = (PuzzleElement) axesElement.getElementsByTagName("right").item(0);
-// PuzzleElement bottomElement = (PuzzleElement) axesElement.getElementsByTagName("bottom").item(0);
-// NodeList rightClueList = rightElement.getElementsByTagName("clue");
-// NodeList bottomClueList = bottomElement.getElementsByTagName("clue");
-// NodeList shipList = shipElement.getElementsByTagName("ship");
-// NodeList cells = cellElement.getElementsByTagName("cell");
-//
-// int size = Integer.valueOf(boardElement.getAttribute("size"));
-// battleShipBoard = new BattleShipBoard(size);
-//
-// ArrayList battleShipData = new ArrayList<>();
-// for(int i = 0; i < size * size; i++)
-// {
-// battleShipData.add(null);
-// }
-//
-// for (int i = 0; i < rightClueList.getLength(); i++) {
-// battleShipBoard.getRight()[i] = Integer.valueOf(rightClueList.item(i).getAttributes().getNamedItem("value").getNodeValue());
-// }
-//
-// for (int i = 0; i < bottomClueList.getLength(); i++) {
-// battleShipBoard.getBottom()[i] = Integer.valueOf(bottomClueList.item(i).getAttributes().getNamedItem("value").getNodeValue());
-// }
-//
-// for (int i = 0; i < shipList.getLength(); i++) {
-// int length = Integer.valueOf(shipList.item(i).getAttributes().getNamedItem("length").getNodeValue());
-// int count = Integer.valueOf(shipList.item(i).getAttributes().getNamedItem("count").getNodeValue());
-// battleShipBoard.getShips().add(new Ship(length, count));
-// }
-//
-// for (int i = 0; i < cells.getLength(); i++) {
-// int x = Integer.valueOf(cells.item(i).getAttributes().getNamedItem("x").getNodeValue());
-// int y = Integer.valueOf(cells.item(i).getAttributes().getNamedItem("y").getNodeValue());
-// String value = cells.item(i).getAttributes().getNamedItem("value").getNodeValue().toUpperCase();
-//
-// BattleShipCell cell = new BattleShipCell(BattleShipType.valueOf(value).ordinal(), new Point(x, y));
-// battleShipBoard.setCell(x, y, cell);
-// cell.setModifiable(false);
-// cell.setGiven(true);
-// }
-//
-// for (int x = 0; x < size; x++) {
-// for (int y = 0; y < size; y++) {
-// if (battleShipBoard.getCell(x, y) == null) {
-// BattleShipCell cell = new BattleShipCell(9, new Point(x, y));
-// cell.setModifiable(true);
-// battleShipBoard.setCell(x, y, cell);
-// }
-// }
-// }
-// this.currentBoard = battleShipBoard;
-// this.tree = new Tree(currentBoard);
-// }
+ // if(fileName != null)
+ // {
+ // InputStream inputStream = new FileInputStream(fileName);
+ // DocumentBuilder builder = null;//factory.newDocumentBuilder();
+ // Document document = builder.parse(inputStream);
+ //
+ // BattleShipBoard battleShipBoard;
+ //
+ // PuzzleElement rootNode = document.getDocumentElement();
+ // PuzzleElement puzzleElement = (PuzzleElement)
+ // rootNode.getElementsByTagName("edu.rpi.legup.puzzle").item(0);
+ // PuzzleElement boardElement = (PuzzleElement)
+ // puzzleElement.getElementsByTagName("board").item(0);
+ // PuzzleElement axesElement = (PuzzleElement)
+ // boardElement.getElementsByTagName("axes").item(0);
+ // PuzzleElement shipElement = (PuzzleElement)
+ // boardElement.getElementsByTagName("ships").item(0);
+ // PuzzleElement cellElement = (PuzzleElement)
+ // boardElement.getElementsByTagName("cells").item(0);
+ // PuzzleElement rightElement = (PuzzleElement)
+ // axesElement.getElementsByTagName("right").item(0);
+ // PuzzleElement bottomElement = (PuzzleElement)
+ // axesElement.getElementsByTagName("bottom").item(0);
+ // NodeList rightClueList = rightElement.getElementsByTagName("clue");
+ // NodeList bottomClueList = bottomElement.getElementsByTagName("clue");
+ // NodeList shipList = shipElement.getElementsByTagName("ship");
+ // NodeList cells = cellElement.getElementsByTagName("cell");
+ //
+ // int size = Integer.valueOf(boardElement.getAttribute("size"));
+ // battleShipBoard = new BattleShipBoard(size);
+ //
+ // ArrayList battleShipData = new ArrayList<>();
+ // for(int i = 0; i < size * size; i++)
+ // {
+ // battleShipData.add(null);
+ // }
+ //
+ // for (int i = 0; i < rightClueList.getLength(); i++) {
+ // battleShipBoard.getRight()[i] =
+ // Integer.valueOf(rightClueList.item(i).getAttributes().getNamedItem("value").getNodeValue());
+ // }
+ //
+ // for (int i = 0; i < bottomClueList.getLength(); i++) {
+ // battleShipBoard.getBottom()[i] =
+ // Integer.valueOf(bottomClueList.item(i).getAttributes().getNamedItem("value").getNodeValue());
+ // }
+ //
+ // for (int i = 0; i < shipList.getLength(); i++) {
+ // int length =
+ // Integer.valueOf(shipList.item(i).getAttributes().getNamedItem("length").getNodeValue());
+ // int count =
+ // Integer.valueOf(shipList.item(i).getAttributes().getNamedItem("count").getNodeValue());
+ // battleShipBoard.getShips().add(new Ship(length, count));
+ // }
+ //
+ // for (int i = 0; i < cells.getLength(); i++) {
+ // int x =
+ // Integer.valueOf(cells.item(i).getAttributes().getNamedItem("x").getNodeValue());
+ // int y =
+ // Integer.valueOf(cells.item(i).getAttributes().getNamedItem("y").getNodeValue());
+ // String value =
+ // cells.item(i).getAttributes().getNamedItem("value").getNodeValue().toUpperCase();
+ //
+ // BattleShipCell cell = new
+ // BattleShipCell(BattleShipType.valueOf(value).ordinal(), new Point(x, y));
+ // battleShipBoard.setCell(x, y, cell);
+ // cell.setModifiable(false);
+ // cell.setGiven(true);
+ // }
+ //
+ // for (int x = 0; x < size; x++) {
+ // for (int y = 0; y < size; y++) {
+ // if (battleShipBoard.getCell(x, y) == null) {
+ // BattleShipCell cell = new BattleShipCell(9, new Point(x, y));
+ // cell.setModifiable(true);
+ // battleShipBoard.setCell(x, y, cell);
+ // }
+ // }
+ // }
+ // this.currentBoard = battleShipBoard;
+ // this.tree = new Tree(currentBoard);
+ // }
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipBoard.java b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipBoard.java
index 5965f7055..555c8471f 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipBoard.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipBoard.java
@@ -2,7 +2,6 @@
import edu.rpi.legup.model.gameboard.GridBoard;
import edu.rpi.legup.model.gameboard.PuzzleElement;
-
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
@@ -15,7 +14,7 @@ public class BattleshipBoard extends GridBoard {
/**
* Constructor for creating a rectangular battleship board.
*
- * @param width width of the board
+ * @param width width of the board
* @param height height of the board
*/
public BattleshipBoard(int width, int height) {
@@ -44,8 +43,7 @@ public BattleshipBoard(int size) {
/**
* Gets the east {@link BattleshipClue}
*
- * @return List of BattleShipClue
objects on the east
- * side of the board
+ * @return List of BattleShipClue
objects on the east side of the board
*/
public List getEast() {
return east;
@@ -90,8 +88,7 @@ public BattleshipBoard copy() {
* Get a list of all orthogonally adjacent cells.
*
* @param cell The cell to get adjacent cells from.
- * @return List of adjacent cells in clockwise order:
- * { up, right, down, left }
+ * @return List of adjacent cells in clockwise order: { up, right, down, left }
*/
public List getAdjOrthogonals(BattleshipCell cell) {
List adj = new ArrayList<>();
@@ -111,8 +108,8 @@ public List getAdjOrthogonals(BattleshipCell cell) {
* Get a list of all diagonally adjacent cells.
*
* @param cell The cell to get diagonally adjacent cells from.
- * @return List of diagonally adjacent cells in clockwise order:
- * { upRight, downRight, downLeft, upLeft }
+ * @return List of diagonally adjacent cells in clockwise order:
+ * { upRight, downRight, downLeft, upLeft }
*/
public List getAdjDiagonals(BattleshipCell cell) {
List dia = new ArrayList<>();
@@ -155,4 +152,4 @@ public List getColumn(int x) {
}
return column;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipCell.java b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipCell.java
index 5f2c5b975..5a5b86094 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipCell.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipCell.java
@@ -1,7 +1,6 @@
package edu.rpi.legup.puzzle.battleship;
import edu.rpi.legup.model.gameboard.GridCell;
-
import java.awt.*;
public class BattleshipCell extends GridCell {
@@ -9,7 +8,7 @@ public class BattleshipCell extends GridCell {
/**
* BattleShipCell Constructor - creates a BattleShipCell from the specified value and location
*
- * @param value value of the BattleShipCell
+ * @param value value of the BattleShipCell
* @param location position of the BattleShipCell
*/
public BattleshipCell(BattleshipType value, Point location) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipCellController.java b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipCellController.java
index 89b5fa19a..9db0cca84 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipCellController.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipCellController.java
@@ -2,39 +2,39 @@
import edu.rpi.legup.controller.ElementController;
import edu.rpi.legup.model.gameboard.PuzzleElement;
-
import java.awt.event.MouseEvent;
public class BattleshipCellController extends ElementController {
/**
- * Controller class for the Battleship puzzle -
- * receives user mouse input and changes what's shown on the GUI
+ * Controller class for the Battleship puzzle - receives user mouse input and changes what's
+ * shown on the GUI
*
* @param data the PuzzleElement to be changed
- * @param e the user mouse input
+ * @param e the user mouse input
*/
@Override
public void changeCell(MouseEvent e, PuzzleElement data) {
BattleshipCell cell = (BattleshipCell) 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 {
+ this.boardView
+ .getSelectionPopupMenu()
+ .show(
+ boardView,
+ this.boardView.getCanvas().getX() + e.getX(),
+ this.boardView.getCanvas().getY() + e.getY());
+ } else {
if (cell.getData() == BattleshipType.SHIP_MIDDLE) {
cell.setData(BattleshipType.UNKNOWN);
- }
- else {
+ } else {
cell.setData(BattleshipType.getType(cell.getData().value + 1));
}
}
- }
- else {
+ } else {
if (e.getButton() == MouseEvent.BUTTON3) {
if (cell.getData() == BattleshipType.UNKNOWN) {
cell.setData(BattleshipType.SHIP_MIDDLE);
- }
- else {
+ } else {
cell.setData(BattleshipType.getType(cell.getData().value - 1));
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipCellFactory.java b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipCellFactory.java
index 81629c360..1b3b6c427 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipCellFactory.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipCellFactory.java
@@ -4,23 +4,23 @@
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;
-import java.awt.*;
-
public class BattleshipCellFactory extends ElementFactory {
/**
* Creates a puzzleElement based on the xml document Node and adds it to the board
*
- * @param node node that represents the puzzleElement
+ * @param node node that represents the puzzleElement
* @param board board to add the newly created cell
* @return newly created cell from the xml document Node
* @throws InvalidFileFormatException if file is invalid
*/
@Override
- public PuzzleElement importCell(Node node, Board board) throws InvalidFileFormatException {
+ public PuzzleElement importCell(Node node, Board board)
+ throws InvalidFileFormatException {
try {
BattleshipBoard battleShipBoard = (BattleshipBoard) board;
int width = battleShipBoard.getWidth();
@@ -32,24 +32,25 @@ public PuzzleElement importCell(Node node, Board board) throws I
int x = Integer.parseInt(attributeList.getNamedItem("x").getNodeValue());
int y = Integer.parseInt(attributeList.getNamedItem("y").getNodeValue());
if (x >= width || y >= height) {
- throw new InvalidFileFormatException("BattleShip Factory: cell location out of bounds");
+ throw new InvalidFileFormatException(
+ "BattleShip Factory: cell location out of bounds");
}
if (value < 0 || value > 3) {
throw new InvalidFileFormatException("BattleShip Factory: cell unknown value");
}
- BattleshipCell cell = new BattleshipCell(BattleshipType.getType(value), new Point(x, y));
+ BattleshipCell cell =
+ new BattleshipCell(BattleshipType.getType(value), new Point(x, y));
cell.setIndex(y * height + x);
return cell;
+ } else {
+ throw new InvalidFileFormatException(
+ "BattleShip Factory: unknown puzzleElement puzzleElement");
}
- else {
- throw new InvalidFileFormatException("BattleShip Factory: unknown puzzleElement puzzleElement");
- }
- }
- catch (NumberFormatException e) {
- throw new InvalidFileFormatException("BattleShip Factory: unknown value where integer expected");
- }
- catch (NullPointerException e) {
+ } catch (NumberFormatException e) {
+ throw new InvalidFileFormatException(
+ "BattleShip Factory: unknown value where integer expected");
+ } catch (NullPointerException e) {
throw new InvalidFileFormatException("BattleShip Factory: could not find attribute(s)");
}
}
@@ -57,7 +58,7 @@ public PuzzleElement importCell(Node node, Board board) throws I
/**
* Creates a xml document puzzleElement from a cell for exporting
*
- * @param document xml document
+ * @param document xml document
* @param puzzleElement PuzzleElement cell
* @return xml PuzzleElement
*/
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipClueView.java b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipClueView.java
index 6a29eb7a3..788c860f3 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipClueView.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipClueView.java
@@ -1,7 +1,6 @@
package edu.rpi.legup.puzzle.battleship;
import edu.rpi.legup.ui.boardview.ElementView;
-
import java.awt.*;
public class BattleshipClueView extends ElementView {
@@ -26,6 +25,7 @@ public BattleshipClue getPuzzleElement() {
@Override
/**
* Draws the clue from the PuzzleElement associated with this view on the given frame
+ *
* @param graphics2D the frame the clue is to be drawn on
*/
public void draw(Graphics2D graphics2D) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipElementView.java b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipElementView.java
index d66f159d7..1898468ce 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipElementView.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipElementView.java
@@ -1,7 +1,6 @@
package edu.rpi.legup.puzzle.battleship;
import edu.rpi.legup.ui.boardview.GridElementView;
-
import java.awt.*;
public class BattleshipElementView extends GridElementView {
@@ -22,6 +21,7 @@ public BattleshipElementView(BattleshipCell cell) {
@Override
/**
* Draws on the given frame based on the type of the cell of the current puzzleElement
+ *
* @param graphics2D the frame to be drawn on
*/
public void drawElement(Graphics2D graphics2D) {
@@ -39,37 +39,60 @@ public void drawElement(Graphics2D graphics2D) {
break;
case SHIP_UNKNOWN:
graphics2D.setColor(SHIP_COLOR);
- graphics2D.fillRect(location.x + 3 * size.width / 8, location.y + 3 * size.height / 8,
- size.width / 4, size.height / 4);
+ graphics2D.fillRect(
+ location.x + 3 * size.width / 8,
+ location.y + 3 * size.height / 8,
+ size.width / 4,
+ size.height / 4);
graphics2D.setColor(FONT_COLOR);
graphics2D.setFont(FONT);
FontMetrics metrics = graphics2D.getFontMetrics(FONT);
String value = "?";
int xText = location.x + (size.width - metrics.stringWidth(value)) / 2;
- int yText = location.y + ((size.height - metrics.getHeight()) / 2) + metrics.getAscent();
+ int yText =
+ location.y
+ + ((size.height - metrics.getHeight()) / 2)
+ + metrics.getAscent();
graphics2D.drawString(value, xText, yText);
break;
case SUBMARINE:
graphics2D.setColor(SHIP_COLOR);
- graphics2D.fillOval(location.x + size.width / 4, location.y + size.width / 4,
- size.width / 2, size.height / 2);
+ graphics2D.fillOval(
+ location.x + size.width / 4,
+ location.y + size.width / 4,
+ size.width / 2,
+ size.height / 2);
break;
case SHIP_TOP:
graphics2D.setColor(SHIP_COLOR);
- graphics2D.fillArc(location.x, location.y - size.height / 2, size.width, size.height, 180, 180);
+ graphics2D.fillArc(
+ location.x,
+ location.y - size.height / 2,
+ size.width,
+ size.height,
+ 180,
+ 180);
break;
case SHIP_RIGHT:
graphics2D.setColor(SHIP_COLOR);
- graphics2D.fillArc(location.x + size.height / 2, location.y, size.width, size.height, 90, 180);
+ graphics2D.fillArc(
+ location.x + size.height / 2, location.y, size.width, size.height, 90, 180);
break;
case SHIP_BOTTOM:
graphics2D.setColor(SHIP_COLOR);
- graphics2D.fillArc(location.x, location.y + size.height / 2, size.width, size.height, 0, 180);
+ graphics2D.fillArc(
+ location.x, location.y + size.height / 2, size.width, size.height, 0, 180);
break;
case SHIP_LEFT:
graphics2D.setColor(SHIP_COLOR);
- graphics2D.fillArc(location.x - size.height / 2, location.y, size.width, size.height, 270, 180);
+ graphics2D.fillArc(
+ location.x - size.height / 2,
+ location.y,
+ size.width,
+ size.height,
+ 270,
+ 180);
break;
case SHIP_MIDDLE:
graphics2D.setColor(SHIP_COLOR);
@@ -84,4 +107,4 @@ public void drawElement(Graphics2D graphics2D) {
graphics2D.setStroke(OUTLINE_STROKE);
graphics2D.drawRect(location.x, location.y, size.width, size.height);
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipExporter.java b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipExporter.java
index 4205d0125..cbc364842 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipExporter.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipExporter.java
@@ -2,7 +2,6 @@
import edu.rpi.legup.model.PuzzleExporter;
import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.puzzle.shorttruthtable.ShortTruthTableBoard;
import org.w3c.dom.Document;
public class BattleshipExporter extends PuzzleExporter {
@@ -22,8 +21,7 @@ protected org.w3c.dom.Element createBoardElement(Document newDocument) {
BattleshipBoard board;
if (puzzle.getTree() != null) {
board = (BattleshipBoard) puzzle.getTree().getRootNode().getBoard();
- }
- else {
+ } else {
board = (BattleshipBoard) puzzle.getBoardView().getBoard();
}
@@ -35,7 +33,8 @@ protected org.w3c.dom.Element createBoardElement(Document newDocument) {
for (PuzzleElement puzzleElement : board.getPuzzleElements()) {
BattleshipCell cell = (BattleshipCell) puzzleElement;
if (cell.getData() != BattleshipType.getType(0)) {
- org.w3c.dom.Element cellElement = puzzle.getFactory().exportCell(newDocument, puzzleElement);
+ org.w3c.dom.Element cellElement =
+ puzzle.getFactory().exportCell(newDocument, puzzleElement);
cellsElement.appendChild(cellElement);
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipImporter.java b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipImporter.java
index 749ceaaa9..cbc1dd02b 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipImporter.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipImporter.java
@@ -2,12 +2,11 @@
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;
-import java.awt.*;
-
public class BattleshipImporter extends PuzzleImporter {
public BattleshipImporter(Battleship battleShip) {
super(battleShip);
@@ -26,14 +25,12 @@ public boolean acceptsTextInput() {
/**
* Creates an empty board for building
*
- * @param rows the number of rows on the board
+ * @param rows the number of rows on the board
* @param columns the number of columns on the board
* @throws RuntimeException if board can not be created
*/
@Override
- public void initializeBoard(int rows, int columns) {
-
- }
+ public void initializeBoard(int rows, int columns) {}
/**
* Creates the board for building
@@ -45,46 +42,43 @@ public void initializeBoard(int rows, int columns) {
public void initializeBoard(Node node) throws InvalidFileFormatException {
try {
if (!node.getNodeName().equalsIgnoreCase("board")) {
- throw new InvalidFileFormatException("BattleShip Importer: " +
- "cannot find board puzzleElement");
+ throw new InvalidFileFormatException(
+ "BattleShip Importer: " + "cannot find board puzzleElement");
}
Element boardElement = (Element) node;
if (boardElement.getElementsByTagName("cells").getLength() == 0) {
- throw new InvalidFileFormatException("BattleShip Importer: " +
- "no puzzleElement found for board");
+ throw new InvalidFileFormatException(
+ "BattleShip Importer: " + "no puzzleElement found for board");
}
- Element dataElement = (Element) boardElement.getElementsByTagName(
- "cells").item(0);
+ Element dataElement = (Element) boardElement.getElementsByTagName("cells").item(0);
NodeList elementDataList = dataElement.getElementsByTagName("cell");
BattleshipBoard battleShipBoard = null;
if (!boardElement.getAttribute("size").isEmpty()) {
- int size = Integer.valueOf(boardElement.getAttribute(
- "size"));
+ int size = Integer.valueOf(boardElement.getAttribute("size"));
battleShipBoard = new BattleshipBoard(size);
- }
- else {
+ } else {
if (!boardElement.getAttribute("width").isEmpty()
&& !boardElement.getAttribute("height").isEmpty()) {
- int width = Integer.valueOf(boardElement.getAttribute(
- "width"));
- int height = Integer.valueOf(boardElement.getAttribute(
- "height"));
+ int width = Integer.valueOf(boardElement.getAttribute("width"));
+ int height = Integer.valueOf(boardElement.getAttribute("height"));
battleShipBoard = new BattleshipBoard(width, height);
}
}
if (battleShipBoard == null) {
- throw new InvalidFileFormatException("BattleShip Importer: " +
- "invalid board dimensions");
+ throw new InvalidFileFormatException(
+ "BattleShip Importer: " + "invalid board dimensions");
}
int width = battleShipBoard.getWidth();
int height = battleShipBoard.getHeight();
for (int i = 0; i < elementDataList.getLength(); i++) {
- BattleshipCell cell = (BattleshipCell) puzzle.getFactory()
- .importCell(elementDataList.item(i), battleShipBoard);
+ BattleshipCell cell =
+ (BattleshipCell)
+ puzzle.getFactory()
+ .importCell(elementDataList.item(i), battleShipBoard);
Point loc = cell.getLocation();
if (cell.getData() != BattleshipType.getType(0)) {
cell.setModifiable(false);
@@ -96,8 +90,8 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (battleShipBoard.getCell(x, y) == null) {
- BattleshipCell cell = new BattleshipCell(
- BattleshipType.UNKNOWN, new Point(x, y));
+ BattleshipCell cell =
+ new BattleshipCell(BattleshipType.UNKNOWN, new Point(x, y));
cell.setIndex(y * height + x);
cell.setModifiable(true);
battleShipBoard.setCell(x, y, cell);
@@ -107,59 +101,58 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
NodeList axes = boardElement.getElementsByTagName("axis");
if (axes.getLength() != 2) {
- throw new InvalidFileFormatException("BattleShip Importer: " +
- "cannot find axes");
+ throw new InvalidFileFormatException("BattleShip Importer: " + "cannot find axes");
}
Element axis1 = (Element) axes.item(0);
Element axis2 = (Element) axes.item(1);
- if (!axis1.hasAttribute("side") || !axis2.hasAttribute(
- "side")) {
- throw new InvalidFileFormatException("BattleShip Importer: " +
- "side attribute of axis not specified");
+ if (!axis1.hasAttribute("side") || !axis2.hasAttribute("side")) {
+ throw new InvalidFileFormatException(
+ "BattleShip Importer: " + "side attribute of axis not specified");
}
String side1 = axis1.getAttribute("side");
String side2 = axis2.getAttribute("side");
if (side1.equalsIgnoreCase(side2)
- || !(side1.equalsIgnoreCase("east")
- || side1.equalsIgnoreCase("south"))
- || !(side2.equalsIgnoreCase("east")
- || side2.equalsIgnoreCase("south"))) {
- throw new InvalidFileFormatException("BattleShip Importer: " +
- "axes must be different and be {east | south}");
+ || !(side1.equalsIgnoreCase("east") || side1.equalsIgnoreCase("south"))
+ || !(side2.equalsIgnoreCase("east") || side2.equalsIgnoreCase("south"))) {
+ throw new InvalidFileFormatException(
+ "BattleShip Importer: " + "axes must be different and be {east | south}");
}
- NodeList eastClues = side1.equalsIgnoreCase("east")
- ? axis1.getElementsByTagName("clue") :
- axis2.getElementsByTagName("clue");
- NodeList southClues = side1.equalsIgnoreCase("south")
- ? axis1.getElementsByTagName("clue") :
- axis2.getElementsByTagName("clue");
+ NodeList eastClues =
+ side1.equalsIgnoreCase("east")
+ ? axis1.getElementsByTagName("clue")
+ : axis2.getElementsByTagName("clue");
+ NodeList southClues =
+ side1.equalsIgnoreCase("south")
+ ? axis1.getElementsByTagName("clue")
+ : axis2.getElementsByTagName("clue");
if (eastClues.getLength() != battleShipBoard.getHeight()
|| southClues.getLength() != battleShipBoard.getWidth()) {
- throw new InvalidFileFormatException("BattleShip Importer: " +
- "there must be same number of clues as the dimension " +
- "of the board");
+ throw new InvalidFileFormatException(
+ "BattleShip Importer: "
+ + "there must be same number of clues as the dimension "
+ + "of the board");
}
for (int i = 0; i < eastClues.getLength(); i++) {
Element clue = (Element) eastClues.item(i);
int value = Integer.valueOf(clue.getAttribute("value"));
- int index = BattleshipClue.colStringToColNum(
- clue.getAttribute("index"));
+ int index = BattleshipClue.colStringToColNum(clue.getAttribute("index"));
if (index - 1 < 0 || index - 1 > battleShipBoard.getHeight()) {
- throw new InvalidFileFormatException("BattleShip Importer: " +
- "clue index out of bounds");
+ throw new InvalidFileFormatException(
+ "BattleShip Importer: " + "clue index out of bounds");
}
if (battleShipBoard.getEast().get(index - 1) != null) {
- throw new InvalidFileFormatException("BattleShip Importer: " +
- "duplicate clue index");
+ throw new InvalidFileFormatException(
+ "BattleShip Importer: " + "duplicate clue index");
}
- battleShipBoard.getEast().set(index - 1, new BattleshipClue(
- value, index, BattleshipType.CLUE_EAST));
+ battleShipBoard
+ .getEast()
+ .set(index - 1, new BattleshipClue(value, index, BattleshipType.CLUE_EAST));
}
for (int i = 0; i < southClues.getLength(); i++) {
@@ -168,23 +161,25 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
int index = Integer.valueOf(clue.getAttribute("index"));
if (index - 1 < 0 || index - 1 > battleShipBoard.getWidth()) {
- throw new InvalidFileFormatException("BattleShip Importer: " +
- "clue index out of bounds");
+ throw new InvalidFileFormatException(
+ "BattleShip Importer: " + "clue index out of bounds");
}
if (battleShipBoard.getSouth().get(index - 1) != null) {
- throw new InvalidFileFormatException("BattleShip Importer: " +
- "duplicate clue index");
+ throw new InvalidFileFormatException(
+ "BattleShip Importer: " + "duplicate clue index");
}
- battleShipBoard.getSouth().set(index - 1, new BattleshipClue(
- value, index, BattleshipType.CLUE_SOUTH));
+ battleShipBoard
+ .getSouth()
+ .set(
+ index - 1,
+ new BattleshipClue(value, index, BattleshipType.CLUE_SOUTH));
}
puzzle.setCurrentBoard(battleShipBoard);
- }
- catch (NumberFormatException e) {
- throw new InvalidFileFormatException("BattleShip Importer: " +
- "unknown value where integer expected");
+ } catch (NumberFormatException e) {
+ throw new InvalidFileFormatException(
+ "BattleShip Importer: " + "unknown value where integer expected");
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipType.java b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipType.java
index 6994222e3..0d505f43c 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipType.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipType.java
@@ -1,9 +1,19 @@
package edu.rpi.legup.puzzle.battleship;
public enum BattleshipType {
- UNKNOWN, WATER, SUBMARINE, SHIP_UNKNOWN,
- SHIP_TOP, SHIP_RIGHT, SHIP_BOTTOM, SHIP_LEFT, SHIP_MIDDLE,
- CLUE_NORTH, CLUE_EAST, CLUE_SOUTH, CLUE_WEST;
+ UNKNOWN,
+ WATER,
+ SUBMARINE,
+ SHIP_UNKNOWN,
+ SHIP_TOP,
+ SHIP_RIGHT,
+ SHIP_BOTTOM,
+ SHIP_LEFT,
+ SHIP_MIDDLE,
+ CLUE_NORTH,
+ CLUE_EAST,
+ CLUE_SOUTH,
+ CLUE_WEST;
public int value;
@@ -13,6 +23,7 @@ public enum BattleshipType {
/**
* Gets the enum of this BattleShipType
+ *
* @param value the integer value input
* @return enum equivalent BattleShipType of integer value
*/
@@ -31,7 +42,11 @@ public static BattleshipType getType(int value) {
* @return true if the type is a ship, false otherwise
*/
public static boolean isShip(BattleshipType type) {
- return type == SHIP_UNKNOWN || type == SHIP_TOP || type == SHIP_RIGHT
- || type == SHIP_BOTTOM || type == SHIP_LEFT || type == SHIP_MIDDLE;
+ return type == SHIP_UNKNOWN
+ || type == SHIP_TOP
+ || type == SHIP_RIGHT
+ || type == SHIP_BOTTOM
+ || type == SHIP_LEFT
+ || type == SHIP_MIDDLE;
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipView.java b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipView.java
index fbae2fa99..4095db54a 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipView.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/BattleshipView.java
@@ -3,7 +3,6 @@
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 BattleshipView extends GridBoardView {
@@ -17,7 +16,8 @@ public BattleshipView(BattleshipBoard board) {
BattleshipElementView elementView = new BattleshipElementView(cell);
elementView.setIndex(cell.getIndex());
elementView.setSize(elementSize);
- elementView.setLocation(new Point(loc.x * elementSize.width, loc.y * elementSize.height));
+ elementView.setLocation(
+ new Point(loc.x * elementSize.width, loc.y * elementSize.height));
elementViews.add(elementView);
}
}
@@ -26,4 +26,4 @@ public BattleshipView(BattleshipBoard board) {
public void drawBoard(Graphics2D graphics2D) {
super.drawBoard(graphics2D);
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/AdjacentShipsContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/AdjacentShipsContradictionRule.java
index 49bee101a..f1ecd6685 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/AdjacentShipsContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/AdjacentShipsContradictionRule.java
@@ -6,31 +6,29 @@
import edu.rpi.legup.puzzle.battleship.BattleshipBoard;
import edu.rpi.legup.puzzle.battleship.BattleshipCell;
import edu.rpi.legup.puzzle.battleship.BattleshipType;
-
import java.util.List;
public class AdjacentShipsContradictionRule extends ContradictionRule {
- private final String NO_CONTRADICTION_MESSAGE
- = "No instance of the contradiction " + this.ruleName + " here";
+ private final String NO_CONTRADICTION_MESSAGE =
+ "No instance of the contradiction " + this.ruleName + " here";
public AdjacentShipsContradictionRule() {
- super("BTSP-CONT-0001",
+ super(
+ "BTSP-CONT-0001",
"Adjacent Ships",
"Cells next to the battleship must be water.",
- "edu/rpi/legup/images/battleship/contradictions" +
- "/AdjacentShips.png");
+ "edu/rpi/legup/images/battleship/contradictions" + "/AdjacentShips.png");
}
/**
- * Checks whether the transition has a contradiction at the specific
- * {@link PuzzleElement} index using this rule.
+ * Checks whether the transition has a contradiction at the specific {@link PuzzleElement} index
+ * using this rule.
*
- * @param board board to check contradiction
+ * @param board board to check contradiction
* @param puzzleElement equivalent {@link PuzzleElement}
- * @return null
if the transition contains a
- * contradiction at the specified {@link PuzzleElement},
- * otherwise return a no contradiction message.
+ * @return null
if the transition contains a contradiction at the specified {@link
+ * PuzzleElement}, otherwise return a no contradiction message.
*/
@Override
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
@@ -43,19 +41,20 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
}
// check orthogonally adjacent cells
- List orthoAdjCells
- = bsBoard.getAdjOrthogonals(cell);
+ List orthoAdjCells = bsBoard.getAdjOrthogonals(cell);
BattleshipCell up = orthoAdjCells.get(0);
BattleshipCell right = orthoAdjCells.get(1);
BattleshipCell down = orthoAdjCells.get(2);
BattleshipCell left = orthoAdjCells.get(3);
- boolean isVertical = (up != null && BattleshipType.isShip(up.getData()))
- || (down != null && BattleshipType.isShip(down.getData()));
+ boolean isVertical =
+ (up != null && BattleshipType.isShip(up.getData()))
+ || (down != null && BattleshipType.isShip(down.getData()));
- boolean isHorizontal = (left != null && BattleshipType.isShip(left.getData()))
- || (right != null && BattleshipType.isShip(right.getData()));
+ boolean isHorizontal =
+ (left != null && BattleshipType.isShip(left.getData()))
+ || (right != null && BattleshipType.isShip(right.getData()));
// ships cannot be both vertical and horizontal
if (isVertical && isHorizontal) {
@@ -63,8 +62,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
}
// check diagonally adjacent cells
- List diagAdjCells
- = bsBoard.getAdjDiagonals(cell);
+ List diagAdjCells = bsBoard.getAdjDiagonals(cell);
BattleshipCell upRight = diagAdjCells.get(0);
BattleshipCell downRight = diagAdjCells.get(1);
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/ContinueShipDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/ContinueShipDirectRule.java
index 18c55d635..670a136a4 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/ContinueShipDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/ContinueShipDirectRule.java
@@ -1,43 +1,45 @@
-package edu.rpi.legup.puzzle.battleship.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.model.rules.DirectRule;
-import edu.rpi.legup.model.tree.TreeNode;
-import edu.rpi.legup.model.tree.TreeTransition;
-
-public class ContinueShipDirectRule extends DirectRule {
-
- public ContinueShipDirectRule() {
- super("BTSP-BASC-0001",
- "Continue Ship",
- "",
- "edu/rpi/legup/images/battleship/rules/ContinueShip.png");
- }
-
- /**
- * Checks whether the child node logically follows from the parent node
- * at the specific puzzleElement index using this rule
- * This method is the one that should be overridden in child classes
- *
- * @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
- protected String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
- return null;
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- return null;
- }
-}
+package edu.rpi.legup.puzzle.battleship.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.DirectRule;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+
+public class ContinueShipDirectRule extends DirectRule {
+
+ public ContinueShipDirectRule() {
+ super(
+ "BTSP-BASC-0001",
+ "Continue Ship",
+ "",
+ "edu/rpi/legup/images/battleship/rules/ContinueShip.png");
+ }
+
+ /**
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule This method is the one that should be overridden in child
+ * classes
+ *
+ * @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
+ protected String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ return null;
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ return null;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/FinishWithShipsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/FinishWithShipsDirectRule.java
index 3374d1806..9bc4065aa 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/FinishWithShipsDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/FinishWithShipsDirectRule.java
@@ -1,116 +1,108 @@
-package edu.rpi.legup.puzzle.battleship.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-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.battleship.BattleshipBoard;
-import edu.rpi.legup.puzzle.battleship.BattleshipCell;
-import edu.rpi.legup.puzzle.battleship.BattleshipClue;
-import edu.rpi.legup.puzzle.battleship.BattleshipType;
-
-import java.awt.*;
-import java.util.List;
-
-public class FinishWithShipsDirectRule extends DirectRule {
-
- public FinishWithShipsDirectRule() {
- super("BTSP-BASC-0002",
- "Finish with Ships",
- "The number of undetermined squares is equal to the number " +
- "of segments remaining for each clue.",
- "edu/rpi/legup/images/battleship/rules/finishShip.png");
- }
-
- /**
- * Checks whether the child node logically follows from the parent node
- * at the specific puzzleElement index using this rule
- * This method is the one that should be overridden in child classes
- *
- * @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
- protected String checkRuleRawAt(TreeTransition transition,
- PuzzleElement puzzleElement) {
- BattleshipBoard initBoard = (BattleshipBoard) transition.getParents()
- .get(0).getBoard();
- BattleshipCell initCell = (BattleshipCell) initBoard
- .getPuzzleElement(puzzleElement);
- BattleshipBoard finalBoard = (BattleshipBoard) transition.getBoard();
- BattleshipCell finalCell = (BattleshipCell) finalBoard
- .getPuzzleElement(puzzleElement);
- if (!(initCell.getType() == BattleshipType.UNKNOWN
- && BattleshipType.isShip(finalCell.getType()))) {
- return super.getInvalidUseOfRuleMessage() + ": This cell must be a ship.";
- }
-
- if (isForced(initBoard, initCell)) {
- return null;
- }
- else {
- return super.getInvalidUseOfRuleMessage() + ": This cell is not forced to" +
- "be a ship segment.";
- }
- }
-
- private boolean isForced(BattleshipBoard board, BattleshipCell cell) {
- Point loc = cell.getLocation();
-
- // count the number of ship segments and unknowns in the row
- List row = board.getRow(loc.y);
- int rowCount = 0;
- for (BattleshipCell c : row) {
- if (c.getType() == BattleshipType.SHIP_UNKNOWN
- || BattleshipType.isShip(c.getType())) {
- rowCount++;
- }
- }
-
- // count the number of ship segments and unknowns in the column
- List col = board.getColumn(loc.x);
- int colCount = 0;
- for (BattleshipCell c : col) {
- if (c.getType() == BattleshipType.SHIP_UNKNOWN
- || BattleshipType.isShip(c.getType())) {
- colCount++;
- }
- }
-
- // compare the counts with the clues
- BattleshipClue east = board.getEast().get(loc.y);
- BattleshipClue south = board.getSouth().get(loc.x);
-
- return rowCount <= east.getData() && colCount <= south.getData();
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the
- * {@link TreeNode}.
- *
- * @param node tree node used to create default transition board.
- * @return default board or null if this rule cannot be applied to this tree
- * node.
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- BattleshipBoard board = (BattleshipBoard) node.getBoard().copy();
- for (PuzzleElement element : board.getPuzzleElements()) {
- BattleshipCell cell = (BattleshipCell) element;
- if (cell.getType() == BattleshipType.UNKNOWN && isForced(board, cell)) {
- cell.setData(BattleshipType.SHIP_UNKNOWN);
- board.addModifiedData(cell);
- }
- }
-
- if (board.getModifiedData().isEmpty()) {
- return null;
- }
- else {
- return board;
- }
- }
-}
+package edu.rpi.legup.puzzle.battleship.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+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.battleship.BattleshipBoard;
+import edu.rpi.legup.puzzle.battleship.BattleshipCell;
+import edu.rpi.legup.puzzle.battleship.BattleshipClue;
+import edu.rpi.legup.puzzle.battleship.BattleshipType;
+import java.awt.*;
+import java.util.List;
+
+public class FinishWithShipsDirectRule extends DirectRule {
+
+ public FinishWithShipsDirectRule() {
+ super(
+ "BTSP-BASC-0002",
+ "Finish with Ships",
+ "The number of undetermined squares is equal to the number "
+ + "of segments remaining for each clue.",
+ "edu/rpi/legup/images/battleship/rules/finishShip.png");
+ }
+
+ /**
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule This method is the one that should be overridden in child
+ * classes
+ *
+ * @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
+ protected String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ BattleshipBoard initBoard = (BattleshipBoard) transition.getParents().get(0).getBoard();
+ BattleshipCell initCell = (BattleshipCell) initBoard.getPuzzleElement(puzzleElement);
+ BattleshipBoard finalBoard = (BattleshipBoard) transition.getBoard();
+ BattleshipCell finalCell = (BattleshipCell) finalBoard.getPuzzleElement(puzzleElement);
+ if (!(initCell.getType() == BattleshipType.UNKNOWN
+ && BattleshipType.isShip(finalCell.getType()))) {
+ return super.getInvalidUseOfRuleMessage() + ": This cell must be a ship.";
+ }
+
+ if (isForced(initBoard, initCell)) {
+ return null;
+ } else {
+ return super.getInvalidUseOfRuleMessage()
+ + ": This cell is not forced to"
+ + "be a ship segment.";
+ }
+ }
+
+ private boolean isForced(BattleshipBoard board, BattleshipCell cell) {
+ Point loc = cell.getLocation();
+
+ // count the number of ship segments and unknowns in the row
+ List row = board.getRow(loc.y);
+ int rowCount = 0;
+ for (BattleshipCell c : row) {
+ if (c.getType() == BattleshipType.SHIP_UNKNOWN || BattleshipType.isShip(c.getType())) {
+ rowCount++;
+ }
+ }
+
+ // count the number of ship segments and unknowns in the column
+ List col = board.getColumn(loc.x);
+ int colCount = 0;
+ for (BattleshipCell c : col) {
+ if (c.getType() == BattleshipType.SHIP_UNKNOWN || BattleshipType.isShip(c.getType())) {
+ colCount++;
+ }
+ }
+
+ // compare the counts with the clues
+ BattleshipClue east = board.getEast().get(loc.y);
+ BattleshipClue south = board.getSouth().get(loc.x);
+
+ return rowCount <= east.getData() && colCount <= south.getData();
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board.
+ * @return default board or null if this rule cannot be applied to this tree node.
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ BattleshipBoard board = (BattleshipBoard) node.getBoard().copy();
+ for (PuzzleElement element : board.getPuzzleElements()) {
+ BattleshipCell cell = (BattleshipCell) element;
+ if (cell.getType() == BattleshipType.UNKNOWN && isForced(board, cell)) {
+ cell.setData(BattleshipType.SHIP_UNKNOWN);
+ board.addModifiedData(cell);
+ }
+ }
+
+ if (board.getModifiedData().isEmpty()) {
+ return null;
+ } else {
+ return board;
+ }
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/FinishWithWaterDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/FinishWithWaterDirectRule.java
index 157b13d01..99e5925e0 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/FinishWithWaterDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/FinishWithWaterDirectRule.java
@@ -1,43 +1,45 @@
-package edu.rpi.legup.puzzle.battleship.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.model.rules.DirectRule;
-import edu.rpi.legup.model.tree.TreeNode;
-import edu.rpi.legup.model.tree.TreeTransition;
-
-public class FinishWithWaterDirectRule extends DirectRule {
-
- public FinishWithWaterDirectRule() {
- super("BTSP-BASC-0003",
- "Finish with Water",
- "",
- "edu/rpi/legup/images/battleship/rules/finishWater.png");
- }
-
- /**
- * Checks whether the child node logically follows from the parent node
- * at the specific puzzleElement index using this rule
- * This method is the one that should overridden in child classes
- *
- * @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
- protected String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
- return null;
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- return null;
- }
-}
+package edu.rpi.legup.puzzle.battleship.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.DirectRule;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+
+public class FinishWithWaterDirectRule extends DirectRule {
+
+ public FinishWithWaterDirectRule() {
+ super(
+ "BTSP-BASC-0003",
+ "Finish with Water",
+ "",
+ "edu/rpi/legup/images/battleship/rules/finishWater.png");
+ }
+
+ /**
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule This method is the one that should overridden in child
+ * classes
+ *
+ * @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
+ protected String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ return null;
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ return null;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/IncompleteShipContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/IncompleteShipContradictionRule.java
index 4a6cb3d15..e8cfebb90 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/IncompleteShipContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/IncompleteShipContradictionRule.java
@@ -7,19 +7,21 @@
public class IncompleteShipContradictionRule extends ContradictionRule {
public IncompleteShipContradictionRule() {
- super("BTSP-CONT-0002",
+ super(
+ "BTSP-CONT-0002",
"Incomplete Ship",
"",
"edu/rpi/legup/images/battleship/contradictions/IncompleteShip.png");
}
/**
- * Checks whether the transition has a contradiction at the specific puzzleElement index using this rule
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
*
- * @param board board to check contradiction
+ * @param board board to check contradiction
* @param puzzleElement equivalent puzzleElement
* @return null if the transition contains a contradiction at the specified puzzleElement,
- * otherwise error message
+ * otherwise error message
*/
@Override
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/SegmentTypeCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/SegmentTypeCaseRule.java
index 3850ee39f..93079fb71 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/SegmentTypeCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/SegmentTypeCaseRule.java
@@ -5,20 +5,20 @@
import edu.rpi.legup.model.gameboard.PuzzleElement;
import edu.rpi.legup.model.rules.CaseRule;
import edu.rpi.legup.model.tree.TreeTransition;
-
import java.util.List;
public class SegmentTypeCaseRule extends CaseRule {
public SegmentTypeCaseRule() {
- super("BTSP-CASE-0001",
+ super(
+ "BTSP-CASE-0001",
"Segment Type",
"",
"edu/rpi/legup/images/battleship/cases/SegmentType.png");
}
/**
- * Checks whether the {@link TreeTransition} logically follows from the parent node using this rule. This method is
- * the one that should overridden in child classes.
+ * Checks whether the {@link TreeTransition} logically follows from the parent node using this
+ * rule. This method is the one that should overridden in child classes.
*
* @param transition transition to check
* @return null if the child node logically follow from the parent node, otherwise error message
@@ -29,13 +29,14 @@ public String checkRuleRaw(TreeTransition transition) {
}
/**
- * Checks whether the child node logically follows from the parent node at the specific puzzleElement index using
- * this rule. This method is the one that should overridden in child classes.
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule. This method is the one that should overridden in child
+ * classes.
*
- * @param transition transition to check
+ * @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
+ * @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) {
@@ -43,7 +44,8 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem
}
/**
- * Gets the case board that indicates where this case rule can be applied on the given {@link Board}.
+ * Gets the case board that indicates where this case rule can be applied on the given {@link
+ * Board}.
*
* @param board board to find locations where this case rule can be applied
* @return a case board
@@ -54,9 +56,10 @@ public CaseBoard getCaseBoard(Board board) {
}
/**
- * Gets the possible cases for this {@link Board} at a specific {@link PuzzleElement} based on this case rule.
+ * Gets the possible cases for this {@link Board} at a specific {@link PuzzleElement} based on
+ * this case rule.
*
- * @param board the current board state
+ * @param board the current board state
* @param puzzleElement equivalent puzzleElement
* @return a list of elements the specified could be
*/
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/SegmentTypeDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/SegmentTypeDirectRule.java
index f90dea1bd..8576ef722 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/SegmentTypeDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/SegmentTypeDirectRule.java
@@ -1,43 +1,45 @@
-package edu.rpi.legup.puzzle.battleship.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.model.rules.DirectRule;
-import edu.rpi.legup.model.tree.TreeNode;
-import edu.rpi.legup.model.tree.TreeTransition;
-
-public class SegmentTypeDirectRule extends DirectRule {
-
- public SegmentTypeDirectRule() {
- super("BTSP-BASC-0004",
- "Segment Type",
- "",
- "edu/rpi/legup/images/battleship/rules/SegmentChoice.png");
- }
-
- /**
- * Checks whether the child node logically follows from the parent node
- * at the specific puzzleElement index using this rule
- * This method is the one that should overridden in child classes
- *
- * @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
- protected String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
- return null;
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- return null;
- }
-}
+package edu.rpi.legup.puzzle.battleship.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.DirectRule;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+
+public class SegmentTypeDirectRule extends DirectRule {
+
+ public SegmentTypeDirectRule() {
+ super(
+ "BTSP-BASC-0004",
+ "Segment Type",
+ "",
+ "edu/rpi/legup/images/battleship/rules/SegmentChoice.png");
+ }
+
+ /**
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule This method is the one that should overridden in child
+ * classes
+ *
+ * @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
+ protected String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ return null;
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ return null;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/ShipLocationCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/ShipLocationCaseRule.java
index f21488cca..da8f33cc2 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/ShipLocationCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/ShipLocationCaseRule.java
@@ -5,21 +5,21 @@
import edu.rpi.legup.model.gameboard.PuzzleElement;
import edu.rpi.legup.model.rules.CaseRule;
import edu.rpi.legup.model.tree.TreeTransition;
-
import java.util.List;
public class ShipLocationCaseRule extends CaseRule {
public ShipLocationCaseRule() {
- super("BTSP-CASE-0002",
+ super(
+ "BTSP-CASE-0002",
"Ship Location",
"",
"edu/rpi/legup/images/battleship/cases/ShipLocations.png");
}
/**
- * Checks whether the {@link TreeTransition} logically follows from the parent node using this rule. This method is
- * the one that should overridden in child classes.
+ * Checks whether the {@link TreeTransition} logically follows from the parent node using this
+ * rule. This method is the one that should overridden in child classes.
*
* @param transition transition to check
* @return null if the child node logically follow from the parent node, otherwise error message
@@ -30,13 +30,14 @@ public String checkRuleRaw(TreeTransition transition) {
}
/**
- * Checks whether the child node logically follows from the parent node at the specific puzzleElement index using
- * this rule. This method is the one that should overridden in child classes.
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule. This method is the one that should overridden in child
+ * classes.
*
- * @param transition transition to check
+ * @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
+ * @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) {
@@ -44,7 +45,8 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem
}
/**
- * Gets the case board that indicates where this case rule can be applied on the given {@link Board}.
+ * Gets the case board that indicates where this case rule can be applied on the given {@link
+ * Board}.
*
* @param board board to find locations where this case rule can be applied
* @return a case board
@@ -55,9 +57,10 @@ public CaseBoard getCaseBoard(Board board) {
}
/**
- * Gets the possible cases for this {@link Board} at a specific {@link PuzzleElement} based on this case rule.
+ * Gets the possible cases for this {@link Board} at a specific {@link PuzzleElement} based on
+ * this case rule.
*
- * @param board the current board state
+ * @param board the current board state
* @param puzzleElement equivalent puzzleElement
* @return a list of elements the specified could be
*/
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/ShipOrWaterCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/ShipOrWaterCaseRule.java
index a419b831f..3c123d7c1 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/ShipOrWaterCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/ShipOrWaterCaseRule.java
@@ -5,21 +5,21 @@
import edu.rpi.legup.model.gameboard.PuzzleElement;
import edu.rpi.legup.model.rules.CaseRule;
import edu.rpi.legup.model.tree.TreeTransition;
-
import java.util.List;
public class ShipOrWaterCaseRule extends CaseRule {
public ShipOrWaterCaseRule() {
- super("BTSP-CASE-0003",
+ super(
+ "BTSP-CASE-0003",
"Ship or Water",
"",
"edu/rpi/legup/images/battleship/cases/ShipOrWater.png");
}
/**
- * Checks whether the {@link TreeTransition} logically follows from the parent node using this rule. This method is
- * the one that should overridden in child classes.
+ * Checks whether the {@link TreeTransition} logically follows from the parent node using this
+ * rule. This method is the one that should overridden in child classes.
*
* @param transition transition to check
* @return null if the child node logically follow from the parent node, otherwise error message
@@ -30,13 +30,14 @@ public String checkRuleRaw(TreeTransition transition) {
}
/**
- * Checks whether the child node logically follows from the parent node at the specific puzzleElement index using
- * this rule. This method is the one that should overridden in child classes.
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule. This method is the one that should overridden in child
+ * classes.
*
- * @param transition transition to check
+ * @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
+ * @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) {
@@ -44,7 +45,8 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem
}
/**
- * Gets the case board that indicates where this case rule can be applied on the given {@link Board}.
+ * Gets the case board that indicates where this case rule can be applied on the given {@link
+ * Board}.
*
* @param board board to find locations where this case rule can be applied
* @return a case board
@@ -55,9 +57,10 @@ public CaseBoard getCaseBoard(Board board) {
}
/**
- * Gets the possible cases for this {@link Board} at a specific {@link PuzzleElement} based on this case rule.
+ * Gets the possible cases for this {@link Board} at a specific {@link PuzzleElement} based on
+ * this case rule.
*
- * @param board the current board state
+ * @param board the current board state
* @param puzzleElement equivalent puzzleElement
* @return a list of elements the specified could be
*/
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/SurroundShipDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/SurroundShipDirectRule.java
index 57ad42121..d26c3ed29 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/SurroundShipDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/SurroundShipDirectRule.java
@@ -1,43 +1,45 @@
-package edu.rpi.legup.puzzle.battleship.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.model.rules.DirectRule;
-import edu.rpi.legup.model.tree.TreeNode;
-import edu.rpi.legup.model.tree.TreeTransition;
-
-public class SurroundShipDirectRule extends DirectRule {
-
- public SurroundShipDirectRule() {
- super("BTSP-BASC-0005",
- "Surround Ship",
- "",
- "edu/rpi/legup/images/battleship/rules/SurroundShip.png");
- }
-
- /**
- * Checks whether the child node logically follows from the parent node
- * at the specific puzzleElement index using this rule
- * This method is the one that should overridden in child classes
- *
- * @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
- protected String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
- return null;
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- return null;
- }
-}
+package edu.rpi.legup.puzzle.battleship.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.DirectRule;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+
+public class SurroundShipDirectRule extends DirectRule {
+
+ public SurroundShipDirectRule() {
+ super(
+ "BTSP-BASC-0005",
+ "Surround Ship",
+ "",
+ "edu/rpi/legup/images/battleship/rules/SurroundShip.png");
+ }
+
+ /**
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule This method is the one that should overridden in child
+ * classes
+ *
+ * @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
+ protected String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ return null;
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ return null;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/TooFewInFleetContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/TooFewInFleetContradictionRule.java
index 5a4eb187e..d10e086d2 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/TooFewInFleetContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/TooFewInFleetContradictionRule.java
@@ -7,19 +7,21 @@
public class TooFewInFleetContradictionRule extends ContradictionRule {
public TooFewInFleetContradictionRule() {
- super("BTSP-CONT-0003",
+ super(
+ "BTSP-CONT-0003",
"Too Few in Fleet",
"",
"edu/rpi/legup/images/battleship/contradictions/too_few_in_fleet.png");
}
/**
- * Checks whether the transition has a contradiction at the specific puzzleElement index using this rule
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
*
- * @param board board to check contradiction
+ * @param board board to check contradiction
* @param puzzleElement equivalent puzzleElement
* @return null if the transition contains a contradiction at the specified puzzleElement,
- * otherwise error message
+ * otherwise error message
*/
@Override
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/TooFewRowColContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/TooFewRowColContradictionRule.java
index 7c2fa7819..382ba6e39 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/TooFewRowColContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/TooFewRowColContradictionRule.java
@@ -7,19 +7,21 @@
public class TooFewRowColContradictionRule extends ContradictionRule {
public TooFewRowColContradictionRule() {
- super("BTSP-CONT-0004",
+ super(
+ "BTSP-CONT-0004",
"Too few in row/col",
"",
"edu/rpi/legup/images/battleship/contradictions/too_few_segments.png");
}
/**
- * Checks whether the transition has a contradiction at the specific puzzleElement index using this rule
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
*
- * @param board board to check contradiction
+ * @param board board to check contradiction
* @param puzzleElement equivalent puzzleElement
* @return null if the transition contains a contradiction at the specified puzzleElement,
- * otherwise error message
+ * otherwise error message
*/
@Override
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/TooManyInFleetContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/TooManyInFleetContradictionRule.java
index 3aad88613..d58701c0b 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/TooManyInFleetContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/TooManyInFleetContradictionRule.java
@@ -7,19 +7,21 @@
public class TooManyInFleetContradictionRule extends ContradictionRule {
public TooManyInFleetContradictionRule() {
- super("BTSP-CONT-0005",
+ super(
+ "BTSP-CONT-0005",
"Too Many in Fleet",
"",
"edu/rpi/legup/images/battleship/contradictions/too_many_in_fleet.png");
}
/**
- * Checks whether the transition has a contradiction at the specific puzzleElement index using this rule
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
*
- * @param board board to check contradiction
+ * @param board board to check contradiction
* @param puzzleElement equivalent puzzleElement
* @return null if the transition contains a contradiction at the specified puzzleElement,
- * otherwise error message
+ * otherwise error message
*/
@Override
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/TooManyRowColContradiction.java b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/TooManyRowColContradiction.java
index 0970c9c69..27caa0524 100644
--- a/src/main/java/edu/rpi/legup/puzzle/battleship/rules/TooManyRowColContradiction.java
+++ b/src/main/java/edu/rpi/legup/puzzle/battleship/rules/TooManyRowColContradiction.java
@@ -7,19 +7,21 @@
public class TooManyRowColContradiction extends ContradictionRule {
public TooManyRowColContradiction() {
- super("BTSP-CONT-0006",
+ super(
+ "BTSP-CONT-0006",
"Too Many row/col",
"",
"edu/rpi/legup/images/battleship/contradictions/too_many_segments.png");
}
/**
- * Checks whether the transition has a contradiction at the specific puzzleElement index using this rule
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
*
- * @param board board to check contradiction
+ * @param board board to check contradiction
* @param puzzleElement equivalent puzzleElement
* @return null if the transition contains a contradiction at the specified puzzleElement,
- * otherwise error message
+ * otherwise error message
*/
@Override
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
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..d2dd0b181
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/Binary.java
@@ -0,0 +1,83 @@
+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 current board is a valid state
+ *
+ * @param board board to check for validity
+ * @return true if board is valid, false otherwise
+ */
+ @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;
+ }
+
+ /**
+ * Callback for when the board puzzleElement changes
+ *
+ * @param board the board that has changed
+ */
+ @Override
+ public void onBoardChange(Board board) {}
+
+
+ /**
+ * 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 && rows == columns;
+ }
+}
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..34819410b
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryBoard.java
@@ -0,0 +1,118 @@
+package edu.rpi.legup.puzzle.binary;
+
+import edu.rpi.legup.model.gameboard.GridBoard;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+
+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;
+ }
+
+ /**
+ * Gets the cell at the (x,y) position
+ *
+ * @param x x-coordinate
+ * @param y y-coordinate
+ * @return BinaryCell cell at (x,y)
+ */
+ @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);
+ }
+
+ /**
+ * Get all the binary cells in a row
+ *
+ * @param rowNum row number
+ * @return set of all binary cells in specified rowNum
+ */
+ 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;
+ }
+
+ /**
+ * Get all the binary cells in a column
+ *
+ * @param colNum column number
+ * @return set of all binary cells in specified colNum
+ */
+ public Set getColCells(int colNum) {
+ Set col = new HashSet<>();
+ for (int i = 0; i < size; i++) {
+ col.add(getCell(colNum, i));
+ }
+ return col;
+ }
+
+ /**
+ * Get all the binary types in a row
+ *
+ * @param rowNum row number
+ * @return ArrayList of all binary types in specified rowNum
+ */
+ 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;
+ }
+
+ /**
+ * Get all the binary types in a column
+ *
+ * @param colNum column number
+ * @return ArrayList of all binary types in specified colNum
+ */
+ 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;
+ }
+
+ /**
+ * Get a copy of the binary board
+ * @return copy of current BinaryBoard
+ */
+ @Override
+ public 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..d09f7115e
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCell.java
@@ -0,0 +1,86 @@
+package edu.rpi.legup.puzzle.binary;
+
+import edu.rpi.legup.model.elements.Element;
+import edu.rpi.legup.model.gameboard.GridCell;
+import java.awt.Point;
+import java.awt.event.MouseEvent;
+
+
+public class BinaryCell extends GridCell {
+ /**
+ * BinaryCell Constructor - creates a BinaryCell from the specified value and location
+ *
+ * @param value value of the BinaryCell
+ * @param location position of the BinaryCell
+ */
+ public BinaryCell(int value, Point location) {
+ super(value, location);
+ }
+
+ /**
+ * Gets the type of this BinaryCell
+ *
+ * @return type of BinaryCell
+ */
+ 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;
+ }
+
+ /**
+ * Performs a deep copy on the BinaryCell
+ *
+ * @return a new copy of the BinaryCell that is independent of this one
+ */
+ @Override
+ public BinaryCell copy() {
+ BinaryCell copy = new BinaryCell(data, (Point) location.clone());
+ copy.setIndex(index);
+ copy.setModifiable(isModifiable);
+ copy.setGiven(isGiven);
+ return copy;
+ }
+
+ /**
+ * Sets the type of this BinaryCell
+ *
+ * @param e element to set the type of this binary cell to
+ */
+ @Override
+ public void setType(Element e, MouseEvent m) {
+ if (e.getElementName().equals("Number Tile")) {
+ if (m.getButton() == MouseEvent.BUTTON1) {
+ if (this.data == 2) {
+ this.data = 0;
+ }
+ else {
+ this.data = this.data + 1;
+ }
+ }
+ else {
+ if (m.getButton() == MouseEvent.BUTTON3) {
+ if (this.data > 0) {
+ this.data = this.data - 1;
+ }
+ else {
+ this.data = 2;
+ }
+ }
+ }
+ }
+ else { // unknown tile
+ this.data = 2;
+ }
+ }
+}
\ No newline at end of file
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..a819177d6
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryCellFactory.java
@@ -0,0 +1,73 @@
+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 {
+ /**
+ * Creates a puzzleElement based on the xml document Node and adds it to the board
+ *
+ * @param node node that represents the puzzleElement
+ * @param board board to add the newly created cell
+ * @return newly created cell from the xml document Node
+ * @throws InvalidFileFormatException if file is invalid
+ */
+ 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)");
+ }
+ }
+
+ /**
+ * Creates a xml document puzzleElement from a cell for exporting
+ *
+ * @param document xml document
+ * @param puzzleElement PuzzleElement cell
+ * @return xml PuzzleElement
+ */
+ 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..caf62f3fe
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryController.java
@@ -0,0 +1,55 @@
+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 {
+
+ /**
+ * Handles cell state changes in the binary puzzle when a mouse event occurs
+ * If the left mouse button is clicked:
+ * - If the control key is held down, shows a context menu at the mouse position
+ * - Otherwise, toggles the cell data state between 0, 1, and 2 in a cyclic manner
+ * If the right mouse button is clicked, the cell state is also toggled between 2, 1, and 0
+ *
+ * @param e MouseEvent triggered by the user interaction
+ * @param data PuzzleElement representing the cell being modified
+ */
+ @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() == 2) {
+ data.setData(1);
+ } else {
+ if (cell.getData() == 1) {
+ data.setData(0);
+ } else {
+ data.setData(2);
+ }
+ }
+ }
+ }
+ }
+}
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..f5ea33d4a
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryElementView.java
@@ -0,0 +1,89 @@
+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;
+ private static final Color GIVEN_COLOR = Color.LIGHT_GRAY;
+ private static final Color ELEMENT_COLOR = Color.WHITE;
+
+ 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();
+ }
+
+
+ /**
+ * Draws the cells provided in the puzzle's .xml file with light gray background
+ *
+ * @param graphics2D The graphics object to draw on
+ */
+ @Override
+ public void drawGiven(Graphics2D graphics2D) {
+ drawCell(graphics2D, GIVEN_COLOR);
+ }
+
+ /**
+ * Draws new cells being added to board with white background
+ *
+ * @param graphics2D The graphics object to draw on
+ */
+ @Override
+ public void drawElement(Graphics2D graphics2D) {
+ drawCell(graphics2D, ELEMENT_COLOR);
+ }
+
+ /**
+ * Helper method to handle drawing the cell based on its type and background color
+ *
+ * @param graphics2D The graphics object to draw on
+ * @param bgColor The background color for the cell
+ */
+ private void drawCell(Graphics2D graphics2D, Color bgColor) {
+ BinaryCell cell = (BinaryCell) puzzleElement;
+ BinaryType type = cell.getType();
+
+ if (type == BinaryType.ZERO || type == BinaryType.ONE) {
+ graphics2D.setStroke(new BasicStroke(1));
+ graphics2D.setColor(bgColor);
+ graphics2D.fillRect(location.x, location.y, size.width, size.height);
+ graphics2D.setColor(Color.BLACK);
+ graphics2D.drawRect(location.x, location.y, size.width, size.height);
+ drawCenteredText(graphics2D);
+ } 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);
+ }
+ }
+
+ /**
+ * Helper method to draw the centered text within the cell
+ *
+ * @param graphics2D The graphics object to draw on
+ */
+ private void drawCenteredText(Graphics2D graphics2D) {
+ 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(value, xText, yText);
+ }
+}
+
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..f12a07378
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryExporter.java
@@ -0,0 +1,46 @@
+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);
+ }
+
+ /**
+ * Generates an XML element for the binary puzzle board, including its dimensions and the
+ * state of each cell. Binary cells that are not in the `UNKNOWN` state are included in the XML.
+ *
+ * @param newDocument The XML document to which the board element belongs.
+ * @return The XML element representing the board.
+ */
+ @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() != BinaryType.UNKNOWN.toValue()) {
+ 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..8a4bad01e
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryImporter.java
@@ -0,0 +1,139 @@
+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);
+ }
+
+ /**
+ * Determines if puzzle uses row and column input
+ *
+ * @return true if row and column input is used, false otherwise
+ */
+ @Override
+ public boolean acceptsRowsAndColumnsInput() {
+ return true;
+ }
+
+ /**
+ * Determines if puzzle uses text input
+ *
+ * @return true if text input is used, false otherwise
+ */
+ @Override
+ public boolean acceptsTextInput() {
+ return false;
+ }
+
+ /**
+ * Creates an empty board for building
+ *
+ * @param rows the number of rows on the board
+ * @param columns the number of columns on the board
+ * @throws RuntimeException if board can not be created
+ */
+ @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");
+ }
+ }
+
+ /**
+ * Initializes a board with text
+ * @param statements the text being used
+ * @throws UnsupportedOperationException Binary does not use text input
+ */
+ @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..f03f2ee08
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryType.java
@@ -0,0 +1,24 @@
+package edu.rpi.legup.puzzle.binary;
+
+/**
+ * Enum representing the possible states of a binary puzzle cell
+ *
+ * The states include:
+ * - ZERO: Represents a cell with a value of 0
+ * - ONE: Represents a cell with a value of 1
+ * - UNKNOWN: Represents an empty cell
+ *
+ */
+public enum BinaryType {
+ ZERO, // Enum constant 0
+ ONE, // Enum constant 1
+ UNKNOWN; // Enum constant 2
+
+ /**
+ * The `toValue` method returns the ordinal value of the enum constant,
+ * which can be used to convert the enum to an integer representation.
+ */
+ 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..e1869de6b
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/BinaryView.java
@@ -0,0 +1,31 @@
+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 {
+
+ /** Creates and arranges the visual components for each cell in the binary puzzle. Initializes
+ * the view by setting up the board controller, binary controller, and the grid dimensions.
+ * For each cell in the BinaryBoard, it creates a corresponding BinaryElementView, sets its index,
+ * size, and location, and adds it to the list of element views to be displayed.
+ *
+ * @param board The BinaryBoard representing the current state of the binary puzzle
+ */
+ 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/NumberTile.java b/src/main/java/edu/rpi/legup/puzzle/binary/elements/NumberTile.java
new file mode 100644
index 000000000..e996e246b
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/elements/NumberTile.java
@@ -0,0 +1,14 @@
+
+package edu.rpi.legup.puzzle.binary.elements;
+
+import edu.rpi.legup.model.elements.PlaceableElement;
+
+public class NumberTile extends PlaceableElement {
+ public NumberTile() {
+ super(
+ "BINA-ELEM-0001",
+ "Number Tile",
+ "A number tile",
+ "edu/rpi/legup/images/binary/tiles/NumberTile.png");
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/elements/UnknownTile.java b/src/main/java/edu/rpi/legup/puzzle/binary/elements/UnknownTile.java
new file mode 100644
index 000000000..8c60ea8c3
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/elements/UnknownTile.java
@@ -0,0 +1,13 @@
+package edu.rpi.legup.puzzle.binary.elements;
+
+import edu.rpi.legup.model.elements.PlaceableElement;
+
+public class UnknownTile extends PlaceableElement {
+ public UnknownTile() {
+ super(
+ "BINA-ELEM-0002",
+ "Unknown Tile",
+ "A blank tile",
+ "edu/rpi/legup/images/binary/tiles/UnknownTile.png");
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/elements/binary_elements_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/binary/elements/binary_elements_reference_sheet.txt
new file mode 100644
index 000000000..54db0ee0b
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/elements/binary_elements_reference_sheet.txt
@@ -0,0 +1,2 @@
+BINA-ELEM-0001 : NumberTile
+BINA-ELEM-0002 : UnknownTile
\ No newline at end of file
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..359433685
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/CompleteRowColumnDirectRule.java
@@ -0,0 +1,60 @@
+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 UnbalancedRowColumnContradictionRule();
+ BinaryCell binaryCell = (BinaryCell) puzzleElement;
+ BinaryBoard modified = origBoard.copy();
+
+ // Flip the cell and check to see if there will be an unbalanced row/column contradiction,
+ // if so the rule is applied correctly
+ modified.getPuzzleElement(puzzleElement).setData(Math.abs(binaryCell.getData() - 1));
+ if (contraRule.checkContradictionAt(modified, puzzleElement) == null) {
+ return null;
+ }
+
+ return "Unbalanced row/column found";
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ return null;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/EliminateTheImpossibleDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/EliminateTheImpossibleDirectRule.java
new file mode 100644
index 000000000..02c1c2c31
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/EliminateTheImpossibleDirectRule.java
@@ -0,0 +1,201 @@
+//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.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;
+//import edu.rpi.legup.puzzle.binary.BinaryType;
+//
+//import java.util.LinkedList;
+//import java.util.Queue;
+//import java.lang.Math.*;
+//import java.lang.reflect.Array;
+//import java.util.ArrayList;
+//
+//public class EliminateTheImpossibleDirectRule extends DirectRule {
+// private final String INVALID_USE_MESSAGE = "Number at cell is incorrect";
+//
+// public EliminateTheImpossibleDirectRule() {
+// super(
+// "BINA-BASC-0004",
+// "Eliminate The Impossible",
+// "Out of the remaining empty cells in this row or column, this digit must go here, otherwise there will be a future contradiction",
+// "edu/rpi/legup/images/binary/rules/EliminateTheImpossibleDirectRule.png");
+// }
+//
+// // Function to generate all binary strings
+// void generatePossibilitites(int spots, ArrayList possibilities, int zeroCount, int oneCount)
+// // This function generates all the possible combinations of 0s and 1s for a
+// // certain size, it does this
+// // by basically just counting from 0 to the number - 1, so if you want all the
+// // possible combinations for 3
+// // spots, you can just count in binary from 0 to 7 (taking 3 spots, so from 000
+// // to 111). To be practical,
+// // the function does not return an array with all the possibilities as an array,
+// // but populates the
+// // arraylist you pass in (possibilities)
+// {
+// if (zeroCount + oneCount != spots) {
+// System.out.println("INVALID INPUT");
+// return;
+// }
+//
+// if (zeroCount == spots) {
+// String zero = "";
+// for (int i = 0; i < spots; i++) {
+// zero = zero + "0";
+// }
+// possibilities.add(zero);
+//
+// }
+// int count = (int) Math.pow(2, spots) - 1;
+// int finalLen = spots;
+// Queue q = new LinkedList();
+// q.add("1");
+//
+// while (count-- > 0) {
+// String s1 = q.peek();
+// q.remove();
+//
+// String newS1 = s1;
+// int curLen = newS1.length();
+// int runFor = spots - curLen;
+// if (curLen < finalLen) {
+// for (int i = 0; i < runFor; i++) {
+// newS1 = "0" + newS1;
+// }
+// }
+// int curZeros = 0;
+// int curOnes = 0;
+//
+// for (int i = 0; i < spots; i++) {
+// if (newS1.charAt(i) == '0') {
+// curZeros++;
+// }
+// if (newS1.charAt(i) == '1') {
+// curOnes++;
+// }
+// }
+//
+// if (zeroCount == curZeros && oneCount == curOnes) {
+// possibilities.add(newS1);
+// }
+// String s2 = s1;
+// q.add(s1 + "0");
+// q.add(s2 + "1");
+// }
+// }
+//
+// @Override
+// public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+// // This function should first check if there are three open spaces, if so,
+// // continue, else figure out
+// // how many spots are open, all the possible binary combinations that could be
+// // put there, and by
+// // analyzing the common factors, logically determine which number has a set
+// // spot, meaning that we know
+// // that a certain spot must be a zero or a one
+//
+// BinaryBoard origBoard = (BinaryBoard) transition.getParents().get(0).getBoard();
+// BinaryCell binaryCell = (BinaryCell) puzzleElement;
+//
+// //Getting the row where the user clicked
+// ArrayList row = origBoard.listRowCells(binaryCell.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++;
+// }
+// }
+//
+// ArrayList rowResult = new ArrayList();
+//
+// // To call generatePossibilitites(), you must call it and pass in the amount of
+// // unknown spots left,
+// // an ArrayList that will be populated with the possible results (in String
+// // form), the amount of zeros left and ones left
+// generatePossibilitites((size - rowNumZeros - rowNumOnes), rowResult, size / 2 - rowNumZeros, size / 2 - rowNumOnes);
+//
+// // Create deep copies of each row
+// ArrayList> rowCopies = new ArrayList<>();
+// for (int i = 0; i < rowResult.size(); i++) {
+// ArrayList newRow = new ArrayList<>();
+// for (BinaryCell cell : row) {
+// newRow.add(cell.copy());
+// }
+// rowCopies.add(newRow);
+// }
+//
+// System.out.println("Number of possible binary combinations: " + rowCopies.size());
+//
+// ArrayList> nonContraRows = new ArrayList<>();
+// int rowIdx = 0;
+// for(ArrayList curRow : rowCopies){
+// int charIdx = 0;
+// System.out.println(rowResult.get(rowIdx));
+// for(int i = 0; i < curRow.size(); i++) {
+// if (curRow.get(i).getData() == 2) {
+// if (rowResult.get(rowIdx).charAt(charIdx) == '0') {
+// curRow.get(i).setData(0);
+// }
+// else if (rowResult.get(rowIdx).charAt(charIdx) == '1') {
+// curRow.get(i).setData(1);
+// }
+// charIdx++;
+// }
+// System.out.print(curRow.get(i).getData() + " ");
+// }
+//
+// boolean threeAdjacent = false;
+// int count = 1;
+// for(int i = 1; i < curRow.size(); i++) {
+// if (curRow.get(i).getData() == curRow.get(i-1).getData()) {
+// count++;
+// if (count == 3) {
+// threeAdjacent = true;
+// break;
+// }
+// } else {
+// count = 1;
+// }
+// }
+//
+// if (!threeAdjacent) {
+// nonContraRows.add(curRow);
+// }
+//
+// rowIdx++;
+// System.out.println();
+// }
+//
+// System.out.println("Number of non contradiction rows: " + nonContraRows.size());
+// int colNum = binaryCell.getLocation().x;
+// boolean invalid = false;
+// for(int i = 0; i < nonContraRows.size(); i++) {
+// if (nonContraRows.get(i).get(colNum).getData() != binaryCell.getData()) {
+// invalid = true;
+// break;
+// }
+// }
+//
+// if (!invalid) {
+// return null;
+// }
+//
+// return "This cell can either be a 0 or a 1";
+//
+// }
+//
+// @Override
+// public Board getDefaultBoard(TreeNode node) {
+// return null;
+// }
+//}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/PreventTrioDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/PreventTrioDirectRule.java
new file mode 100644
index 000000000..745e35d4e
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/PreventTrioDirectRule.java
@@ -0,0 +1,58 @@
+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.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 PreventTrioDirectRule extends DirectRule {
+ private final String INVALID_USE_MESSAGE = "Number at cell is incorrect";
+
+ public PreventTrioDirectRule() {
+ super(
+ "BINA-BASC-0001",
+ "Prevent Trio",
+ "If a trio contradiction state could appear, use the opposite digit to prevent the trio",
+ "edu/rpi/legup/images/binary/rules/PreventTrioDirectRule.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();
+ TrioContradictionRule contraRule = new TrioContradictionRule();
+ BinaryCell binaryCell = (BinaryCell) puzzleElement;
+ BinaryBoard modified = origBoard.copy();
+
+ // Flip the cell and check to see if there will be a trio contradiction, if so the rule is applied correctly
+ modified.getPuzzleElement(puzzleElement).setData(Math.abs(binaryCell.getData() - 1));
+ if (contraRule.checkContradictionAt(modified, binaryCell) == null) {
+ return null;
+ }
+
+ return "Trio Found";
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/RepeatedRowColumnContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/RepeatedRowColumnContradictionRule.java
new file mode 100644
index 000000000..13eb35283
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/RepeatedRowColumnContradictionRule.java
@@ -0,0 +1,63 @@
+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 RepeatedRowColumnContradictionRule 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 RepeatedRowColumnContradictionRule() {
+ super(
+ "BINA-CONT-0003",
+ "Repeated Row/Column",
+ "There must not be two of the same row or two of the same column in the puzzle",
+ "edu/rpi/legup/images/binary/rules/RepeatedRowColumnContradictionRule.png");
+ }
+
+ /**
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
+ *
+ * @param board board to check contradiction
+ * @param puzzleElement equivalent puzzleElement
+ * @return null if the transition contains a contradiction at the specified puzzleElement,
+ * otherwise error message
+ */
+ @Override
+ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
+ BinaryBoard binaryBoard = (BinaryBoard) board;
+ BinaryCell cell = (BinaryCell) binaryBoard.getPuzzleElement(puzzleElement);
+
+ // Compare each row with row of current cell to see if they are equal, if so the rule is applied correctly
+ 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;
+ }
+ }
+ }
+
+ // Compare each column with column of current cell to see if they are equal, if so the rule is applied correctly
+ 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/SaveBlockerDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/SaveBlockerDirectRule.java
new file mode 100644
index 000000000..5f76c4f59
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/SaveBlockerDirectRule.java
@@ -0,0 +1,60 @@
+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.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 SaveBlockerDirectRule extends DirectRule {
+
+ private final String INVALID_USE_MESSAGE = "Number at cell is incorrect";
+
+ public SaveBlockerDirectRule() {
+ super(
+ "BINA-BASC-0003",
+ "Save Blocker",
+ "If a future trio could appear in this row/col, save the digit that could block that trio",
+ "edu/rpi/legup/images/binary/rules/SaveBlockerDirectRule.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
+ */
+ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ BinaryBoard origBoard = (BinaryBoard) transition.getParents().get(0).getBoard();
+ WastedBlockerContradictionRule contraRule = new WastedBlockerContradictionRule();
+ BinaryCell binaryCell = (BinaryCell) puzzleElement;
+ BinaryBoard modified = origBoard.copy();
+
+ // Flip the cell and check to see if a blocker digit is wasted, if so the rule is applied correctly
+ modified.getPuzzleElement(puzzleElement).setData(Math.abs(binaryCell.getData() - 1));
+ if (contraRule.checkContradictionAt(modified, binaryCell) == null) {
+ return null;
+ }
+
+ return "Wasted Digit Found";
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ return null;
+ }
+
+
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/TrioContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/TrioContradictionRule.java
new file mode 100644
index 000000000..dce7fe371
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/TrioContradictionRule.java
@@ -0,0 +1,185 @@
+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 TrioContradictionRule 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 TrioContradictionRule() {
+ super(
+ "BINA-CONT-0001",
+ "Trio",
+ "There must not be three adjacent zeros or three adjacent ones in a row or column",
+ "edu/rpi/legup/images/binary/rules/TrioContradictionRule.png");
+ }
+
+ /**
+ * This method checks the surrounding cells of a given puzzle element at a specified distance
+ * in both the vertical and horizontal directions
+ *
+ * @param board The board where the puzzle elements are located
+ * @param puzzleElement The puzzle element from which the distance is calculated
+ * @param n The distance away from the puzzle element to retrieve the surrounding cells
+ * @return An array of BinaryCells representing the surrounding cells
+ */
+ public BinaryCell[] getCellsNAway(Board board, PuzzleElement puzzleElement, int n) {
+ BinaryBoard binaryBoard = (BinaryBoard) board;
+ BinaryCell cell = (BinaryCell) binaryBoard.getPuzzleElement(puzzleElement);
+ int cellX = cell.getLocation().x;
+ int cellY = cell.getLocation().y;
+
+ BinaryCell[] cells = new BinaryCell[4]; // [0] up x, [1] down x, [2] right x, [3] left x
+ cells[0] = null;
+ cells[1] = null;
+ cells[2] = null;
+ cells[3] = null;
+
+ if (binaryBoard.getCell(cellX, cellY + n) != null) {
+ cells[0] = binaryBoard.getCell(cellX, cellY + n);
+ }
+ if (binaryBoard.getCell(cellX, cellY - n) != null) {
+ cells[1] = binaryBoard.getCell(cellX, cellY - n);
+ }
+ if (binaryBoard.getCell(cellX + n, cellY) != null) {
+ cells[2] = binaryBoard.getCell(cellX + n, cellY);
+ }
+ if (binaryBoard.getCell(cellX - n, cellY) != null) {
+ cells[3] = binaryBoard.getCell(cellX - n, cellY);
+ }
+
+ return cells;
+ }
+
+ /**
+ * Checks whether the cell and its two surrounding cells form a trio of zeros or ones;
+ * If a trio is found, it indicates a contradiction
+ *
+ * @param board The board where the puzzle elements are located
+ * @param puzzleElement The puzzle element to check for contradiction
+ * @return true if no contradiction is found, false if contradiction detected
+ */
+ public boolean checkSurroundPair(Board board, PuzzleElement puzzleElement) {
+ BinaryBoard binaryBoard = (BinaryBoard) board;
+ BinaryCell cell = (BinaryCell) binaryBoard.getPuzzleElement(puzzleElement);
+
+ // [0] up n, [1] down n, [2] right n, [3] left n
+ BinaryCell[] cellsOneAway = getCellsNAway(board, puzzleElement, 1);
+ BinaryCell[] cellsTwoAway = getCellsNAway(board, puzzleElement, 2);
+
+ if (cell.getType() == BinaryType.ONE || cell.getType() == BinaryType.ZERO) {
+ // left one and left two
+ if (cellsOneAway[3] != null
+ && cellsTwoAway[3] != null
+ && cellsOneAway[3].getType() != BinaryType.UNKNOWN
+ && cellsTwoAway[3].getType() != BinaryType.UNKNOWN) {
+ if (cellsOneAway[3].getType() == cell.getType()
+ && cellsTwoAway[3].getType() == cell.getType()) {
+ return false;
+ }
+ }
+ // right one and right two
+ if (cellsOneAway[2] != null
+ && cellsTwoAway[2] != null
+ && cellsOneAway[2].getType() != BinaryType.UNKNOWN
+ && cellsTwoAway[2].getType() != BinaryType.UNKNOWN) {
+ if (cellsOneAway[2].getType() == cell.getType()
+ && cellsTwoAway[2].getType() == cell.getType()) {
+ return false;
+ }
+ }
+ // down one and down two
+ if (cellsOneAway[1] != null
+ && cellsTwoAway[1] != null
+ && cellsOneAway[1].getType() != BinaryType.UNKNOWN
+ && cellsTwoAway[1].getType() != BinaryType.UNKNOWN) {
+ if (cellsOneAway[1].getType() == cell.getType()
+ && cellsTwoAway[1].getType() == cell.getType()) {
+ return false;
+ }
+ }
+ // up one and up two
+ if (cellsOneAway[0] != null
+ && cellsTwoAway[0] != null
+ && cellsOneAway[0].getType() != BinaryType.UNKNOWN
+ && cellsTwoAway[0].getType() != BinaryType.UNKNOWN) {
+ if (cellsOneAway[0].getType() == cell.getType()
+ && cellsTwoAway[0].getType() == cell.getType()) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Checks whether there are two of the same cell type separated by one cell that also has
+ * the same type in any direction. If a trio is found, it indicates a contradiction
+ *
+ * @param board The board where the puzzle elements are located
+ * @param puzzleElement The puzzle element to check for contradiction
+ * @return true if no contradiction is found, false if contradiction detected
+ */
+ public boolean checkOneTileGap(Board board, PuzzleElement puzzleElement) {
+ BinaryBoard binaryBoard = (BinaryBoard) board;
+ BinaryCell cell = (BinaryCell) binaryBoard.getPuzzleElement(puzzleElement);
+
+ // [0] up n, [1] down n, [2] right n, [3] left n
+ BinaryCell[] cellsOneAway = getCellsNAway(board, puzzleElement, 1);
+
+ if (cell.getType() == BinaryType.ONE || cell.getType() == BinaryType.ZERO) {
+ // left one and right one
+ if (cellsOneAway[3] != null
+ && cellsOneAway[2] != null
+ && cellsOneAway[3].getType() != BinaryType.UNKNOWN
+ && cellsOneAway[2].getType() != BinaryType.UNKNOWN) {
+ if (cellsOneAway[3].getType() == cell.getType()
+ && cellsOneAway[2].getType() == cell.getType()) {
+ return false;
+ }
+ }
+ // down one and up one
+ if (cellsOneAway[1] != null
+ && cellsOneAway[0] != null
+ && cellsOneAway[1].getType() != BinaryType.UNKNOWN
+ && cellsOneAway[0].getType() != BinaryType.UNKNOWN) {
+ if (cellsOneAway[1].getType() == cell.getType()
+ && cellsOneAway[0].getType() == cell.getType()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
+ *
+ * @param board board to check contradiction
+ * @param puzzleElement equivalent puzzleElement
+ * @return null if the transition contains a contradiction at the specified puzzleElement,
+ * otherwise error message
+ */
+ @Override
+ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
+
+ boolean surroundPairValid = checkSurroundPair(board, puzzleElement);
+ if (!surroundPairValid) {
+ return null;
+ }
+ boolean oneTileGapValid = checkOneTileGap(board, puzzleElement);
+ if (!oneTileGapValid) {
+ return null;
+ }
+
+ return super.getNoContradictionMessage() + ": " + this.NO_CONTRADICTION_MESSAGE;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/UnbalancedRowColumnContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/UnbalancedRowColumnContradictionRule.java
new file mode 100644
index 000000000..82f658013
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/UnbalancedRowColumnContradictionRule.java
@@ -0,0 +1,81 @@
+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 UnbalancedRowColumnContradictionRule 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 UnbalancedRowColumnContradictionRule() {
+ super(
+ "BINA-CONT-0002",
+ "Unbalanced Row/Column",
+ "Each row or column must contain an equal number of zeros and ones",
+ "edu/rpi/legup/images/binary/rules/UnbalancedRowColumnContradictionRule.png");
+ }
+
+ /**
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
+ *
+ * @param board board to check contradiction
+ * @param puzzleElement equivalent puzzleElement
+ * @return null if the transition contains a contradiction at the specified puzzleElement,
+ * otherwise error message
+ */
+ @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 there are too many zeros or ones in this row
+ if (rowNumZeros > size / 2 || rowNumOnes > size / 2) {
+ return null;
+ }
+
+
+ Set col = binaryBoard.getColCells(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 there are too many zeros or ones in this column
+ if (colNumZeros > size / 2 || colNumOnes > size / 2) {
+ return null;
+ }
+
+ return super.getNoContradictionMessage() + ": " + this.NO_CONTRADICTION_MESSAGE;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/UniqueRowColumnDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/UniqueRowColumnDirectRule.java
new file mode 100644
index 000000000..3f90510e3
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/UniqueRowColumnDirectRule.java
@@ -0,0 +1,288 @@
+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.DirectRule;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.binary.Binary;
+import edu.rpi.legup.puzzle.binary.BinaryBoard;
+import edu.rpi.legup.puzzle.binary.BinaryCell;
+import edu.rpi.legup.puzzle.binary.BinaryType;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+
+public class UniqueRowColumnDirectRule extends DirectRule {
+ private final String INVALID_USE_MESSAGE = "Number at cell is incorrect";
+
+ public UniqueRowColumnDirectRule() {
+ super(
+ "BINA-BASC-0004",
+ "Unique Row/Column",
+ "If an unfinished row/column only differs by empty cells from a finished one, " +
+ "fill contradicting empty cells with opposite digit to prevent a repeated row/column",
+ "edu/rpi/legup/images/binary/rules/UniqueRowColumnDirectRule.png");
+ }
+
+ /**
+ * Counts the number of empty (UNKNOWN) cells in a given sequence
+ *
+ * @param seq The sequence of BinaryType elements to check
+ * @return The number of empty (UNKNOWN) cells in the sequence
+ */
+ private int getNumEmpty(ArrayList seq) {
+ int numEmpty = 0;
+ for (BinaryType t : seq) {
+ if (t.equals(BinaryType.UNKNOWN)) {
+ numEmpty++;
+ }
+ }
+ return numEmpty;
+ }
+
+ /**
+ * Checks if there is a valid opposite digit to prevent a repeated row/column
+ *
+ * @param seq The sequence (row or column) to check
+ * @param origBoard The original board
+ * @param binaryCell The binary cell being checked
+ * @param rowOrColumn Flag to indicate whether checking a row (0) or a column (1)
+ * @return Null if a valid opposite digit is found, otherwise an error message
+ */
+ private String checkOppositeDigitDifference(ArrayList seq, BinaryBoard origBoard,
+ BinaryCell binaryCell, int rowOrColumn) {
+ // rowOrColumn : 0 for row, 1 for column
+
+ int numEmpty = getNumEmpty(seq);
+ if (numEmpty > 2) {
+ return "Row/Column must have at most 2 empty cells";
+ }
+
+ boolean valid = false;
+ for (int i = 0; i < seq.size(); i++) {
+ ArrayList currSeq;
+ // Get the sequence (row or column) from the original board to compare
+ if (rowOrColumn == 0) {
+ if (i == binaryCell.getLocation().y) {
+ continue;
+ }
+ currSeq = origBoard.getRowTypes(i);
+ } else {
+ if (i == binaryCell.getLocation().x) {
+ continue;
+ }
+ currSeq = origBoard.getColTypes(i);
+ }
+
+ int numDifferentCells = 0;
+ for (int j = 0; j < currSeq.size(); j++) {
+ int numEmptyInCurrSeq = getNumEmpty(currSeq);
+ // If the current sequence has empty cells, it's not valid for comparison
+ if (numEmptyInCurrSeq != 0) {
+ valid = false;
+ break;
+ }
+ // Count differences between the sequences, stopping if more than 1 difference is found
+ if (!seq.get(j).equals(currSeq.get(j)) && !seq.get(j).equals(BinaryType.UNKNOWN)) {
+ if (++numDifferentCells > 1 || numEmpty != 1) {
+ valid = false;
+ break;
+ }
+ }
+
+ // Check if there's a contradiction with the current cell, if not mark as valid
+ if (currSeq.get(j).equals(BinaryType.ZERO) && seq.get(j).equals(BinaryType.UNKNOWN)
+ && binaryCell.getType().equals(BinaryType.ONE)) {
+ if ((rowOrColumn == 0 && binaryCell.getLocation().x == j) || rowOrColumn == 1
+ && binaryCell.getLocation().y == j) {
+ valid = true;
+ }
+ }
+ else if (currSeq.get(j).equals(BinaryType.ONE) && seq.get(j).equals(BinaryType.UNKNOWN)
+ && binaryCell.getType().equals(BinaryType.ZERO)) {
+ if ((rowOrColumn == 0 && binaryCell.getLocation().x == j) || rowOrColumn == 1
+ && binaryCell.getLocation().y == j) {
+ valid = true;
+ }
+ }
+ }
+ // Exit if a valid sequence is found
+ if (valid) {
+ break;
+ }
+ }
+
+ if (valid) {
+ return null;
+ }
+ return "There does not exist an opposite digit difference in ";
+ }
+
+ /**
+ * Checks if there is one digit remaining in a sequence that can be filled to avoid repeating
+ * another sequence on the board
+ *
+ * @param seq The sequence (row or column) to check
+ * @param origBoard The original board
+ * @param binaryCell The binary cell being checked
+ * @param rowOrColumn Flag to indicate whether checking a row (0) or a column (1)
+ * @param zeroOrOne Flag to indicate whether checking for 0s (0) or 1s (1)
+ * @return Null if the rule can be applied, otherwise an error message
+ */
+ private String checkRemainingOneDigitDifference(ArrayList seq, BinaryBoard origBoard,
+ BinaryCell binaryCell, int rowOrColumn, int zeroOrOne) {
+ // zeroOrOne: zero for 0, one for 1
+
+ for (int i = 0; i < seq.size(); i++) {
+ ArrayList currSeq;
+ if (rowOrColumn == 0) {
+ if (i == binaryCell.getLocation().y) {
+ continue;
+ }
+ currSeq = origBoard.getRowTypes(i);
+ }
+ else {
+ if (i == binaryCell.getLocation().x) {
+ continue;
+ }
+ currSeq = origBoard.getColTypes(i);
+ }
+
+ boolean valid = true;
+ for (int j = 0; j < currSeq.size(); j++) {
+ int numEmptyInCurrSeq = getNumEmpty(currSeq);
+ // If the current sequence has empty cells, it's not valid for comparison
+ if (numEmptyInCurrSeq != 0) {
+ valid = false;
+ break;
+ }
+ // Check if there is a cell difference from this seq and current seq
+ if (!seq.get(j).equals(currSeq.get(j)) && !seq.get(j).equals(BinaryType.UNKNOWN)) {
+ valid = false;
+ break;
+ }
+ }
+ // Determine if the current sequence can be modified to prevent repetition
+ if (valid) {
+ BinaryType currSeqCell = currSeq.get(binaryCell.getLocation().x);
+ if (rowOrColumn == 0) {
+ currSeqCell = currSeq.get(binaryCell.getLocation().x);
+ } else if (rowOrColumn == 1) {
+ currSeqCell = currSeq.get(binaryCell.getLocation().y);
+ }
+
+ // Check if this sequence has only one more zero remaining and current sequence fills that zero in,
+ // if so, zero in this seq must go in another cell to prevent repetition
+ if (zeroOrOne == 0) {
+ if (currSeqCell.equals(BinaryType.ZERO) && binaryCell.getType().equals(BinaryType.ONE)) {
+ return null;
+ }
+ }
+ // Check if this sequence has only one more one remaining and current sequence fills that one in,
+ // if so, one in this seq must go in another cell to prevent repetition
+ else if (zeroOrOne == 1) {
+ if (currSeqCell.equals(BinaryType.ONE) && binaryCell.getType().equals(BinaryType.ZERO)) {
+ return null;
+ }
+ }
+ }
+ }
+
+
+ return "There does not exist a sequence that can be prevented by a remaining digit difference";
+ }
+
+ /**
+ * 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
+ */
+ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ BinaryBoard origBoard = (BinaryBoard) transition.getParents().get(0).getBoard();
+ BinaryCell binaryCell = (BinaryCell) puzzleElement;
+
+ // Check if filling the current cell with the opposite digit would prevent repetition with another row
+ ArrayList row = origBoard.getRowTypes(binaryCell.getLocation().y);
+ if (checkOppositeDigitDifference(row, origBoard, binaryCell, 0) == null) {
+ return null;
+ }
+ int numZeros = 0;
+ int numOnes = 0;
+ for (int i = 0; i < row.size(); i++) {
+ if (row.get(i).equals(BinaryType.ZERO)) {
+ numZeros++;
+ }
+ else if (row.get(i).equals(BinaryType.ONE)) {
+ numOnes++;
+ }
+ }
+
+ // Check if only one more zero is needed, then see this row will be repeated by another row
+ // if current cell is filled in with last zero as well
+ if (numZeros == row.size()/2 - 1) {
+ if (checkRemainingOneDigitDifference(row, origBoard, binaryCell, 0, 0) == null) {
+ return null;
+ }
+ }
+
+ // Check if only one more one is needed, then see this row will be repeated by another row
+ // if current cell is filled in with last one as well
+ if (numOnes == row.size()/2 - 1) {
+ if (checkRemainingOneDigitDifference(row, origBoard, binaryCell, 0, 1) == null) {
+ return null;
+ }
+ }
+
+ // Check if filling the current cell with the opposite digit would prevent repetition with another column
+ ArrayList col = origBoard.getColTypes(binaryCell.getLocation().x);
+ if (checkOppositeDigitDifference(col, origBoard, binaryCell, 1) == null) {
+ return null;
+ }
+
+ numZeros = 0;
+ numOnes = 0;
+ for (int i = 0; i < col.size(); i++) {
+ if (col.get(i).equals(BinaryType.ZERO)) {
+ numZeros++;
+ }
+ else if (col.get(i).equals(BinaryType.ONE)) {
+ numOnes++;
+ }
+ }
+
+ // Check if only one more zero is needed, then see this column will be repeated by another column
+ // if current cell is filled in with last zero as well
+ if (numZeros == col.size()/2 - 1) {
+ if (checkRemainingOneDigitDifference(col, origBoard, binaryCell, 1, 0) == null) {
+ return null;
+ }
+ }
+
+ // Check if only one more one is needed, then see this column will be repeated by another column
+ // if current cell is filled in with last one as well
+ if (numOnes == col.size()/2 - 1) {
+ if (checkRemainingOneDigitDifference(col, origBoard, binaryCell, 1, 1) == null) {
+ return null;
+ }
+ }
+
+ return "There is no row/column that forces this cell to be a " + binaryCell.getData().toString();
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ return null;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/WastedBlockerContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/WastedBlockerContradictionRule.java
new file mode 100644
index 000000000..e7ab51b41
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/WastedBlockerContradictionRule.java
@@ -0,0 +1,178 @@
+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 WastedBlockerContradictionRule extends ContradictionRule {
+ private final String NO_CONTRADICTION_MESSAGE = "Does not contain a contradiction at this index";
+
+ public WastedBlockerContradictionRule() {
+ super(
+ "BINA-CONT-0004",
+ "Wasted Blocker",
+ "There exists a cell in this row/column that allocates a digit unnecessarily and" +
+ " will cause a future trio to appear",
+ "edu/rpi/legup/images/binary/rules/WastedBlockerContradictionRule.png");
+ }
+
+ /*
+ i [ n ] j
+ i -> digit on left (0 if no digit exists)
+ n -> number of empty cells
+ j -> digit on right (0 if no digit exists)
+ neededZeros = ( n + i + j ) / 3
+ */
+ /**
+ * Calculates the number of zeros needed in a sequence based on the values on either side and the number of empty cells.
+ *
+ * @param leftVal The value on the left side of the empty cells
+ * @param rightVal The value on the right side of the empty cells
+ * @param emptyCellsInCurSec The number of empty cells in the current section
+ * @return The number of zeros needed in the sequence
+ */
+ private int calculateNeededZeros(int leftVal, int rightVal, int emptyCellsInCurSec) {
+ int leftCopy = leftVal;
+ int rightCopy = rightVal;
+ if (leftCopy == -1) {
+ leftCopy = 0;
+ }
+ if (rightCopy == -1) {
+ rightCopy = 0;
+ }
+ return ((emptyCellsInCurSec + leftCopy + rightCopy) / 3);
+ }
+
+ /*
+ i [ n ] j
+ i -> digit on left (1 if no digit exists)
+ n -> number of empty cells
+ j -> digit on right (1 if no digit exists)
+ neededOnes = ( n + ( 1 - i ) + ( 1 - j ) ) / 3
+ */
+ /**
+ * Calculates the number of ones needed in a sequence based on the values on either side and the number of empty cells
+ *
+ * @param leftVal The value on the left side of the empty cells
+ * @param rightVal The value on the right side of the empty cells
+ * @param emptyCellsInCurSec The number of empty cells in the current section
+ * @return The number of ones needed in the sequence
+ */
+ private int calculateNeededOnes(int leftVal, int rightVal, int emptyCellsInCurSec) {
+ int leftCopy = leftVal;
+ int rightCopy = rightVal;
+ if (leftCopy == -1) {
+ leftCopy = 1;
+ }
+ if (rightCopy == -1) {
+ rightCopy = 1;
+ }
+ return ((emptyCellsInCurSec + (1 - leftCopy) + (1 - rightCopy)) / 3);
+ }
+
+ /**
+ * Checks a sequence (row or column) to see if a wasted blocker digit is used
+ *
+ * @param seq The sequence to check
+ * @return Null if the sequence contains a contradiction, otherwise an error message
+ */
+ private String checkSequence(ArrayList seq) {
+ int numZeros = 0;
+ int numOnes = 0;
+ boolean emptyCell = false;
+ int emptyCellsInCurSec = 0;
+ int neededZeros = 0;
+ int neededOnes = 0;
+
+ for (int i = 0; i < seq.size(); i++) {
+ if (seq.get(i).equals(BinaryType.ZERO) || seq.get(i).equals(BinaryType.ONE)) {
+ if (seq.get(i).equals(BinaryType.ZERO)) {
+ numZeros++;
+ } else if (seq.get(i).equals(BinaryType.ONE)) {
+ numOnes++;
+ }
+
+ if (emptyCell) {
+ if (emptyCellsInCurSec > 1) { // Ignore case where there is only one empty cell
+ int leftVal;
+ int rightVal;
+ // Check if left cell is out of bounds
+ if (i-emptyCellsInCurSec-1 < 0) {
+ leftVal = -1;
+ } else {
+ leftVal = seq.get(i-emptyCellsInCurSec-1).toValue();
+ }
+ rightVal = seq.get(i).toValue();
+ neededZeros += calculateNeededZeros(leftVal, rightVal, emptyCellsInCurSec);
+ neededOnes += calculateNeededOnes(leftVal, rightVal, emptyCellsInCurSec);
+ }
+ emptyCell = false;
+ emptyCellsInCurSec = 0;
+ }
+ } else {
+ if (!emptyCell) {
+ emptyCell = true;
+ }
+ emptyCellsInCurSec++;
+ }
+ }
+
+ // Check last cell is empty
+ if (emptyCell) {
+ if (emptyCellsInCurSec > 1) { // Ignore case where there is only one empty cell
+ int leftVal;
+ int rightVal;
+ // Check if left cell is out of bounds
+ if (seq.size()-1-emptyCellsInCurSec-1 < 0) {
+ leftVal = -1;
+ } else {
+ leftVal = seq.get(seq.size()-1-emptyCellsInCurSec).toValue();
+ }
+ rightVal = -1;
+ neededZeros += calculateNeededZeros(leftVal, rightVal, emptyCellsInCurSec);
+ neededOnes += calculateNeededOnes(leftVal, rightVal, emptyCellsInCurSec);
+ }
+ }
+
+ // Check if the number of needed zeros or ones exceeds half the sequence length
+ // If so, return null to indicate contradiction has occurred
+ if ((numZeros + neededZeros > seq.size()/2) || (numOnes + neededOnes > seq.size()/2)) {
+ return null;
+ }
+
+ return super.getNoContradictionMessage() + ": " + this.NO_CONTRADICTION_MESSAGE;
+ }
+
+ /**
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
+ *
+ * @param board board to check contradiction
+ * @param puzzleElement equivalent puzzleElement
+ * @return null if the transition contains a contradiction at the specified puzzleElement,
+ * otherwise error message
+ */
+ @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);
+ if (checkSequence(row) == null) {
+ return null;
+ }
+
+ ArrayList col = binaryBoard.getColTypes(cell.getLocation().x);
+ if (checkSequence(col) == null) {
+ return null;
+ }
+
+ return super.getNoContradictionMessage() + ": " + this.NO_CONTRADICTION_MESSAGE;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/binary/rules/ZeroOrOneCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/binary/rules/ZeroOrOneCaseRule.java
new file mode 100644
index 000000000..3ae7a424d
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/ZeroOrOneCaseRule.java
@@ -0,0 +1,121 @@
+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 ZeroOrOneCaseRule extends CaseRule {
+
+ public ZeroOrOneCaseRule() {
+ super(
+ "BINA-CASE-0001",
+ "Zero Or One",
+ "Each blank cell is either a zero or a one",
+ "edu/rpi/legup/images/binary/rules/ZeroOrOneCaseRule.png");
+ }
+
+ /**
+ * Checks whether the {@link TreeTransition} logically follows from the parent node using this
+ * rule. This method is the one that should be overridden in child classes.
+ *
+ * @param transition transition to check
+ * @return null if the child node logically follow from the parent node, otherwise error message
+ */
+ @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 modify an empty cell.";
+ }
+
+ return null;
+ }
+
+ /**
+ * Generates a {@link CaseBoard} that includes all blank cells from the given board that this
+ * case rule can be applied to
+ *
+ * @param board The board to find locations where this case rule can be applied
+ * @return A CaseBoard containing pickable elements where the case rule can be applied
+ */
+ @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;
+ }
+
+ /**
+ * Gets the possible cases at a specific location based on this case rule
+ *
+ * @param board the current board state
+ * @param puzzleElement equivalent puzzleElement
+ * @return a list of elements the specified could be
+ */
+ @Override
+ public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
+ ArrayList cases = new ArrayList<>();
+ if (puzzleElement == null) {
+ return cases;
+ }
+
+ Board case1 = board.copy();
+ PuzzleElement data1 = case1.getPuzzleElement(puzzleElement);
+ data1.setData(BinaryType.ONE.toValue());
+ case1.addModifiedData(data1);
+ cases.add(case1);
+
+ Board case2 = board.copy();
+ PuzzleElement data2 = case2.getPuzzleElement(puzzleElement);
+ data2.setData(BinaryType.ZERO.toValue());
+ case2.addModifiedData(data2);
+ cases.add(case2);
+
+ return cases;
+ }
+
+ /**
+ * 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) {
+ 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..619d183a5
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/binary/rules/binary_reference_sheet.txt
@@ -0,0 +1,11 @@
+BINA-BASC-0001 : PreventTrioContradictionRule
+BINA-BASC-0002 : CompleteRowColumnDirectRule
+BINA-BASC-0003 : SaveBlockerDirectRule
+BINA-BASC-0004 : UniqueRowColumnDirectRule
+
+BINA-CONT-0001 : TrioContradictionRule
+BINA-CONT-0002 : UnbalancedRowColumnContradictionRule
+BINA-CONT-0003 : RepeatedRowColumnContradictionRule
+BINA-CONT-0004 : WastedBlockerContradictionRule
+
+BINA-CASE-0001 : ZeroOrOneCaseRule
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/Fillapix.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/Fillapix.java
index ef78f66aa..79574caa6 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/Fillapix.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/Fillapix.java
@@ -6,9 +6,7 @@
import edu.rpi.legup.model.rules.ContradictionRule;
public class Fillapix extends Puzzle {
- /**
- * Fillapix Constructor
- */
+ /** Fillapix Constructor */
public Fillapix() {
super();
@@ -20,9 +18,7 @@ public Fillapix() {
this.factory = new FillapixCellFactory();
}
- /**
- * Initializes the game board
- */
+ /** Initializes the game board */
@Override
public void initializeView() {
boardView = new FillapixView((FillapixBoard) currentBoard);
@@ -39,8 +35,8 @@ public Board generatePuzzle(int difficulty) {
/**
* Determines if the given dimensions are valid for Fillapix
*
- * @param rows the number of rows
- * @param columns the number of columns
+ * @param rows the number of rows
+ * @param columns the number of columns
* @return true if the given dimensions are valid for Fillapix, false otherwise
*/
public boolean isValidDimensions(int rows, int columns) {
@@ -65,7 +61,5 @@ public boolean isBoardComplete(Board board) {
}
@Override
- public void onBoardChange(Board board) {
-
- }
-}
\ No newline at end of file
+ public void onBoardChange(Board board) {}
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixBoard.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixBoard.java
index 67987a6fd..a6672bd4f 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixBoard.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixBoard.java
@@ -2,12 +2,11 @@
import edu.rpi.legup.model.gameboard.GridBoard;
import edu.rpi.legup.model.gameboard.PuzzleElement;
-
import java.awt.*;
import java.util.logging.Logger;
public class FillapixBoard extends GridBoard {
- private final static Logger LOGGER = Logger.getLogger(FillapixBoard.class.getName());
+ private static final Logger LOGGER = Logger.getLogger(FillapixBoard.class.getName());
public FillapixBoard(int width, int height) {
super(width, height);
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCell.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCell.java
index 5e6d4b9ed..40c5e4a54 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCell.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCell.java
@@ -2,7 +2,6 @@
import edu.rpi.legup.model.elements.Element;
import edu.rpi.legup.model.gameboard.GridCell;
-
import java.awt.*;
import java.awt.event.MouseEvent;
import java.util.Objects;
@@ -42,14 +41,14 @@ public void setCellType(FillapixCellType type) {
@Override
public void setType(Element e, MouseEvent m) {
- switch(e.getElementID()) {
- case "FPIX-PLAC-0001":
+ switch (e.getElementID()) {
+ case "FPIX-ELEM-0001":
this.setCellType(FillapixCellType.BLACK);
break;
- case "FPIX-PLAC-0002":
+ case "FPIX-ELEM-0004":
this.setCellType(FillapixCellType.WHITE);
break;
- case "FPIX-UNPL-0001":
+ case "FPIX-ELEM-0002":
int n = this.getNumber();
switch (m.getButton()) {
case MouseEvent.BUTTON1:
@@ -88,9 +87,11 @@ public FillapixCell copy() {
}
public boolean equals(FillapixCell otherCell) {
-// return this.location.equals(otherCell.location) && this.index == otherCell.index && this.data == otherCell.data;
- //return this.index == otherCell.index && this.data == otherCell.data;
- //return this.index == otherCell.index;
+ // return this.location.equals(otherCell.location) && this.index == otherCell.index
+ // &&
+ // this.data == otherCell.data;
+ // return this.index == otherCell.index && this.data == otherCell.data;
+ // return this.index == otherCell.index;
return this.location.x == otherCell.location.x && this.location.y == otherCell.location.y;
}
@@ -101,4 +102,4 @@ public int compareTo(FillapixCell otherCell) {
public int hashCode() {
return Objects.hash(this.index);
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCellController.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCellController.java
index df3bba403..f59c0df47 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCellController.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCellController.java
@@ -2,7 +2,6 @@
import edu.rpi.legup.controller.ElementController;
import edu.rpi.legup.model.gameboard.PuzzleElement;
-
import java.awt.event.MouseEvent;
public class FillapixCellController extends ElementController {
@@ -11,34 +10,33 @@ public void changeCell(MouseEvent e, PuzzleElement puzzleElement) {
FillapixCell cell = (FillapixCell) puzzleElement;
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 {
+ this.boardView
+ .getSelectionPopupMenu()
+ .show(
+ boardView,
+ this.boardView.getCanvas().getX() + e.getX(),
+ this.boardView.getCanvas().getY() + e.getY());
+ } else {
if (cell.getType() == FillapixCellType.UNKNOWN) {
cell.setCellType(FillapixCellType.BLACK);
- }
- else {
+ } else {
if (cell.getType() == FillapixCellType.BLACK) {
cell.setCellType(FillapixCellType.WHITE);
- }
- else {
+ } else {
if (cell.getType() == FillapixCellType.WHITE) {
cell.setCellType(FillapixCellType.UNKNOWN);
}
}
}
}
- }
- else {
+ } else {
if (e.getButton() == MouseEvent.BUTTON3) {
if (cell.getType() == FillapixCellType.UNKNOWN) {
cell.setCellType(FillapixCellType.WHITE);
- }
- else {
+ } else {
if (cell.getType() == FillapixCellType.BLACK) {
cell.setCellType(FillapixCellType.UNKNOWN);
- }
- else {
+ } else {
if (cell.getType() == FillapixCellType.WHITE) {
cell.setCellType(FillapixCellType.BLACK);
}
@@ -47,4 +45,4 @@ public void changeCell(MouseEvent e, PuzzleElement puzzleElement) {
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCellFactory.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCellFactory.java
index fcc48bccd..9f689bc96 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCellFactory.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCellFactory.java
@@ -4,17 +4,16 @@
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;
-import java.awt.*;
-
public class FillapixCellFactory extends ElementFactory {
/**
* Creates a puzzleElement based on the xml document Node and adds it to the board
*
- * @param node node that represents the puzzleElement
+ * @param node node that represents the puzzleElement
* @param board board to add the newly created cell
* @return newly created cell from the xml document Node
* @throws InvalidFileFormatException if file is invalid
@@ -23,7 +22,8 @@ public class FillapixCellFactory extends ElementFactory {
public FillapixCell importCell(Node node, Board board) throws InvalidFileFormatException {
try {
if (!node.getNodeName().equalsIgnoreCase("cell")) {
- throw new InvalidFileFormatException("Fillapix Factory: unknown puzzleElement puzzleElement");
+ throw new InvalidFileFormatException(
+ "Fillapix Factory: unknown puzzleElement puzzleElement");
}
FillapixBoard fillapixBoard = (FillapixBoard) board;
@@ -35,7 +35,8 @@ public FillapixCell importCell(Node node, Board board) throws InvalidFileFormatE
int x = Integer.valueOf(attributeList.getNamedItem("x").getNodeValue());
int y = Integer.valueOf(attributeList.getNamedItem("y").getNodeValue());
if (x >= width || y >= height) {
- throw new InvalidFileFormatException("Fillapix Factory: cell location out of bounds");
+ throw new InvalidFileFormatException(
+ "Fillapix Factory: cell location out of bounds");
}
if (value / 100 > 2 || value % 100 > 10) {
throw new InvalidFileFormatException("Fillapix Factory: cell unknown value");
@@ -44,11 +45,10 @@ public FillapixCell importCell(Node node, Board board) throws InvalidFileFormatE
FillapixCell cell = new FillapixCell(value, new Point(x, y));
cell.setIndex(y * height + x);
return cell;
- }
- catch (NumberFormatException e) {
- throw new InvalidFileFormatException("Fillapix Factory: unknown value where integer expected");
- }
- catch (NullPointerException e) {
+ } catch (NumberFormatException e) {
+ throw new InvalidFileFormatException(
+ "Fillapix Factory: unknown value where integer expected");
+ } catch (NullPointerException e) {
throw new InvalidFileFormatException("Fillapix Factory: could not find attribute(s)");
}
}
@@ -56,7 +56,7 @@ public FillapixCell importCell(Node node, Board board) throws InvalidFileFormatE
/**
* Creates a xml document puzzleElement from a cell for exporting
*
- * @param document xml document
+ * @param document xml document
* @param puzzleElement PuzzleElement cell
* @return xml PuzzleElement
*/
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCellType.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCellType.java
index 3789fe339..28a263467 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCellType.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixCellType.java
@@ -1,7 +1,9 @@
package edu.rpi.legup.puzzle.fillapix;
public enum FillapixCellType {
- UNKNOWN(0), BLACK(1), WHITE(2);
+ UNKNOWN(0),
+ BLACK(1),
+ WHITE(2);
public int value;
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixElementView.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixElementView.java
index 93fa0d451..47465a522 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixElementView.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixElementView.java
@@ -1,7 +1,6 @@
package edu.rpi.legup.puzzle.fillapix;
import edu.rpi.legup.ui.boardview.GridElementView;
-
import java.awt.*;
public class FillapixElementView extends GridElementView {
@@ -53,10 +52,11 @@ public void drawElement(Graphics2D graphics2D) {
FontMetrics metrics = graphics2D.getFontMetrics(FONT);
String value = String.valueOf(cell.getNumber());
int xText = location.x + (size.width - metrics.stringWidth(value)) / 2;
- int yText = location.y + ((size.height - metrics.getHeight()) / 2) + metrics.getAscent();
+ int yText =
+ location.y + ((size.height - metrics.getHeight()) / 2) + metrics.getAscent();
graphics2D.drawString(value, xText, yText);
}
graphics2D.setColor(BLACK_COLOR);
graphics2D.drawRect(location.x, location.y, size.width, size.height);
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixExporter.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixExporter.java
index 757d14cd8..ffabd8762 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixExporter.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixExporter.java
@@ -2,7 +2,6 @@
import edu.rpi.legup.model.PuzzleExporter;
import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.puzzle.shorttruthtable.ShortTruthTableBoard;
import org.w3c.dom.Document;
public class FillapixExporter extends PuzzleExporter {
@@ -16,8 +15,7 @@ protected org.w3c.dom.Element createBoardElement(Document newDocument) {
FillapixBoard board;
if (puzzle.getTree() != null) {
board = (FillapixBoard) puzzle.getTree().getRootNode().getBoard();
- }
- else {
+ } else {
board = (FillapixBoard) puzzle.getBoardView().getBoard();
}
@@ -29,7 +27,8 @@ protected org.w3c.dom.Element createBoardElement(Document newDocument) {
for (PuzzleElement puzzleElement : board.getPuzzleElements()) {
FillapixCell cell = (FillapixCell) puzzleElement;
if (cell.getNumber() != -1 || cell.getType() != FillapixCellType.UNKNOWN) {
- org.w3c.dom.Element cellElement = puzzle.getFactory().exportCell(newDocument, puzzleElement);
+ org.w3c.dom.Element cellElement =
+ puzzle.getFactory().exportCell(newDocument, puzzleElement);
cellsElement.appendChild(cellElement);
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixImporter.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixImporter.java
index 5213e7139..d16bc8219 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixImporter.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixImporter.java
@@ -2,12 +2,11 @@
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;
-import java.awt.*;
-
public class FillapixImporter extends PuzzleImporter {
public FillapixImporter(Fillapix fillapix) {
super(fillapix);
@@ -26,7 +25,7 @@ public boolean acceptsTextInput() {
/**
* Creates an empty board for building
*
- * @param rows the number of rows on the board
+ * @param rows the number of rows on the board
* @param columns the number of columns on the board
* @throws RuntimeException if board can not be made
*/
@@ -36,7 +35,8 @@ public void initializeBoard(int rows, int columns) {
for (int y = 0; y < rows; y++) {
for (int x = 0; x < columns; x++) {
- FillapixCell cell = new FillapixCell(FillapixCellType.UNKNOWN.value, new Point(x, y));
+ FillapixCell cell =
+ new FillapixCell(FillapixCellType.UNKNOWN.value, new Point(x, y));
cell.setIndex(y * columns + x);
cell.setNumber(FillapixCell.DEFAULT_VALUE);
cell.setModifiable(true);
@@ -56,11 +56,13 @@ public void initializeBoard(int rows, int columns) {
public void initializeBoard(Node node) throws InvalidFileFormatException {
try {
if (!node.getNodeName().equalsIgnoreCase("board")) {
- throw new InvalidFileFormatException("Fillapix Importer: cannot find board puzzleElement");
+ throw new InvalidFileFormatException(
+ "Fillapix Importer: cannot find board puzzleElement");
}
Element boardElement = (Element) node;
if (boardElement.getElementsByTagName("cells").getLength() == 0) {
- throw new InvalidFileFormatException("Fillapix Importer: no puzzleElement found for board");
+ throw new InvalidFileFormatException(
+ "Fillapix Importer: no puzzleElement found for board");
}
Element dataElement = (Element) boardElement.getElementsByTagName("cells").item(0);
NodeList elementDataList = dataElement.getElementsByTagName("cell");
@@ -69,9 +71,9 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
if (!boardElement.getAttribute("size").isEmpty()) {
int size = Integer.valueOf(boardElement.getAttribute("size"));
fillapixBoard = new FillapixBoard(size);
- }
- else {
- if (!boardElement.getAttribute("width").isEmpty() && !boardElement.getAttribute("height").isEmpty()) {
+ } else {
+ if (!boardElement.getAttribute("width").isEmpty()
+ && !boardElement.getAttribute("height").isEmpty()) {
int width = Integer.valueOf(boardElement.getAttribute("width"));
int height = Integer.valueOf(boardElement.getAttribute("height"));
fillapixBoard = new FillapixBoard(width, height);
@@ -86,7 +88,10 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
int height = fillapixBoard.getHeight();
for (int i = 0; i < elementDataList.getLength(); i++) {
- FillapixCell cell = (FillapixCell) puzzle.getFactory().importCell(elementDataList.item(i), fillapixBoard);
+ FillapixCell cell =
+ (FillapixCell)
+ puzzle.getFactory()
+ .importCell(elementDataList.item(i), fillapixBoard);
Point loc = cell.getLocation();
cell.setModifiable(true);
cell.setGiven(true);
@@ -96,7 +101,8 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (fillapixBoard.getCell(x, y) == null) {
- FillapixCell cell = new FillapixCell(FillapixCell.DEFAULT_VALUE, new Point(x, y));
+ FillapixCell cell =
+ new FillapixCell(FillapixCell.DEFAULT_VALUE, new Point(x, y));
cell.setIndex(y * height + x);
cell.setModifiable(true);
fillapixBoard.setCell(x, y, cell);
@@ -104,9 +110,9 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
}
}
puzzle.setCurrentBoard(fillapixBoard);
- }
- catch (NumberFormatException e) {
- throw new InvalidFileFormatException("Fillapix Importer: unknown value where integer expected");
+ } catch (NumberFormatException e) {
+ throw new InvalidFileFormatException(
+ "Fillapix Importer: unknown value where integer expected");
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixUtilities.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixUtilities.java
index a7feac91d..571a0c7f7 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixUtilities.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixUtilities.java
@@ -3,14 +3,14 @@
import edu.rpi.legup.model.rules.ContradictionRule;
import edu.rpi.legup.puzzle.fillapix.rules.TooFewBlackCellsContradictionRule;
import edu.rpi.legup.puzzle.fillapix.rules.TooManyBlackCellsContradictionRule;
-
import java.awt.*;
import java.util.ArrayList;
public class FillapixUtilities {
public static boolean isForcedBlack(FillapixBoard board, FillapixCell cell) {
- TooFewBlackCellsContradictionRule tooManyBlackCells = new TooFewBlackCellsContradictionRule();
+ TooFewBlackCellsContradictionRule tooManyBlackCells =
+ new TooFewBlackCellsContradictionRule();
FillapixBoard whiteCaseBoard = board.copy();
FillapixCell whiteCell = (FillapixCell) whiteCaseBoard.getPuzzleElement(cell);
whiteCell.setCellType(FillapixCellType.WHITE);
@@ -24,7 +24,8 @@ public static boolean isForcedBlack(FillapixBoard board, FillapixCell cell) {
}
public static boolean isForcedWhite(FillapixBoard board, FillapixCell cell) {
- TooManyBlackCellsContradictionRule tooManyBlackCells = new TooManyBlackCellsContradictionRule();
+ TooManyBlackCellsContradictionRule tooManyBlackCells =
+ new TooManyBlackCellsContradictionRule();
FillapixBoard blackCaseBoard = board.copy();
FillapixCell blackCell = (FillapixCell) blackCaseBoard.getPuzzleElement(cell);
blackCell.setCellType(FillapixCellType.BLACK);
@@ -59,15 +60,16 @@ public static boolean hasEmptyAdjacent(FillapixBoard board, FillapixCell cell) {
return false;
}
- /**
- * Gets all cells adjacent to a specific cell. The cell itself will be included.
- */
+ /** Gets all cells adjacent to a specific cell. The cell itself will be included. */
public static ArrayList getAdjacentCells(FillapixBoard board, FillapixCell cell) {
ArrayList adjCells = new ArrayList();
Point cellLoc = cell.getLocation();
- for (int i=-1; i <= 1; i++) {
- for (int j=-1; j <= 1; j++) {
- if (cellLoc.getX() + i < 0 || cellLoc.y + j < 0 || cellLoc.x + i >= board.getWidth() || cellLoc.y + j >= board.getHeight()) {
+ for (int i = -1; i <= 1; i++) {
+ for (int j = -1; j <= 1; j++) {
+ if (cellLoc.getX() + i < 0
+ || cellLoc.y + j < 0
+ || cellLoc.x + i >= board.getWidth()
+ || cellLoc.y + j >= board.getHeight()) {
continue;
}
FillapixCell adjCell = board.getCell(cellLoc.x + i, cellLoc.y + j);
@@ -81,22 +83,34 @@ public static ArrayList getAdjacentCells(FillapixBoard board, Fill
}
/**
- * Gets all cells that are contained in the square defined as having 'distance'
- * cells between the center and the outer wall. For example, distance = 1:
- * |X|X|X|X|X|
- * |X| | | |X|
- * |X| |O| |X|
- * |X| | | |X|
- * |X|X|X|X|X|
- * O is 'cell', and all 'X' will be returned in the ArrayList
+ * Gets all cells that are contained in the square defined as having 'distance' cells between
+ * the center and the outer wall. For example, distance = 1:
+ *
+ *
|X|X|X|X|X|
+ *
+ *
|X| | | |X|
+ *
+ *
|X| |O| |X|
+ *
+ *
|X| | | |X|
+ *
+ *
|X|X|X|X|X|
+ *
+ *
O is 'cell', and all 'X' will be returned in the ArrayList
*/
- public static ArrayList getCellsAtDistance(FillapixBoard board, FillapixCell cell, int distance) {
+ public static ArrayList getCellsAtDistance(
+ FillapixBoard board, FillapixCell cell, int distance) {
ArrayList adjCells = new ArrayList();
Point cellLoc = cell.getLocation();
int i = 0, j = 0;
// top line
- for (i = cellLoc.x - (distance), j = cellLoc.y - (distance+1); i <= cellLoc.x + (distance+1); i++) {
- if (cellLoc.getX() + i < 0 || cellLoc.y + j < 0 || cellLoc.x + i >= board.getWidth() || cellLoc.y + j >= board.getHeight()) {
+ for (i = cellLoc.x - (distance), j = cellLoc.y - (distance + 1);
+ i <= cellLoc.x + (distance + 1);
+ i++) {
+ if (cellLoc.getX() + i < 0
+ || cellLoc.y + j < 0
+ || cellLoc.x + i >= board.getWidth()
+ || cellLoc.y + j >= board.getHeight()) {
continue;
}
FillapixCell adjCell = board.getCell(cellLoc.x + i, cellLoc.y + j);
@@ -106,8 +120,13 @@ public static ArrayList getCellsAtDistance(FillapixBoard board, Fi
adjCells.add(adjCell);
}
// right line
- for (i = cellLoc.x + (distance+1), j = cellLoc.y - (distance); j <= cellLoc.y + (distance+1); j++) {
- if (cellLoc.getX() + i < 0 || cellLoc.y + j < 0 || cellLoc.x + i >= board.getWidth() || cellLoc.y + j >= board.getHeight()) {
+ for (i = cellLoc.x + (distance + 1), j = cellLoc.y - (distance);
+ j <= cellLoc.y + (distance + 1);
+ j++) {
+ if (cellLoc.getX() + i < 0
+ || cellLoc.y + j < 0
+ || cellLoc.x + i >= board.getWidth()
+ || cellLoc.y + j >= board.getHeight()) {
continue;
}
FillapixCell adjCell = board.getCell(cellLoc.x + i, cellLoc.y + j);
@@ -115,10 +134,15 @@ public static ArrayList getCellsAtDistance(FillapixBoard board, Fi
continue;
}
adjCells.add(adjCell);
- }
+ }
// bottom line
- for (i = cellLoc.x + (distance), j = cellLoc.y + (distance+1); i <= cellLoc.x - (distance+1); i--) {
- if (cellLoc.getX() + i < 0 || cellLoc.y + j < 0 || cellLoc.x + i >= board.getWidth() || cellLoc.y + j >= board.getHeight()) {
+ for (i = cellLoc.x + (distance), j = cellLoc.y + (distance + 1);
+ i <= cellLoc.x - (distance + 1);
+ i--) {
+ if (cellLoc.getX() + i < 0
+ || cellLoc.y + j < 0
+ || cellLoc.x + i >= board.getWidth()
+ || cellLoc.y + j >= board.getHeight()) {
continue;
}
FillapixCell adjCell = board.getCell(cellLoc.x + i, cellLoc.y + j);
@@ -126,10 +150,15 @@ public static ArrayList getCellsAtDistance(FillapixBoard board, Fi
continue;
}
adjCells.add(adjCell);
- }
+ }
// left line
- for (i = cellLoc.x - (distance+1), j = cellLoc.y + (distance); j <= cellLoc.y - (distance+1); j--) {
- if (cellLoc.getX() + i < 0 || cellLoc.y + j < 0 || cellLoc.x + i >= board.getWidth() || cellLoc.y + j >= board.getHeight()) {
+ for (i = cellLoc.x - (distance + 1), j = cellLoc.y + (distance);
+ j <= cellLoc.y - (distance + 1);
+ j--) {
+ if (cellLoc.getX() + i < 0
+ || cellLoc.y + j < 0
+ || cellLoc.x + i >= board.getWidth()
+ || cellLoc.y + j >= board.getHeight()) {
continue;
}
FillapixCell adjCell = board.getCell(cellLoc.x + i, cellLoc.y + j);
@@ -137,25 +166,25 @@ public static ArrayList getCellsAtDistance(FillapixBoard board, Fi
continue;
}
adjCells.add(adjCell);
- }
+ }
return adjCells;
- }
+ }
/**
- * Finds all possible combinations of chosenNumObj
items can be
- * chosen from totalNumObj
total items.
- * For example, if 1 item is chosen from 2 possible items, the combinations
- * are:
+ * Finds all possible combinations of chosenNumObj
items can be chosen from
+ * totalNumObj
total items. For example, if 1 item is chosen from 2 possible items, the
+ * combinations are:
+ *
* [ [true,false], [false,true] ]
- *
+ *
* @param totalNumItems the total number of items that can possibly be chosen
* @param chosenNumItems the number of items to be chosen
- *
- * @return an ArrayList of Boolean arrays. Each index in the ArrayList represents
- * a distinct combination. Each Boolean array will be totalNumItems
- * long and each index will be true
if the corresponding item is
- * included in that combination, and false
otherwise.
+ * @return an ArrayList of Boolean arrays. Each index in the ArrayList represents a distinct
+ * combination. Each Boolean array will be totalNumItems
long and each index
+ * will be true
if the corresponding item is included in that combination, and
+ *
+ * false
otherwise.
*/
public static ArrayList getCombinations(int chosenNumItems, int totalNumItems) {
ArrayList combinations = new ArrayList();
@@ -165,9 +194,15 @@ public static ArrayList getCombinations(int chosenNumItems, int total
recurseCombinations(combinations, 0, chosenNumItems, 0, totalNumItems, array);
return combinations;
- }
+ }
- private static void recurseCombinations(ArrayList result, int curIndex, int maxBlack, int numBlack, int len, boolean[] workingArray) {
+ private static void recurseCombinations(
+ ArrayList result,
+ int curIndex,
+ int maxBlack,
+ int numBlack,
+ int len,
+ boolean[] workingArray) {
if (curIndex == len) {
// complete, but not valid solution
if (numBlack != maxBlack) {
@@ -184,19 +219,19 @@ private static void recurseCombinations(ArrayList result, int curInde
if (numBlack < maxBlack) {
workingArray[curIndex] = true;
- recurseCombinations(result, curIndex+1, maxBlack, numBlack+1, len, workingArray);
+ recurseCombinations(result, curIndex + 1, maxBlack, numBlack + 1, len, workingArray);
}
workingArray[curIndex] = false;
- recurseCombinations(result, curIndex+1, maxBlack, numBlack, len, workingArray);
+ recurseCombinations(result, curIndex + 1, maxBlack, numBlack, len, workingArray);
}
-
+
public static boolean checkBoardForContradiction(FillapixBoard board) {
ContradictionRule tooManyBlack = new TooManyBlackCellsContradictionRule();
ContradictionRule tooManyWhite = new TooFewBlackCellsContradictionRule();
- for (int i= 0; i < board.getWidth(); i++) {
- for (int j=0; j < board.getHeight(); j++) {
- if (tooManyBlack.checkContradictionAt(board, board.getCell(i, j)) == null ||
- tooManyWhite.checkContradictionAt(board, board.getCell(i, j)) == null) {
+ for (int i = 0; i < board.getWidth(); i++) {
+ for (int j = 0; j < board.getHeight(); j++) {
+ if (tooManyBlack.checkContradictionAt(board, board.getCell(i, j)) == null
+ || tooManyWhite.checkContradictionAt(board, board.getCell(i, j)) == null) {
return true;
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixView.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixView.java
index 7e6453f58..55332e47d 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixView.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/FillapixView.java
@@ -3,7 +3,6 @@
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 FillapixView extends GridBoardView {
@@ -16,8 +15,9 @@ public FillapixView(FillapixBoard board) {
FillapixElementView elementView = new FillapixElementView(cell);
elementView.setIndex(cell.getIndex());
elementView.setSize(elementSize);
- elementView.setLocation(new Point(loc.x * elementSize.width, loc.y * elementSize.height));
+ elementView.setLocation(
+ new Point(loc.x * elementSize.width, loc.y * elementSize.height));
elementViews.add(elementView);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/BlackTile.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/BlackTile.java
index 7e43fc6b4..a6993778d 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/BlackTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/BlackTile.java
@@ -4,6 +4,10 @@
public class BlackTile extends PlaceableElement {
public BlackTile() {
- super("FPIX-PLAC-0001", "Black Tile", "The black tile", "edu/rpi/legup/images/fillapix/tiles/BlackTile.png");
+ super(
+ "FPIX-ELEM-0001",
+ "Black Tile",
+ "The black tile",
+ "edu/rpi/legup/images/fillapix/tiles/BlackTile.png");
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/NumberTile.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/NumberTile.java
index beee70e21..5852c1ad7 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/NumberTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/NumberTile.java
@@ -1,12 +1,16 @@
package edu.rpi.legup.puzzle.fillapix.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class NumberTile extends NonPlaceableElement {
+public class NumberTile extends PlaceableElement {
private int object_num;
public NumberTile() {
- super("FPIX-UNPL-0001", "Number Tile", "A numbered tile", "edu/rpi/legup/images/fillapix/tiles/NumberTile.png");
+ super(
+ "FPIX-ELEM-0002",
+ "Number Tile",
+ "A numbered tile",
+ "edu/rpi/legup/images/fillapix/tiles/NumberTile.png");
object_num = 0;
}
@@ -23,5 +27,4 @@ public int getTileNumber() {
public void setTileNumber(int num) {
object_num = num;
}
-
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/UnknownTile.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/UnknownTile.java
index ef754782f..82d0dffb9 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/UnknownTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/UnknownTile.java
@@ -1,9 +1,13 @@
package edu.rpi.legup.puzzle.fillapix.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class UnknownTile extends NonPlaceableElement {
+public class UnknownTile extends PlaceableElement {
public UnknownTile() {
- super("FPIX-UNPL-0002", "Unknown Tile", "A blank tile", "edu/rpi/legup/images/fillapix/tiles/UnknownTile.png");
+ super(
+ "FPIX-ELEM-0003",
+ "Unknown Tile",
+ "A blank tile",
+ "edu/rpi/legup/images/fillapix/tiles/UnknownTile.png");
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/WhiteTile.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/WhiteTile.java
index dd27d2834..b2eedfc09 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/WhiteTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/WhiteTile.java
@@ -4,6 +4,10 @@
public class WhiteTile extends PlaceableElement {
public WhiteTile() {
- super("FPIX-PLAC-0002", "White Tile", "The white tile", "edu/rpi/legup/images/fillapix/tiles/WhiteTile.png");
+ super(
+ "FPIX-ELEM-0004",
+ "White Tile",
+ "The white tile",
+ "edu/rpi/legup/images/fillapix/tiles/WhiteTile.png");
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/fillapix_elements_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/fillapix_elements_reference_sheet.txt
index 0409fa800..1aece4b97 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/fillapix_elements_reference_sheet.txt
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/elements/fillapix_elements_reference_sheet.txt
@@ -1,5 +1,4 @@
-FPIX-PLAC-0001 : BlackTile
-FPIX-PLAC-0002 : WhiteTile
-
-FPIX-UNPL-0001 : NumberTile
-FPIX-UNPL-0002 : UnknownTile
\ No newline at end of file
+FPIX-ELEM-0001 : BlackTile
+FPIX-ELEM-0002 : NumberTile
+FPIX-ELEM-0003 : UnknownTile
+FPIX-ELEM-0004 : WhiteTile
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/BlackOrWhiteCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/BlackOrWhiteCaseRule.java
index 1e5151c48..f0194bd39 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/BlackOrWhiteCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/BlackOrWhiteCaseRule.java
@@ -8,13 +8,13 @@
import edu.rpi.legup.puzzle.fillapix.FillapixBoard;
import edu.rpi.legup.puzzle.fillapix.FillapixCell;
import edu.rpi.legup.puzzle.fillapix.FillapixCellType;
-
import java.util.ArrayList;
import java.util.List;
public class BlackOrWhiteCaseRule extends CaseRule {
public BlackOrWhiteCaseRule() {
- super("FPIX-CASE-0001",
+ super(
+ "FPIX-CASE-0001",
"Black or White",
"Each cell is either black or white.",
"edu/rpi/legup/images/fillapix/cases/BlackOrWhite.png");
@@ -37,6 +37,9 @@ public CaseBoard getCaseBoard(Board board) {
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
ArrayList cases = new ArrayList<>();
+ if (puzzleElement == null) {
+ return cases;
+ }
Board case1 = board.copy();
FillapixCell cell1 = (FillapixCell) case1.getPuzzleElement(puzzleElement);
@@ -62,20 +65,24 @@ public String checkRuleRaw(TreeTransition transition) {
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.";
+ 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.";
}
FillapixCell mod1 = (FillapixCell) case1.getBoard().getModifiedData().iterator().next();
FillapixCell mod2 = (FillapixCell) 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.";
+ return super.getInvalidUseOfRuleMessage()
+ + ": This case rule must modify the same cell for each case.";
}
if (!((mod1.getType() == FillapixCellType.BLACK && mod2.getType() == FillapixCellType.WHITE)
- || (mod2.getType() == FillapixCellType.BLACK && mod1.getType() == FillapixCellType.WHITE))) {
- return super.getInvalidUseOfRuleMessage() + ": This case rule must an empty cell and a lit cell.";
+ || (mod2.getType() == FillapixCellType.BLACK
+ && mod1.getType() == FillapixCellType.WHITE))) {
+ return super.getInvalidUseOfRuleMessage()
+ + ": This case rule must an empty cell and a lit cell.";
}
return null;
@@ -85,4 +92,4 @@ public String checkRuleRaw(TreeTransition transition) {
public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
return null;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/FinishWithBlackDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/FinishWithBlackDirectRule.java
index 06a8045ed..ccc002f46 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/FinishWithBlackDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/FinishWithBlackDirectRule.java
@@ -1,63 +1,66 @@
-package edu.rpi.legup.puzzle.fillapix.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-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.fillapix.FillapixBoard;
-import edu.rpi.legup.puzzle.fillapix.FillapixCell;
-import edu.rpi.legup.puzzle.fillapix.FillapixCellType;
-import edu.rpi.legup.puzzle.fillapix.FillapixUtilities;
-
-public class FinishWithBlackDirectRule extends DirectRule {
- public FinishWithBlackDirectRule() {
- super("FPIX-BASC-0001",
- "Finish with Black",
- "The remaining unknowns around and on a cell must be black to satisfy the number",
- "edu/rpi/legup/images/fillapix/rules/FinishWithBlack.png");
- }
-
- @Override
- public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
- FillapixBoard board = (FillapixBoard) transition.getBoard();
- FillapixBoard parentBoard = (FillapixBoard) transition.getParents().get(0).getBoard();
- FillapixCell cell = (FillapixCell) board.getPuzzleElement(puzzleElement);
- FillapixCell parentCell = (FillapixCell) parentBoard.getPuzzleElement(puzzleElement);
-
- if (!(parentCell.getType() == FillapixCellType.UNKNOWN && cell.getType() == FillapixCellType.BLACK)) {
- return super.getInvalidUseOfRuleMessage() + ": This cell must be black to be applicable with this rule.";
- }
-
- if (FillapixUtilities.isForcedBlack(parentBoard, cell)) {
- return null;
- }
- else {
- return super.getInvalidUseOfRuleMessage() + ": This cell is not forced to be black";
- }
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- FillapixBoard fillapixBoard = (FillapixBoard) node.getBoard().copy();
- for (PuzzleElement element : fillapixBoard.getPuzzleElements()) {
- FillapixCell cell = (FillapixCell) element;
- if (cell.getType() == FillapixCellType.UNKNOWN && FillapixUtilities.isForcedBlack((FillapixBoard) node.getBoard(), cell)) {
- cell.setCellType(FillapixCellType.BLACK);
- fillapixBoard.addModifiedData(cell);
- }
- }
- if (fillapixBoard.getModifiedData().isEmpty()) {
- return null;
- }
- else {
- return fillapixBoard;
- }
- }
-}
\ No newline at end of file
+package edu.rpi.legup.puzzle.fillapix.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+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.fillapix.FillapixBoard;
+import edu.rpi.legup.puzzle.fillapix.FillapixCell;
+import edu.rpi.legup.puzzle.fillapix.FillapixCellType;
+import edu.rpi.legup.puzzle.fillapix.FillapixUtilities;
+
+public class FinishWithBlackDirectRule extends DirectRule {
+ public FinishWithBlackDirectRule() {
+ super(
+ "FPIX-BASC-0001",
+ "Finish with Black",
+ "The remaining unknowns around and on a cell must be black to satisfy the number",
+ "edu/rpi/legup/images/fillapix/rules/FinishWithBlack.png");
+ }
+
+ @Override
+ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ FillapixBoard board = (FillapixBoard) transition.getBoard();
+ FillapixBoard parentBoard = (FillapixBoard) transition.getParents().get(0).getBoard();
+ FillapixCell cell = (FillapixCell) board.getPuzzleElement(puzzleElement);
+ FillapixCell parentCell = (FillapixCell) parentBoard.getPuzzleElement(puzzleElement);
+
+ if (!(parentCell.getType() == FillapixCellType.UNKNOWN
+ && cell.getType() == FillapixCellType.BLACK)) {
+ return super.getInvalidUseOfRuleMessage()
+ + ": This cell must be black to be applicable with this rule.";
+ }
+
+ if (FillapixUtilities.isForcedBlack(parentBoard, cell)) {
+ return null;
+ } else {
+ return super.getInvalidUseOfRuleMessage() + ": This cell is not forced to be black";
+ }
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ FillapixBoard fillapixBoard = (FillapixBoard) node.getBoard().copy();
+ for (PuzzleElement element : fillapixBoard.getPuzzleElements()) {
+ FillapixCell cell = (FillapixCell) element;
+ if (cell.getType() == FillapixCellType.UNKNOWN
+ && FillapixUtilities.isForcedBlack((FillapixBoard) node.getBoard(), cell)) {
+ cell.setCellType(FillapixCellType.BLACK);
+ fillapixBoard.addModifiedData(cell);
+ }
+ }
+ if (fillapixBoard.getModifiedData().isEmpty()) {
+ return null;
+ } else {
+ return fillapixBoard;
+ }
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/FinishWithWhiteDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/FinishWithWhiteDirectRule.java
index 7e213a59c..6735fb8f4 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/FinishWithWhiteDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/FinishWithWhiteDirectRule.java
@@ -1,63 +1,66 @@
-package edu.rpi.legup.puzzle.fillapix.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-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.fillapix.FillapixBoard;
-import edu.rpi.legup.puzzle.fillapix.FillapixCell;
-import edu.rpi.legup.puzzle.fillapix.FillapixCellType;
-import edu.rpi.legup.puzzle.fillapix.FillapixUtilities;
-
-public class FinishWithWhiteDirectRule extends DirectRule {
- public FinishWithWhiteDirectRule() {
- super("FPIX-BASC-0002",
- "Finish with White",
- "The remaining unknowns around and on a cell must be white to satisfy the number",
- "edu/rpi/legup/images/fillapix/rules/FinishWithWhite.png");
- }
-
- @Override
- public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
- FillapixBoard board = (FillapixBoard) transition.getBoard();
- FillapixBoard parentBoard = (FillapixBoard) transition.getParents().get(0).getBoard();
- FillapixCell cell = (FillapixCell) board.getPuzzleElement(puzzleElement);
- FillapixCell parentCell = (FillapixCell) parentBoard.getPuzzleElement(puzzleElement);
-
- if (!(parentCell.getType() == FillapixCellType.UNKNOWN && cell.getType() == FillapixCellType.WHITE)) {
- return super.getInvalidUseOfRuleMessage() + ": This cell must be white to be applicable with this rule";
- }
-
- if (FillapixUtilities.isForcedWhite(parentBoard, cell)) {
- return null;
- }
- else {
- return super.getInvalidUseOfRuleMessage() + ": This cell is not forced to be white";
- }
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- FillapixBoard fillapixBoard = (FillapixBoard) node.getBoard().copy();
- for (PuzzleElement element : fillapixBoard.getPuzzleElements()) {
- FillapixCell cell = (FillapixCell) element;
- if (cell.getType() == FillapixCellType.UNKNOWN && FillapixUtilities.isForcedWhite((FillapixBoard) node.getBoard(), cell)) {
- cell.setCellType(FillapixCellType.WHITE);
- fillapixBoard.addModifiedData(cell);
- }
- }
- if (fillapixBoard.getModifiedData().isEmpty()) {
- return null;
- }
- else {
- return fillapixBoard;
- }
- }
-}
\ No newline at end of file
+package edu.rpi.legup.puzzle.fillapix.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+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.fillapix.FillapixBoard;
+import edu.rpi.legup.puzzle.fillapix.FillapixCell;
+import edu.rpi.legup.puzzle.fillapix.FillapixCellType;
+import edu.rpi.legup.puzzle.fillapix.FillapixUtilities;
+
+public class FinishWithWhiteDirectRule extends DirectRule {
+ public FinishWithWhiteDirectRule() {
+ super(
+ "FPIX-BASC-0002",
+ "Finish with White",
+ "The remaining unknowns around and on a cell must be white to satisfy the number",
+ "edu/rpi/legup/images/fillapix/rules/FinishWithWhite.png");
+ }
+
+ @Override
+ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ FillapixBoard board = (FillapixBoard) transition.getBoard();
+ FillapixBoard parentBoard = (FillapixBoard) transition.getParents().get(0).getBoard();
+ FillapixCell cell = (FillapixCell) board.getPuzzleElement(puzzleElement);
+ FillapixCell parentCell = (FillapixCell) parentBoard.getPuzzleElement(puzzleElement);
+
+ if (!(parentCell.getType() == FillapixCellType.UNKNOWN
+ && cell.getType() == FillapixCellType.WHITE)) {
+ return super.getInvalidUseOfRuleMessage()
+ + ": This cell must be white to be applicable with this rule";
+ }
+
+ if (FillapixUtilities.isForcedWhite(parentBoard, cell)) {
+ return null;
+ } else {
+ return super.getInvalidUseOfRuleMessage() + ": This cell is not forced to be white";
+ }
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ FillapixBoard fillapixBoard = (FillapixBoard) node.getBoard().copy();
+ for (PuzzleElement element : fillapixBoard.getPuzzleElements()) {
+ FillapixCell cell = (FillapixCell) element;
+ if (cell.getType() == FillapixCellType.UNKNOWN
+ && FillapixUtilities.isForcedWhite((FillapixBoard) node.getBoard(), cell)) {
+ cell.setCellType(FillapixCellType.WHITE);
+ fillapixBoard.addModifiedData(cell);
+ }
+ }
+ if (fillapixBoard.getModifiedData().isEmpty()) {
+ return null;
+ } else {
+ return fillapixBoard;
+ }
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/MirrorDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/MirrorDirectRule.java
index 656cedb3f..e91931bd4 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/MirrorDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/MirrorDirectRule.java
@@ -1,103 +1,107 @@
-package edu.rpi.legup.puzzle.fillapix.rules;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.model.rules.CaseRule;
-import edu.rpi.legup.model.rules.DirectRule;
-import edu.rpi.legup.model.tree.TreeNode;
-import edu.rpi.legup.model.tree.TreeTransition;
-import edu.rpi.legup.puzzle.fillapix.FillapixBoard;
-import edu.rpi.legup.puzzle.fillapix.FillapixCell;
-import edu.rpi.legup.puzzle.fillapix.FillapixCellType;
-import edu.rpi.legup.puzzle.fillapix.FillapixUtilities;
-
-public class MirrorDirectRule extends DirectRule {
- public MirrorDirectRule() {
- super("FPIX-BASC-0003",
- "Mirror",
- "Two adjacent clues with the same value must have the same number of black squares in their unshared regions",
- "edu/rpi/legup/images/fillapix/rules/Mirror.png");
- }
-
- @Override
- public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
- FillapixBoard board = (FillapixBoard) transition.getBoard();
- FillapixBoard parentBoard = (FillapixBoard) transition.getParents().get(0).getBoard().copy();
- FillapixCell cell = (FillapixCell) board.getPuzzleElement(puzzleElement);
- FillapixCell parentCell = (FillapixCell) parentBoard.getPuzzleElement(puzzleElement);
-
- // cell has to have been empty before
- if (parentCell.getType() != FillapixCellType.UNKNOWN) {
- return super.getInvalidUseOfRuleMessage();
- }
-
- // parentBoard cannot have any contradictions
- if (FillapixUtilities.checkBoardForContradiction(parentBoard)) {
- return super.getInvalidUseOfRuleMessage();
- }
-
- // find all cells adjacent to cell that are numbered
- ArrayList adjCells = FillapixUtilities.getAdjacentCells(parentBoard, parentCell);
- ArrayList adjNums = new ArrayList();
- for (int i=0; i < adjCells.size(); i++) {
- if ((adjCells.get(i)).getNumber() >= 0 && adjCells.get(i).getNumber() < 10) {
- adjNums.add(adjCells.get(i));
- }
- }
- // the numbered cells must be next to another numbered cell of the same value
- Iterator itr = adjNums.iterator();
- while (itr.hasNext()) {
- FillapixCell adjNum = itr.next();
- adjCells = FillapixUtilities.getAdjacentCells(parentBoard, adjNum);
- boolean found = false;
- for (FillapixCell adjCell : adjCells) {
- if (adjCell.getNumber() == adjNum.getNumber() && adjCell.getIndex() != adjNum.getIndex()) {
- found = true;
- }
- }
- if (!found) {
- itr.remove();
- }
- }
-
- // change the color of the parentCell, and check if there exists a valid board
- if (cell.getType() == FillapixCellType.BLACK) {
- parentCell.setCellType(FillapixCellType.WHITE);
- }
- else {
- parentCell.setCellType(FillapixCellType.BLACK);
- }
- parentBoard.addModifiedData(parentCell);
- CaseRule completeClue = new SatisfyClueCaseRule();
- List caseBoards;
- for (FillapixCell adjNum : adjNums) {
- caseBoards = completeClue.getCases(parentBoard, adjNum);
- boolean found = true;
- for (Board b : caseBoards) {
- if (!FillapixUtilities.checkBoardForContradiction((FillapixBoard) b)) {
- found = false;
- }
- }
- if (found) {
- return null;
- }
- }
-
- return super.getInvalidUseOfRuleMessage();
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- return null;
- }
-}
\ No newline at end of file
+package edu.rpi.legup.puzzle.fillapix.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.CaseRule;
+import edu.rpi.legup.model.rules.DirectRule;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.fillapix.FillapixBoard;
+import edu.rpi.legup.puzzle.fillapix.FillapixCell;
+import edu.rpi.legup.puzzle.fillapix.FillapixCellType;
+import edu.rpi.legup.puzzle.fillapix.FillapixUtilities;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class MirrorDirectRule extends DirectRule {
+ public MirrorDirectRule() {
+ super(
+ "FPIX-BASC-0003",
+ "Mirror",
+ "Two adjacent clues with the same value must have the same number of black squares"
+ + " in their unshared regions",
+ "edu/rpi/legup/images/fillapix/rules/Mirror.png");
+ }
+
+ @Override
+ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ FillapixBoard board = (FillapixBoard) transition.getBoard();
+ FillapixBoard parentBoard =
+ (FillapixBoard) transition.getParents().get(0).getBoard().copy();
+ FillapixCell cell = (FillapixCell) board.getPuzzleElement(puzzleElement);
+ FillapixCell parentCell = (FillapixCell) parentBoard.getPuzzleElement(puzzleElement);
+
+ // cell has to have been empty before
+ if (parentCell.getType() != FillapixCellType.UNKNOWN) {
+ return super.getInvalidUseOfRuleMessage();
+ }
+
+ // parentBoard cannot have any contradictions
+ if (FillapixUtilities.checkBoardForContradiction(parentBoard)) {
+ return super.getInvalidUseOfRuleMessage();
+ }
+
+ // find all cells adjacent to cell that are numbered
+ ArrayList adjCells =
+ FillapixUtilities.getAdjacentCells(parentBoard, parentCell);
+ ArrayList adjNums = new ArrayList();
+ for (int i = 0; i < adjCells.size(); i++) {
+ if ((adjCells.get(i)).getNumber() >= 0 && adjCells.get(i).getNumber() < 10) {
+ adjNums.add(adjCells.get(i));
+ }
+ }
+ // the numbered cells must be next to another numbered cell of the same value
+ Iterator itr = adjNums.iterator();
+ while (itr.hasNext()) {
+ FillapixCell adjNum = itr.next();
+ adjCells = FillapixUtilities.getAdjacentCells(parentBoard, adjNum);
+ boolean found = false;
+ for (FillapixCell adjCell : adjCells) {
+ if (adjCell.getNumber() == adjNum.getNumber()
+ && adjCell.getIndex() != adjNum.getIndex()) {
+ found = true;
+ }
+ }
+ if (!found) {
+ itr.remove();
+ }
+ }
+
+ // change the color of the parentCell, and check if there exists a valid board
+ if (cell.getType() == FillapixCellType.BLACK) {
+ parentCell.setCellType(FillapixCellType.WHITE);
+ } else {
+ parentCell.setCellType(FillapixCellType.BLACK);
+ }
+ parentBoard.addModifiedData(parentCell);
+ CaseRule completeClue = new SatisfyClueCaseRule();
+ List caseBoards;
+ for (FillapixCell adjNum : adjNums) {
+ caseBoards = completeClue.getCases(parentBoard, adjNum);
+ boolean found = true;
+ for (Board b : caseBoards) {
+ if (!FillapixUtilities.checkBoardForContradiction((FillapixBoard) b)) {
+ found = false;
+ }
+ }
+ if (found) {
+ return null;
+ }
+ }
+
+ return super.getInvalidUseOfRuleMessage();
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ return null;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/NonTouchingSharedDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/NonTouchingSharedDirectRule.java
index fe94dbcb4..71a85a95b 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/NonTouchingSharedDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/NonTouchingSharedDirectRule.java
@@ -1,99 +1,103 @@
-package edu.rpi.legup.puzzle.fillapix.rules;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.model.rules.CaseRule;
-import edu.rpi.legup.model.rules.DirectRule;
-import edu.rpi.legup.model.tree.TreeNode;
-import edu.rpi.legup.model.tree.TreeTransition;
-import edu.rpi.legup.puzzle.fillapix.FillapixBoard;
-import edu.rpi.legup.puzzle.fillapix.FillapixCell;
-import edu.rpi.legup.puzzle.fillapix.FillapixCellType;
-import edu.rpi.legup.puzzle.fillapix.FillapixUtilities;
-
-public class NonTouchingSharedDirectRule extends DirectRule {
- public NonTouchingSharedDirectRule() {
- super("FPIX-BASC-0005",
- "NonTouching Shared",
- "Clues with shared cells have the same difference in black cells in their unshared regions as the difference in their numbers",
- "edu/rpi/legup/images/fillapix/rules/TouchingSides.png");
- }
-
- @Override
- public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
- FillapixBoard board = (FillapixBoard) transition.getBoard();
- FillapixBoard parentBoard = (FillapixBoard) transition.getParents().get(0).getBoard().copy();
- FillapixCell cell = (FillapixCell) board.getPuzzleElement(puzzleElement);
- FillapixCell parentCell = (FillapixCell) parentBoard.getPuzzleElement(puzzleElement);
-
- // cell has to have been empty before
- if (parentCell.getType() != FillapixCellType.UNKNOWN) {
- return super.getInvalidUseOfRuleMessage();
- }
-
- // parentBoard cannot have any contradictions
- if (FillapixUtilities.checkBoardForContradiction(parentBoard)) {
- return super.getInvalidUseOfRuleMessage();
- }
-
- // get all adjCells that have a number
- ArrayList adjCells = FillapixUtilities.getAdjacentCells(parentBoard, parentCell);
- adjCells.removeIf(x -> x.getNumber() < 0 || x.getNumber() >= 10);
- /* remove any number cell that does not have another number cell not
- * touching, but sharing cells */
- Iterator itr = adjCells.iterator();
- while (itr.hasNext()) {
- ArrayList sharingCells = FillapixUtilities.getCellsAtDistance(parentBoard, parentCell, 1);
- boolean found = false;
- for (FillapixCell sharingCell : sharingCells) {
- if (sharingCell.getNumber() >= 0 && sharingCell.getNumber() < 10) {
- found = true;
- }
- }
- if (!found) {
- itr.remove();
- }
- }
-
- // change the cell to the opposite color
- if (cell.getType() == FillapixCellType.BLACK) {
- parentCell.setCellType(FillapixCellType.WHITE);
- }
- else {
- parentCell.setCellType(FillapixCellType.BLACK);
- }
- // check for some contradiction in all cases
- parentBoard.addModifiedData(parentCell);
- CaseRule completeClue = new SatisfyClueCaseRule();
- List caseBoards;
- for (FillapixCell adjCell : adjCells) {
- caseBoards = completeClue.getCases(parentBoard, adjCell);
- boolean found = true;
- for (Board b : caseBoards) {
- if (!FillapixUtilities.checkBoardForContradiction((FillapixBoard) b)) {
- found = false;
- }
- }
- if (found) {
- return null;
- }
- }
-
- return super.getInvalidUseOfRuleMessage();
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- return null;
- }
-}
\ No newline at end of file
+package edu.rpi.legup.puzzle.fillapix.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.CaseRule;
+import edu.rpi.legup.model.rules.DirectRule;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.fillapix.FillapixBoard;
+import edu.rpi.legup.puzzle.fillapix.FillapixCell;
+import edu.rpi.legup.puzzle.fillapix.FillapixCellType;
+import edu.rpi.legup.puzzle.fillapix.FillapixUtilities;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class NonTouchingSharedDirectRule extends DirectRule {
+ public NonTouchingSharedDirectRule() {
+ super(
+ "FPIX-BASC-0005",
+ "NonTouching Shared",
+ "Clues with shared cells have the same difference in black cells in their unshared"
+ + " regions as the difference in their numbers",
+ "edu/rpi/legup/images/fillapix/rules/TouchingSides.png");
+ }
+
+ @Override
+ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ FillapixBoard board = (FillapixBoard) transition.getBoard();
+ FillapixBoard parentBoard =
+ (FillapixBoard) transition.getParents().get(0).getBoard().copy();
+ FillapixCell cell = (FillapixCell) board.getPuzzleElement(puzzleElement);
+ FillapixCell parentCell = (FillapixCell) parentBoard.getPuzzleElement(puzzleElement);
+
+ // cell has to have been empty before
+ if (parentCell.getType() != FillapixCellType.UNKNOWN) {
+ return super.getInvalidUseOfRuleMessage();
+ }
+
+ // parentBoard cannot have any contradictions
+ if (FillapixUtilities.checkBoardForContradiction(parentBoard)) {
+ return super.getInvalidUseOfRuleMessage();
+ }
+
+ // get all adjCells that have a number
+ ArrayList adjCells =
+ FillapixUtilities.getAdjacentCells(parentBoard, parentCell);
+ adjCells.removeIf(x -> x.getNumber() < 0 || x.getNumber() >= 10);
+ /* remove any number cell that does not have another number cell not
+ * touching, but sharing cells */
+ Iterator itr = adjCells.iterator();
+ while (itr.hasNext()) {
+ ArrayList sharingCells =
+ FillapixUtilities.getCellsAtDistance(parentBoard, parentCell, 1);
+ boolean found = false;
+ for (FillapixCell sharingCell : sharingCells) {
+ if (sharingCell.getNumber() >= 0 && sharingCell.getNumber() < 10) {
+ found = true;
+ }
+ }
+ if (!found) {
+ itr.remove();
+ }
+ }
+
+ // change the cell to the opposite color
+ if (cell.getType() == FillapixCellType.BLACK) {
+ parentCell.setCellType(FillapixCellType.WHITE);
+ } else {
+ parentCell.setCellType(FillapixCellType.BLACK);
+ }
+ // check for some contradiction in all cases
+ parentBoard.addModifiedData(parentCell);
+ CaseRule completeClue = new SatisfyClueCaseRule();
+ List caseBoards;
+ for (FillapixCell adjCell : adjCells) {
+ caseBoards = completeClue.getCases(parentBoard, adjCell);
+ boolean found = true;
+ for (Board b : caseBoards) {
+ if (!FillapixUtilities.checkBoardForContradiction((FillapixBoard) b)) {
+ found = false;
+ }
+ }
+ if (found) {
+ return null;
+ }
+ }
+
+ return super.getInvalidUseOfRuleMessage();
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ return null;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/SatisfyClueCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/SatisfyClueCaseRule.java
index 4520add31..f8bb2d4f5 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/SatisfyClueCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/SatisfyClueCaseRule.java
@@ -1,12 +1,5 @@
package edu.rpi.legup.puzzle.fillapix.rules;
-import java.awt.Point;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-
import edu.rpi.legup.model.gameboard.Board;
import edu.rpi.legup.model.gameboard.CaseBoard;
import edu.rpi.legup.model.gameboard.PuzzleElement;
@@ -17,13 +10,20 @@
import edu.rpi.legup.puzzle.fillapix.FillapixCell;
import edu.rpi.legup.puzzle.fillapix.FillapixCellType;
import edu.rpi.legup.puzzle.fillapix.FillapixUtilities;
+import java.awt.Point;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
public class SatisfyClueCaseRule extends CaseRule {
public SatisfyClueCaseRule() {
- super("FPIX-CASE-0002",
- "Satisfy Clue",
- "Each clue must touch that number of squares.",
- "edu/rpi/legup/images/fillapix/cases/SatisfyClue.png");
+ super(
+ "FPIX-CASE-0002",
+ "Satisfy Clue",
+ "Each clue must touch that number of squares.",
+ "edu/rpi/legup/images/fillapix/cases/SatisfyClue.png");
}
@Override
@@ -33,7 +33,9 @@ public CaseBoard getCaseBoard(Board board) {
fillapixBoard.setModifiable(false);
for (PuzzleElement data : fillapixBoard.getPuzzleElements()) {
FillapixCell cell = (FillapixCell) data;
- if (cell.getNumber() >= 0 && cell.getNumber() <= 9 && FillapixUtilities.hasEmptyAdjacent(fillapixBoard, cell)) {
+ if (cell.getNumber() >= 0
+ && cell.getNumber() <= 9
+ && FillapixUtilities.hasEmptyAdjacent(fillapixBoard, cell)) {
caseBoard.addPickableElement(data);
}
}
@@ -43,6 +45,9 @@ public CaseBoard getCaseBoard(Board board) {
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
ArrayList cases = new ArrayList();
+ if (puzzleElement == null) {
+ return cases;
+ }
// get value of cell
FillapixBoard fillapixBoard = (FillapixBoard) board.copy();
@@ -70,26 +75,25 @@ public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
if (cellNumBlack > cellMaxBlack || cellNumEmpty == 0) {
return cases;
}
-
+
// generate all cases as boolean expressions
ArrayList combinations;
combinations = FillapixUtilities.getCombinations(cellMaxBlack - cellNumBlack, cellNumEmpty);
- for (int i=0; i < combinations.size(); i++) {
+ for (int i = 0; i < combinations.size(); i++) {
Board case_ = board.copy();
- for (int j=0; j < combinations.get(i).length; j++) {
+ for (int j = 0; j < combinations.get(i).length; j++) {
cell = (FillapixCell) case_.getPuzzleElement(emptyCells.get(j));
if (combinations.get(i)[j]) {
cell.setCellType(FillapixCellType.BLACK);
- }
- else {
+ } else {
cell.setCellType(FillapixCellType.WHITE);
}
case_.addModifiedData(cell);
}
cases.add(case_);
}
-
+
return cases;
}
@@ -99,26 +103,24 @@ public String checkRuleRaw(TreeTransition transition) {
List childTransitions = parent.getChildren();
/*
- * In order for the transition to be valid, it can only be applied to
+ * In order for the transition to be valid, it can only be applied to
* one cell, thus:
* * there must be modified cells
* * all modified cells must share at least one common adjacent
* cell
* * all modified cells must fit within a 3X3 square
- * * the center of one of the possible squaress must be a cell
+ * * the center of one of the possible squaress must be a cell
* with a number
* * that cells possible combinations must match the transitions
* If all the above is verified, then the transition is valid
*/
-
/* ensure there are modified cells */
Set modCells = transition.getBoard().getModifiedData();
if (modCells.size() <= 0) {
return super.getInvalidUseOfRuleMessage();
}
-
/* ensure modified cells occur within a 3X3 square */
int minVertLoc = Integer.MAX_VALUE, maxVertLoc = Integer.MIN_VALUE;
int minHorzLoc = Integer.MAX_VALUE, maxHorzLoc = Integer.MIN_VALUE;
@@ -141,14 +143,16 @@ public String checkRuleRaw(TreeTransition transition) {
return super.getInvalidUseOfRuleMessage();
}
-
- /* get the center of all possible 3X3 squares,
+ /* get the center of all possible 3X3 squares,
* and collect all that have numbers */
FillapixBoard board = (FillapixBoard) transition.getParents().get(0).getBoard();
Set possibleCenters = new TreeSet();
- possibleCenters.addAll(FillapixUtilities.getAdjacentCells(board, (FillapixCell) modCells.iterator().next()));
+ possibleCenters.addAll(
+ FillapixUtilities.getAdjacentCells(
+ board, (FillapixCell) modCells.iterator().next()));
for (PuzzleElement modCell : modCells) {
- possibleCenters.retainAll((FillapixUtilities.getAdjacentCells(board, (FillapixCell) modCell)));
+ possibleCenters.retainAll(
+ (FillapixUtilities.getAdjacentCells(board, (FillapixCell) modCell)));
}
// removing all elements without a valid number
possibleCenters.removeIf(x -> x.getNumber() < 0 || x.getNumber() >= 10);
@@ -156,7 +160,6 @@ public String checkRuleRaw(TreeTransition transition) {
return super.getInvalidUseOfRuleMessage();
}
-
/* Now go through the remaining centers, and check if their combinations
* match the transitions */
for (FillapixCell possibleCenter : possibleCenters) {
@@ -176,7 +179,8 @@ public String checkRuleRaw(TreeTransition transition) {
continue;
}
- ArrayList combinations = FillapixUtilities.getCombinations(maxBlack - numBlack, numEmpty);
+ ArrayList combinations =
+ FillapixUtilities.getCombinations(maxBlack - numBlack, numEmpty);
if (combinations.size() != childTransitions.size()) {
// not this center because combinations do not match transitions
continue;
@@ -192,11 +196,10 @@ public String checkRuleRaw(TreeTransition transition) {
}
boolean[] translatedModCells = new boolean[transModCells.size()];
- for (int i=0; i < transModCells.size(); i++) {
+ for (int i = 0; i < transModCells.size(); i++) {
if (transModCells.get(i).getType() == FillapixCellType.BLACK) {
translatedModCells[i] = true;
- }
- else {
+ } else {
translatedModCells[i] = false;
}
}
@@ -226,9 +229,8 @@ public String checkRuleRaw(TreeTransition transition) {
return super.getInvalidUseOfRuleMessage();
}
-
@Override
public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
return null;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/TooFewBlackCellsContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/TooFewBlackCellsContradictionRule.java
index c37050978..df5954d63 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/TooFewBlackCellsContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/TooFewBlackCellsContradictionRule.java
@@ -7,25 +7,26 @@
import edu.rpi.legup.puzzle.fillapix.FillapixCell;
import edu.rpi.legup.puzzle.fillapix.FillapixCellType;
import edu.rpi.legup.puzzle.fillapix.FillapixUtilities;
-
import java.util.ArrayList;
public class TooFewBlackCellsContradictionRule extends ContradictionRule {
public TooFewBlackCellsContradictionRule() {
- super("FPIX-CONT-0001",
+ super(
+ "FPIX-CONT-0001",
"Too Few Black Cells",
"There may not be fewer black cells than the number.",
"edu/rpi/legup/images/fillapix/contradictions/TooFewBlackCells.png");
}
/**
- * Checks whether the transition has a contradiction at the specific puzzleElement index using this rule
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
*
- * @param board board to check contradiction
+ * @param board board to check contradiction
* @param puzzleElement equivalent puzzleElement
* @return null if the transition contains a contradiction at the specified puzzleElement,
- * otherwise error message
+ * otherwise error message
*/
@Override
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/TooManyBlackCellsContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/TooManyBlackCellsContradictionRule.java
index 68395ce7f..38b47c972 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/TooManyBlackCellsContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/TooManyBlackCellsContradictionRule.java
@@ -7,25 +7,26 @@
import edu.rpi.legup.puzzle.fillapix.FillapixCell;
import edu.rpi.legup.puzzle.fillapix.FillapixCellType;
import edu.rpi.legup.puzzle.fillapix.FillapixUtilities;
-
import java.util.ArrayList;
public class TooManyBlackCellsContradictionRule extends ContradictionRule {
public TooManyBlackCellsContradictionRule() {
- super("FPIX-CONT-0002",
+ super(
+ "FPIX-CONT-0002",
"Too Many Black Cells",
"There may not be more black cells than the number",
"edu/rpi/legup/images/fillapix/contradictions/TooManyBlackCells.png");
}
/**
- * Checks whether the transition has a contradiction at the specific puzzleElement index using this rule
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
*
- * @param board board to check contradiction
+ * @param board board to check contradiction
* @param puzzleElement equivalent puzzleElement
* @return null if the transition contains a contradiction at the specified puzzleElement,
- * otherwise error message
+ * otherwise error message
*/
@Override
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
@@ -45,8 +46,8 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
}
if (numBlack > cellNum) {
return null;
- }
-
+ }
+
return super.getNoContradictionMessage();
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/TouchingCornersDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/TouchingCornersDirectRule.java
index 6f4be7842..72e2def47 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/TouchingCornersDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/TouchingCornersDirectRule.java
@@ -1,108 +1,113 @@
-package edu.rpi.legup.puzzle.fillapix.rules;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.model.rules.CaseRule;
-import edu.rpi.legup.model.rules.DirectRule;
-import edu.rpi.legup.model.tree.TreeNode;
-import edu.rpi.legup.model.tree.TreeTransition;
-import edu.rpi.legup.puzzle.fillapix.FillapixBoard;
-import edu.rpi.legup.puzzle.fillapix.FillapixCell;
-import edu.rpi.legup.puzzle.fillapix.FillapixCellType;
-import edu.rpi.legup.puzzle.fillapix.FillapixUtilities;
-
-public class TouchingCornersDirectRule extends DirectRule {
- public TouchingCornersDirectRule() {
- super("FPIX-BASC-0005",
- "Touching Corners",
- "Clues with touching corners have the same difference in black cells in their unshared regions as the difference in their numbers",
- "edu/rpi/legup/images/fillapix/rules/TouchingCorners.png");
- }
-
- @Override
- public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
- FillapixBoard board = (FillapixBoard) transition.getBoard();
- FillapixBoard parentBoard = (FillapixBoard) transition.getParents().get(0).getBoard().copy();
- FillapixCell cell = (FillapixCell) board.getPuzzleElement(puzzleElement);
- FillapixCell parentCell = (FillapixCell) parentBoard.getPuzzleElement(puzzleElement);
-
- // cell has to have been empty before
- if (parentCell.getType() != FillapixCellType.UNKNOWN) {
- return super.getInvalidUseOfRuleMessage();
- }
-
- // parentBoard cannot have any contradictions
- if (FillapixUtilities.checkBoardForContradiction(parentBoard)) {
- return super.getInvalidUseOfRuleMessage();
- }
-
- // get all adjCells that have a number
- ArrayList adjCells = FillapixUtilities.getAdjacentCells(parentBoard, parentCell);
- adjCells.removeIf(x -> x.getNumber() < 0 || x.getNumber() >= 10);
- /* remove any number cell that does not have another number cell diagonally
- * adjacent to it on the opposite side of the modified cell */
- Iterator itr = adjCells.iterator();
- while (itr.hasNext()) {
- FillapixCell adjCell = itr.next();
-
- boolean found = false;
- ArrayList adjAdjCells = FillapixUtilities.getAdjacentCells(parentBoard, adjCell);
- for (FillapixCell adjAdjCell : adjAdjCells) {
- if (adjAdjCell.getLocation().x != adjCell.getLocation().x &&
- adjAdjCell.getLocation().y != adjCell.getLocation().y &&
- adjAdjCell.getNumber() >= 0 && adjAdjCell.getNumber() < 10 &&
- adjAdjCell.getIndex() != parentCell.getIndex()) {
- // adjAdjCell is diagonally adjacent to adjCell && it has a
- // number && it is not parentCell
- found = true;
- }
- }
-
- // does not qualify for this rule
- if (!found) {
- itr.remove();
- }
- }
-
- // change the cell to the opposite color
- if (cell.getType() == FillapixCellType.BLACK) {
- parentCell.setCellType(FillapixCellType.WHITE);
- }
- else {
- parentCell.setCellType(FillapixCellType.BLACK);
- }
- // check for some contradiction in all cases
- parentBoard.addModifiedData(parentCell);
- CaseRule completeClue = new SatisfyClueCaseRule();
- List caseBoards;
- for (FillapixCell adjCell : adjCells) {
- caseBoards = completeClue.getCases(parentBoard, adjCell);
- boolean found = true;
- for (Board b : caseBoards) {
- if (!FillapixUtilities.checkBoardForContradiction((FillapixBoard) b)) {
- found = false;
- }
- }
- if (found) {
- return null;
- }
- }
-
- return super.getInvalidUseOfRuleMessage();
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- return null;
- }
-}
\ No newline at end of file
+package edu.rpi.legup.puzzle.fillapix.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.CaseRule;
+import edu.rpi.legup.model.rules.DirectRule;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.fillapix.FillapixBoard;
+import edu.rpi.legup.puzzle.fillapix.FillapixCell;
+import edu.rpi.legup.puzzle.fillapix.FillapixCellType;
+import edu.rpi.legup.puzzle.fillapix.FillapixUtilities;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class TouchingCornersDirectRule extends DirectRule {
+ public TouchingCornersDirectRule() {
+ super(
+ "FPIX-BASC-0005",
+ "Touching Corners",
+ "Clues with touching corners have the same difference in black cells in their"
+ + " unshared regions as the difference in their numbers",
+ "edu/rpi/legup/images/fillapix/rules/TouchingCorners.png");
+ }
+
+ @Override
+ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ FillapixBoard board = (FillapixBoard) transition.getBoard();
+ FillapixBoard parentBoard =
+ (FillapixBoard) transition.getParents().get(0).getBoard().copy();
+ FillapixCell cell = (FillapixCell) board.getPuzzleElement(puzzleElement);
+ FillapixCell parentCell = (FillapixCell) parentBoard.getPuzzleElement(puzzleElement);
+
+ // cell has to have been empty before
+ if (parentCell.getType() != FillapixCellType.UNKNOWN) {
+ return super.getInvalidUseOfRuleMessage();
+ }
+
+ // parentBoard cannot have any contradictions
+ if (FillapixUtilities.checkBoardForContradiction(parentBoard)) {
+ return super.getInvalidUseOfRuleMessage();
+ }
+
+ // get all adjCells that have a number
+ ArrayList adjCells =
+ FillapixUtilities.getAdjacentCells(parentBoard, parentCell);
+ adjCells.removeIf(x -> x.getNumber() < 0 || x.getNumber() >= 10);
+ /* remove any number cell that does not have another number cell diagonally
+ * adjacent to it on the opposite side of the modified cell */
+ Iterator itr = adjCells.iterator();
+ while (itr.hasNext()) {
+ FillapixCell adjCell = itr.next();
+
+ boolean found = false;
+ ArrayList adjAdjCells =
+ FillapixUtilities.getAdjacentCells(parentBoard, adjCell);
+ for (FillapixCell adjAdjCell : adjAdjCells) {
+ if (adjAdjCell.getLocation().x != adjCell.getLocation().x
+ && adjAdjCell.getLocation().y != adjCell.getLocation().y
+ && adjAdjCell.getNumber() >= 0
+ && adjAdjCell.getNumber() < 10
+ && adjAdjCell.getIndex() != parentCell.getIndex()) {
+ // adjAdjCell is diagonally adjacent to adjCell && it has a
+ // number && it is not parentCell
+ found = true;
+ }
+ }
+
+ // does not qualify for this rule
+ if (!found) {
+ itr.remove();
+ }
+ }
+
+ // change the cell to the opposite color
+ if (cell.getType() == FillapixCellType.BLACK) {
+ parentCell.setCellType(FillapixCellType.WHITE);
+ } else {
+ parentCell.setCellType(FillapixCellType.BLACK);
+ }
+ // check for some contradiction in all cases
+ parentBoard.addModifiedData(parentCell);
+ CaseRule completeClue = new SatisfyClueCaseRule();
+ List caseBoards;
+ for (FillapixCell adjCell : adjCells) {
+ caseBoards = completeClue.getCases(parentBoard, adjCell);
+ boolean found = true;
+ for (Board b : caseBoards) {
+ if (!FillapixUtilities.checkBoardForContradiction((FillapixBoard) b)) {
+ found = false;
+ }
+ }
+ if (found) {
+ return null;
+ }
+ }
+
+ return super.getInvalidUseOfRuleMessage();
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ return null;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/TouchingSidesDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/TouchingSidesDirectRule.java
index bd6dd0169..281dd5392 100644
--- a/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/TouchingSidesDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/fillapix/rules/TouchingSidesDirectRule.java
@@ -1,115 +1,126 @@
-package edu.rpi.legup.puzzle.fillapix.rules;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.model.rules.CaseRule;
-import edu.rpi.legup.model.rules.DirectRule;
-import edu.rpi.legup.model.tree.TreeNode;
-import edu.rpi.legup.model.tree.TreeTransition;
-import edu.rpi.legup.puzzle.fillapix.FillapixBoard;
-import edu.rpi.legup.puzzle.fillapix.FillapixCell;
-import edu.rpi.legup.puzzle.fillapix.FillapixCellType;
-import edu.rpi.legup.puzzle.fillapix.FillapixUtilities;
-
-public class TouchingSidesDirectRule extends DirectRule {
- public TouchingSidesDirectRule() {
- super("FPIX-BASC-0004",
- "Touching Sides",
- "Clues with touching sides have the same difference in black cells in their unshared regions as the difference in their numbers",
- "edu/rpi/legup/images/fillapix/rules/TouchingSides.png");
- }
-
- @Override
- public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
- FillapixBoard board = (FillapixBoard) transition.getBoard();
- FillapixBoard parentBoard = (FillapixBoard) transition.getParents().get(0).getBoard().copy();
- FillapixCell cell = (FillapixCell) board.getPuzzleElement(puzzleElement);
- FillapixCell parentCell = (FillapixCell) parentBoard.getPuzzleElement(puzzleElement);
-
- // cell has to have been empty before
- if (parentCell.getType() != FillapixCellType.UNKNOWN) {
- return super.getInvalidUseOfRuleMessage();
- }
-
- // parentBoard cannot have any contradictions
- if (FillapixUtilities.checkBoardForContradiction(parentBoard)) {
- return super.getInvalidUseOfRuleMessage();
- }
-
- // get all adjCells that have a number
- ArrayList adjCells = FillapixUtilities.getAdjacentCells(parentBoard, parentCell);
- adjCells.removeIf(x -> x.getNumber() < 0 || x.getNumber() >= 10);
- /* remove any number cell that does not have another number cell adjacent
- * to it on the opposite side of the modified cell */
- Iterator itr = adjCells.iterator();
- while (itr.hasNext()) {
- // calculate x and y offset of adjCell from cell
- FillapixCell adjCell = itr.next();
- int xOffset = adjCell.getLocation().x - cell.getLocation().x;
- int yOffset = adjCell.getLocation().y - cell.getLocation().y;
-
- boolean found = false;
- // check vertically for numbered cell in opposite direction of cell
- if (adjCell.getLocation().x + xOffset >= 0 && adjCell.getLocation().x < parentBoard.getWidth()) {
- int adjNum = parentBoard.getCell(adjCell.getLocation().x + xOffset, adjCell.getLocation().y).getNumber();
- if (adjNum >= 0 && adjNum < 10) {
- found = true;
- }
- }
- // check horizontally for numbered cell in opposite direction of cell
- if (adjCell.getLocation().y + yOffset >= 0 && adjCell.getLocation().y < parentBoard.getHeight()) {
- int adjNum = parentBoard.getCell(adjCell.getLocation().x, adjCell.getLocation().y + yOffset).getNumber();
- if (adjNum >= 0 && adjNum < 10) {
- found = true;
- }
- }
-
- // if no horizontally or vertically adjacent cell on opposite side of 'cell' has number,
- // then adjCell is not valid, so should be removed
- if (!found) {
- itr.remove();
- }
- }
-
- // change the cell to the opposite color
- if (cell.getType() == FillapixCellType.BLACK) {
- parentCell.setCellType(FillapixCellType.WHITE);
- }
- else {
- parentCell.setCellType(FillapixCellType.BLACK);
- }
- // check for some contradiction in all cases
- parentBoard.addModifiedData(parentCell);
- CaseRule completeClue = new SatisfyClueCaseRule();
- List caseBoards;
- for (FillapixCell adjCell : adjCells) {
- caseBoards = completeClue.getCases(parentBoard, adjCell);
- boolean found = true;
- for (Board b : caseBoards) {
- if (!FillapixUtilities.checkBoardForContradiction((FillapixBoard) b)) {
- found = false;
- }
- }
- if (found) {
- return null;
- }
- }
-
- return super.getInvalidUseOfRuleMessage();
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- return null;
- }
-}
\ No newline at end of file
+package edu.rpi.legup.puzzle.fillapix.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.CaseRule;
+import edu.rpi.legup.model.rules.DirectRule;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+import edu.rpi.legup.puzzle.fillapix.FillapixBoard;
+import edu.rpi.legup.puzzle.fillapix.FillapixCell;
+import edu.rpi.legup.puzzle.fillapix.FillapixCellType;
+import edu.rpi.legup.puzzle.fillapix.FillapixUtilities;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class TouchingSidesDirectRule extends DirectRule {
+ public TouchingSidesDirectRule() {
+ super(
+ "FPIX-BASC-0004",
+ "Touching Sides",
+ "Clues with touching sides have the same difference in black cells in their"
+ + " unshared regions as the difference in their numbers",
+ "edu/rpi/legup/images/fillapix/rules/TouchingSides.png");
+ }
+
+ @Override
+ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ FillapixBoard board = (FillapixBoard) transition.getBoard();
+ FillapixBoard parentBoard =
+ (FillapixBoard) transition.getParents().get(0).getBoard().copy();
+ FillapixCell cell = (FillapixCell) board.getPuzzleElement(puzzleElement);
+ FillapixCell parentCell = (FillapixCell) parentBoard.getPuzzleElement(puzzleElement);
+
+ // cell has to have been empty before
+ if (parentCell.getType() != FillapixCellType.UNKNOWN) {
+ return super.getInvalidUseOfRuleMessage();
+ }
+
+ // parentBoard cannot have any contradictions
+ if (FillapixUtilities.checkBoardForContradiction(parentBoard)) {
+ return super.getInvalidUseOfRuleMessage();
+ }
+
+ // get all adjCells that have a number
+ ArrayList adjCells =
+ FillapixUtilities.getAdjacentCells(parentBoard, parentCell);
+ adjCells.removeIf(x -> x.getNumber() < 0 || x.getNumber() >= 10);
+ /* remove any number cell that does not have another number cell adjacent
+ * to it on the opposite side of the modified cell */
+ Iterator itr = adjCells.iterator();
+ while (itr.hasNext()) {
+ // calculate x and y offset of adjCell from cell
+ FillapixCell adjCell = itr.next();
+ int xOffset = adjCell.getLocation().x - cell.getLocation().x;
+ int yOffset = adjCell.getLocation().y - cell.getLocation().y;
+
+ boolean found = false;
+ // check vertically for numbered cell in opposite direction of cell
+ if (adjCell.getLocation().x + xOffset >= 0
+ && adjCell.getLocation().x < parentBoard.getWidth()) {
+ int adjNum =
+ parentBoard
+ .getCell(adjCell.getLocation().x + xOffset, adjCell.getLocation().y)
+ .getNumber();
+ if (adjNum >= 0 && adjNum < 10) {
+ found = true;
+ }
+ }
+ // check horizontally for numbered cell in opposite direction of cell
+ if (adjCell.getLocation().y + yOffset >= 0
+ && adjCell.getLocation().y < parentBoard.getHeight()) {
+ int adjNum =
+ parentBoard
+ .getCell(adjCell.getLocation().x, adjCell.getLocation().y + yOffset)
+ .getNumber();
+ if (adjNum >= 0 && adjNum < 10) {
+ found = true;
+ }
+ }
+
+ // if no horizontally or vertically adjacent cell on opposite side of 'cell' has number,
+ // then adjCell is not valid, so should be removed
+ if (!found) {
+ itr.remove();
+ }
+ }
+
+ // change the cell to the opposite color
+ if (cell.getType() == FillapixCellType.BLACK) {
+ parentCell.setCellType(FillapixCellType.WHITE);
+ } else {
+ parentCell.setCellType(FillapixCellType.BLACK);
+ }
+ // check for some contradiction in all cases
+ parentBoard.addModifiedData(parentCell);
+ CaseRule completeClue = new SatisfyClueCaseRule();
+ List caseBoards;
+ for (FillapixCell adjCell : adjCells) {
+ caseBoards = completeClue.getCases(parentBoard, adjCell);
+ boolean found = true;
+ for (Board b : caseBoards) {
+ if (!FillapixUtilities.checkBoardForContradiction((FillapixBoard) b)) {
+ found = false;
+ }
+ }
+ if (found) {
+ return null;
+ }
+ }
+
+ return super.getInvalidUseOfRuleMessage();
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ return null;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/Heyawake.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/Heyawake.java
index fc52a6fff..afe3dd652 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/Heyawake.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/Heyawake.java
@@ -16,9 +16,7 @@ public Heyawake() {
this.importer = new HeyawakeImporter(this);
}
- /**
- * Initializes the view. Called by the invoker of the class
- */
+ /** Initializes the view. Called by the invoker of the class */
@Override
public void initializeView() {
boardView = new HeyawakeView((HeyawakeBoard) currentBoard);
@@ -39,8 +37,8 @@ public Board generatePuzzle(int difficulty) {
/**
* Determines if the given dimensions are valid for HeyAwake
*
- * @param rows the number of rows
- * @param columns the number of columns
+ * @param rows the number of rows
+ * @param columns the number of columns
* @return true if the given dimensions are valid for HeyAwake, false otherwise
*/
public boolean isValidDimensions(int rows, int columns) {
@@ -65,7 +63,5 @@ public boolean isBoardComplete(Board board) {
* @param board the board that has changed
*/
@Override
- public void onBoardChange(Board board) {
-
- }
+ public void onBoardChange(Board board) {}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeBoard.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeBoard.java
index 2f15213ec..cedb3a91b 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeBoard.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeBoard.java
@@ -2,7 +2,6 @@
import edu.rpi.legup.model.gameboard.GridBoard;
import edu.rpi.legup.model.gameboard.PuzzleElement;
-
import java.awt.*;
import java.util.ArrayList;
import java.util.HashMap;
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeCell.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeCell.java
index ce8c73424..480e2e39b 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeCell.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeCell.java
@@ -1,7 +1,6 @@
package edu.rpi.legup.puzzle.heyawake;
import edu.rpi.legup.model.gameboard.GridCell;
-
import java.awt.*;
public class HeyawakeCell extends GridCell {
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeController.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeController.java
index 2bad91933..2d081d7da 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeController.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeController.java
@@ -2,5 +2,4 @@
import edu.rpi.legup.controller.ElementController;
-public class HeyawakeController extends ElementController {
-}
+public class HeyawakeController extends ElementController {}
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeElementView.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeElementView.java
index 5efec44ff..d30159856 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeElementView.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeElementView.java
@@ -1,7 +1,6 @@
package edu.rpi.legup.puzzle.heyawake;
import edu.rpi.legup.ui.boardview.GridElementView;
-
import java.awt.*;
public class HeyawakeElementView extends GridElementView {
@@ -39,7 +38,8 @@ public void drawElement(Graphics2D graphics2D) {
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();
+ int yText =
+ location.y + ((size.height - metrics.getHeight()) / 2) + metrics.getAscent();
graphics2D.drawString(String.valueOf(puzzleElement.getData()), xText, yText);
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeExporter.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeExporter.java
index 344a0be92..4470d77be 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeExporter.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeExporter.java
@@ -2,7 +2,6 @@
import edu.rpi.legup.model.PuzzleExporter;
import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.puzzle.shorttruthtable.ShortTruthTableBoard;
import org.w3c.dom.Document;
public class HeyawakeExporter extends PuzzleExporter {
@@ -16,8 +15,7 @@ protected org.w3c.dom.Element createBoardElement(Document newDocument) {
HeyawakeBoard board;
if (puzzle.getTree() != null) {
board = (HeyawakeBoard) puzzle.getTree().getRootNode().getBoard();
- }
- else {
+ } else {
board = (HeyawakeBoard) puzzle.getBoardView().getBoard();
}
@@ -29,7 +27,8 @@ protected org.w3c.dom.Element createBoardElement(Document newDocument) {
for (PuzzleElement puzzleElement : board.getPuzzleElements()) {
HeyawakeCell cell = (HeyawakeCell) puzzleElement;
if (cell.getData() != -2) {
- org.w3c.dom.Element cellElement = puzzle.getFactory().exportCell(newDocument, puzzleElement);
+ org.w3c.dom.Element cellElement =
+ puzzle.getFactory().exportCell(newDocument, puzzleElement);
cellsElement.appendChild(cellElement);
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeFactory.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeFactory.java
index 96fc20e6f..8ecf24135 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeFactory.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeFactory.java
@@ -4,17 +4,16 @@
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;
-import java.awt.*;
-
public class HeyawakeFactory extends ElementFactory {
/**
* Creates a puzzleElement based on the xml document Node and adds it to the board
*
- * @param node node that represents the puzzleElement
+ * @param node node that represents the puzzleElement
* @param board board to add the newly created cell
* @return newly created cell from the xml document Node
* @throws InvalidFileFormatException if file is invalid
@@ -23,7 +22,8 @@ public class HeyawakeFactory extends ElementFactory {
public HeyawakeCell importCell(Node node, Board board) throws InvalidFileFormatException {
try {
if (!node.getNodeName().equalsIgnoreCase("cell")) {
- throw new InvalidFileFormatException("Heyawake Factory: unknown puzzleElement puzzleElement");
+ throw new InvalidFileFormatException(
+ "Heyawake Factory: unknown puzzleElement puzzleElement");
}
HeyawakeBoard heyawakeBoard = (HeyawakeBoard) board;
@@ -36,7 +36,8 @@ public HeyawakeCell importCell(Node node, Board board) throws InvalidFileFormatE
int y = Integer.valueOf(attributeList.getNamedItem("y").getNodeValue());
int regionIndex = Integer.valueOf(attributeList.getNamedItem("region").getNodeValue());
if (x >= width || y >= height) {
- throw new InvalidFileFormatException("Heyawake Factory: cell location out of bounds");
+ throw new InvalidFileFormatException(
+ "Heyawake Factory: cell location out of bounds");
}
if (value < -4 || value > 4) {
throw new InvalidFileFormatException("Heyawake Factory: cell unknown value");
@@ -46,11 +47,10 @@ public HeyawakeCell importCell(Node node, Board board) throws InvalidFileFormatE
cell.setIndex(y * height + x);
heyawakeBoard.getRegions();
return cell;
- }
- catch (NumberFormatException e) {
- throw new InvalidFileFormatException("Heyawake Factory: unknown value where integer expected");
- }
- catch (NullPointerException e) {
+ } catch (NumberFormatException e) {
+ throw new InvalidFileFormatException(
+ "Heyawake Factory: unknown value where integer expected");
+ } catch (NullPointerException e) {
throw new InvalidFileFormatException("Heyawake Factory: could not find attribute(s)");
}
}
@@ -58,7 +58,7 @@ public HeyawakeCell importCell(Node node, Board board) throws InvalidFileFormatE
/**
* Creates a xml document puzzleElement from a cell for exporting
*
- * @param document xml document
+ * @param document xml document
* @param puzzleElement PuzzleElement cell
* @return xml PuzzleElement
*/
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeImporter.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeImporter.java
index 7527c717f..6bbabd54d 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeImporter.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeImporter.java
@@ -2,12 +2,11 @@
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;
-import java.awt.*;
-
public class HeyawakeImporter extends PuzzleImporter {
public HeyawakeImporter(Heyawake heyawake) {
@@ -27,14 +26,12 @@ public boolean acceptsTextInput() {
/**
* Creates an empty board for building
*
- * @param rows the number of rows on the board
+ * @param rows the number of rows on the board
* @param columns the number of columns on the board
* @throws RuntimeException if board can not be created
*/
@Override
- public void initializeBoard(int rows, int columns) {
-
- }
+ public void initializeBoard(int rows, int columns) {}
/**
* Creates the board for building
@@ -46,11 +43,13 @@ public void initializeBoard(int rows, int columns) {
public void initializeBoard(Node node) throws InvalidFileFormatException {
try {
if (!node.getNodeName().equalsIgnoreCase("board")) {
- throw new InvalidFileFormatException("Heyawake Importer: cannot find board puzzleElement");
+ throw new InvalidFileFormatException(
+ "Heyawake Importer: cannot find board puzzleElement");
}
Element boardElement = (Element) node;
if (boardElement.getElementsByTagName("cells").getLength() == 0) {
- throw new InvalidFileFormatException("Heyawake Importer: no puzzleElement found for board");
+ throw new InvalidFileFormatException(
+ "Heyawake Importer: no puzzleElement found for board");
}
Element dataElement = (Element) boardElement.getElementsByTagName("cells").item(0);
NodeList elementDataList = dataElement.getElementsByTagName("cell");
@@ -59,9 +58,9 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
if (!boardElement.getAttribute("size").isEmpty()) {
int size = Integer.valueOf(boardElement.getAttribute("size"));
heyawakeBoard = new HeyawakeBoard(size);
- }
- else {
- if (!boardElement.getAttribute("width").isEmpty() && !boardElement.getAttribute("height").isEmpty()) {
+ } else {
+ if (!boardElement.getAttribute("width").isEmpty()
+ && !boardElement.getAttribute("height").isEmpty()) {
int width = Integer.valueOf(boardElement.getAttribute("width"));
int height = Integer.valueOf(boardElement.getAttribute("height"));
heyawakeBoard = new HeyawakeBoard(width, height);
@@ -76,7 +75,10 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
int height = heyawakeBoard.getHeight();
for (int i = 0; i < elementDataList.getLength(); i++) {
- HeyawakeCell cell = (HeyawakeCell) puzzle.getFactory().importCell(elementDataList.item(i), heyawakeBoard);
+ HeyawakeCell cell =
+ (HeyawakeCell)
+ puzzle.getFactory()
+ .importCell(elementDataList.item(i), heyawakeBoard);
Point loc = cell.getLocation();
if (cell.getData() != -2) {
cell.setModifiable(false);
@@ -96,9 +98,9 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
}
}
puzzle.setCurrentBoard(heyawakeBoard);
- }
- catch (NumberFormatException e) {
- throw new InvalidFileFormatException("Heyawake Importer: unknown value where integer expected");
+ } catch (NumberFormatException e) {
+ throw new InvalidFileFormatException(
+ "Heyawake Importer: unknown value where integer expected");
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeView.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeView.java
index 00506df0f..fba5f0eb7 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeView.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/HeyawakeView.java
@@ -4,7 +4,6 @@
import edu.rpi.legup.model.gameboard.PuzzleElement;
import edu.rpi.legup.ui.boardview.ElementView;
import edu.rpi.legup.ui.boardview.GridBoardView;
-
import java.awt.*;
import java.awt.geom.Area;
import java.util.HashMap;
@@ -25,14 +24,14 @@ public HeyawakeView(HeyawakeBoard board) {
HeyawakeElementView elementView = new HeyawakeElementView(cell);
elementView.setIndex(cell.getIndex());
elementView.setSize(elementSize);
- elementView.setLocation(new Point(loc.x * elementSize.width, loc.y * elementSize.height));
+ elementView.setLocation(
+ new Point(loc.x * elementSize.width, loc.y * elementSize.height));
elementViews.add(elementView);
int regionIndex = cell.getRegionIndex();
if (regionsBoundaries.get(regionIndex) == null) {
regionsBoundaries.put(regionIndex, new Area(elementView.getBounds()));
- }
- else {
+ } else {
regionsBoundaries.get(regionIndex).add(new Area(elementView.getBounds()));
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/AdjacentBlacksContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/AdjacentBlacksContradictionRule.java
index d2eceb7a1..88d293f5e 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/AdjacentBlacksContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/AdjacentBlacksContradictionRule.java
@@ -7,18 +7,21 @@
public class AdjacentBlacksContradictionRule extends ContradictionRule {
public AdjacentBlacksContradictionRule() {
- super("HEYA-CONT-0001", "Adjacent Blacks",
+ super(
+ "HEYA-CONT-0001",
+ "Adjacent Blacks",
"",
"edu/rpi/legup/images/heyawake/contradictions/adjacentBlacks.png");
}
/**
- * Checks whether the transition has a contradiction at the specific puzzleElement index using this rule
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
*
- * @param board board to check contradiction
+ * @param board board to check contradiction
* @param puzzleElement equivalent puzzleElement
* @return null if the transition contains a contradiction at the specified puzzleElement,
- * otherwise error message
+ * otherwise error message
*/
@Override
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/BlackOrWhiteCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/BlackOrWhiteCaseRule.java
index 0e7552dd2..251be46ee 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/BlackOrWhiteCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/BlackOrWhiteCaseRule.java
@@ -5,21 +5,21 @@
import edu.rpi.legup.model.gameboard.PuzzleElement;
import edu.rpi.legup.model.rules.CaseRule;
import edu.rpi.legup.model.tree.TreeTransition;
-
import java.util.List;
public class BlackOrWhiteCaseRule extends CaseRule {
public BlackOrWhiteCaseRule() {
- super("HEYA-CASE-0001",
+ super(
+ "HEYA-CASE-0001",
"Black or White",
"",
"edu/rpi/legup/images/heyawake/cases/BlackOrWhite.png");
}
/**
- * Checks whether the {@link TreeTransition} logically follows from the parent node using this rule. This method is
- * the one that should overridden in child classes.
+ * Checks whether the {@link TreeTransition} logically follows from the parent node using this
+ * rule. This method is the one that should overridden in child classes.
*
* @param transition transition to check
* @return null if the child node logically follow from the parent node, otherwise error message
@@ -30,13 +30,14 @@ public String checkRuleRaw(TreeTransition transition) {
}
/**
- * Checks whether the child node logically follows from the parent node at the specific puzzleElement index using
- * this rule. This method is the one that should overridden in child classes.
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule. This method is the one that should overridden in child
+ * classes.
*
- * @param transition transition to check
+ * @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
+ * @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) {
@@ -44,7 +45,8 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem
}
/**
- * Gets the case board that indicates where this case rule can be applied on the given {@link Board}.
+ * Gets the case board that indicates where this case rule can be applied on the given {@link
+ * Board}.
*
* @param board board to find locations where this case rule can be applied
* @return a case board
@@ -55,9 +57,10 @@ public CaseBoard getCaseBoard(Board board) {
}
/**
- * Gets the possible cases for this {@link Board} at a specific {@link PuzzleElement} based on this case rule.
+ * Gets the possible cases for this {@link Board} at a specific {@link PuzzleElement} based on
+ * this case rule.
*
- * @param board the current board state
+ * @param board the current board state
* @param puzzleElement equivalent puzzleElement
* @return a list of elements the specified could be
*/
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/BlackPathDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/BlackPathDirectRule.java
index 474bdccdd..1fc3d0776 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/BlackPathDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/BlackPathDirectRule.java
@@ -1,7 +1,7 @@
-package edu.rpi.legup.puzzle.heyawake.rules;
-
-public class BlackPathDirectRule {
- public BlackPathDirectRule() {
- throw new RuntimeException("This rule has not been implemented");
- }
-}
+package edu.rpi.legup.puzzle.heyawake.rules;
+
+public class BlackPathDirectRule {
+ public BlackPathDirectRule() {
+ throw new RuntimeException("This rule has not been implemented");
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/BottleNeckDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/BottleNeckDirectRule.java
index f2e7fef5c..41d950378 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/BottleNeckDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/BottleNeckDirectRule.java
@@ -1,7 +1,7 @@
-package edu.rpi.legup.puzzle.heyawake.rules;
-
-public class BottleNeckDirectRule {
- public BottleNeckDirectRule() {
- throw new RuntimeException("This rule has not been implemented");
- }
-}
+package edu.rpi.legup.puzzle.heyawake.rules;
+
+public class BottleNeckDirectRule {
+ public BottleNeckDirectRule() {
+ throw new RuntimeException("This rule has not been implemented");
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/FillRoomBlackDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/FillRoomBlackDirectRule.java
index 828739160..aee1ae4bf 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/FillRoomBlackDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/FillRoomBlackDirectRule.java
@@ -1,43 +1,45 @@
-package edu.rpi.legup.puzzle.heyawake.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.model.rules.DirectRule;
-import edu.rpi.legup.model.tree.TreeNode;
-import edu.rpi.legup.model.tree.TreeTransition;
-
-public class FillRoomBlackDirectRule extends DirectRule {
-
- public FillRoomBlackDirectRule() {
- super("HEYA-BASC-0003",
- "Fill Room Black",
- "",
- "edu/rpi/legup/images/heyawake/rules/FillRoomBlack.png");
- }
-
- /**
- * Checks whether the child node logically follows from the parent node
- * at the specific puzzleElement index using this rule
- * This method is the one that should overridden in child classes
- *
- * @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
- protected String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
- return null;
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- return null;
- }
-}
+package edu.rpi.legup.puzzle.heyawake.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.DirectRule;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+
+public class FillRoomBlackDirectRule extends DirectRule {
+
+ public FillRoomBlackDirectRule() {
+ super(
+ "HEYA-BASC-0003",
+ "Fill Room Black",
+ "",
+ "edu/rpi/legup/images/heyawake/rules/FillRoomBlack.png");
+ }
+
+ /**
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule This method is the one that should overridden in child
+ * classes
+ *
+ * @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
+ protected String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ return null;
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ return null;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/FillRoomWhiteDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/FillRoomWhiteDirectRule.java
index 6b1a11c29..c4609b239 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/FillRoomWhiteDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/FillRoomWhiteDirectRule.java
@@ -1,43 +1,45 @@
-package edu.rpi.legup.puzzle.heyawake.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.model.rules.DirectRule;
-import edu.rpi.legup.model.tree.TreeNode;
-import edu.rpi.legup.model.tree.TreeTransition;
-
-public class FillRoomWhiteDirectRule extends DirectRule {
-
- public FillRoomWhiteDirectRule() {
- super("HEYA-BASC-0004",
- "Fill Room White",
- "",
- "edu/rpi/legup/images/heyawake/rules/FillRoomWhite.png");
- }
-
- /**
- * Checks whether the child node logically follows from the parent node
- * at the specific puzzleElement index using this rule
- * This method is the one that should overridden in child classes
- *
- * @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
- protected String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
- return null;
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- return null;
- }
-}
+package edu.rpi.legup.puzzle.heyawake.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.DirectRule;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+
+public class FillRoomWhiteDirectRule extends DirectRule {
+
+ public FillRoomWhiteDirectRule() {
+ super(
+ "HEYA-BASC-0004",
+ "Fill Room White",
+ "",
+ "edu/rpi/legup/images/heyawake/rules/FillRoomWhite.png");
+ }
+
+ /**
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule This method is the one that should overridden in child
+ * classes
+ *
+ * @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
+ protected String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ return null;
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ return null;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/OneRowDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/OneRowDirectRule.java
index 3e8c07a4d..8b6f21564 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/OneRowDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/OneRowDirectRule.java
@@ -1,7 +1,7 @@
-package edu.rpi.legup.puzzle.heyawake.rules;
-
-public class OneRowDirectRule {
- public OneRowDirectRule() {
- throw new RuntimeException("This rule has not been implemented");
- }
-}
+package edu.rpi.legup.puzzle.heyawake.rules;
+
+public class OneRowDirectRule {
+ public OneRowDirectRule() {
+ throw new RuntimeException("This rule has not been implemented");
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/PreventWhiteLineDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/PreventWhiteLineDirectRule.java
index 0efd90694..f5d4e78b7 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/PreventWhiteLineDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/PreventWhiteLineDirectRule.java
@@ -1,7 +1,7 @@
-package edu.rpi.legup.puzzle.heyawake.rules;
-
-public class PreventWhiteLineDirectRule {
- public PreventWhiteLineDirectRule() {
- throw new RuntimeException("This rule has not been implemented");
- }
-}
+package edu.rpi.legup.puzzle.heyawake.rules;
+
+public class PreventWhiteLineDirectRule {
+ public PreventWhiteLineDirectRule() {
+ throw new RuntimeException("This rule has not been implemented");
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/RoomTooEmptyContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/RoomTooEmptyContradictionRule.java
index 0e0beaeb2..762b435a2 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/RoomTooEmptyContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/RoomTooEmptyContradictionRule.java
@@ -7,19 +7,21 @@
public class RoomTooEmptyContradictionRule extends ContradictionRule {
public RoomTooEmptyContradictionRule() {
- super("HEYA-CONT-0002",
+ super(
+ "HEYA-CONT-0002",
"Room too Empty",
"",
"edu/rpi/legup/images/heyawake/contradictions/RoomTooEmpty.png");
}
/**
- * Checks whether the transition has a contradiction at the specific puzzleElement index using this rule
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
*
- * @param board board to check contradiction
+ * @param board board to check contradiction
* @param puzzleElement equivalent puzzleElement
* @return null if the transition contains a contradiction at the specified puzzleElement,
- * otherwise error message
+ * otherwise error message
*/
@Override
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/RoomTooFullContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/RoomTooFullContradictionRule.java
index 1de746cb2..643f75f13 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/RoomTooFullContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/RoomTooFullContradictionRule.java
@@ -7,19 +7,21 @@
public class RoomTooFullContradictionRule extends ContradictionRule {
public RoomTooFullContradictionRule() {
- super("HEYA-CONT-0003",
+ super(
+ "HEYA-CONT-0003",
"Room too Full",
"",
"edu/rpi/legup/images/heyawake/contradictions/RoomTooFull.png");
}
/**
- * Checks whether the transition has a contradiction at the specific puzzleElement index using this rule
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
*
- * @param board board to check contradiction
+ * @param board board to check contradiction
* @param puzzleElement equivalent puzzleElement
* @return null if the transition contains a contradiction at the specified puzzleElement,
- * otherwise error message
+ * otherwise error message
*/
@Override
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/ThreeByThreeDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/ThreeByThreeDirectRule.java
index 6dee3fc83..cf2c241e3 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/ThreeByThreeDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/ThreeByThreeDirectRule.java
@@ -1,7 +1,7 @@
-package edu.rpi.legup.puzzle.heyawake.rules;
-
-public class ThreeByThreeDirectRule {
- public ThreeByThreeDirectRule() {
- throw new RuntimeException("This rule has not been implemented");
- }
-}
+package edu.rpi.legup.puzzle.heyawake.rules;
+
+public class ThreeByThreeDirectRule {
+ public ThreeByThreeDirectRule() {
+ throw new RuntimeException("This rule has not been implemented");
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/TwoInCornerDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/TwoInCornerDirectRule.java
index 8e2776fc7..83f1ca72f 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/TwoInCornerDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/TwoInCornerDirectRule.java
@@ -1,7 +1,7 @@
-package edu.rpi.legup.puzzle.heyawake.rules;
-
-public class TwoInCornerDirectRule {
- public TwoInCornerDirectRule() {
- throw new RuntimeException("This rule has not been implemented");
- }
-}
+package edu.rpi.legup.puzzle.heyawake.rules;
+
+public class TwoInCornerDirectRule {
+ public TwoInCornerDirectRule() {
+ throw new RuntimeException("This rule has not been implemented");
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/WhiteAreaContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/WhiteAreaContradictionRule.java
index a287d9c78..c0987d4f9 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/WhiteAreaContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/WhiteAreaContradictionRule.java
@@ -7,19 +7,21 @@
public class WhiteAreaContradictionRule extends ContradictionRule {
public WhiteAreaContradictionRule() {
- super("HEYA-CONT-0004",
+ super(
+ "HEYA-CONT-0004",
"White Area",
"",
"edu/rpi/legup/images/heyawake/contradictions/WhiteArea.png");
}
/**
- * Checks whether the transition has a contradiction at the specific puzzleElement index using this rule
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
*
- * @param board board to check contradiction
+ * @param board board to check contradiction
* @param puzzleElement equivalent puzzleElement
* @return null if the transition contains a contradiction at the specified puzzleElement,
- * otherwise error message
+ * otherwise error message
*/
@Override
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/WhiteAroundBlackDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/WhiteAroundBlackDirectRule.java
index 21a698d41..2e3bc1812 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/WhiteAroundBlackDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/WhiteAroundBlackDirectRule.java
@@ -1,43 +1,45 @@
-package edu.rpi.legup.puzzle.heyawake.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.model.rules.DirectRule;
-import edu.rpi.legup.model.tree.TreeNode;
-import edu.rpi.legup.model.tree.TreeTransition;
-
-public class WhiteAroundBlackDirectRule extends DirectRule {
-
- public WhiteAroundBlackDirectRule() {
- super("HEYA-BASC-0009",
- "White Around Black",
- "",
- "edu/rpi/legup/images/heyawake/rules/WhiteAroundBlack.png");
- }
-
- /**
- * Checks whether the child node logically follows from the parent node
- * at the specific puzzleElement index using this rule
- * This method is the one that should overridden in child classes
- *
- * @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
- protected String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
- return null;
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- return null;
- }
-}
+package edu.rpi.legup.puzzle.heyawake.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+import edu.rpi.legup.model.rules.DirectRule;
+import edu.rpi.legup.model.tree.TreeNode;
+import edu.rpi.legup.model.tree.TreeTransition;
+
+public class WhiteAroundBlackDirectRule extends DirectRule {
+
+ public WhiteAroundBlackDirectRule() {
+ super(
+ "HEYA-BASC-0009",
+ "White Around Black",
+ "",
+ "edu/rpi/legup/images/heyawake/rules/WhiteAroundBlack.png");
+ }
+
+ /**
+ * Checks whether the child node logically follows from the parent node at the specific
+ * puzzleElement index using this rule This method is the one that should overridden in child
+ * classes
+ *
+ * @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
+ protected String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
+ return null;
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ return null;
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/WhiteEscapeDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/WhiteEscapeDirectRule.java
index 231d353e6..f151ec12a 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/WhiteEscapeDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/WhiteEscapeDirectRule.java
@@ -1,7 +1,7 @@
-package edu.rpi.legup.puzzle.heyawake.rules;
-
-public class WhiteEscapeDirectRule {
- public WhiteEscapeDirectRule() {
- throw new RuntimeException("This rule has not been implemented");
- }
-}
+package edu.rpi.legup.puzzle.heyawake.rules;
+
+public class WhiteEscapeDirectRule {
+ public WhiteEscapeDirectRule() {
+ throw new RuntimeException("This rule has not been implemented");
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/WhiteLineContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/WhiteLineContradictionRule.java
index 835bce98c..b695b8206 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/WhiteLineContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/WhiteLineContradictionRule.java
@@ -7,20 +7,21 @@
public class WhiteLineContradictionRule extends ContradictionRule {
public WhiteLineContradictionRule() {
- super("HEYA-CONT-0005",
+ super(
+ "HEYA-CONT-0005",
"White Line",
"",
"edu/rpi/legup/images/heyawake/contradictions/WhiteLine.png");
-
}
/**
- * Checks whether the transition has a contradiction at the specific puzzleElement index using this rule
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
*
- * @param board board to check contradiction
+ * @param board board to check contradiction
* @param puzzleElement equivalent puzzleElement
* @return null if the transition contains a contradiction at the specified puzzleElement,
- * otherwise error message
+ * otherwise error message
*/
@Override
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/ZigZagWhiteDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/ZigZagWhiteDirectRule.java
index 22a76b9a9..9df735b0b 100644
--- a/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/ZigZagWhiteDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/heyawake/rules/ZigZagWhiteDirectRule.java
@@ -1,7 +1,7 @@
-package edu.rpi.legup.puzzle.heyawake.rules;
-
-public class ZigZagWhiteDirectRule {
- public ZigZagWhiteDirectRule() {
- throw new RuntimeException("This rule has not been implemented");
- }
-}
+package edu.rpi.legup.puzzle.heyawake.rules;
+
+public class ZigZagWhiteDirectRule {
+ public ZigZagWhiteDirectRule() {
+ throw new RuntimeException("This rule has not been implemented");
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUp.java b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUp.java
index 6a67d28ca..a73806cd7 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUp.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUp.java
@@ -19,9 +19,7 @@ public LightUp() {
this.factory = new LightUpCellFactory();
}
- /**
- * Initializes the game board. Called by the invoker of the class
- */
+ /** Initializes the game board. Called by the invoker of the class */
@Override
public void initializeView() {
boardView = new LightUpView((LightUpBoard) currentBoard);
@@ -44,12 +42,12 @@ public Board generatePuzzle(int difficulty) {
/**
* Determines if the given dimensions are valid for Light Up
*
- * @param rows the number of rows
- * @param columns the number of columns
+ * @param rows the number of rows
+ * @param columns the number of columns
* @return true if the given dimensions are valid for Light Up, false otherwise
*/
public boolean isValidDimensions(int rows, int columns) {
- return rows > 0 && columns > 0;
+ return rows >= 0 && columns >= 0;
}
/**
@@ -71,7 +69,9 @@ public boolean isBoardComplete(Board board) {
}
for (PuzzleElement data : lightUpBoard.getPuzzleElements()) {
LightUpCell cell = (LightUpCell) data;
- if ((cell.getType() == LightUpCellType.UNKNOWN || cell.getType() == LightUpCellType.EMPTY) && !cell.isLite()) {
+ if ((cell.getType() == LightUpCellType.UNKNOWN
+ || cell.getType() == LightUpCellType.EMPTY)
+ && !cell.isLite()) {
return false;
}
}
@@ -84,7 +84,5 @@ public boolean isBoardComplete(Board board) {
* @param board the board that has changed
*/
@Override
- public void onBoardChange(Board board) {
-
- }
+ public void onBoardChange(Board board) {}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpBoard.java b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpBoard.java
index b15f49919..21084b8c7 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpBoard.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpBoard.java
@@ -2,7 +2,6 @@
import edu.rpi.legup.model.gameboard.GridBoard;
import edu.rpi.legup.model.gameboard.PuzzleElement;
-
import java.awt.*;
import java.util.HashSet;
import java.util.Set;
@@ -17,7 +16,8 @@ public LightUpBoard(int size) {
}
/**
- * Sets cells in board to lite depending on whether there is a bulb cell in the current row or column
+ * Sets cells in board to lite depending on whether there is a bulb cell in the current row or
+ * column
*/
public void fillWithLight() {
for (int y = 0; y < this.dimension.height; y++) {
@@ -33,28 +33,32 @@ public void fillWithLight() {
cell.setLite(true);
for (int i = x + 1; i < this.dimension.width; i++) {
LightUpCell c = getCell(i, y);
- if (c.getType() == LightUpCellType.NUMBER || c.getType() == LightUpCellType.BLACK) {
+ if (c.getType() == LightUpCellType.NUMBER
+ || c.getType() == LightUpCellType.BLACK) {
break;
}
c.setLite(true);
}
for (int i = x - 1; i >= 0; i--) {
LightUpCell c = getCell(i, y);
- if (c.getType() == LightUpCellType.NUMBER || c.getType() == LightUpCellType.BLACK) {
+ if (c.getType() == LightUpCellType.NUMBER
+ || c.getType() == LightUpCellType.BLACK) {
break;
}
c.setLite(true);
}
for (int i = y + 1; i < this.dimension.height; i++) {
LightUpCell c = getCell(x, i);
- if (c.getType() == LightUpCellType.NUMBER || c.getType() == LightUpCellType.BLACK) {
+ if (c.getType() == LightUpCellType.NUMBER
+ || c.getType() == LightUpCellType.BLACK) {
break;
}
c.setLite(true);
}
for (int i = y - 1; i >= 0; i--) {
LightUpCell c = getCell(x, i);
- if (c.getType() == LightUpCellType.NUMBER || c.getType() == LightUpCellType.BLACK) {
+ if (c.getType() == LightUpCellType.NUMBER
+ || c.getType() == LightUpCellType.BLACK) {
break;
}
c.setLite(true);
@@ -130,12 +134,12 @@ public int getNumAdjLite(LightUpCell cell) {
}
/**
- * Gets the number of adjacent cells that are placable
+ * Gets the number of adjacent cells that are placeable
*
* @param cell specified cell
- * @return number of adjacent cells that are placable
+ * @return number of adjacent cells that are placeable
*/
- public int getNumPlacble(LightUpCell cell) {
+ public int getNumPlaceable(LightUpCell cell) {
int num = 0;
Set adjCells = getAdj(cell);
for (LightUpCell c : adjCells) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCell.java b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCell.java
index 36e5a5088..6d890e67b 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCell.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCell.java
@@ -2,7 +2,6 @@
import edu.rpi.legup.model.elements.Element;
import edu.rpi.legup.model.gameboard.GridCell;
-
import java.awt.*;
import java.awt.event.MouseEvent;
@@ -17,30 +16,28 @@ public LightUpCell(int valueInt, Point location) {
@Override
public void setType(Element e, MouseEvent m) {
switch (e.getElementID()) {
- case "LTUP-PLAC-0001":
+ case "LTUP-ELEM-0002":
this.data = -4;
break;
- case "LTUP-UNPL-0002":
+ case "LTUP-ELEM-0001":
this.data = -1;
break;
- case "LTUP-UNPL-0003":
+ case "LTUP-ELEM-0004":
this.data = -2;
break;
- case "LTUP-UNPL-0001":
- switch (m.getButton()){
+ case "LTUP-ELEM-0003":
+ switch (m.getButton()) {
case MouseEvent.BUTTON1:
if (this.data < 0 || this.data > 3) {
this.data = 0;
- }
- else {
+ } else {
this.data = this.data + 1;
}
break;
case MouseEvent.BUTTON3:
if (this.data > 0) {
this.data = this.data - 1;
- }
- else {
+ } else {
this.data = 4;
}
break;
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCellController.java b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCellController.java
index 9c94b24f7..d4049897d 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCellController.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCellController.java
@@ -2,7 +2,6 @@
import edu.rpi.legup.controller.ElementController;
import edu.rpi.legup.model.gameboard.PuzzleElement;
-
import java.awt.event.MouseEvent;
public class LightUpCellController extends ElementController {
@@ -11,32 +10,31 @@ public void changeCell(MouseEvent e, PuzzleElement data) {
LightUpCell cell = (LightUpCell) 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 {
+ this.boardView
+ .getSelectionPopupMenu()
+ .show(
+ boardView,
+ this.boardView.getCanvas().getX() + e.getX(),
+ this.boardView.getCanvas().getY() + e.getY());
+ } else {
if (cell.getData() == -2) {
data.setData(-4);
- }
- else {
+ } else {
if (cell.getData() == -4) {
data.setData(-3);
- }
- else {
+ } else {
data.setData(-2);
}
}
}
- }
- else {
+ } else {
if (e.getButton() == MouseEvent.BUTTON3) {
if (cell.getData() == -4) {
data.setData(-2);
- }
- else {
+ } else {
if (cell.getData() == -2) {
data.setData(-3);
- }
- else {
+ } else {
data.setData(-4);
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCellFactory.java b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCellFactory.java
index 4914facfa..384aa2b74 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCellFactory.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCellFactory.java
@@ -4,17 +4,16 @@
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;
-import java.awt.*;
-
public class LightUpCellFactory extends ElementFactory {
/**
* Creates a puzzleElement based on the xml document Node and adds it to the board
*
- * @param node node that represents the puzzleElement
+ * @param node node that represents the puzzleElement
* @param board board to add the newly created cell
* @return newly created cell from the xml document Node
* @throws InvalidFileFormatException if file is invalid
@@ -23,7 +22,8 @@ public class LightUpCellFactory extends ElementFactory {
public LightUpCell importCell(Node node, Board board) throws InvalidFileFormatException {
try {
if (!node.getNodeName().equalsIgnoreCase("cell")) {
- throw new InvalidFileFormatException("lightup Factory: unknown puzzleElement puzzleElement");
+ throw new InvalidFileFormatException(
+ "lightup Factory: unknown puzzleElement puzzleElement");
}
LightUpBoard lightUpBoard = (LightUpBoard) board;
@@ -35,7 +35,8 @@ public LightUpCell importCell(Node node, Board board) throws InvalidFileFormatEx
int x = Integer.valueOf(attributeList.getNamedItem("x").getNodeValue());
int y = Integer.valueOf(attributeList.getNamedItem("y").getNodeValue());
if (x >= width || y >= height) {
- throw new InvalidFileFormatException("lightup Factory: cell location out of bounds");
+ throw new InvalidFileFormatException(
+ "lightup Factory: cell location out of bounds");
}
if (value < -4 || value > 4) {
throw new InvalidFileFormatException("lightup Factory: cell unknown value");
@@ -44,11 +45,10 @@ public LightUpCell importCell(Node node, Board board) throws InvalidFileFormatEx
LightUpCell cell = new LightUpCell(value, new Point(x, y));
cell.setIndex(y * height + x);
return cell;
- }
- catch (NumberFormatException e) {
- throw new InvalidFileFormatException("lightup Factory: unknown value where integer expected");
- }
- catch (NullPointerException e) {
+ } catch (NumberFormatException e) {
+ throw new InvalidFileFormatException(
+ "lightup Factory: unknown value where integer expected");
+ } catch (NullPointerException e) {
throw new InvalidFileFormatException("lightup Factory: could not find attribute(s)");
}
}
@@ -56,7 +56,7 @@ public LightUpCell importCell(Node node, Board board) throws InvalidFileFormatEx
/**
* Creates a xml document puzzleElement from a cell for exporting
*
- * @param document xml document
+ * @param document xml document
* @param puzzleElement PuzzleElement cell
* @return xml PuzzleElement
*/
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCellType.java b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCellType.java
index b0825910d..8472be7a6 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCellType.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpCellType.java
@@ -1,7 +1,11 @@
package edu.rpi.legup.puzzle.lightup;
public enum LightUpCellType {
- BULB(-4), EMPTY(-3), UNKNOWN(-2), BLACK(-1), NUMBER(0);
+ BULB(-4),
+ EMPTY(-3),
+ UNKNOWN(-2),
+ BLACK(-1),
+ NUMBER(0);
public int value;
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpElementView.java b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpElementView.java
index 7f35d46a6..1b00b007d 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpElementView.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpElementView.java
@@ -1,7 +1,6 @@
package edu.rpi.legup.puzzle.lightup;
import edu.rpi.legup.ui.boardview.GridElementView;
-
import java.awt.*;
public class LightUpElementView extends GridElementView {
@@ -40,37 +39,45 @@ public void drawElement(Graphics2D graphics2D) {
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();
+ int yText =
+ location.y + ((size.height - metrics.getHeight()) / 2) + metrics.getAscent();
graphics2D.drawString(String.valueOf(puzzleElement.getData()), xText, yText);
- }
- else {
+ } else {
if (type == LightUpCellType.BLACK) {
graphics2D.setStroke(new BasicStroke(1));
graphics2D.setColor(BLACK_COLOR);
graphics2D.fillRect(location.x, location.y, size.width, size.height);
- }
- else {
+ } else {
if (type == LightUpCellType.EMPTY) {
graphics2D.setStroke(new BasicStroke(1));
graphics2D.setColor(cell.isLite() ? LITE : WHITE_COLOR);
graphics2D.fillRect(location.x, location.y, size.width, size.height);
graphics2D.setColor(BLACK_COLOR);
- graphics2D.fillRect(location.x + size.width * 7 / 16, location.y + size.height * 7 / 16, size.width / 8, size.height / 8);
+ graphics2D.fillRect(
+ location.x + size.width * 7 / 16,
+ location.y + size.height * 7 / 16,
+ size.width / 8,
+ size.height / 8);
graphics2D.drawRect(location.x, location.y, size.width, size.height);
- }
- else {
+ } else {
if (type == LightUpCellType.UNKNOWN) {
graphics2D.setStroke(new BasicStroke(1));
graphics2D.setColor(cell.isLite() ? LITE : 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);
- }
- else {
+ } else {
if (type == LightUpCellType.BULB) {
graphics2D.setColor(Color.LIGHT_GRAY);
graphics2D.fillRect(location.x, location.y, size.width, size.height);
- graphics2D.drawImage(LightUpView.lightImage, location.x, location.y, size.width, size.height, LITE, null);
+ graphics2D.drawImage(
+ LightUpView.lightImage,
+ location.x,
+ location.y,
+ size.width,
+ size.height,
+ LITE,
+ null);
graphics2D.setColor(BLACK_COLOR);
graphics2D.drawRect(location.x, location.y, size.width, size.height);
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpExporter.java b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpExporter.java
index 89024ad6c..0e8987020 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpExporter.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpExporter.java
@@ -2,7 +2,6 @@
import edu.rpi.legup.model.PuzzleExporter;
import edu.rpi.legup.model.gameboard.PuzzleElement;
-import edu.rpi.legup.puzzle.shorttruthtable.ShortTruthTableBoard;
import org.w3c.dom.Document;
public class LightUpExporter extends PuzzleExporter {
@@ -16,8 +15,7 @@ protected org.w3c.dom.Element createBoardElement(Document newDocument) {
LightUpBoard board;
if (puzzle.getTree() != null) {
board = (LightUpBoard) puzzle.getTree().getRootNode().getBoard();
- }
- else {
+ } else {
board = (LightUpBoard) puzzle.getBoardView().getBoard();
}
@@ -29,7 +27,8 @@ protected org.w3c.dom.Element createBoardElement(Document newDocument) {
for (PuzzleElement puzzleElement : board.getPuzzleElements()) {
LightUpCell cell = (LightUpCell) puzzleElement;
if (cell.getData() != -2) {
- org.w3c.dom.Element cellElement = puzzle.getFactory().exportCell(newDocument, puzzleElement);
+ org.w3c.dom.Element cellElement =
+ puzzle.getFactory().exportCell(newDocument, puzzleElement);
cellsElement.appendChild(cellElement);
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpImporter.java b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpImporter.java
index 7ef24ca69..336b063f6 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpImporter.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpImporter.java
@@ -2,12 +2,11 @@
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;
-import java.awt.*;
-
public class LightUpImporter extends PuzzleImporter {
public LightUpImporter(LightUp lightUp) {
super(lightUp);
@@ -26,7 +25,7 @@ public boolean acceptsTextInput() {
/**
* Creates an empty board for building
*
- * @param rows the number of rows on the board
+ * @param rows the number of rows on the board
* @param columns the number of columns on the board
* @throws RuntimeException if board can not be created
*/
@@ -57,11 +56,13 @@ public void initializeBoard(int rows, int columns) {
public void initializeBoard(Node node) throws InvalidFileFormatException {
try {
if (!node.getNodeName().equalsIgnoreCase("board")) {
- throw new InvalidFileFormatException("lightup Importer: cannot find board puzzleElement");
+ throw new InvalidFileFormatException(
+ "lightup Importer: cannot find board puzzleElement");
}
Element boardElement = (Element) node;
if (boardElement.getElementsByTagName("cells").getLength() == 0) {
- throw new InvalidFileFormatException("lightup Importer: no puzzleElement found for board");
+ throw new InvalidFileFormatException(
+ "lightup Importer: no puzzleElement found for board");
}
Element dataElement = (Element) boardElement.getElementsByTagName("cells").item(0);
NodeList elementDataList = dataElement.getElementsByTagName("cell");
@@ -70,9 +71,9 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
if (!boardElement.getAttribute("size").isEmpty()) {
int size = Integer.valueOf(boardElement.getAttribute("size"));
lightUpBoard = new LightUpBoard(size);
- }
- else {
- if (!boardElement.getAttribute("width").isEmpty() && !boardElement.getAttribute("height").isEmpty()) {
+ } else {
+ if (!boardElement.getAttribute("width").isEmpty()
+ && !boardElement.getAttribute("height").isEmpty()) {
int width = Integer.valueOf(boardElement.getAttribute("width"));
int height = Integer.valueOf(boardElement.getAttribute("height"));
lightUpBoard = new LightUpBoard(width, height);
@@ -87,7 +88,10 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
int height = lightUpBoard.getHeight();
for (int i = 0; i < elementDataList.getLength(); i++) {
- LightUpCell cell = (LightUpCell) puzzle.getFactory().importCell(elementDataList.item(i), lightUpBoard);
+ LightUpCell cell =
+ (LightUpCell)
+ puzzle.getFactory()
+ .importCell(elementDataList.item(i), lightUpBoard);
Point loc = cell.getLocation();
if (cell.getData() != -2) {
cell.setModifiable(false);
@@ -107,9 +111,9 @@ public void initializeBoard(Node node) throws InvalidFileFormatException {
}
}
puzzle.setCurrentBoard(lightUpBoard);
- }
- catch (NumberFormatException e) {
- throw new InvalidFileFormatException("lightup Importer: unknown value where integer expected");
+ } catch (NumberFormatException e) {
+ throw new InvalidFileFormatException(
+ "lightup Importer: unknown value where integer expected");
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpView.java b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpView.java
index 0fd57e705..ebce6a682 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpView.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/LightUpView.java
@@ -7,23 +7,24 @@
import edu.rpi.legup.ui.boardview.DataSelectionView;
import edu.rpi.legup.ui.boardview.GridBoardView;
import edu.rpi.legup.ui.boardview.SelectionItemView;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import javax.imageio.ImageIO;
-import javax.swing.*;
import java.awt.*;
import java.io.IOException;
+import javax.imageio.ImageIO;
+import javax.swing.*;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
public class LightUpView extends GridBoardView {
- private final static Logger LOGGER = LogManager.getLogger(LightUpView.class.getName());
+ private static final Logger LOGGER = LogManager.getLogger(LightUpView.class.getName());
static Image lightImage;
static {
try {
- lightImage = ImageIO.read(ClassLoader.getSystemClassLoader().getResource("edu/rpi/legup/images/lightup/light.png"));
- }
- catch (IOException e) {
+ lightImage =
+ ImageIO.read(
+ ClassLoader.getSystemClassLoader()
+ .getResource("edu/rpi/legup/images/lightup/light.png"));
+ } catch (IOException e) {
LOGGER.error("Failed to open TreeTent images");
}
}
@@ -37,7 +38,8 @@ public LightUpView(LightUpBoard board) {
LightUpElementView elementView = new LightUpElementView(cell);
elementView.setIndex(cell.getIndex());
elementView.setSize(elementSize);
- elementView.setLocation(new Point(loc.x * elementSize.width, loc.y * elementSize.height));
+ elementView.setLocation(
+ new Point(loc.x * elementSize.width, loc.y * elementSize.height));
elementViews.add(elementView);
}
}
@@ -50,14 +52,15 @@ public LightUpView(LightUpBoard board) {
@Override
public void onTreeElementChanged(TreeElement treeElement) {
super.onTreeElementChanged(treeElement);
- LightUpBoard lightUpBoard = board instanceof CaseBoard ? (LightUpBoard) ((CaseBoard) board).getBaseBoard() : (LightUpBoard) board;
+ LightUpBoard lightUpBoard =
+ board instanceof CaseBoard
+ ? (LightUpBoard) ((CaseBoard) board).getBaseBoard()
+ : (LightUpBoard) board;
lightUpBoard.fillWithLight();
repaint();
}
- /**
- * Returns a DataSelectionView popup menu
- */
+ /** Returns a DataSelectionView popup menu */
public DataSelectionView getSelectionPopupMenu() {
DataSelectionView selectionView = new DataSelectionView(elementController);
GridLayout layout = new GridLayout(3, 1);
@@ -69,7 +72,9 @@ public DataSelectionView getSelectionPopupMenu() {
LightUpElementView element1 = new LightUpElementView(new LightUpCell(-2, null));
element1.setSize(iconSize);
element1.setLocation(loc);
- SelectionItemView item1 = new SelectionItemView(element1.getPuzzleElement(), new ImageIcon(element1.getImage()));
+ SelectionItemView item1 =
+ new SelectionItemView(
+ element1.getPuzzleElement(), new ImageIcon(element1.getImage()));
item1.addActionListener(elementController);
item1.setHorizontalTextPosition(SwingConstants.CENTER);
selectionView.add(item1);
@@ -77,7 +82,9 @@ public DataSelectionView getSelectionPopupMenu() {
LightUpElementView element2 = new LightUpElementView(new LightUpCell(-4, null));
element2.setSize(iconSize);
element2.setLocation(loc);
- SelectionItemView item2 = new SelectionItemView(element2.getPuzzleElement(), new ImageIcon(element2.getImage()));
+ SelectionItemView item2 =
+ new SelectionItemView(
+ element2.getPuzzleElement(), new ImageIcon(element2.getImage()));
item2.addActionListener(elementController);
item2.setHorizontalTextPosition(SwingConstants.CENTER);
selectionView.add(item2);
@@ -85,7 +92,9 @@ public DataSelectionView getSelectionPopupMenu() {
LightUpElementView element3 = new LightUpElementView(new LightUpCell(-3, null));
element3.setSize(iconSize);
element3.setLocation(loc);
- SelectionItemView item3 = new SelectionItemView(element3.getPuzzleElement(), new ImageIcon(element3.getImage()));
+ SelectionItemView item3 =
+ new SelectionItemView(
+ element3.getPuzzleElement(), new ImageIcon(element3.getImage()));
item3.addActionListener(elementController);
item3.setHorizontalTextPosition(SwingConstants.CENTER);
selectionView.add(item3);
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/BlackTile.java b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/BlackTile.java
index d3e8cf506..eed3795d7 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/BlackTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/BlackTile.java
@@ -1,9 +1,13 @@
package edu.rpi.legup.puzzle.lightup.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class BlackTile extends NonPlaceableElement {
+public class BlackTile extends PlaceableElement {
public BlackTile() {
- super("LTUP-UNPL-0002", "Black Tile", "The black tile", "edu/rpi/legup/images/lightup/black.gif");
+ super(
+ "LTUP-ELEM-0001",
+ "Black Tile",
+ "The black tile",
+ "edu/rpi/legup/images/lightup/black.gif");
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/BulbTile.java b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/BulbTile.java
index 5fc4a334f..61ebac3d0 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/BulbTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/BulbTile.java
@@ -4,6 +4,10 @@
public class BulbTile extends PlaceableElement {
public BulbTile() {
- super("LTUP-PLAC-0001", "Bulb Tile", "The bulb tile", "edu/rpi/legup/images/lightup/light.png");
+ super(
+ "LTUP-ELEM-0002",
+ "Bulb Tile",
+ "The bulb tile",
+ "edu/rpi/legup/images/lightup/light.png");
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/NumberTile.java b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/NumberTile.java
index e96a969e5..26f9be46c 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/NumberTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/NumberTile.java
@@ -1,18 +1,26 @@
package edu.rpi.legup.puzzle.lightup.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class NumberTile extends NonPlaceableElement {
+public class NumberTile extends PlaceableElement {
int object_number;
// Follow the default format and resolves the NoSuchMethod error
public NumberTile() {
- super("LTUP-UNPL-0001", "Number Tile", "The number tile", "edu/rpi/legup/images/lightup/1.gif");
+ super(
+ "LTUP-ELEM-0003",
+ "Number Tile",
+ "The number tile",
+ "edu/rpi/legup/images/lightup/1.gif");
}
public NumberTile(int num) {
- super("LTUP-UNPL-0001", "Number Tile", "The number tile", "edu/rpi/legup/images/lightup/" + num + ".gif");
+ super(
+ "LTUP-ELEM-0003",
+ "Number Tile",
+ "The number tile",
+ "edu/rpi/legup/images/lightup/" + num + ".gif");
if (num > 3 || num < 1) num = 1;
object_number = num;
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/UnknownTile.java b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/UnknownTile.java
index 6839e70de..a724be600 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/UnknownTile.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/UnknownTile.java
@@ -1,9 +1,13 @@
package edu.rpi.legup.puzzle.lightup.elements;
-import edu.rpi.legup.model.elements.NonPlaceableElement;
+import edu.rpi.legup.model.elements.PlaceableElement;
-public class UnknownTile extends NonPlaceableElement {
+public class UnknownTile extends PlaceableElement {
public UnknownTile() {
- super("LTUP-UNPL-0003", "Unknown Tile", "A blank tile", "edu/rpi/legup/images/lightup/UnknownTile.png");
+ super(
+ "LTUP-ELEM-0004",
+ "Unknown Tile",
+ "A blank tile",
+ "edu/rpi/legup/images/lightup/UnknownTile.png");
}
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/elements/lightup_elements_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/lightup_elements_reference_sheet.txt
new file mode 100644
index 000000000..93c97de1c
--- /dev/null
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/elements/lightup_elements_reference_sheet.txt
@@ -0,0 +1,4 @@
+LTUP-ELEM-0001 : BlackTile
+LTUP-ELEM-0002 : BulbTile
+LTUP-ELEM-0003 : NumberTile
+LTUP-ELEM-0004 : UnknownTile
\ No newline at end of file
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/BulbsInPathContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/BulbsInPathContradictionRule.java
index 2804e6eab..90652888c 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/BulbsInPathContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/BulbsInPathContradictionRule.java
@@ -6,24 +6,26 @@
import edu.rpi.legup.puzzle.lightup.LightUpBoard;
import edu.rpi.legup.puzzle.lightup.LightUpCell;
import edu.rpi.legup.puzzle.lightup.LightUpCellType;
-
import java.awt.*;
public class BulbsInPathContradictionRule extends ContradictionRule {
public BulbsInPathContradictionRule() {
- super("LTUP-CONT-0001", "Bulbs In Path",
+ super(
+ "LTUP-CONT-0001",
+ "Bulbs In Path",
"A bulb cannot be placed in another bulb's path.",
"edu/rpi/legup/images/lightup/contradictions/BulbsInPath.png");
}
/**
- * Checks whether the transition has a contradiction at the specific puzzleElement index using this rule
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
*
- * @param board board to check contradiction
+ * @param board board to check contradiction
* @param puzzleElement equivalent puzzleElement
* @return null if the transition contains a contradiction at the specified puzzleElement,
- * otherwise error message
+ * otherwise error message
*/
@Override
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
@@ -38,8 +40,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
LightUpCell c = lightUpBoard.getCell(i, location.y);
if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
break;
- }
- else {
+ } else {
if (c.getType() == LightUpCellType.BULB) {
return null;
}
@@ -49,8 +50,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
LightUpCell c = lightUpBoard.getCell(i, location.y);
if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
break;
- }
- else {
+ } else {
if (c.getType() == LightUpCellType.BULB) {
return null;
}
@@ -60,8 +60,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
LightUpCell c = lightUpBoard.getCell(location.x, i);
if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
break;
- }
- else {
+ } else {
if (c.getType() == LightUpCellType.BULB) {
return null;
}
@@ -71,8 +70,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
LightUpCell c = lightUpBoard.getCell(location.x, i);
if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
break;
- }
- else {
+ } else {
if (c.getType() == LightUpCellType.BULB) {
return null;
}
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/CannotLightACellContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/CannotLightACellContradictionRule.java
index 011bf1c0a..0ed88636c 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/CannotLightACellContradictionRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/CannotLightACellContradictionRule.java
@@ -6,24 +6,26 @@
import edu.rpi.legup.puzzle.lightup.LightUpBoard;
import edu.rpi.legup.puzzle.lightup.LightUpCell;
import edu.rpi.legup.puzzle.lightup.LightUpCellType;
-
import java.awt.*;
public class CannotLightACellContradictionRule extends ContradictionRule {
public CannotLightACellContradictionRule() {
- super("LTUP-CONT-0002", "Cannot Light A Cell",
+ super(
+ "LTUP-CONT-0002",
+ "Cannot Light A Cell",
"All cells must be able to be lit.",
"edu/rpi/legup/images/lightup/contradictions/CannotLightACell.png");
}
/**
- * Checks whether the transition has a contradiction at the specific puzzleElement index using this rule
+ * Checks whether the transition has a contradiction at the specific puzzleElement index using
+ * this rule
*
- * @param board board to check contradiction
+ * @param board board to check contradiction
* @param puzzleElement equivalent puzzleElement
* @return null if the transition contains a contradiction at the specified puzzleElement,
- * otherwise error message
+ * otherwise error message
*/
@Override
public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
@@ -42,8 +44,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
LightUpCell c = lightUpBoard.getCell(i, location.y);
if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
break;
- }
- else {
+ } else {
if (c.getType() == LightUpCellType.UNKNOWN && !c.isLite()) {
hor_count += 1;
}
@@ -53,8 +54,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
LightUpCell c = lightUpBoard.getCell(i, location.y);
if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
break;
- }
- else {
+ } else {
if (c.getType() == LightUpCellType.UNKNOWN && !c.isLite()) {
hor_count += 1;
}
@@ -64,8 +64,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
LightUpCell c = lightUpBoard.getCell(location.x, i);
if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
break;
- }
- else {
+ } else {
if (c.getType() == LightUpCellType.UNKNOWN && !c.isLite()) {
ver_count += 1;
}
@@ -75,8 +74,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
LightUpCell c = lightUpBoard.getCell(location.x, i);
if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
break;
- }
- else {
+ } else {
if (c.getType() == LightUpCellType.UNKNOWN && !c.isLite()) {
ver_count += 1;
}
@@ -88,4 +86,4 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
}
return super.getNoContradictionMessage();
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/EmptyCellinLightDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/EmptyCellinLightDirectRule.java
index a40ede284..269ef0ad5 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/EmptyCellinLightDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/EmptyCellinLightDirectRule.java
@@ -1,64 +1,68 @@
-package edu.rpi.legup.puzzle.lightup.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-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.lightup.LightUpBoard;
-import edu.rpi.legup.puzzle.lightup.LightUpCell;
-import edu.rpi.legup.puzzle.lightup.LightUpCellType;
-
-public class EmptyCellinLightDirectRule extends DirectRule {
-
- public EmptyCellinLightDirectRule() {
- super("LTUP-BASC-0002", "Empty Cells in Light",
- "Cells in light must be empty.",
- "edu/rpi/legup/images/lightup/rules/EmptyCellInLight.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 index of the 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) {
- LightUpBoard initialBoard = (LightUpBoard) transition.getParents().get(0).getBoard();
- initialBoard.fillWithLight();
- LightUpCell initCell = (LightUpCell) initialBoard.getPuzzleElement(puzzleElement);
- LightUpCell finalCell = (LightUpCell) transition.getBoard().getPuzzleElement(puzzleElement);
- if (finalCell.getType() == LightUpCellType.EMPTY && initCell.getType() == LightUpCellType.UNKNOWN && initCell.isLite()) {
- return null;
- }
- return super.getInvalidUseOfRuleMessage() + ": Cell is not forced to be empty";
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- LightUpBoard lightUpBoard = (LightUpBoard) node.getBoard().copy();
- for (PuzzleElement element : lightUpBoard.getPuzzleElements()) {
- LightUpCell cell = (LightUpCell) element;
- if (cell.getType() == LightUpCellType.UNKNOWN && cell.isLite()) {
- cell.setData(LightUpCellType.EMPTY.value);
- lightUpBoard.addModifiedData(cell);
- }
- }
- if (lightUpBoard.getModifiedData().isEmpty()) {
- return null;
- }
- else {
- return lightUpBoard;
- }
- }
-}
+package edu.rpi.legup.puzzle.lightup.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+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.lightup.LightUpBoard;
+import edu.rpi.legup.puzzle.lightup.LightUpCell;
+import edu.rpi.legup.puzzle.lightup.LightUpCellType;
+
+public class EmptyCellinLightDirectRule extends DirectRule {
+
+ public EmptyCellinLightDirectRule() {
+ super(
+ "LTUP-BASC-0002",
+ "Empty Cells in Light",
+ "Cells in light must be empty.",
+ "edu/rpi/legup/images/lightup/rules/EmptyCellInLight.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 index of the 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) {
+ LightUpBoard initialBoard = (LightUpBoard) transition.getParents().get(0).getBoard();
+ initialBoard.fillWithLight();
+ LightUpCell initCell = (LightUpCell) initialBoard.getPuzzleElement(puzzleElement);
+ LightUpCell finalCell = (LightUpCell) transition.getBoard().getPuzzleElement(puzzleElement);
+ if (finalCell.getType() == LightUpCellType.EMPTY
+ && initCell.getType() == LightUpCellType.UNKNOWN
+ && initCell.isLite()) {
+ return null;
+ }
+ return super.getInvalidUseOfRuleMessage() + ": Cell is not forced to be empty";
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ LightUpBoard lightUpBoard = (LightUpBoard) node.getBoard().copy();
+ for (PuzzleElement element : lightUpBoard.getPuzzleElements()) {
+ LightUpCell cell = (LightUpCell) element;
+ if (cell.getType() == LightUpCellType.UNKNOWN && cell.isLite()) {
+ cell.setData(LightUpCellType.EMPTY.value);
+ lightUpBoard.addModifiedData(cell);
+ }
+ }
+ if (lightUpBoard.getModifiedData().isEmpty()) {
+ return null;
+ } else {
+ return lightUpBoard;
+ }
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/EmptyCornersDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/EmptyCornersDirectRule.java
index 04c493f08..702c116c1 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/EmptyCornersDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/EmptyCornersDirectRule.java
@@ -1,115 +1,117 @@
-package edu.rpi.legup.puzzle.lightup.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-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.lightup.LightUpBoard;
-import edu.rpi.legup.puzzle.lightup.LightUpCell;
-import edu.rpi.legup.puzzle.lightup.LightUpCellType;
-
-import java.awt.*;
-import java.util.ArrayList;
-import java.util.List;
-
-public class EmptyCornersDirectRule extends DirectRule {
-
- public EmptyCornersDirectRule() {
- super("LTUP-BASC-0003", "Empty Corners",
- "Cells on the corners of a number must be empty if placing bulbs would prevent the number from being satisfied.",
- "edu/rpi/legup/images/lightup/rules/EmptyCorners.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 index of the 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) {
- LightUpBoard initialBoard = (LightUpBoard) transition.getParents().get(0).getBoard();
- LightUpCell cell = (LightUpCell) initialBoard.getPuzzleElement(puzzleElement);
- LightUpBoard finalBoard = (LightUpBoard) transition.getBoard();
- LightUpCell finalCell = (LightUpCell) finalBoard.getPuzzleElement(puzzleElement);
-
- if (!(cell.getType() == LightUpCellType.UNKNOWN && finalCell.getType() == LightUpCellType.EMPTY)) {
- return super.getInvalidUseOfRuleMessage() + ": This cell must be an empty cell";
- }
-
- Point loc = finalCell.getLocation();
- List numberedCells = new ArrayList<>();
- LightUpCell upperRight = finalBoard.getCell(loc.x + 1, loc.y - 1);
- if (upperRight != null && upperRight.getType() == LightUpCellType.NUMBER) {
- numberedCells.add(upperRight);
- }
- LightUpCell upperLeft = finalBoard.getCell(loc.x - 1, loc.y - 1);
- if (upperLeft != null && upperLeft.getType() == LightUpCellType.NUMBER) {
- numberedCells.add(upperLeft);
- }
- LightUpCell lowerRight = finalBoard.getCell(loc.x + 1, loc.y + 1);
- if (lowerRight != null && lowerRight.getType() == LightUpCellType.NUMBER) {
- numberedCells.add(lowerRight);
- }
- LightUpCell lowerLeft = finalBoard.getCell(loc.x - 1, loc.y + 1);
- if (lowerLeft != null && lowerLeft.getType() == LightUpCellType.NUMBER) {
- numberedCells.add(lowerLeft);
- }
- if (numberedCells.isEmpty()) {
- return super.getInvalidUseOfRuleMessage() + ": This cell must diagonal to a numbered cell";
- }
-
- TooFewBulbsContradictionRule tooFew = new TooFewBulbsContradictionRule();
- LightUpBoard bulbCaseBoard = finalBoard.copy();
- LightUpCell bulbCaseCell = (LightUpCell) bulbCaseBoard.getPuzzleElement(puzzleElement);
- bulbCaseCell.setData(LightUpCellType.BULB.value);
- bulbCaseBoard.fillWithLight();
-
- boolean createsContra = false;
- for (LightUpCell c : numberedCells) {
- createsContra |= tooFew.checkContradictionAt(bulbCaseBoard, c) == null;
- }
- if (createsContra) {
- return null;
- }
- else {
- return super.getInvalidUseOfRuleMessage() + ": This cell is not forced to be empty";
- }
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- LightUpBoard lightUpBoard = (LightUpBoard) node.getBoard().copy();
- LightUpBoard lightUpBoardCopy = (LightUpBoard) node.getBoard().copy();
- TreeTransition transition = new TreeTransition(node, lightUpBoardCopy);
- for (PuzzleElement element : lightUpBoardCopy.getPuzzleElements()) {
- LightUpCell cell = (LightUpCell) element;
- int temp = cell.getData();
- cell.setData(LightUpCellType.EMPTY.value);
- if (checkRuleRawAt(transition, cell) == null) {
- LightUpCell modCell = (LightUpCell) lightUpBoard.getPuzzleElement(cell);
- modCell.setData(LightUpCellType.EMPTY.value);
- lightUpBoard.addModifiedData(modCell);
- }
- else {
- cell.setData(temp);
- }
- }
- if (lightUpBoard.getModifiedData().isEmpty()) {
- return null;
- }
- else {
- return lightUpBoard;
- }
- }
-}
+package edu.rpi.legup.puzzle.lightup.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+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.lightup.LightUpBoard;
+import edu.rpi.legup.puzzle.lightup.LightUpCell;
+import edu.rpi.legup.puzzle.lightup.LightUpCellType;
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
+
+public class EmptyCornersDirectRule extends DirectRule {
+
+ public EmptyCornersDirectRule() {
+ super(
+ "LTUP-BASC-0003",
+ "Empty Corners",
+ "Cells on the corners of a number must be empty if placing bulbs would prevent the"
+ + " number from being satisfied.",
+ "edu/rpi/legup/images/lightup/rules/EmptyCorners.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 index of the 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) {
+ LightUpBoard initialBoard = (LightUpBoard) transition.getParents().get(0).getBoard();
+ LightUpCell cell = (LightUpCell) initialBoard.getPuzzleElement(puzzleElement);
+ LightUpBoard finalBoard = (LightUpBoard) transition.getBoard();
+ LightUpCell finalCell = (LightUpCell) finalBoard.getPuzzleElement(puzzleElement);
+
+ if (!(cell.getType() == LightUpCellType.UNKNOWN
+ && finalCell.getType() == LightUpCellType.EMPTY)) {
+ return super.getInvalidUseOfRuleMessage() + ": This cell must be an empty cell";
+ }
+
+ Point loc = finalCell.getLocation();
+ List numberedCells = new ArrayList<>();
+ LightUpCell upperRight = finalBoard.getCell(loc.x + 1, loc.y - 1);
+ if (upperRight != null && upperRight.getType() == LightUpCellType.NUMBER) {
+ numberedCells.add(upperRight);
+ }
+ LightUpCell upperLeft = finalBoard.getCell(loc.x - 1, loc.y - 1);
+ if (upperLeft != null && upperLeft.getType() == LightUpCellType.NUMBER) {
+ numberedCells.add(upperLeft);
+ }
+ LightUpCell lowerRight = finalBoard.getCell(loc.x + 1, loc.y + 1);
+ if (lowerRight != null && lowerRight.getType() == LightUpCellType.NUMBER) {
+ numberedCells.add(lowerRight);
+ }
+ LightUpCell lowerLeft = finalBoard.getCell(loc.x - 1, loc.y + 1);
+ if (lowerLeft != null && lowerLeft.getType() == LightUpCellType.NUMBER) {
+ numberedCells.add(lowerLeft);
+ }
+ if (numberedCells.isEmpty()) {
+ return super.getInvalidUseOfRuleMessage()
+ + ": This cell must diagonal to a numbered cell";
+ }
+
+ TooFewBulbsContradictionRule tooFew = new TooFewBulbsContradictionRule();
+ LightUpBoard bulbCaseBoard = finalBoard.copy();
+ LightUpCell bulbCaseCell = (LightUpCell) bulbCaseBoard.getPuzzleElement(puzzleElement);
+ bulbCaseCell.setData(LightUpCellType.BULB.value);
+ bulbCaseBoard.fillWithLight();
+
+ boolean createsContra = false;
+ for (LightUpCell c : numberedCells) {
+ createsContra |= tooFew.checkContradictionAt(bulbCaseBoard, c) == null;
+ }
+ if (createsContra) {
+ return null;
+ } else {
+ return super.getInvalidUseOfRuleMessage() + ": This cell is not forced to be empty";
+ }
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ LightUpBoard lightUpBoard = (LightUpBoard) node.getBoard().copy();
+ LightUpBoard lightUpBoardCopy = (LightUpBoard) node.getBoard().copy();
+ TreeTransition transition = new TreeTransition(node, lightUpBoardCopy);
+ for (PuzzleElement element : lightUpBoardCopy.getPuzzleElements()) {
+ LightUpCell cell = (LightUpCell) element;
+ int temp = cell.getData();
+ cell.setData(LightUpCellType.EMPTY.value);
+ if (checkRuleRawAt(transition, cell) == null) {
+ LightUpCell modCell = (LightUpCell) lightUpBoard.getPuzzleElement(cell);
+ modCell.setData(LightUpCellType.EMPTY.value);
+ lightUpBoard.addModifiedData(modCell);
+ } else {
+ cell.setData(temp);
+ }
+ }
+ if (lightUpBoard.getModifiedData().isEmpty()) {
+ return null;
+ } else {
+ return lightUpBoard;
+ }
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/FinishWithBulbsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/FinishWithBulbsDirectRule.java
index cdea7880f..3f884d459 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/FinishWithBulbsDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/FinishWithBulbsDirectRule.java
@@ -1,107 +1,110 @@
-package edu.rpi.legup.puzzle.lightup.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-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.lightup.LightUpBoard;
-import edu.rpi.legup.puzzle.lightup.LightUpCell;
-import edu.rpi.legup.puzzle.lightup.LightUpCellType;
-
-import java.util.Set;
-
-public class FinishWithBulbsDirectRule extends DirectRule {
-
- public FinishWithBulbsDirectRule() {
- super("LTUP-BASC-0004", "Finish with Bulbs",
- "The remaining unknowns around a block must be bulbs to satisfy the number.",
- "edu/rpi/legup/images/lightup/rules/FinishWithBulbs.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 index of the 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) {
- LightUpBoard initialBoard = (LightUpBoard) transition.getParents().get(0).getBoard();
- LightUpCell initCell = (LightUpCell) initialBoard.getPuzzleElement(puzzleElement);
- LightUpBoard finalBoard = (LightUpBoard) transition.getBoard();
- LightUpCell finalCell = (LightUpCell) finalBoard.getPuzzleElement(puzzleElement);
- if (!(initCell.getType() == LightUpCellType.UNKNOWN && finalCell.getType() == LightUpCellType.BULB)) {
- return super.getInvalidUseOfRuleMessage() + ": Modified cells must be bulbs";
- }
-
- Set adjCells = finalBoard.getAdj(finalCell);
- adjCells.removeIf(cell -> cell.getType() != LightUpCellType.NUMBER);
- if (adjCells.isEmpty()) {
- return super.getInvalidUseOfRuleMessage() + ": This cell is not adjacent to a numbered cell";
- }
-
- LightUpBoard emptyCase = initialBoard.copy();
- emptyCase.getPuzzleElement(finalCell).setData(LightUpCellType.EMPTY.value);
- TooFewBulbsContradictionRule tooFew = new TooFewBulbsContradictionRule();
- for (LightUpCell c : adjCells) {
- if (tooFew.checkContradictionAt(emptyCase, c) == null) {
- return null;
- }
- }
- return super.getInvalidUseOfRuleMessage() + ": This cell is not forced to be a bulb";
- }
-
- /**
- * Determines whether the specified cell is forced to be a bulb or not
- *
- * @param board the entire board
- * @param cell specified cell
- * @return whether cell is forced to be a bulb or not
- */
- private boolean isForced(LightUpBoard board, LightUpCell cell) {
- Set adjCells = board.getAdj(cell);
- adjCells.removeIf(c -> c.getType() != LightUpCellType.NUMBER);
- if (adjCells.isEmpty()) {
- return false;
- }
-
- LightUpBoard emptyCase = board.copy();
- emptyCase.getPuzzleElement(cell).setData(LightUpCellType.EMPTY.value);
- TooFewBulbsContradictionRule tooFew = new TooFewBulbsContradictionRule();
- for (LightUpCell c : adjCells) {
- if (tooFew.checkContradictionAt(emptyCase, c) == null) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- LightUpBoard initialBoard = (LightUpBoard) node.getBoard();
- LightUpBoard lightUpBoard = (LightUpBoard) node.getBoard().copy();
- for (PuzzleElement element : lightUpBoard.getPuzzleElements()) {
- LightUpCell cell = (LightUpCell) element;
- if (cell.getType() == LightUpCellType.UNKNOWN && isForced(initialBoard, cell)) {
- cell.setData(LightUpCellType.BULB.value);
- lightUpBoard.addModifiedData(cell);
- }
- }
- if (lightUpBoard.getModifiedData().isEmpty()) {
- return null;
- }
- else {
- return lightUpBoard;
- }
- }
-}
+package edu.rpi.legup.puzzle.lightup.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+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.lightup.LightUpBoard;
+import edu.rpi.legup.puzzle.lightup.LightUpCell;
+import edu.rpi.legup.puzzle.lightup.LightUpCellType;
+import java.util.Set;
+
+public class FinishWithBulbsDirectRule extends DirectRule {
+
+ public FinishWithBulbsDirectRule() {
+ super(
+ "LTUP-BASC-0004",
+ "Finish with Bulbs",
+ "The remaining unknowns around a block must be bulbs to satisfy the number.",
+ "edu/rpi/legup/images/lightup/rules/FinishWithBulbs.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 index of the 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) {
+ LightUpBoard initialBoard = (LightUpBoard) transition.getParents().get(0).getBoard();
+ LightUpCell initCell = (LightUpCell) initialBoard.getPuzzleElement(puzzleElement);
+ LightUpBoard finalBoard = (LightUpBoard) transition.getBoard();
+ LightUpCell finalCell = (LightUpCell) finalBoard.getPuzzleElement(puzzleElement);
+ if (!(initCell.getType() == LightUpCellType.UNKNOWN
+ && finalCell.getType() == LightUpCellType.BULB)) {
+ return super.getInvalidUseOfRuleMessage() + ": Modified cells must be bulbs";
+ }
+
+ Set adjCells = finalBoard.getAdj(finalCell);
+ adjCells.removeIf(cell -> cell.getType() != LightUpCellType.NUMBER);
+ if (adjCells.isEmpty()) {
+ return super.getInvalidUseOfRuleMessage()
+ + ": This cell is not adjacent to a numbered cell";
+ }
+
+ LightUpBoard emptyCase = initialBoard.copy();
+ emptyCase.getPuzzleElement(finalCell).setData(LightUpCellType.EMPTY.value);
+ TooFewBulbsContradictionRule tooFew = new TooFewBulbsContradictionRule();
+ for (LightUpCell c : adjCells) {
+ if (tooFew.checkContradictionAt(emptyCase, c) == null) {
+ return null;
+ }
+ }
+ return super.getInvalidUseOfRuleMessage() + ": This cell is not forced to be a bulb";
+ }
+
+ /**
+ * Determines whether the specified cell is forced to be a bulb or not
+ *
+ * @param board the entire board
+ * @param cell specified cell
+ * @return whether cell is forced to be a bulb or not
+ */
+ private boolean isForced(LightUpBoard board, LightUpCell cell) {
+ Set adjCells = board.getAdj(cell);
+ adjCells.removeIf(c -> c.getType() != LightUpCellType.NUMBER);
+ if (adjCells.isEmpty()) {
+ return false;
+ }
+
+ LightUpBoard emptyCase = board.copy();
+ emptyCase.getPuzzleElement(cell).setData(LightUpCellType.EMPTY.value);
+ TooFewBulbsContradictionRule tooFew = new TooFewBulbsContradictionRule();
+ for (LightUpCell c : adjCells) {
+ if (tooFew.checkContradictionAt(emptyCase, c) == null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ LightUpBoard initialBoard = (LightUpBoard) node.getBoard();
+ LightUpBoard lightUpBoard = (LightUpBoard) node.getBoard().copy();
+ for (PuzzleElement element : lightUpBoard.getPuzzleElements()) {
+ LightUpCell cell = (LightUpCell) element;
+ if (cell.getType() == LightUpCellType.UNKNOWN && isForced(initialBoard, cell)) {
+ cell.setData(LightUpCellType.BULB.value);
+ lightUpBoard.addModifiedData(cell);
+ }
+ }
+ if (lightUpBoard.getModifiedData().isEmpty()) {
+ return null;
+ } else {
+ return lightUpBoard;
+ }
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/FinishWithEmptyDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/FinishWithEmptyDirectRule.java
index f7433150c..678ee67a2 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/FinishWithEmptyDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/FinishWithEmptyDirectRule.java
@@ -1,118 +1,122 @@
-package edu.rpi.legup.puzzle.lightup.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-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.lightup.LightUpBoard;
-import edu.rpi.legup.puzzle.lightup.LightUpCell;
-import edu.rpi.legup.puzzle.lightup.LightUpCellType;
-
-import java.awt.*;
-
-public class FinishWithEmptyDirectRule extends DirectRule {
-
- public FinishWithEmptyDirectRule() {
- super("LTUP-BASC-0005", "Finish with Empty",
- "The remaining unknowns around a block must be empty if the number is satisfied.",
- "edu/rpi/legup/images/lightup/rules/FinishWithEmpty.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 index of the 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) {
- LightUpBoard initialBoard = (LightUpBoard) transition.getParents().get(0).getBoard();
- LightUpBoard finalBoard = (LightUpBoard) transition.getBoard();
- LightUpCell cell = (LightUpCell) finalBoard.getPuzzleElement(puzzleElement);
- if (cell.getType() != LightUpCellType.EMPTY) {
- return super.getInvalidUseOfRuleMessage() + ": Modified cells must be empty";
- }
-
- if (isForced(initialBoard, cell.getLocation())) {
- return null;
- }
- return super.getInvalidUseOfRuleMessage() + ": Empty is not forced";
- }
-
- /**
- * Checks whether a certain cell is forced to not be a bulb
- *
- * @param board specified board
- * @param location location of cell to check
- * @return boolean value based on whether a certain cell has an adjacent cell that has the required amount of adjacent bulbs
- */
- private boolean isForced(LightUpBoard board, Point location) {
- return isForcedEmpty(board, new Point(location.x + 1, location.y)) ||
- isForcedEmpty(board, new Point(location.x, location.y + 1)) ||
- isForcedEmpty(board, new Point(location.x - 1, location.y)) ||
- isForcedEmpty(board, new Point(location.x, location.y - 1));
- }
-
- /**
- * Checks whether a certain cell has the required amount of adjacent bulbs
- *
- * @param board specified board
- * @param loc location of cell to check
- * @return boolean value based on whether a certain cell has the required amount of adjacent bulbs
- */
- private boolean isForcedEmpty(LightUpBoard board, Point loc) {
- LightUpCell cell = board.getCell(loc.x, loc.y);
- if (cell == null || cell.getType() != LightUpCellType.NUMBER) {
- return false;
- }
-
- int bulbs = 0;
- int bulbsNeeded = cell.getData();
- cell = board.getCell(loc.x + 1, loc.y);
- if (cell != null && cell.getType() == LightUpCellType.BULB) {
- bulbs++;
- }
- cell = board.getCell(loc.x, loc.y + 1);
- if (cell != null && cell.getType() == LightUpCellType.BULB) {
- bulbs++;
- }
- cell = board.getCell(loc.x - 1, loc.y);
- if (cell != null && cell.getType() == LightUpCellType.BULB) {
- bulbs++;
- }
- cell = board.getCell(loc.x, loc.y - 1);
- if (cell != null && cell.getType() == LightUpCellType.BULB) {
- bulbs++;
- }
- return bulbs == bulbsNeeded;
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- LightUpBoard initialBoard = (LightUpBoard) node.getBoard();
- LightUpBoard lightUpBoard = (LightUpBoard) node.getBoard().copy();
- for (PuzzleElement element : lightUpBoard.getPuzzleElements()) {
- LightUpCell cell = (LightUpCell) element;
- if (cell.getType() == LightUpCellType.UNKNOWN && isForced(initialBoard, cell.getLocation())) {
- cell.setData(LightUpCellType.EMPTY.value);
- lightUpBoard.addModifiedData(cell);
- }
- }
- if (lightUpBoard.getModifiedData().isEmpty()) {
- return null;
- }
- else {
- return lightUpBoard;
- }
- }
-}
+package edu.rpi.legup.puzzle.lightup.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+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.lightup.LightUpBoard;
+import edu.rpi.legup.puzzle.lightup.LightUpCell;
+import edu.rpi.legup.puzzle.lightup.LightUpCellType;
+import java.awt.*;
+
+public class FinishWithEmptyDirectRule extends DirectRule {
+
+ public FinishWithEmptyDirectRule() {
+ super(
+ "LTUP-BASC-0005",
+ "Finish with Empty",
+ "The remaining unknowns around a block must be empty if the number is satisfied.",
+ "edu/rpi/legup/images/lightup/rules/FinishWithEmpty.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 index of the 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) {
+ LightUpBoard initialBoard = (LightUpBoard) transition.getParents().get(0).getBoard();
+ LightUpBoard finalBoard = (LightUpBoard) transition.getBoard();
+ LightUpCell cell = (LightUpCell) finalBoard.getPuzzleElement(puzzleElement);
+ if (cell.getType() != LightUpCellType.EMPTY) {
+ return super.getInvalidUseOfRuleMessage() + ": Modified cells must be empty";
+ }
+
+ if (isForced(initialBoard, cell.getLocation())) {
+ return null;
+ }
+ return super.getInvalidUseOfRuleMessage() + ": Empty is not forced";
+ }
+
+ /**
+ * Checks whether a certain cell is forced to not be a bulb
+ *
+ * @param board specified board
+ * @param location location of cell to check
+ * @return boolean value based on whether a certain cell has an adjacent cell that has the
+ * required amount of adjacent bulbs
+ */
+ private boolean isForced(LightUpBoard board, Point location) {
+ return isForcedEmpty(board, new Point(location.x + 1, location.y))
+ || isForcedEmpty(board, new Point(location.x, location.y + 1))
+ || isForcedEmpty(board, new Point(location.x - 1, location.y))
+ || isForcedEmpty(board, new Point(location.x, location.y - 1));
+ }
+
+ /**
+ * Checks whether a certain cell has the required amount of adjacent bulbs
+ *
+ * @param board specified board
+ * @param loc location of cell to check
+ * @return boolean value based on whether a certain cell has the required amount of adjacent
+ * bulbs
+ */
+ private boolean isForcedEmpty(LightUpBoard board, Point loc) {
+ LightUpCell cell = board.getCell(loc.x, loc.y);
+ if (cell == null || cell.getType() != LightUpCellType.NUMBER) {
+ return false;
+ }
+
+ int bulbs = 0;
+ int bulbsNeeded = cell.getData();
+ cell = board.getCell(loc.x + 1, loc.y);
+ if (cell != null && cell.getType() == LightUpCellType.BULB) {
+ bulbs++;
+ }
+ cell = board.getCell(loc.x, loc.y + 1);
+ if (cell != null && cell.getType() == LightUpCellType.BULB) {
+ bulbs++;
+ }
+ cell = board.getCell(loc.x - 1, loc.y);
+ if (cell != null && cell.getType() == LightUpCellType.BULB) {
+ bulbs++;
+ }
+ cell = board.getCell(loc.x, loc.y - 1);
+ if (cell != null && cell.getType() == LightUpCellType.BULB) {
+ bulbs++;
+ }
+ return bulbs == bulbsNeeded;
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ LightUpBoard initialBoard = (LightUpBoard) node.getBoard();
+ LightUpBoard lightUpBoard = (LightUpBoard) node.getBoard().copy();
+ for (PuzzleElement element : lightUpBoard.getPuzzleElements()) {
+ LightUpCell cell = (LightUpCell) element;
+ if (cell.getType() == LightUpCellType.UNKNOWN
+ && isForced(initialBoard, cell.getLocation())) {
+ cell.setData(LightUpCellType.EMPTY.value);
+ lightUpBoard.addModifiedData(cell);
+ }
+ }
+ if (lightUpBoard.getModifiedData().isEmpty()) {
+ return null;
+ } else {
+ return lightUpBoard;
+ }
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/LightOrEmptyCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/LightOrEmptyCaseRule.java
index 410c30e9c..53efb6587 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/LightOrEmptyCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/LightOrEmptyCaseRule.java
@@ -8,14 +8,15 @@
import edu.rpi.legup.puzzle.lightup.LightUpBoard;
import edu.rpi.legup.puzzle.lightup.LightUpCell;
import edu.rpi.legup.puzzle.lightup.LightUpCellType;
-
import java.util.ArrayList;
import java.util.List;
public class LightOrEmptyCaseRule extends CaseRule {
public LightOrEmptyCaseRule() {
- super("LTUP-CASE-0001", "Light or Empty",
+ super(
+ "LTUP-CASE-0001",
+ "Light or Empty",
"Each blank cell is either a light or empty.",
"edu/rpi/legup/images/lightup/cases/LightOrEmpty.png");
}
@@ -36,13 +37,17 @@ public CaseBoard getCaseBoard(Board board) {
/**
* Gets the possible cases at a specific location based on this case rule
*
- * @param board the current board state
+ * @param board the current board state
* @param puzzleElement puzzleElement to determine the possible cases for
* @return a list of elements the specified could be
*/
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
ArrayList cases = new ArrayList<>();
+ if (puzzleElement == null) {
+ return cases;
+ }
+
Board case1 = board.copy();
PuzzleElement data1 = case1.getPuzzleElement(puzzleElement);
data1.setData(-4);
@@ -73,33 +78,37 @@ public String checkRuleRaw(TreeTransition transition) {
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";
+ 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";
}
LightUpCell mod1 = (LightUpCell) case1.getBoard().getModifiedData().iterator().next();
LightUpCell mod2 = (LightUpCell) 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";
+ return super.getInvalidUseOfRuleMessage()
+ + ": This case rule must modify the same cell for each case";
}
- if (!((mod1.getType() == LightUpCellType.EMPTY && mod2.getType() == LightUpCellType.BULB) ||
- (mod2.getType() == LightUpCellType.EMPTY && mod1.getType() == LightUpCellType.BULB))) {
- return super.getInvalidUseOfRuleMessage() + ": This case rule must an empty cell and a bulb cell";
+ if (!((mod1.getType() == LightUpCellType.EMPTY && mod2.getType() == LightUpCellType.BULB)
+ || (mod2.getType() == LightUpCellType.EMPTY
+ && mod1.getType() == LightUpCellType.BULB))) {
+ return super.getInvalidUseOfRuleMessage()
+ + ": This case rule must an empty cell and a bulb cell";
}
return null;
}
/**
- * Checks whether the child node logically follows from the parent node
- * at the specific puzzleElement index using this rule
+ * 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 transition transition to check
* @param puzzleElement index of the puzzleElement
- * @return null if the child node logically follow from the parent node at the specified puzzleElement,
- * otherwise error message
+ * @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) {
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/MustLightDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/MustLightDirectRule.java
index f0f943401..bf1843728 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/MustLightDirectRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/MustLightDirectRule.java
@@ -1,149 +1,153 @@
-package edu.rpi.legup.puzzle.lightup.rules;
-
-import edu.rpi.legup.model.gameboard.Board;
-import edu.rpi.legup.model.gameboard.PuzzleElement;
-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.lightup.LightUpBoard;
-import edu.rpi.legup.puzzle.lightup.LightUpCell;
-import edu.rpi.legup.puzzle.lightup.LightUpCellType;
-
-import java.awt.*;
-
-public class MustLightDirectRule extends DirectRule {
-
- public MustLightDirectRule() {
- super("LTUP-BASC-0006", "Must Light",
- "A cell must be a bulb if it is the only cell to be able to light another.",
- "edu/rpi/legup/images/lightup/rules/MustLight.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 index of the 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) {
- LightUpBoard parentBoard = (LightUpBoard) transition.getParents().get(0).getBoard();
- LightUpBoard finalBoard = (LightUpBoard) transition.getBoard();
- LightUpCell parentCell = (LightUpCell) parentBoard.getPuzzleElement(puzzleElement);
- LightUpCell finalCell = (LightUpCell) finalBoard.getPuzzleElement(puzzleElement);
- if (!(parentCell.getType() == LightUpCellType.UNKNOWN && !parentCell.isLite() && finalCell.getType() == LightUpCellType.BULB)) {
- return super.getInvalidUseOfRuleMessage() + ": Modified cells must be bulbs";
- }
-
- finalBoard.fillWithLight();
- boolean isForced = isForcedBulb(parentBoard, parentCell.getLocation());
- finalCell.setData(LightUpCellType.BULB.value);
- finalBoard.fillWithLight();
-
- if (isForced) {
- return null;
- }
- else {
- return super.getInvalidUseOfRuleMessage() + ": This cell can be lit by another cell";
- }
- }
-
- private boolean isForcedBulb(LightUpBoard board, Point loc) {
- CannotLightACellContradictionRule cannotLite = new CannotLightACellContradictionRule();
- LightUpBoard modifiedBoard = board.copy();
- LightUpCell modifiedCell = modifiedBoard.getCell(loc.x, loc.y);
- modifiedCell.setData(LightUpCellType.EMPTY.value);
- //Check if this cell itself (the one with the bulb) has no other lighting option
- if ((modifiedCell.getType() == LightUpCellType.EMPTY || modifiedCell.getType() == LightUpCellType.UNKNOWN) &&
- !modifiedCell.isLite() && cannotLite.checkContradictionAt(modifiedBoard, modifiedCell) == null) {
- return true;
- }
- //Look right
- for (int i = loc.x + 1; i < modifiedBoard.getWidth(); i++) {
- LightUpCell c = modifiedBoard.getCell(i, loc.y);
- if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
- break;
- }
- else {
- if (c.getType() == LightUpCellType.EMPTY &&
- !c.isLite() && cannotLite.checkContradictionAt(modifiedBoard, c) == null) {
- return true;
- }
- }
- }
- //Look left
- for (int i = loc.x - 1; i >= 0; i--) {
- LightUpCell c = modifiedBoard.getCell(i, loc.y);
- if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
- break;
- }
- else {
- if (c.getType() == LightUpCellType.EMPTY &&
- !c.isLite() && cannotLite.checkContradictionAt(modifiedBoard, c) == null) {
- return true;
- }
- }
- }
- //Look down
- for (int i = loc.y + 1; i < modifiedBoard.getHeight(); i++) {
- LightUpCell c = modifiedBoard.getCell(loc.x, i);
- if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
- break;
- }
- else {
- if (c.getType() == LightUpCellType.EMPTY &&
- !c.isLite() && cannotLite.checkContradictionAt(modifiedBoard, c) == null) {
- return true;
- }
- }
- }
- //Look up
- for (int i = loc.y - 1; i >= 0; i--) {
- LightUpCell c = modifiedBoard.getCell(loc.x, i);
- if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
- break;
- }
- else {
- if (c.getType() == LightUpCellType.EMPTY &&
- !c.isLite() && cannotLite.checkContradictionAt(modifiedBoard, c) == null) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Creates a transition {@link Board} that has this rule applied to it using the {@link TreeNode}.
- *
- * @param node tree node used to create default transition board
- * @return default board or null if this rule cannot be applied to this tree node
- */
- @Override
- public Board getDefaultBoard(TreeNode node) {
- LightUpBoard initialBoard = (LightUpBoard) node.getBoard();
- LightUpBoard tempBoard = (LightUpBoard) node.getBoard().copy();
- LightUpBoard lightUpBoard = (LightUpBoard) node.getBoard().copy();
- for (PuzzleElement element : tempBoard.getPuzzleElements()) {
- LightUpCell cell = (LightUpCell) element;
- if (cell.getType() == LightUpCellType.UNKNOWN && !cell.isLite()) {
- cell.setData(LightUpCellType.EMPTY.value);
- if (isForcedBulb(initialBoard, cell.getLocation())) {
- LightUpCell modCell = (LightUpCell) lightUpBoard.getPuzzleElement(cell);
- modCell.setData(LightUpCellType.BULB.value);
- lightUpBoard.addModifiedData(modCell);
- }
- cell.setData(LightUpCellType.UNKNOWN.value);
- }
- }
- if (lightUpBoard.getModifiedData().isEmpty()) {
- return null;
- }
- else {
- return lightUpBoard;
- }
- }
-}
+package edu.rpi.legup.puzzle.lightup.rules;
+
+import edu.rpi.legup.model.gameboard.Board;
+import edu.rpi.legup.model.gameboard.PuzzleElement;
+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.lightup.LightUpBoard;
+import edu.rpi.legup.puzzle.lightup.LightUpCell;
+import edu.rpi.legup.puzzle.lightup.LightUpCellType;
+import java.awt.*;
+
+public class MustLightDirectRule extends DirectRule {
+
+ public MustLightDirectRule() {
+ super(
+ "LTUP-BASC-0006",
+ "Must Light",
+ "A cell must be a bulb if it is the only cell to be able to light another.",
+ "edu/rpi/legup/images/lightup/rules/MustLight.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 index of the 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) {
+ LightUpBoard parentBoard = (LightUpBoard) transition.getParents().get(0).getBoard();
+ LightUpBoard finalBoard = (LightUpBoard) transition.getBoard();
+ LightUpCell parentCell = (LightUpCell) parentBoard.getPuzzleElement(puzzleElement);
+ LightUpCell finalCell = (LightUpCell) finalBoard.getPuzzleElement(puzzleElement);
+ if (!(parentCell.getType() == LightUpCellType.UNKNOWN
+ && !parentCell.isLite()
+ && finalCell.getType() == LightUpCellType.BULB)) {
+ return super.getInvalidUseOfRuleMessage() + ": Modified cells must be bulbs";
+ }
+
+ finalBoard.fillWithLight();
+ boolean isForced = isForcedBulb(parentBoard, parentCell.getLocation());
+ finalCell.setData(LightUpCellType.BULB.value);
+ finalBoard.fillWithLight();
+
+ if (isForced) {
+ return null;
+ } else {
+ return super.getInvalidUseOfRuleMessage() + ": This cell can be lit by another cell";
+ }
+ }
+
+ private boolean isForcedBulb(LightUpBoard board, Point loc) {
+ CannotLightACellContradictionRule cannotLite = new CannotLightACellContradictionRule();
+ LightUpBoard modifiedBoard = board.copy();
+ LightUpCell modifiedCell = modifiedBoard.getCell(loc.x, loc.y);
+ modifiedCell.setData(LightUpCellType.EMPTY.value);
+ // Check if this cell itself (the one with the bulb) has no other lighting option
+ if ((modifiedCell.getType() == LightUpCellType.EMPTY
+ || modifiedCell.getType() == LightUpCellType.UNKNOWN)
+ && !modifiedCell.isLite()
+ && cannotLite.checkContradictionAt(modifiedBoard, modifiedCell) == null) {
+ return true;
+ }
+ // Look right
+ for (int i = loc.x + 1; i < modifiedBoard.getWidth(); i++) {
+ LightUpCell c = modifiedBoard.getCell(i, loc.y);
+ if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
+ break;
+ } else {
+ if (c.getType() == LightUpCellType.EMPTY
+ && !c.isLite()
+ && cannotLite.checkContradictionAt(modifiedBoard, c) == null) {
+ return true;
+ }
+ }
+ }
+ // Look left
+ for (int i = loc.x - 1; i >= 0; i--) {
+ LightUpCell c = modifiedBoard.getCell(i, loc.y);
+ if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
+ break;
+ } else {
+ if (c.getType() == LightUpCellType.EMPTY
+ && !c.isLite()
+ && cannotLite.checkContradictionAt(modifiedBoard, c) == null) {
+ return true;
+ }
+ }
+ }
+ // Look down
+ for (int i = loc.y + 1; i < modifiedBoard.getHeight(); i++) {
+ LightUpCell c = modifiedBoard.getCell(loc.x, i);
+ if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
+ break;
+ } else {
+ if (c.getType() == LightUpCellType.EMPTY
+ && !c.isLite()
+ && cannotLite.checkContradictionAt(modifiedBoard, c) == null) {
+ return true;
+ }
+ }
+ }
+ // Look up
+ for (int i = loc.y - 1; i >= 0; i--) {
+ LightUpCell c = modifiedBoard.getCell(loc.x, i);
+ if (c.getType() == LightUpCellType.BLACK || c.getType() == LightUpCellType.NUMBER) {
+ break;
+ } else {
+ if (c.getType() == LightUpCellType.EMPTY
+ && !c.isLite()
+ && cannotLite.checkContradictionAt(modifiedBoard, c) == null) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Creates a transition {@link Board} that has this rule applied to it using the {@link
+ * TreeNode}.
+ *
+ * @param node tree node used to create default transition board
+ * @return default board or null if this rule cannot be applied to this tree node
+ */
+ @Override
+ public Board getDefaultBoard(TreeNode node) {
+ LightUpBoard initialBoard = (LightUpBoard) node.getBoard();
+ LightUpBoard tempBoard = (LightUpBoard) node.getBoard().copy();
+ LightUpBoard lightUpBoard = (LightUpBoard) node.getBoard().copy();
+ for (PuzzleElement element : tempBoard.getPuzzleElements()) {
+ LightUpCell cell = (LightUpCell) element;
+ if (cell.getType() == LightUpCellType.UNKNOWN && !cell.isLite()) {
+ cell.setData(LightUpCellType.EMPTY.value);
+ if (isForcedBulb(initialBoard, cell.getLocation())) {
+ LightUpCell modCell = (LightUpCell) lightUpBoard.getPuzzleElement(cell);
+ modCell.setData(LightUpCellType.BULB.value);
+ lightUpBoard.addModifiedData(modCell);
+ }
+ cell.setData(LightUpCellType.UNKNOWN.value);
+ }
+ }
+ if (lightUpBoard.getModifiedData().isEmpty()) {
+ return null;
+ } else {
+ return lightUpBoard;
+ }
+ }
+}
diff --git a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/SatisfyNumberCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/SatisfyNumberCaseRule.java
index cf7b70ccd..f73a34b2d 100644
--- a/src/main/java/edu/rpi/legup/puzzle/lightup/rules/SatisfyNumberCaseRule.java
+++ b/src/main/java/edu/rpi/legup/puzzle/lightup/rules/SatisfyNumberCaseRule.java
@@ -9,7 +9,6 @@
import edu.rpi.legup.puzzle.lightup.LightUpBoard;
import edu.rpi.legup.puzzle.lightup.LightUpCell;
import edu.rpi.legup.puzzle.lightup.LightUpCellType;
-
import java.awt.*;
import java.util.ArrayList;
import java.util.Iterator;
@@ -19,7 +18,9 @@
public class SatisfyNumberCaseRule extends CaseRule {
public SatisfyNumberCaseRule() {
- super("LTUP-CASE-0002", "Satisfy Number",
+ super(
+ "LTUP-CASE-0002",
+ "Satisfy Number",
"The different ways a blocks number can be satisfied.",
"edu/rpi/legup/images/lightup/cases/SatisfyNumber.png");
}
@@ -40,12 +41,17 @@ public CaseBoard getCaseBoard(Board board) {
/**
* Gets the possible cases at a specific location based on this case rule
*
- * @param board the current board state
+ * @param board the current board state
* @param puzzleElement puzzleElement to determine the possible cases for
* @return a list of elements the specified could be
*/
@Override
public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
+ ArrayList cases = new ArrayList<>();
+ if (puzzleElement == null) {
+ return cases;
+ }
+
LightUpBoard lightUpBoard = (LightUpBoard) board;
LightUpCell cell = (LightUpCell) puzzleElement;
Point loc = cell.getLocation();
@@ -58,8 +64,7 @@ public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
if (checkCell != null) {
if (checkCell.getType() == LightUpCellType.UNKNOWN && !checkCell.isLite()) {
openSpots.add(checkCell);
- }
- else {
+ } else {
if (checkCell.getType() == LightUpCellType.BULB) {
numNeeded--;
}
@@ -69,8 +74,7 @@ public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
if (checkCell != null) {
if (checkCell.getType() == LightUpCellType.UNKNOWN && !checkCell.isLite()) {
openSpots.add(checkCell);
- }
- else {
+ } else {
if (checkCell.getType() == LightUpCellType.BULB) {
numNeeded--;
}
@@ -80,8 +84,7 @@ public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
if (checkCell != null) {
if (checkCell.getType() == LightUpCellType.UNKNOWN && !checkCell.isLite()) {
openSpots.add(checkCell);
- }
- else {
+ } else {
if (checkCell.getType() == LightUpCellType.BULB) {
numNeeded--;
}
@@ -91,15 +94,13 @@ public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
if (checkCell != null) {
if (checkCell.getType() == LightUpCellType.UNKNOWN && !checkCell.isLite()) {
openSpots.add(checkCell);
- }
- else {
+ } else {
if (checkCell.getType() == LightUpCellType.BULB) {
numNeeded--;
}
}
}
- ArrayList cases = new ArrayList<>();
if (numNeeded == 0) {
return cases;
}
@@ -109,7 +110,11 @@ public ArrayList getCases(Board board, PuzzleElement puzzleElement) {
return cases;
}
- private void generateCases(final LightUpBoard board, final int num, List openSpots, List cases) {
+ private void generateCases(
+ final LightUpBoard board,
+ final int num,
+ List openSpots,
+ List cases) {
if (num > openSpots.size()) {
return;
}
@@ -128,7 +133,13 @@ private void generateCases(final LightUpBoard board, final int num, List openSpots, List cases, LightUpBoard curBoard, int index) {
+ private void generateCases(
+ final LightUpBoard board,
+ final int num,
+ List openSpots,
+ List cases,
+ LightUpBoard curBoard,
+ int index) {
if (num <= curBoard.getModifiedData().size()) {
cases.add(curBoard);
return;
@@ -181,8 +192,28 @@ public String checkRuleRaw(TreeTransition transition) {
for (LightUpCell c : spots) {
ArrayList cases = getCases(parent.getBoard(), c);
- // We will allow case rules to have only one option
- if (cases.size() == childTransitions.size() && cases.size() >= 1) {
+ // Note: we will allow case rules to have only one option
+
+ // Some error checking to make sure that weird stuff doesn't happen
+ // if this case rule is incorrectly used to justify changes on the
+ // puzzle board
+ if (cases.size() == childTransitions.size() && cases.size() == 1) {
+ TreeTransition childTransition = childTransitions.get(0);
+
+ // If there is only 1 case, then this case rule should function no
+ // differently than the Finish With Bulbs Direct Rule
+ FinishWithBulbsDirectRule finishWithBulbs = new FinishWithBulbsDirectRule();
+ childTransition.setRule(finishWithBulbs);
+ boolean isCorrect = childTransition.isCorrect();
+
+ // Changes the transition back to this case rule
+ childTransition.setRule(this);
+
+ if (isCorrect) {
+ return null;
+ }
+ return super.getInvalidUseOfRuleMessage();
+ } else if (cases.size() == childTransitions.size() && cases.size() > 1) {
boolean foundSpot = true;
for (TreeTransition childTrans : childTransitions) {
LightUpBoard actCase = (LightUpBoard) childTrans.getBoard();
@@ -197,8 +228,9 @@ public String checkRuleRaw(TreeTransition transition) {
boolean foundCell = false;
for (PuzzleElement posEle : posCase.getModifiedData()) {
LightUpCell posCell = (LightUpCell) posEle;
- if (actCell.getType() == posCell.getType() &&
- actCell.getLocation().equals(posCell.getLocation())) {
+ if (actCell.getType() == posCell.getType()
+ && actCell.getLocation()
+ .equals(posCell.getLocation())) {
foundCell = true;
break;
}
@@ -228,13 +260,13 @@ public String checkRuleRaw(TreeTransition transition) {
}
/**
- * Checks whether the child node logically follows from the parent node
- * at the specific puzzleElement index using this rule
+ * 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 transition transition to check
* @param puzzleElement index of the puzzleElement
- * @return null if the child node logically follow from the parent node at the specified puzzleElement,
- * otherwise error message
+ * @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) {
@@ -245,7 +277,8 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem
* Gets all cells in the TreeTransition board that are adjacent to all modified cells
*
* @param transition TreeTransition object
- * @return list of cells that are adjacent to all modified cells, returns null if the number of modified cells is =0 || >4
+ * @return list of cells that are adjacent to all modified cells, returns null if the number of
+ * modified cells is =0 || >4
*/
private List