From bcc904a9d3a4077a0e419cb5913923deaa8f8dec Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Fri, 2 Feb 2024 17:23:26 -0500 Subject: [PATCH 01/70] Added a text file File represents all files we will put and use to fully implement the StarBattle puzzle later. --- .../rpi/legup/puzzle/starbattle/allfiles.txt | 230 ++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt b/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt new file mode 100644 index 000000000..7f006191a --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt @@ -0,0 +1,230 @@ +//StarBattle.java + +package edu.rpi.legup.puzzle.starbattle; + +import edu.rpi.legup.model.Puzzle; +import edu.rpi.legup.model.gameboard.Board; + +public class StarBattle extends Puzzle { + public StarBattle() { + super(); + this.name = "StarBattle"; + + this.importer = new StarBattleImporter(this); + this.exporter = new StarBattleExporter(this); + + this.factory = new StarBattleCellFactory(); + } + + @Override + public void initializeView() { + } + + @Override + public Board generatePuzzle(int difficulty) { + return null; + } + + @Override + public boolean isBoardComplete(Board board) { + return true; + } + + @Override + public void onBoardChange(Board board) { + } +} + +//StarBattleBoard.java + +package edu.rpi.legup.puzzle.lightup; + +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; + +public class StarBattleBoard extends GridBoard { + + private int size; + private vector group_sizes; + + /** + * StarBattleBoard Constructor - create a new Star Battle board + * + * @param size size of one side of the star battle board + */ + + public StarBattleBoard(int size) { + super(size, size); + group_sizes = vector(size); + } + + @Override + public StarBattleCell getCell(int x, int y) { + return (StarBattleCell) super.getCell(x, y); + } + + +} + +//StarBattleCell.java + +package edu.rpi.legup.puzzle.starbattle; + +import edu.rpi.legup.model.gameboard.GridCell; + +import java.awt.*; +import java.util.HashSet; +import java.util.Set; + +public class StarBattleCell extends GridCell { + private int groupIndex; + private int max; + + /** + * SudokuCell Constructor - creates a new Sudoku cell to hold the puzzleElement + * + * @param valueInt value of the star battle cell denoting its state + * @param location location of the cell on the board + * @param size size of the sudoku cell + */ + public StarBattleCell(int value, Point location, int groupIndex, int size) { + super(value, location); + this.groupIndex = groupIndex; + this.max = size; + } + + @Override + public void setType(Element e, MouseEvent m) { + switch (e.getElementID()) { + case "SBUP-PLAC-0001": + this.data = -4; + break; + case "SBUP-UNPL-0002": + this.data = -1; + break; + case "SBUP-UNPL-0003": + this.data = -2; + break; + case "SBUP-UNPL-0001"://Not sure how button events work + switch (m.getButton()){ + case MouseEvent.BUTTON1: + if (this.data < 0 || this.data > 3) { + this.data = 0; + } + else { + this.data = this.data + 1; + } + break; + case MouseEvent.BUTTON3: + if (this.data > 0) { + this.data = this.data - 1; + } + else { + this.data = 3;//Unsure + } + break; + } + break; + } + } + + public LightUpCellType getType() { + switch (data) { + case -3: + return LightUpCellType.UNKNOWN; + case -2: + return LightUpCellType.STAR; + case -1: + return LightUpCellType.BLACK; + default: + if (data >= 0) { + return StarBattleCellType.WHITE; + } + } + return null; + } + + /** + * Gets the region index of the cell + * + * @return group index of the cell + */ + public int getGroupIndex() { + return groupIndex; + } + + /** + * Gets the size of the cell + * + * @return size of the cell + */ + + public int getMax() { + return max; + } + +} + +//StarBattleCellController.java + +package edu.rpi.legup.puzzle.starbattle; + +import edu.rpi.legup.controller.ElementController; +import edu.rpi.legup.model.gameboard.PuzzleElement; + +import java.awt.event.MouseEvent; + +public class StarBattleCellController extends ElementController { + @Override + public void changeCell(MouseEvent e, PuzzleElement data) { + StarBattleCell cell = (StarBattleCell) 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(-3); + } + else { + data.setData(cell.getData() + 1); + } + } + } + else { + if (e.getButton() == MouseEvent.BUTTON3) { + if (cell.getData() == -3) { + data.setData(0); + } + else { + data.setData(cell.getData() - 1); + } + } + } + } +} + +//StarBattleCellFactory.java + + + +//StarBattleCellType.java +package edu.rpi.legup.puzzle.starbattle; + +public enum StarBattleType { + UNKNOWN(-3), STAR(-2), BLACK(-1), WHITE(0); + + public int value; + + StarBattleCell(int value) { + this.value = value; + } +} + +//StarBattleExporter.java +//StarBattleImporter.java +//StarBattleView.java \ No newline at end of file From 9fa0e0205a7f744b9597135202290e1363339593 Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Fri, 9 Feb 2024 17:45:28 -0500 Subject: [PATCH 02/70] Imported the black and star tiles ID probably needs to be changed in the future, and more assets on the way. --- .../puzzle/starbattle/elements/BlackTile.java | 9 +++++++++ .../puzzle/starbattle/elements/StarTile.java | 9 +++++++++ .../edu/rpi/legup/images/starbattle/black.gif | Bin 0 -> 856 bytes .../edu/rpi/legup/images/starbattle/star.gif | Bin 0 -> 545 bytes 4 files changed, 18 insertions(+) create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/elements/BlackTile.java create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/elements/StarTile.java create mode 100644 src/main/resources/edu/rpi/legup/images/starbattle/black.gif create mode 100644 src/main/resources/edu/rpi/legup/images/starbattle/star.gif diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/BlackTile.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/BlackTile.java new file mode 100644 index 000000000..fd74774a7 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/BlackTile.java @@ -0,0 +1,9 @@ +package edu.rpi.legup.puzzle.starbattle.elements; + +import edu.rpi.legup.model.elements.NonPlaceableElement; + +public class BlackTile extends NonPlaceableElement { + public BlackTile() { + super("STBL-PLAC-0002", "Black Tile", "The black tile", "edu/rpi/legup/images/lightup/black.gif"); + } +} diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/StarTile.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/StarTile.java new file mode 100644 index 000000000..2510869eb --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/StarTile.java @@ -0,0 +1,9 @@ +package edu.rpi.legup.puzzle.starbattle.elements; + +import edu.rpi.legup.model.elements.NonPlaceableElement; + +public class StarTile extends NonPlaceableElement { + public StarTile() { + super("LTUP-PLAC-0001", "Star Tile", "The star tile", "edu/rpi/legup/images/starbattle/star.gif"); + } +} diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/black.gif b/src/main/resources/edu/rpi/legup/images/starbattle/black.gif new file mode 100644 index 0000000000000000000000000000000000000000..13381a7179c2af7ad23ef064b743d3e479b56070 GIT binary patch literal 856 zcmZ?wbhEHbRA5kG_|Cv^;=~DtQ7{?;BQ*pRf3kqRt^*=Ld4hq%l;J<8jK_ur2b(#B zwPH?eSa`TyK-p`K$HqlRyCsaX?wr`T_;|m9bC-Px$+et)0R7gwB)k~;OQ4|O8-%S#Q6f(WuN(@LbxC6?>z|bQh@)#H)BSjf;3uWXn zP!c6GWTuoTBMJi~86e~tQXYG0-#TsIx!*bRl~udbx7OP0zy9m7zdk*dz8=T--vKPZ zNZe}5ye)&{8DLYd0Dk7cjT39^h^+_)Av2;~qv~I+oyO zH;_68qf-gSS5A~<6}DyFAzZ*gyu-&-wh#DP0#*UeVHPIj6985Df-zYUfr3d@-r_ah z<1to;v1D)nd-JVpIkQjs`y%Q0XIp&7Vq88Gu{7JF`N8ys&8EnBIreozzwXyvjSvlDruB;5x!$Xnyj1X!07h$Pn6jcYf6SBM5q!d&djqZoq_nZLnHO!*stxbz$k z^O6OVs+_<8W@9oUnLlJW2AgrJxN#Uiu)EO55S(udFjW7z7Y*E=w)sI0G84zJJpYbF zwzLI!nx2AqGGew**VH(+^=R_>j2PR-CF)OWzawq%uDa$G`gogyQMoI%|H<=lr(y6R jw|ThRX3<*4@9h2yt8`HryKo;Y00000NkvXXu0mjflb`cS literal 0 HcmV?d00001 From 17d26d73444b353a1ea31abde928c754020f754d Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Sat, 10 Feb 2024 14:53:11 -0500 Subject: [PATCH 03/70] Added UnknownTile Also fixed the descriptions of the black and star tile, not sure if we need another asset. --- .../puzzle/starbattle/elements/BlackTile.java | 2 +- .../puzzle/starbattle/elements/StarTile.java | 2 +- .../puzzle/starbattle/elements/UnknownTile.java | 9 +++++++++ .../edu/rpi/legup/images/starbattle/empty.gif | Bin 0 -> 857 bytes 4 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/elements/UnknownTile.java create mode 100644 src/main/resources/edu/rpi/legup/images/starbattle/empty.gif diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/BlackTile.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/BlackTile.java index fd74774a7..2601bd351 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/BlackTile.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/BlackTile.java @@ -4,6 +4,6 @@ public class BlackTile extends NonPlaceableElement { public BlackTile() { - super("STBL-PLAC-0002", "Black Tile", "The black tile", "edu/rpi/legup/images/lightup/black.gif"); + super("STBL-PLAC-0002", "Black Tile", "The black tile that shows where you cannot place a star", "edu/rpi/legup/images/lightup/black.gif"); } } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/StarTile.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/StarTile.java index 2510869eb..19ba7baed 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/StarTile.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/StarTile.java @@ -4,6 +4,6 @@ public class StarTile extends NonPlaceableElement { public StarTile() { - super("LTUP-PLAC-0001", "Star Tile", "The star tile", "edu/rpi/legup/images/starbattle/star.gif"); + super("LTUP-PLAC-0001", "Star Tile", "The star tile, the token of the game.", "edu/rpi/legup/images/starbattle/star.gif"); } } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/UnknownTile.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/UnknownTile.java new file mode 100644 index 000000000..192a95357 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/UnknownTile.java @@ -0,0 +1,9 @@ +package edu.rpi.legup.puzzle.starbattle.elements; + +import edu.rpi.legup.model.elements.NonPlaceableElement; + +public class UnknownTile extends NonPlaceableElement { + public UnknownTile() { + super("LTUP-PLAC-0001", "Unknown Tile", "An empty tile", "edu/rpi/legup/images/starbattle/star.gif"); + } +} diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/empty.gif b/src/main/resources/edu/rpi/legup/images/starbattle/empty.gif new file mode 100644 index 0000000000000000000000000000000000000000..38b91d0a2b9c6599eb19d14466db047a86d2ea97 GIT binary patch literal 857 zcmZ?wbhEHbRA5kG_|Cxa|Nno6Q7{?;BQ*qcKpqF>1qKc~21X7Uj|~eBHggDT#hlo% z@Nm0;vez7sjf;+UOBiR}IkEBaF$M+Z0v^pz$tNbN+pdZ^xoPR?=?2NC=6GICbzrat E0QgHHq5uE@ literal 0 HcmV?d00001 From 8955343d8bbdac96fa80cb31480b1784a58c1db5 Mon Sep 17 00:00:00 2001 From: summerhenson Date: Tue, 13 Feb 2024 16:32:48 -0500 Subject: [PATCH 04/70] Create StarBattleCellType.java Created StarBattleCellType.java file --- .../legup/puzzle/starbattle/StarBattleCellType.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellType.java diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellType.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellType.java new file mode 100644 index 000000000..0548a6b38 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellType.java @@ -0,0 +1,12 @@ +//StarBattleCellType.java +package edu.rpi.legup.puzzle.starbattle; + +public enum StarBattleType { + UNKNOWN(-3), STAR(-2), BLACK(-1); + + public int value; + + StarBattleCell(int value) { + this.value = value; + } +} \ No newline at end of file From 1ad2347247d53afe83646401416f5ee4e3ecd735 Mon Sep 17 00:00:00 2001 From: summerhenson Date: Tue, 13 Feb 2024 16:37:59 -0500 Subject: [PATCH 05/70] Update StarBattleCellType.java Fixed StarBattleCellType typos --- .../edu/rpi/legup/puzzle/starbattle/StarBattleCellType.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellType.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellType.java index 0548a6b38..8fb3338f7 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellType.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellType.java @@ -1,12 +1,12 @@ //StarBattleCellType.java package edu.rpi.legup.puzzle.starbattle; -public enum StarBattleType { +public enum StarBattleCellType { UNKNOWN(-3), STAR(-2), BLACK(-1); public int value; - StarBattleCell(int value) { + StarBattleCellType(int value) { this.value = value; } } \ No newline at end of file From 12b7a4358c042c863ea0a03792cd790207244d18 Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Tue, 13 Feb 2024 16:41:30 -0500 Subject: [PATCH 06/70] Added StarBattle.java Also changed the IDs for our assets --- .../legup/puzzle/starbattle/StarBattle.java | 33 +++++++++++++++++++ .../puzzle/starbattle/StarBattleCell.java | 0 .../puzzle/starbattle/elements/StarTile.java | 2 +- .../starbattle/elements/UnknownTile.java | 2 +- 4 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattle.java create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattle.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattle.java new file mode 100644 index 000000000..e9e18b92a --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattle.java @@ -0,0 +1,33 @@ +package edu.rpi.legup.puzzle.starbattle; +import edu.rpi.legup.model.Puzzle; +import edu.rpi.legup.model.gameboard.Board; + +public class StarBattle extends Puzzle { + public StarBattle() { + super(); + //this.name = "StarBattle"; + + //this.importer = new StarBattleImporter(this); + //this.exporter = new StarBattleExporter(this); + + //this.factory = new StarBattleCellFactory(); + } + + @Override + public void initializeView() { + } + + @Override + public Board generatePuzzle(int difficulty) { + return null; + } + + @Override + public boolean isBoardComplete(Board board) { + return true; + } + + @Override + public void onBoardChange(Board board) { + } +} diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java new file mode 100644 index 000000000..e69de29bb diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/StarTile.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/StarTile.java index 19ba7baed..d42cc0010 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/StarTile.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/StarTile.java @@ -4,6 +4,6 @@ public class StarTile extends NonPlaceableElement { public StarTile() { - super("LTUP-PLAC-0001", "Star Tile", "The star tile, the token of the game.", "edu/rpi/legup/images/starbattle/star.gif"); + super("STBL-PLAC-0001", "Star Tile", "The star tile, the token of the game.", "edu/rpi/legup/images/starbattle/star.gif"); } } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/UnknownTile.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/UnknownTile.java index 192a95357..3e1cbca26 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/UnknownTile.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/UnknownTile.java @@ -4,6 +4,6 @@ public class UnknownTile extends NonPlaceableElement { public UnknownTile() { - super("LTUP-PLAC-0001", "Unknown Tile", "An empty tile", "edu/rpi/legup/images/starbattle/star.gif"); + super("STBL-PLAC-0001", "Unknown Tile", "An empty tile", "edu/rpi/legup/images/starbattle/star.gif"); } } From 24450fd99b358f5dfb06d76933c21ad49e13d0bd Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:31:13 -0500 Subject: [PATCH 07/70] Added White Tile and finished starter code for Cell Only Board needs to be added to get the basic puzzle running. --- .../puzzle/starbattle/StarBattleCell.java | 85 ++++++++++++++++++ .../puzzle/starbattle/StarBattleCellType.java | 2 +- .../starbattle/elements/UnknownTile.java | 2 +- .../puzzle/starbattle/elements/WhiteTile.java | 10 +++ .../edu/rpi/legup/images/starbattle/white.gif | Bin 0 -> 9700 bytes 5 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/elements/WhiteTile.java create mode 100644 src/main/resources/edu/rpi/legup/images/starbattle/white.gif diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java index e69de29bb..22d74dd7f 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java @@ -0,0 +1,85 @@ +package edu.rpi.legup.puzzle.starbattle; + +import edu.rpi.legup.model.elements.Element; +import edu.rpi.legup.model.gameboard.GridCell; + +import java.awt.*; +import java.awt.event.MouseEvent; + +public class StarBattleCell extends GridCell { + private int groupIndex; + private int max; + + /** + * StarBattleCell Constructor - creates a new StarBattle cell to hold the puzzleElement + * + * @param valueInt value of the star battle cell denoting its state + * @param location location of the cell on the board + * @param size size of the star battle cell + */ + public StarBattleCell(int value, Point location, int groupIndex, int size) { + super(value, location); + this.groupIndex = groupIndex; + this.max = size; + } + + @Override + public void setType(Element e, MouseEvent m) { + switch (e.getElementID()) { + case "STBL-PLAC-0001": + this.data = -3; + break; + case "STBL-PLAC-0002": + this.data = -2; + break; + case "STBL-PLAC-0003": + this.data = -1; + break; + + case "STBL-UNPL-0001"://Not sure how button events work + switch (m.getButton()){ + case MouseEvent.BUTTON1: + if (this.data > 0 || this.data < -3) { + this.data = -3; + } + else { + this.data = this.data + 1; + } + break; + case MouseEvent.BUTTON3: + if (this.data > -4) { + this.data = this.data - 1; + } + else { + this.data = -1;//Unsure + } + break; + } + break; + } + } + + public StarBattleCellType getType() { + switch (data) { + case -3: + return StarBattleCellType.UNKNOWN; + case -2: + return StarBattleCellType.STAR; + case -1: + return StarBattleCellType.BLACK; + default: + if (data >= 0) { + return StarBattleCellType.UNKNOWN; + } + } + return null; + } + + public StarBattleCell copy() { + StarBattleCell copy = new StarBattleCell(data, (Point) location.clone(), groupIndex, max); + copy.setIndex(index); + copy.setModifiable(isModifiable); + copy.setGiven(isGiven); + return copy; + } +} \ No newline at end of file diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellType.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellType.java index 8fb3338f7..f3524034e 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellType.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellType.java @@ -2,7 +2,7 @@ package edu.rpi.legup.puzzle.starbattle; public enum StarBattleCellType { - UNKNOWN(-3), STAR(-2), BLACK(-1); + WHITE(-3), STAR(-2), BLACK(-1), UNKNOWN(0); public int value; diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/UnknownTile.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/UnknownTile.java index 3e1cbca26..c2459f642 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/UnknownTile.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/UnknownTile.java @@ -4,6 +4,6 @@ public class UnknownTile extends NonPlaceableElement { public UnknownTile() { - super("STBL-PLAC-0001", "Unknown Tile", "An empty tile", "edu/rpi/legup/images/starbattle/star.gif"); + super("STBL-UNPL-0001", "Unknown Tile", "An empty tile", "edu/rpi/legup/images/starbattle/star.gif"); } } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/WhiteTile.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/WhiteTile.java new file mode 100644 index 000000000..a064c1fad --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/elements/WhiteTile.java @@ -0,0 +1,10 @@ +package edu.rpi.legup.puzzle.starbattle.elements; + +import edu.rpi.legup.model.elements.PlaceableElement; + +public class WhiteTile extends PlaceableElement { + public WhiteTile() { + super("STBL-PLAC-0001", "White Tile", "The white tile", "edu/rpi/legup/images/starbattle/white.gif"); + } +} + diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/white.gif b/src/main/resources/edu/rpi/legup/images/starbattle/white.gif new file mode 100644 index 0000000000000000000000000000000000000000..fc2c683eb7860f47d4322fe0e73b0508099a89de GIT binary patch literal 9700 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 literal 0 HcmV?d00001 From c64481dbd4f964927f53fa0956c67eb3c83057c6 Mon Sep 17 00:00:00 2001 From: Sarah Date: Fri, 16 Feb 2024 13:36:31 -0500 Subject: [PATCH 08/70] create StarBattleBoard.java --- .../puzzle/starbattle/StarBattleBoard.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java new file mode 100644 index 000000000..300695111 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java @@ -0,0 +1,21 @@ +package edu.rpi.legup.puzzle.starbattle; + +import edu.rpi.legup.model.gameboard.GridBoard; +import edu.rpi.legup.model.gameboard.PuzzleElement; + +public class StarBattleBoard extends GridBoard { + public StarBattleBoard(int width, int height) { + super(width, height); + } + + public StarBattleBoard(int size) { + super(size, size); + } + + @Override + public StarBattleCell getCell(int x, int y) { + return (StarBattleCell) super.getCell(x,y); + } +} + + From f3b23833821404742f88b8dd073e01b5fe25ab0d Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Fri, 16 Feb 2024 16:36:02 -0500 Subject: [PATCH 09/70] Added getRow, getCol, and potential group implementation for later. All StarBattle boards should be square, so I deleted the width height constructor. I also added size for returning a row, col, for future rules. --- .../puzzle/starbattle/StarBattleBoard.java | 34 +++++++++++++++++-- .../rpi/legup/puzzle/starbattle/allfiles.txt | 10 +++--- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java index 300695111..a32197fa7 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java @@ -1,21 +1,49 @@ package edu.rpi.legup.puzzle.starbattle; +import java.util.*; + import edu.rpi.legup.model.gameboard.GridBoard; import edu.rpi.legup.model.gameboard.PuzzleElement; public class StarBattleBoard extends GridBoard { - public StarBattleBoard(int width, int height) { - super(width, height); - } + + private int size; + //private ArrayList groupSizes; public StarBattleBoard(int size) { super(size, size); + this.size = size; } @Override public StarBattleCell getCell(int x, int y) { return (StarBattleCell) super.getCell(x,y); } + + /* + public StarBattleCell getCell(int groupIndex, int x, int y) { + return getCell(x + (groupIndex % groupSize) * groupSize, y + (groupIndex / groupSize) * groupSize); + }*/ + + public int getSize() { + return size; + } + + public Set getRow(int rowNum) { + Set row = new HashSet<>(); + for (int i = 0; i < size; i++) { + row.add(getCell(i, rowNum)); + } + return row; + } + + public Set getCol(int colNum) { + Set column = new HashSet<>(); + for (int i = 0; i < size; i++) { + column.add(getCell(colNum, i)); + } + return column; + } } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt b/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt index 7f006191a..1b1824f21 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt @@ -101,14 +101,14 @@ public class StarBattleCell extends GridCell { public void setType(Element e, MouseEvent m) { switch (e.getElementID()) { case "SBUP-PLAC-0001": - this.data = -4; + this.data = -3; break; - case "SBUP-UNPL-0002": - this.data = -1; - break; - case "SBUP-UNPL-0003": + case "SBUP-PLAC-0002": this.data = -2; break; + case "SBUP-PLAC-0003": + this.data = -1; + break; case "SBUP-UNPL-0001"://Not sure how button events work switch (m.getButton()){ case MouseEvent.BUTTON1: From f6e11dcc1eed36b44a4bae8aead8da03f4e53496 Mon Sep 17 00:00:00 2001 From: summerhenson Date: Fri, 23 Feb 2024 11:49:24 -0500 Subject: [PATCH 10/70] Update allfiles.txt Fixed some temporary documentation to reference star battle instead of sudoku. --- src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt b/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt index 1b1824f21..7970eadbf 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt @@ -85,11 +85,11 @@ public class StarBattleCell extends GridCell { private int max; /** - * SudokuCell Constructor - creates a new Sudoku cell to hold the puzzleElement + * StarBattleCell Constructor - creates a new StarBattle cell to hold the puzzleElement * * @param valueInt value of the star battle cell denoting its state * @param location location of the cell on the board - * @param size size of the sudoku cell + * @param size size of the star battle cell */ public StarBattleCell(int value, Point location, int groupIndex, int size) { super(value, location); From 9c3daa796877a9ade90c6a3cba0378ad09faca1f Mon Sep 17 00:00:00 2001 From: summerhenson Date: Fri, 23 Feb 2024 15:29:26 -0500 Subject: [PATCH 11/70] Direct Rule Classes Created skeletons of classes for direct rules. --- .../starbattle/rules/BlackoutDirectRule.java | 49 +++++++++++++++++++ .../rules/FinishWithStarsDirectRule.java | 47 ++++++++++++++++++ .../RegionsWithinRowsColumnsDirectRule.java | 46 +++++++++++++++++ .../RowsColumnsWithinRegionsDirectRule.java | 46 +++++++++++++++++ .../rules/SurroundStarDirectRule.java | 48 ++++++++++++++++++ 5 files changed, 236 insertions(+) create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsColumnsDirectRule.java create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsColumnsWithinRegionsDirectRule.java create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java new file mode 100644 index 000000000..3c89b0800 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java @@ -0,0 +1,49 @@ +package edu.rpi.legup.puzzle.starbattle.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.starbattle.StarBattleBoard; +import edu.rpi.legup.puzzle.starbattle.StarBattleCell; +import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; + +public class BlackoutDirectRule extends DirectRule { + + public BlackoutDirectRule() { + super("STBL-BASC-0001", + "Blackout", + "If a row, column, or region has enough stars, its unknown spaces are black.", + "INSERT IMAGE NAME HERE"); + } + + /** + * 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; + } + + /** + * 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/starbattle/rules/FinishWithStarsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java new file mode 100644 index 000000000..d2711eced --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java @@ -0,0 +1,47 @@ +package edu.rpi.legup.puzzle.starbattle.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.starbattle.StarBattleBoard; +import edu.rpi.legup.puzzle.starbattle.StarBattleCell; +import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; + +public class FinishWithStarsDirectRule extends DirectRule { + + public FinishWithStarsDirectRule() { + super("STBL-BASC-0002", + "Finish With Stars", + "Unknown spaces must be stars if there are just enough in a row, column, or region to satisfy the puzzle number.", + "INSERT IMAGE NAME HERE"); + } + + /** + * 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; + } + + /** + * 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/starbattle/rules/RegionsWithinRowsColumnsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsColumnsDirectRule.java new file mode 100644 index 000000000..81645a2ad --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsColumnsDirectRule.java @@ -0,0 +1,46 @@ +package edu.rpi.legup.puzzle.starbattle.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.starbattle.StarBattleBoard; +import edu.rpi.legup.puzzle.starbattle.StarBattleCell; +import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; + +public class RegionsWithinRowsColumnsDirectRule extends DirectRule { + public RegionsWithinRowsColumnsDirectRule() { + super("STBL-BASC-0003", + "Regions Within Rows/Columns", + "If a number of regions is fully contained by an equal number of rows or columns, spaces of other regions in those rows or columns must be black.", + "INSERT IMAGE NAME HERE"); + } + + /** + * 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; + } + + /** + * 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/starbattle/rules/RowsColumnsWithinRegionsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsColumnsWithinRegionsDirectRule.java new file mode 100644 index 000000000..53a7b27ee --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsColumnsWithinRegionsDirectRule.java @@ -0,0 +1,46 @@ +package edu.rpi.legup.puzzle.starbattle.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.starbattle.StarBattleBoard; +import edu.rpi.legup.puzzle.starbattle.StarBattleCell; +import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; + +public class RowsColumnsWithinRegionsDirectRule extends DirectRule { + public RowsColumnsWithinRegionsDirectRule() { + super("STBL-BASC-0004", + "Rows/Columns Within Regions", + "If a number of rows or columns is fully contained by an equal number of regions, spaces of other rows or columns, respectively, in those regions must be black.", + "INSERT IMAGE NAME HERE"); + } + + /** + * 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; + } + + /** + * 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/starbattle/rules/SurroundStarDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java new file mode 100644 index 000000000..932ef7ddd --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java @@ -0,0 +1,48 @@ +package edu.rpi.legup.puzzle.starbattle.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.starbattle.StarBattleBoard; +import edu.rpi.legup.puzzle.starbattle.StarBattleCell; +import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; + +public class SurroundStarDirectRule extends DirectRule { + + public SurroundStarDirectRule() { + super("STBL-BASC-0005", + "Surround Star", + "Any space adjacent to a star must be black.", + "INSERT IMAGE NAME HERE"); + } + + /** + * 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; + } + + /** + * 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; + } +} + From cda9403b1f9bb82880db422e7e18128b3bd53ba4 Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Fri, 23 Feb 2024 16:01:39 -0500 Subject: [PATCH 12/70] Added javadoc to cell --- .../java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java index 22d74dd7f..2e89649e2 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java @@ -15,6 +15,7 @@ public class StarBattleCell extends GridCell { * * @param valueInt value of the star battle cell denoting its state * @param location location of the cell on the board + * @param groupIndex indicates what group # the cell is in. * @param size size of the star battle cell */ public StarBattleCell(int value, Point location, int groupIndex, int size) { From 0fb71deb5b70bd388e02b2eaa3b3658a81f19fb7 Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Fri, 23 Feb 2024 16:24:04 -0500 Subject: [PATCH 13/70] Adding barebones Contradiction Rules Files Might have to separate the too few and too many rules into 3 files, for row, column, and region. --- .../rules/ClashingOrbitContradictionRule | 33 +++++++++++++++++++ .../rules/TooFewStarsContradictionRule | 33 +++++++++++++++++++ .../rules/TooManyStarsContradictionRule | 33 +++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooFewStarsContradictionRule create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule new file mode 100644 index 000000000..2eb584ea1 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule @@ -0,0 +1,33 @@ +package edu.rpi.legup.puzzle.starbattle.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.tree.TreeNode; +import edu.rpi.legup.model.tree.TreeTransition; +import edu.rpi.legup.puzzle.starbattle.StarBattleBoard; +import edu.rpi.legup.puzzle.starbattle.StarBattleCell; +import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; + +public class ClashingOrbitContradictionRule extends ContradictionRule { + + public ClashingOrbitContradictionRule() { + super("STBL-CONT-0003", + "Clashing Orbit", + "No two stars can be adjacent to each other.", + "INSERT IMAGE NAME HERE"); + } + + /** + * 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) { + return super.getNoContradictionMessage(); + } +} \ No newline at end of file diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooFewStarsContradictionRule b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooFewStarsContradictionRule new file mode 100644 index 000000000..a063b2b6b --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooFewStarsContradictionRule @@ -0,0 +1,33 @@ +package edu.rpi.legup.puzzle.starbattle.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.tree.TreeNode; +import edu.rpi.legup.model.tree.TreeTransition; +import edu.rpi.legup.puzzle.starbattle.StarBattleBoard; +import edu.rpi.legup.puzzle.starbattle.StarBattleCell; +import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; + +public class TooFewStarsContradictionRule extends ContradictionRule { + + public TooFewStarsContradictionRule() { + super("STBL-CONT-0002", + "Too Few Stars", + "There are too few stars in this region/row/column and there are not enough places to put the remaining stars.", + "INSERT IMAGE NAME HERE"); + } + + /** + * 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) { + return super.getNoContradictionMessage(); + } +} \ No newline at end of file diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule new file mode 100644 index 000000000..56cd71ba7 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule @@ -0,0 +1,33 @@ +package edu.rpi.legup.puzzle.starbattle.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.tree.TreeNode; +import edu.rpi.legup.model.tree.TreeTransition; +import edu.rpi.legup.puzzle.starbattle.StarBattleBoard; +import edu.rpi.legup.puzzle.starbattle.StarBattleCell; +import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; + +public class TooManyStarsContradictionRule extends ContradictionRule { + + public TooManyStarsContradictionRule() { + super("STBL-CONT-0001", + "Too Many Stars", + "There are too many stars in this region/row/column.", + "INSERT IMAGE NAME HERE"); + } + + /** + * 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) { + return super.getNoContradictionMessage(); + } +} \ No newline at end of file From cef9d476d8ba74a82112c47b1186a5375a12fb02 Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Fri, 23 Feb 2024 18:06:34 -0500 Subject: [PATCH 14/70] Added the Element and Board Controller Hopefully we can upload puzzles now that regions are done. --- .../legup/puzzle/starbattle/StarBattle.java | 2 + .../starbattle/StarBattleController.java | 36 +++++++++++++++ .../starbattle/StarBattleElementView.java | 46 +++++++++++++++++++ .../puzzle/starbattle/StarBattleView.java | 0 4 files changed, 84 insertions(+) create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleController.java create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleElementView.java create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattle.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattle.java index e9e18b92a..78800916e 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattle.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattle.java @@ -15,6 +15,8 @@ public StarBattle() { @Override public void initializeView() { + boardView = new StarBattleView((StarBattleBoard) currentBoard); + addBoardListener(boardView); } @Override diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleController.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleController.java new file mode 100644 index 000000000..f7a094397 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleController.java @@ -0,0 +1,36 @@ +package edu.rpi.legup.puzzle.starbattle; + +import edu.rpi.legup.controller.ElementController; +import edu.rpi.legup.model.gameboard.PuzzleElement; + +import java.awt.event.MouseEvent; + +public class StarBattleController extends ElementController { + @Override + public void changeCell(MouseEvent e, PuzzleElement data) { + StarBattleCell cell = (StarBattleCell) 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(-3); + } + else { + data.setData(cell.getData() + 1); + } + } + } + else { + if (e.getButton() == MouseEvent.BUTTON3) { + if (cell.getData() == -3) { + data.setData(0); + } + else { + data.setData(cell.getData() - 1); + } + } + } + } +} diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleElementView.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleElementView.java new file mode 100644 index 000000000..a88773a06 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleElementView.java @@ -0,0 +1,46 @@ +package edu.rpi.legup.puzzle.starbattle; + +import edu.rpi.legup.ui.boardview.GridElementView; + +import java.awt.*; + +public class StarBattleElementView extends GridElementView { + + public StarBattleElementView(StarBattleCell cell) { + super(cell); + } + + @Override + public StarBattleCell getPuzzleElement() { + return (StarBattleCell) super.getPuzzleElement(); + } + + @Override + public void drawElement(Graphics2D graphics2D) { + StarBattleCell cell = (StarBattleCell) puzzleElement; + StarBattleCellType type = cell.getType(); + if (type == StarBattleCellType.STAR) { + graphics2D.setColor(Color.LIGHT_GRAY); + graphics2D.fillRect(location.x, location.y, size.width, size.height); + graphics2D.drawImage(StarBattleView.STAR, location.x, location.y, size.width, size.height, Color.WHITE, null); + graphics2D.setColor(Color.BLACK); + graphics2D.drawRect(location.x, location.y, size.width, size.height); + } else if (type == StarBattleCellType.BLACK) { + graphics2D.setStroke(new BasicStroke(1)); + graphics2D.setColor(Color.BLACK); + graphics2D.fillRect(location.x, location.y, size.width, size.height); + } else if (type == StarBattleCellType.WHITE) { + graphics2D.setStroke(new BasicStroke(1)); + graphics2D.setColor(Color.WHITE); + graphics2D.fillRect(location.x, location.y, size.width, size.height); + graphics2D.setColor(Color.BLACK); + graphics2D.drawRect(location.x, location.y, size.width, size.height); + } else if (type == StarBattleCellType.UNKNOWN) { + graphics2D.setStroke(new BasicStroke(1)); + graphics2D.setColor(Color.LIGHT_GRAY); + graphics2D.fillRect(location.x, location.y, size.width, size.height); + graphics2D.setColor(Color.BLACK); + graphics2D.drawRect(location.x, location.y, size.width, size.height); + } + } +} diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java new file mode 100644 index 000000000..e69de29bb From 973f041a5ec3fd67d40406a5d6c39c7be7655267 Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Fri, 23 Feb 2024 20:19:39 -0500 Subject: [PATCH 15/70] Added View file --- .../puzzle/starbattle/StarBattleView.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java index e69de29bb..b79b7743a 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java @@ -0,0 +1,55 @@ +package edu.rpi.legup.puzzle.starbattle; + +import java.io.IOException; + +import javax.imageio.ImageIO; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import edu.rpi.legup.puzzle.nurikabe.NurikabeBoard; +import edu.rpi.legup.puzzle.nurikabe.NurikabeView; +import edu.rpi.legup.puzzle.starbattle.StarBattleBoard; +import edu.rpi.legup.puzzle.starbattle.StarBattleCell; +import edu.rpi.legup.puzzle.starbattle.StarBattleController; +import edu.rpi.legup.puzzle.starbattle.StarBattleElementView; +import edu.rpi.legup.puzzle.starbattle.StarBattleView; +import edu.rpi.legup.ui.boardview.GridBoardView; + +import edu.rpi.legup.controller.BoardController; +import edu.rpi.legup.model.gameboard.CaseBoard; +import edu.rpi.legup.model.gameboard.PuzzleElement; +import edu.rpi.legup.ui.boardview.ElementView; +import java.awt.*; +import java.util.ArrayList; + +public class StarBattleView extends GridBoardView { + private final static Logger LOGGER = LogManager.getLogger(StarBattleView.class.getName()); + + static Image STAR; + + static { + try { + STAR = ImageIO.read(ClassLoader.getSystemResourceAsStream("edu/rpi/legup/images/starbattle/star.png")); + } + catch (IOException e) { + LOGGER.error("Failed to open StarBattle images"); + } + } + + public StarBattleView(StarBattleBoard board) { + super(new BoardController(), new StarBattleController(), board.getDimension()); + + for (PuzzleElement puzzleElement : board.getPuzzleElements()) { + StarBattleCell cell = (StarBattleCell) puzzleElement; + Point loc = cell.getLocation(); + StarBattleElementView elementView = new StarBattleElementView(cell); + elementView.setIndex(cell.getIndex()); + elementView.setSize(elementSize); + elementView.setLocation(new Point(loc.x * elementSize.width, loc.y * elementSize.height)); + elementViews.add(elementView); + } + } + + +} From 3fe6695c1ed01db14c2dcc7ef2a26d8aa3484ff8 Mon Sep 17 00:00:00 2001 From: summerhenson Date: Tue, 27 Feb 2024 16:50:04 -0500 Subject: [PATCH 16/70] Create StarOrEmptyCaseRule.java Created skeleton of class for Star or Empty case rule. --- .../starbattle/rules/StarOrEmptyCaseRule.java | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java new file mode 100644 index 000000000..a30823faa --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java @@ -0,0 +1,78 @@ +package edu.rpi.legup.puzzle.starbattle.rules; + +import edu.rpi.legup.model.rules.CaseRule; +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.TreeTransition; +import edu.rpi.legup.puzzle.starbattle.StarBattleBoard; +import edu.rpi.legup.puzzle.starbattle.StarBattleCell; +import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; + +import java.util.ArrayList; + +public class StarOrEmptyCaseRule extends CaseRule { + + public StarOrEmptyCaseRule() { + super("STBL-CASE-0002", + "Star or Empty", + "Each unknown space is either a star or empty.", + "INSERT IMAGE NAME HERE"); + } + + /** + * 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 + */ + @Override + public String checkRuleRaw(TreeTransition transition) { + //TODO: implement this + return null; + } + + @Override + public CaseBoard getCaseBoard(Board board) { + StarBattleBoard starBattleBoard = (StarBattleBoard) board.copy(); + CaseBoard caseBoard = new CaseBoard(starBattleBoard, this); + starBattleBoard.setModifiable(false); + for (PuzzleElement element : starBattleBoard.getPuzzleElements()) { + if (((StarBattleCell) element).getType() == StarBattleCellType.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<>(); + Board case1 = board.copy(); + PuzzleElement data1 = case1.getPuzzleElement(puzzleElement); + data1.setData(StarBattleCellType.STAR); + case1.addModifiedData(data1); + cases.add(case1); + + Board case2 = board.copy(); + PuzzleElement data2 = case2.getPuzzleElement(puzzleElement); + data2.setData(StarBattleCellType.BLACK); + case2.addModifiedData(data2); + cases.add(case2); + + return cases; + } + + @Override + public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) { + return null; + } +} From e677a6eec68aa48ebe8fe121923f979b227baf2f Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Tue, 27 Feb 2024 16:50:36 -0500 Subject: [PATCH 17/70] Adding Region files --- .../rpi/legup/model/gameboard/GridRegion.java | 53 +++++++++++++++++++ .../puzzle/starbattle/StarBattleRegion.java | 9 ++++ 2 files changed, 62 insertions(+) create mode 100644 src/main/java/edu/rpi/legup/model/gameboard/GridRegion.java create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleRegion.java 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..6718ab6f4 --- /dev/null +++ b/src/main/java/edu/rpi/legup/model/gameboard/GridRegion.java @@ -0,0 +1,53 @@ +package edu.rpi.legup.model.gameboard; + +import java.util.ArrayList; +import java.util.List; + +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 remove 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(); + } + + /* + public void colorRegion(){} + */ + +} diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleRegion.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleRegion.java new file mode 100644 index 000000000..68a25bc3b --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleRegion.java @@ -0,0 +1,9 @@ +package edu.rpi.legup.puzzle.starbattle; + +import edu.rpi.legup.model.gameboard.GridRegion; + +public class StarBattleRegion extends GridRegion{ + public StarBattleRegion() { + super(); + } +} From 23df2a15c08736e4902b1093a9e6eb92084c2ef7 Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Tue, 27 Feb 2024 17:26:50 -0500 Subject: [PATCH 18/70] Added the first XML puzzle file to be read later. --- .../6x6 Star Battle 1star Normal.xml | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 puzzles files/starbattle/6x6 Star Battle 1star Normal.xml diff --git a/puzzles files/starbattle/6x6 Star Battle 1star Normal.xml b/puzzles files/starbattle/6x6 Star Battle 1star Normal.xml new file mode 100644 index 000000000..4d9f8b631 --- /dev/null +++ b/puzzles files/starbattle/6x6 Star Battle 1star Normal.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 47337b7e5457b5991be30616b38e618ae0ffaa3e Mon Sep 17 00:00:00 2001 From: summerhenson Date: Tue, 27 Feb 2024 17:31:09 -0500 Subject: [PATCH 19/70] Implement Surround Star Direct Rule Wrote an implementation for checkRuleRawAt for Surround Star Direct Rule. --- ...le => ClashingOrbitContradictionRule.java} | 0 .../rules/SurroundStarDirectRule.java | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+) rename src/main/java/edu/rpi/legup/puzzle/starbattle/rules/{ClashingOrbitContradictionRule => ClashingOrbitContradictionRule.java} (100%) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule.java similarity index 100% rename from src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule rename to src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule.java diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java index 932ef7ddd..33f148e94 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java @@ -2,9 +2,13 @@ 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.nurikabe.NurikabeBoard; +import edu.rpi.legup.puzzle.nurikabe.NurikabeType; +import edu.rpi.legup.puzzle.nurikabe.rules.NoNumberContradictionRule; import edu.rpi.legup.puzzle.starbattle.StarBattleBoard; import edu.rpi.legup.puzzle.starbattle.StarBattleCell; import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; @@ -29,7 +33,22 @@ public SurroundStarDirectRule() { */ @Override public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) { + StarBattleBoard board = (StarBattleBoard) transition.getBoard(); + StarBattleBoard origBoard = (StarBattleBoard) transition.getParents().get(0).getBoard(); + ContradictionRule contraRule = new ClashingOrbitContradictionRule(); + StarBattleCell cell = (StarBattleCell) board.getPuzzleElement(puzzleElement); + + if (cell.getType() != StarBattleCellType.BLACK) { + return "Only black cells are allowed for this rule!"; + } + + StarBattleBoard modified = (StarBattleBoard) origBoard.copy(); + //TODO: please for the love of god make a copy method for star battle board because this isn't actually going to work otherwise + modified.getPuzzleElement(puzzleElement).setData(StarBattleCellType.STAR); + if (contraRule.checkContradictionAt(modified, puzzleElement) != null) { + return "Black cells must be placed adjacent to a star!"; + } return null; } From 024aa4f94e6b083ed008f7369713e7259519fcdc Mon Sep 17 00:00:00 2001 From: summerhenson Date: Tue, 27 Feb 2024 17:32:33 -0500 Subject: [PATCH 20/70] Changed files to java instead of text. --- ...ewStarsContradictionRule => TooFewStarsContradictionRule.java} | 0 ...yStarsContradictionRule => TooManyStarsContradictionRule.java} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/main/java/edu/rpi/legup/puzzle/starbattle/rules/{TooFewStarsContradictionRule => TooFewStarsContradictionRule.java} (100%) rename src/main/java/edu/rpi/legup/puzzle/starbattle/rules/{TooManyStarsContradictionRule => TooManyStarsContradictionRule.java} (100%) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooFewStarsContradictionRule b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooFewStarsContradictionRule.java similarity index 100% rename from src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooFewStarsContradictionRule rename to src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooFewStarsContradictionRule.java diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java similarity index 100% rename from src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule rename to src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java From 2d9dc038b9b14e029acf4e48a5d62bcc3ac7bb4b Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 27 Feb 2024 18:47:58 -0500 Subject: [PATCH 21/70] created add star case rule and reference sheet to keep track of the rules --- .../starbattle/rules/AddStarCaseRule.java | 57 +++++++++++++++++++ .../rules/starbattle_reference_sheet.txt | 15 +++++ 2 files changed, 72 insertions(+) create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/rules/AddStarCaseRule.java create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/rules/starbattle_reference_sheet.txt diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/AddStarCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/AddStarCaseRule.java new file mode 100644 index 000000000..d945f5be9 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/AddStarCaseRule.java @@ -0,0 +1,57 @@ +package edu.rpi.legup.puzzle.starbattle.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.lightup.LightUpBoard; +import edu.rpi.legup.puzzle.lightup.LightUpCell; +import edu.rpi.legup.puzzle.starbattle.*; + +import java.awt.*; +import java.util.*; +import java.util.List; + +public class AddStarCaseRule extends CaseRule { + public AddStarCaseRule() { + super("STBL-CASE-0001", + "Add Star", + "Different ways a region's star number can be satisfied", + ""); + } + + @Override + public CaseBoard getCaseBoard(Board board) { + StarBattleBoard starbattleBoard = (StarBattleBoard) board.copy(); + CaseBoard caseBoard = new CaseBoard(starbattleBoard, this); + + return caseBoard; + } + + /** + * Gets the possible cases at a specific location based on this case rule + * + * @param board the current board state + * @param puzzleElement the cell to determine the possible cases for + * @return a list of elements the specified spot could be + */ + @Override + public List getCases(Board board, PuzzleElement puzzleElement) { + StarBattleBoard starbattleBoard = (StarBattleBoard) board; + // take selected spot, check if there are any stars in that row, column, and region + + // do we want all possible cases, that seems like a lot + return null; + } + + @Override + public String checkRuleRaw(TreeTransition transition) { + return null; + } + + @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/starbattle/rules/starbattle_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/starbattle_reference_sheet.txt new file mode 100644 index 000000000..70e81bb73 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/starbattle_reference_sheet.txt @@ -0,0 +1,15 @@ +Case Rules: +Add Star: STBL-CASE-0001 +Star or Empty: STBL-CASE-0002 + +Basic Rules: +Blackout: STBL-BASC-0001 +Finish With Stars: STBL-BASC-0002 +Regions Within Rows or Columns: STBL-BASC-0003 +Rows or Columns Within Regions: STBL-BASC-0004 +Surround Star: STBL-BASC-0005 + +Contradiction Rules: +Too Many Stars: STBL-CONT-0001 +Too Few Stars: STBL-CONT-0002 +Clashing Orbit: STBL-CONT-0003 \ No newline at end of file From 7f2406c99d01075d5e25afe5279c08d874a0608b Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Tue, 12 Mar 2024 16:34:56 -0400 Subject: [PATCH 22/70] New puzzle --- ....xml => 6x6 Star Battle 1star Normal1.xml} | 0 .../6x6 Star Battle 1star Normal2.xml | 68 +++++++++++++++++++ 2 files changed, 68 insertions(+) rename puzzles files/starbattle/{6x6 Star Battle 1star Normal.xml => 6x6 Star Battle 1star Normal1.xml} (100%) create mode 100644 puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml diff --git a/puzzles files/starbattle/6x6 Star Battle 1star Normal.xml b/puzzles files/starbattle/6x6 Star Battle 1star Normal1.xml similarity index 100% rename from puzzles files/starbattle/6x6 Star Battle 1star Normal.xml rename to puzzles files/starbattle/6x6 Star Battle 1star Normal1.xml diff --git a/puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml b/puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml new file mode 100644 index 000000000..cd34805e5 --- /dev/null +++ b/puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 555890adc30f1f658be9a45e6ae4cc2a2cae362a Mon Sep 17 00:00:00 2001 From: summerhenson Date: Tue, 12 Mar 2024 17:02:07 -0400 Subject: [PATCH 23/70] Add Regions to StarBattleBoard --- .../puzzle/starbattle/StarBattleBoard.java | 24 +++++++++++++++++++ .../puzzle/starbattle/StarBattleRegion.java | 8 +++++++ .../rules/SurroundStarDirectRule.java | 3 --- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java index a32197fa7..143fbaca6 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java @@ -8,11 +8,13 @@ public class StarBattleBoard extends GridBoard { private int size; + protected List regions; //private ArrayList groupSizes; public StarBattleBoard(int size) { super(size, size); this.size = size; + this.regions = new ArrayList<>(); } @Override @@ -44,6 +46,28 @@ public Set getCol(int colNum) { } return column; } + + public StarBattleRegion getRegion(int index) { + if (index >= size) { + return null; + } + return regions.get(index); + } + + public StarBattleBoard copy() { + StarBattleBoard copy = new StarBattleBoard(size); + 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()); + } + if (x < this.regions.size()) + copy.regions.add(this.getRegion(x).copy()); + } + for (PuzzleElement e : modifiedData) { + copy.getPuzzleElement(e).setModifiable(false); + } + return copy; + } } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleRegion.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleRegion.java index 68a25bc3b..ebae5ce86 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleRegion.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleRegion.java @@ -6,4 +6,12 @@ public class StarBattleRegion extends GridRegion{ public StarBattleRegion() { super(); } + + public StarBattleRegion copy() { + StarBattleRegion copy = new StarBattleRegion(); + for (StarBattleCell c: regionCells) { + copy.addCell(c.copy()); + } + return copy; + } } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java index 33f148e94..1565bff9d 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java @@ -6,9 +6,6 @@ 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.nurikabe.NurikabeBoard; -import edu.rpi.legup.puzzle.nurikabe.NurikabeType; -import edu.rpi.legup.puzzle.nurikabe.rules.NoNumberContradictionRule; import edu.rpi.legup.puzzle.starbattle.StarBattleBoard; import edu.rpi.legup.puzzle.starbattle.StarBattleCell; import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; From 1f72e6ab5d9a9532fc76cbf6fe74b44b5eaca8e1 Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Tue, 12 Mar 2024 17:03:49 -0400 Subject: [PATCH 24/70] Changed some elements in puzzles and added importer --- puzzles files/starbattle/6x6 Star Battle 1star Normal1.xml | 2 +- puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml | 2 +- .../edu/rpi/legup/puzzle/starbattle/StarBattleImporter.java | 0 .../java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java | 2 -- 4 files changed, 2 insertions(+), 4 deletions(-) create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleImporter.java diff --git a/puzzles files/starbattle/6x6 Star Battle 1star Normal1.xml b/puzzles files/starbattle/6x6 Star Battle 1star Normal1.xml index 4d9f8b631..ce1330437 100644 --- a/puzzles files/starbattle/6x6 Star Battle 1star Normal1.xml +++ b/puzzles files/starbattle/6x6 Star Battle 1star Normal1.xml @@ -1,7 +1,7 @@ - + diff --git a/puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml b/puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml index cd34805e5..10eb04aa3 100644 --- a/puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml +++ b/puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml @@ -1,7 +1,7 @@ - + diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleImporter.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleImporter.java new file mode 100644 index 000000000..e69de29bb diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java index b79b7743a..fdf0df221 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java @@ -7,8 +7,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import edu.rpi.legup.puzzle.nurikabe.NurikabeBoard; -import edu.rpi.legup.puzzle.nurikabe.NurikabeView; import edu.rpi.legup.puzzle.starbattle.StarBattleBoard; import edu.rpi.legup.puzzle.starbattle.StarBattleCell; import edu.rpi.legup.puzzle.starbattle.StarBattleController; From be30904d9a2e0b9a7b9dce1deb0b8ec65b29bca6 Mon Sep 17 00:00:00 2001 From: summerhenson Date: Tue, 12 Mar 2024 17:10:49 -0400 Subject: [PATCH 25/70] Blackout rule check method --- .../starbattle/rules/BlackoutDirectRule.java | 16 ++++++++++++++++ .../starbattle/rules/SurroundStarDirectRule.java | 1 - 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java index 3c89b0800..57a5688f2 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java @@ -2,6 +2,7 @@ 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; @@ -30,6 +31,21 @@ public BlackoutDirectRule() { @Override public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) { + StarBattleBoard board = (StarBattleBoard) transition.getBoard(); + StarBattleBoard origBoard = (StarBattleBoard) transition.getParents().get(0).getBoard(); + ContradictionRule contraRule = new TooManyStarsContradictionRule(); + + StarBattleCell cell = (StarBattleCell) board.getPuzzleElement(puzzleElement); + + if (cell.getType() != StarBattleCellType.BLACK) { + return "Only black cells are allowed for this rule!"; + } + + StarBattleBoard modified = (StarBattleBoard) origBoard.copy(); + modified.getPuzzleElement(puzzleElement).setData(StarBattleCellType.STAR); + if (contraRule.checkContradictionAt(modified, puzzleElement) != null) { + return "Black cells must be placed in a row, region, or column with enough stars!"; + } return null; } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java index 1565bff9d..0c46da09c 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java @@ -41,7 +41,6 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem } StarBattleBoard modified = (StarBattleBoard) origBoard.copy(); - //TODO: please for the love of god make a copy method for star battle board because this isn't actually going to work otherwise modified.getPuzzleElement(puzzleElement).setData(StarBattleCellType.STAR); if (contraRule.checkContradictionAt(modified, puzzleElement) != null) { return "Black cells must be placed adjacent to a star!"; From f37f4ef5d78a8e675272c351b11f899fea97b3db Mon Sep 17 00:00:00 2001 From: summerhenson Date: Tue, 12 Mar 2024 17:16:49 -0400 Subject: [PATCH 26/70] FinishWithStars rule check method --- .../rules/FinishWithStarsDirectRule.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java index d2711eced..53ab8d947 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java @@ -2,6 +2,7 @@ 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; @@ -30,6 +31,21 @@ public FinishWithStarsDirectRule() { @Override public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) { + StarBattleBoard board = (StarBattleBoard) transition.getBoard(); + StarBattleBoard origBoard = (StarBattleBoard) transition.getParents().get(0).getBoard(); + ContradictionRule contraRule = new TooFewStarsContradictionRule(); + + StarBattleCell cell = (StarBattleCell) board.getPuzzleElement(puzzleElement); + + if (cell.getType() != StarBattleCellType.STAR) { + return "Only star cells are allowed for this rule!"; + } + + StarBattleBoard modified = (StarBattleBoard) origBoard.copy(); + modified.getPuzzleElement(puzzleElement).setData(StarBattleCellType.BLACK); + if (contraRule.checkContradictionAt(modified, puzzleElement) != null) { + return "Star cells must be placed in a row, region, or column without extra spaces!"; + } return null; } From 9fe76cbb915f25fd098e0a3533d068b26d3662d1 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 12 Mar 2024 17:20:37 -0400 Subject: [PATCH 27/70] Deleted Add Star Case Rule, started on Clashing Orbit --- .../starbattle/rules/AddStarCaseRule.java | 57 ------------------- .../rules/ClashingOrbitContradictionRule.java | 25 ++++++++ .../rules/TooManyStarsContradictionRule.java | 5 ++ 3 files changed, 30 insertions(+), 57 deletions(-) delete mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/rules/AddStarCaseRule.java diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/AddStarCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/AddStarCaseRule.java deleted file mode 100644 index d945f5be9..000000000 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/AddStarCaseRule.java +++ /dev/null @@ -1,57 +0,0 @@ -package edu.rpi.legup.puzzle.starbattle.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.lightup.LightUpBoard; -import edu.rpi.legup.puzzle.lightup.LightUpCell; -import edu.rpi.legup.puzzle.starbattle.*; - -import java.awt.*; -import java.util.*; -import java.util.List; - -public class AddStarCaseRule extends CaseRule { - public AddStarCaseRule() { - super("STBL-CASE-0001", - "Add Star", - "Different ways a region's star number can be satisfied", - ""); - } - - @Override - public CaseBoard getCaseBoard(Board board) { - StarBattleBoard starbattleBoard = (StarBattleBoard) board.copy(); - CaseBoard caseBoard = new CaseBoard(starbattleBoard, this); - - return caseBoard; - } - - /** - * Gets the possible cases at a specific location based on this case rule - * - * @param board the current board state - * @param puzzleElement the cell to determine the possible cases for - * @return a list of elements the specified spot could be - */ - @Override - public List getCases(Board board, PuzzleElement puzzleElement) { - StarBattleBoard starbattleBoard = (StarBattleBoard) board; - // take selected spot, check if there are any stars in that row, column, and region - - // do we want all possible cases, that seems like a lot - return null; - } - - @Override - public String checkRuleRaw(TreeTransition transition) { - return null; - } - - @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/starbattle/rules/ClashingOrbitContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule.java index 2eb584ea1..c15593796 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule.java @@ -9,6 +9,8 @@ import edu.rpi.legup.puzzle.starbattle.StarBattleCell; import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; +import java.awt.*; + public class ClashingOrbitContradictionRule extends ContradictionRule { public ClashingOrbitContradictionRule() { @@ -28,6 +30,29 @@ public ClashingOrbitContradictionRule() { */ @Override public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { + StarBattleBoard starbattleBoard = (StarBattleBoard) board; + StarBattleCell cell = (StarBattleCell) starbattleBoard.getPuzzleElement(puzzleElement); + + if (cell.getType() != StarBattleCellType.STAR) { + return super.getNoContradictionMessage(); + } + + // check neighboring cells for a star + Point location = cell.getLocation(); + + int rowStart = Math.max( location.x - 1, 0 ); + int rowEnd = Math.min( location.x + 1, starbattleBoard.getSize() - 1 ); + int colStart = Math.max( location.y - 1, 0 ); + int colEnd = Math.min( location.y + 1, starbattleBoard.getSize() - 1 ); + + for (int row = rowStart; rowStart <= rowEnd; row++) { + for (int col = colStart; colStart <= colEnd; col++) { + if (starbattleBoard.getCell(row, col).getType() == StarBattleCellType.STAR) { + return null; + } + } + } + return super.getNoContradictionMessage(); } } \ No newline at end of file diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java index 56cd71ba7..09f6e8136 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java @@ -28,6 +28,11 @@ public TooManyStarsContradictionRule() { */ @Override public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { + // check row + + // check column + + // check region return super.getNoContradictionMessage(); } } \ No newline at end of file From 78069d4600b81872eb365df557a1d0dac7d2d875 Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Tue, 12 Mar 2024 17:26:48 -0400 Subject: [PATCH 28/70] Added importer --- .../puzzle/starbattle/StarBattleImporter.java | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleImporter.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleImporter.java index e69de29bb..161b03bf0 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleImporter.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleImporter.java @@ -0,0 +1,110 @@ +package edu.rpi.legup.puzzle.starbattle; + +import edu.rpi.legup.model.PuzzleImporter; +import edu.rpi.legup.save.InvalidFileFormatException; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import java.awt.*; +import java.awt.Point; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +public class StarBattleImporter extends PuzzleImporter{ + + + public StarBattleImporter(StarBattle starbattle) { + super(starbattle); + } + + private Map regionsMap; + + /** + * Puzzle setting to support row and column inputs + */ + @Override + public boolean acceptsRowsAndColumnsInput() { + return true; + } + + /** + * Puzzle setting to disable support for text input + */ + @Override + public boolean acceptsTextInput() { + return false; + } + + + /** + * Constructs empty StarBattle gameboard as per the provided dimensions + * @param rows number of rows and columns for the gameboard + */ + @Override + public void initializeBoard(int rows, int columns) { + StarBattleBoard StarBattleBoard = new StarBattleBoard(rows); + puzzle.setCurrentBoard(StarBattleBoard); + } + + + + /** + * Constructs StarBattle gameboard + * @param node xml document node + * @throws InvalidFileFormatException if file is invalid + */ + @Override + public void initializeBoard(Node node) throws InvalidFileFormatException { + Element puzzleElement = (Element) node; + + NodeList regionNodes = puzzleElement.getElementsByTagName("region"); + if (regionNodes.getLength() == 0) { + throw new InvalidFileFormatException("No regions found for the StarBattle puzzle"); + } + + int size = Integer.parseInt(puzzleElement.getAttribute("size")); + + StarBattleBoard StarBattleBoard = new StarBattleBoard(size); // Initialize the board with width and height from XML + + for (int i = 0; i < regionNodes.getLength(); i++) { + Element regionElement = (Element) regionNodes.item(i); + NodeList cellNodes = regionElement.getElementsByTagName("cell"); + + for (int j = 0; j < cellNodes.getLength(); j++) { + Element cellElement = (Element) cellNodes.item(j); + int x = Integer.parseInt(cellElement.getAttribute("x")); + int y = Integer.parseInt(cellElement.getAttribute("y")); + int value = Integer.parseInt(cellElement.getAttribute("value")); + + Point cellPoint = new Point(x, y); + + // Create the StarBattleCell with the cell type and value + StarBattleCell cell = new StarBattleCell(value, cellPoint, i, size); + cell.setIndex(y * size + x); // Calculate the index based on size + cell.setModifiable(true); + + // Add the cell to the board + StarBattleBoard.setCell(x, y, cell); + } + } + + puzzle.setCurrentBoard(StarBattleBoard); + } + + + + /** + * Initialize board via string of statements. + * @throws UnsupportedOperationException since StarBattle does not support text input + */ + @Override + public void initializeBoard(String[] statements) throws UnsupportedOperationException { + throw new UnsupportedOperationException("Ripple Effect does not accept text input"); + } +} + + + From 4b75d469117c407b38fed10edcfc090618ecdc3b Mon Sep 17 00:00:00 2001 From: summerhenson Date: Fri, 15 Mar 2024 16:18:53 -0400 Subject: [PATCH 29/70] Fix clashing orbit bugs --- .../starbattle/rules/ClashingOrbitContradictionRule.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule.java index c15593796..79453803b 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule.java @@ -45,9 +45,10 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { int colStart = Math.max( location.y - 1, 0 ); int colEnd = Math.min( location.y + 1, starbattleBoard.getSize() - 1 ); - for (int row = rowStart; rowStart <= rowEnd; row++) { - for (int col = colStart; colStart <= colEnd; col++) { - if (starbattleBoard.getCell(row, col).getType() == StarBattleCellType.STAR) { + for (int row = rowStart; row <= rowEnd; row++) { + for (int col = colStart; col <= colEnd; col++) { + if (starbattleBoard.getCell(row, col).getType() == StarBattleCellType.STAR + && (row != location.x || col != location.y)) { return null; } } From 900854f83aa48368507d4a569b21eb27376cb698 Mon Sep 17 00:00:00 2001 From: summerhenson Date: Fri, 15 Mar 2024 16:31:01 -0400 Subject: [PATCH 30/70] Add puzzle number field to board --- .../edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java index 143fbaca6..dedcc0a58 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java @@ -8,12 +8,14 @@ public class StarBattleBoard extends GridBoard { private int size; + private int puzzleNum; protected List regions; //private ArrayList groupSizes; - public StarBattleBoard(int size) { + public StarBattleBoard(int size, int num) { super(size, size); this.size = size; + this.puzzleNum = num; this.regions = new ArrayList<>(); } @@ -39,6 +41,8 @@ public Set getRow(int rowNum) { return row; } + public int getPuzzleNumber() { return puzzleNum; } + public Set getCol(int colNum) { Set column = new HashSet<>(); for (int i = 0; i < size; i++) { @@ -55,7 +59,7 @@ public StarBattleRegion getRegion(int index) { } public StarBattleBoard copy() { - StarBattleBoard copy = new StarBattleBoard(size); + StarBattleBoard copy = new StarBattleBoard(size, puzzleNum); 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()); From e0db10322ebcd8bbb74678c972453db1e4578498 Mon Sep 17 00:00:00 2001 From: summerhenson Date: Fri, 15 Mar 2024 16:57:22 -0400 Subject: [PATCH 31/70] Contradiction check function for too few stars --- .../puzzle/starbattle/StarBattleBoard.java | 4 +++ .../puzzle/starbattle/StarBattleCell.java | 2 ++ .../rules/TooFewStarsContradictionRule.java | 31 +++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java index dedcc0a58..cebe7d2db 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java @@ -58,6 +58,10 @@ public StarBattleRegion getRegion(int index) { return regions.get(index); } + public StarBattleRegion getRegion(StarBattleCell cell) { + return getRegion(cell.getGroupIndex()); + } + public StarBattleBoard copy() { StarBattleBoard copy = new StarBattleBoard(size, puzzleNum); for (int x = 0; x < this.dimension.width; x++) { diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java index 2e89649e2..4296c8230 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java @@ -24,6 +24,8 @@ public StarBattleCell(int value, Point location, int groupIndex, int size) { this.max = size; } + public int getGroupIndex() { return groupIndex; } + @Override public void setType(Element e, MouseEvent m) { switch (e.getElementID()) { diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooFewStarsContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooFewStarsContradictionRule.java index a063b2b6b..af30a5e18 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooFewStarsContradictionRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooFewStarsContradictionRule.java @@ -8,6 +8,9 @@ import edu.rpi.legup.puzzle.starbattle.StarBattleBoard; import edu.rpi.legup.puzzle.starbattle.StarBattleCell; import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; +import edu.rpi.legup.puzzle.starbattle.StarBattleRegion; + +import java.awt.*; public class TooFewStarsContradictionRule extends ContradictionRule { @@ -28,6 +31,34 @@ public TooFewStarsContradictionRule() { */ @Override public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { + StarBattleBoard sbBoard = (StarBattleBoard) board; + StarBattleCell cell = (StarBattleCell) puzzleElement; + Point location = cell.getLocation(); + int column = location.x; + int row = location.y; + int rowCount = 0; + int columnCount = 0; + for (int i = 0; i < sbBoard.getSize(); ++i) { + if (sbBoard.getCell(row, i).getType() != StarBattleCellType.BLACK) { + ++rowCount; + } + if (sbBoard.getCell(i, column).getType() != StarBattleCellType.BLACK) { + ++columnCount; + } + } + if (rowCount < sbBoard.getPuzzleNumber() || columnCount < sbBoard.getPuzzleNumber()) { + return null; + } + StarBattleRegion region = sbBoard.getRegion(cell); + int regionCount = 0; + for (StarBattleCell c: region.getCells()) { + if (c.getType() != StarBattleCellType.BLACK) { + ++regionCount; + } + } + if (regionCount < sbBoard.getPuzzleNumber()) { + return null; + } return super.getNoContradictionMessage(); } } \ No newline at end of file From e8375dbbe4531fc1589b38bdeb402f013969649b Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Fri, 15 Mar 2024 17:10:58 -0400 Subject: [PATCH 32/70] Changed importer and xml files to include puzzleNum --- .../6x6 Star Battle 1star Normal1.xml | 1 + .../6x6 Star Battle 1star Normal2.xml | 1 + .../puzzle/starbattle/StarBattleBoard.java | 7 ++++++ .../puzzle/starbattle/StarBattleImporter.java | 24 ++++++++++--------- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/puzzles files/starbattle/6x6 Star Battle 1star Normal1.xml b/puzzles files/starbattle/6x6 Star Battle 1star Normal1.xml index ce1330437..4163e15a9 100644 --- a/puzzles files/starbattle/6x6 Star Battle 1star Normal1.xml +++ b/puzzles files/starbattle/6x6 Star Battle 1star Normal1.xml @@ -1,6 +1,7 @@ + diff --git a/puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml b/puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml index 10eb04aa3..29307fb58 100644 --- a/puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml +++ b/puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml @@ -1,6 +1,7 @@ + diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java index dedcc0a58..e80e49399 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java @@ -17,6 +17,9 @@ public StarBattleBoard(int size, int num) { this.size = size; this.puzzleNum = num; this.regions = new ArrayList<>(); + for (int i = 0; i < size; i++) { + regions.add(new StarBattleRegion()); + } } @Override @@ -58,6 +61,10 @@ public StarBattleRegion getRegion(int index) { return regions.get(index); } + public void setRegion(int regionNum, StarBattleRegion region) { + regions.set(regionNum, region); + } + public StarBattleBoard copy() { StarBattleBoard copy = new StarBattleBoard(size, puzzleNum); for (int x = 0; x < this.dimension.width; x++) { diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleImporter.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleImporter.java index 161b03bf0..32090172e 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleImporter.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleImporter.java @@ -13,7 +13,7 @@ import java.util.Map; -public class StarBattleImporter extends PuzzleImporter{ +public class StarBattleImporter extends PuzzleImporter{ public StarBattleImporter(StarBattle starbattle) { @@ -38,14 +38,14 @@ public boolean acceptsTextInput() { return false; } - - /** + /** * Constructs empty StarBattle gameboard as per the provided dimensions * @param rows number of rows and columns for the gameboard */ @Override public void initializeBoard(int rows, int columns) { - StarBattleBoard StarBattleBoard = new StarBattleBoard(rows); + int puzzle_num = 1; + StarBattleBoard StarBattleBoard = new StarBattleBoard(rows, puzzle_num); puzzle.setCurrentBoard(StarBattleBoard); } @@ -59,19 +59,19 @@ public void initializeBoard(int rows, int columns) { @Override public void initializeBoard(Node node) throws InvalidFileFormatException { Element puzzleElement = (Element) node; - + int puzzle_num = Integer.parseInt(puzzleElement.getAttribute("puzzle_num")); NodeList regionNodes = puzzleElement.getElementsByTagName("region"); - if (regionNodes.getLength() == 0) { - throw new InvalidFileFormatException("No regions found for the StarBattle puzzle"); - } - int size = Integer.parseInt(puzzleElement.getAttribute("size")); + if (regionNodes.getLength() != size) { + throw new InvalidFileFormatException("Not the current amount of regions in the puzzle."); + } - StarBattleBoard StarBattleBoard = new StarBattleBoard(size); // Initialize the board with width and height from XML + StarBattleBoard StarBattleBoard = new StarBattleBoard(size, puzzle_num); // Initialize the board with width and height from XML for (int i = 0; i < regionNodes.getLength(); i++) { Element regionElement = (Element) regionNodes.item(i); NodeList cellNodes = regionElement.getElementsByTagName("cell"); + StarBattleRegion region_i = new StarBattleRegion(); for (int j = 0; j < cellNodes.getLength(); j++) { Element cellElement = (Element) cellNodes.item(j); @@ -88,7 +88,9 @@ public void initializeBoard(Node node) throws InvalidFileFormatException { // Add the cell to the board StarBattleBoard.setCell(x, y, cell); + region_i.addCell(cell); } + StarBattleBoard.setRegion(i, region_i); } puzzle.setCurrentBoard(StarBattleBoard); @@ -102,7 +104,7 @@ public void initializeBoard(Node node) throws InvalidFileFormatException { */ @Override public void initializeBoard(String[] statements) throws UnsupportedOperationException { - throw new UnsupportedOperationException("Ripple Effect does not accept text input"); + throw new UnsupportedOperationException("Star Battle does not accept text input"); } } From 52c1aee25da3e80586cbdba537be411fa798fff9 Mon Sep 17 00:00:00 2001 From: summerhenson Date: Fri, 15 Mar 2024 17:27:54 -0400 Subject: [PATCH 33/70] Rule check method for star or empty case rule --- .../starbattle/rules/StarOrEmptyCaseRule.java | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java index a30823faa..1bbbe3e92 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java @@ -5,11 +5,14 @@ import edu.rpi.legup.model.gameboard.CaseBoard; import edu.rpi.legup.model.gameboard.PuzzleElement; import edu.rpi.legup.model.tree.TreeTransition; +import edu.rpi.legup.puzzle.nurikabe.NurikabeCell; +import edu.rpi.legup.puzzle.nurikabe.NurikabeType; import edu.rpi.legup.puzzle.starbattle.StarBattleBoard; import edu.rpi.legup.puzzle.starbattle.StarBattleCell; import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; import java.util.ArrayList; +import java.util.List; public class StarOrEmptyCaseRule extends CaseRule { @@ -29,7 +32,29 @@ public StarOrEmptyCaseRule() { */ @Override public String checkRuleRaw(TreeTransition transition) { - //TODO: implement this + 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."; + } + + StarBattleCell mod1 = (StarBattleCell) case1.getBoard().getModifiedData().iterator().next(); + StarBattleCell mod2 = (StarBattleCell) 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() == StarBattleCellType.STAR && mod2.getType() == StarBattleCellType.BLACK) || + (mod2.getType() == StarBattleCellType.STAR && mod1.getType() == StarBattleCellType.BLACK))) { + return super.getInvalidUseOfRuleMessage() + ": This case rule must create a star cell and a black cell."; + } + return null; } From 08492e146af252e83bc9737cba59ebae996df286 Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Fri, 15 Mar 2024 17:40:46 -0400 Subject: [PATCH 34/70] Added exporter --- .../puzzle/starbattle/StarBattleExporter.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleExporter.java diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleExporter.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleExporter.java new file mode 100644 index 000000000..dcf149d0f --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleExporter.java @@ -0,0 +1,36 @@ +package edu.rpi.legup.puzzle.starbattle; + +import edu.rpi.legup.model.PuzzleExporter; +import edu.rpi.legup.model.gameboard.PuzzleElement; + +import org.w3c.dom.Document; + +public class StarBattleExporter extends PuzzleExporter { + public StarBattleExporter(StarBattle starbattle) { + super(starbattle); + } + + @Override + protected org.w3c.dom.Element createBoardElement(Document newDocument) { + StarBattleBoard board = (StarBattleBoard) puzzle.getTree().getRootNode().getBoard(); + org.w3c.dom.Element boardElement = newDocument.createElement("board"); + boardElement.setAttribute("size", String.valueOf(board.getSize())); + boardElement.setAttribute("puzzle_num", String.valueOf(board.getPuzzleNumber())); + for (PuzzleElement puzzleElement : board.getPuzzleElements()) { + org.w3c.dom.Element regionsElement = newDocument.createElement("region"); + StarBattleRegion region = (StarBattleRegion) puzzleElement; + org.w3c.dom.Element cellsElement = newDocument.createElement("cells"); + for (PuzzleElement puzzleElement : region.getPuzzleElements()) { + StarBattleCell cell = (StarBattleCell) puzzleElement; + if (cell.getData() != -2) { + org.w3c.dom.Element cellElement = puzzle.getFactory().exportCell(newDocument, puzzleElement); + cellsElement.appendChild(cellElement); + } + regionsElement.appendChild(cellsElement); + } + boardElement.appendChild(regionsElement); + } + + return boardElement; + } +} From cbe163513b4897bee86a96a209122199b65413be Mon Sep 17 00:00:00 2001 From: Sarah Date: Fri, 15 Mar 2024 20:17:17 -0400 Subject: [PATCH 35/70] Updated TooManyStarsContradictionRule --- .../rules/ClashingOrbitContradictionRule.java | 1 + .../rules/TooManyStarsContradictionRule.java | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule.java index 79453803b..28398143e 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule.java @@ -33,6 +33,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { StarBattleBoard starbattleBoard = (StarBattleBoard) board; StarBattleCell cell = (StarBattleCell) starbattleBoard.getPuzzleElement(puzzleElement); + // Contradiction rule can only be applied to cells with a star in it if (cell.getType() != StarBattleCellType.STAR) { return super.getNoContradictionMessage(); } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java index 09f6e8136..9165a2b1a 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java @@ -5,11 +5,17 @@ import edu.rpi.legup.model.rules.ContradictionRule; import edu.rpi.legup.model.tree.TreeNode; import edu.rpi.legup.model.tree.TreeTransition; +import edu.rpi.legup.puzzle.lightup.LightUpCell; import edu.rpi.legup.puzzle.starbattle.StarBattleBoard; import edu.rpi.legup.puzzle.starbattle.StarBattleCell; import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; +import edu.rpi.legup.puzzle.starbattle.StarBattleRegion; + +import java.awt.*; +import java.util.List; public class TooManyStarsContradictionRule extends ContradictionRule { + private final String INVALID_USE_MESSAGE = "Contradiction must be a cell containing a star."; public TooManyStarsContradictionRule() { super("STBL-CONT-0001", @@ -28,11 +34,68 @@ public TooManyStarsContradictionRule() { */ @Override public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { + StarBattleBoard starbattleBoard = (StarBattleBoard) board; + StarBattleCell cell = (StarBattleCell) starbattleBoard.getPuzzleElement(puzzleElement); + Point location = cell.getLocation(); + int starCount = 0; + int puzzleNum = starbattleBoard.getPuzzleNumber(); + + if (cell.getType() != StarBattleCellType.STAR) { + return super.getNoContradictionMessage(); + } + // check row + for (int i = location.x - 1; i >= 0; i--) { // to the left of selected cell + StarBattleCell check = starbattleBoard.getCell(i, location.y); + if (check.getType() == StarBattleCellType.STAR) { + starCount++; + if (starCount >= puzzleNum) { + break; + } + } + } + + for (int i = location.x + 1; i < starbattleBoard.getWidth(); i++) { // to the right of selected cell + StarBattleCell check = starbattleBoard.getCell(i, location.y); + if (check.getType() == StarBattleCellType.STAR) { + starCount++; + if (starCount >= puzzleNum) { + break; + } + } + } // check column + starCount = 0; + for (int j = location.y - 1; j >= 0; j--) { // above selected cell + StarBattleCell check = starbattleBoard.getCell(location.x, j); + if (check.getType() == StarBattleCellType.STAR) { + starCount++; + if (starCount >= puzzleNum) { + break; + } + } + } + + for (int j = location.y + 1; j < starbattleBoard.getWidth(); j++) { // below selected cell + StarBattleCell check = starbattleBoard.getCell(location.x, j); + if (check.getType() == StarBattleCellType.STAR) { + starCount++; + if (starCount >= puzzleNum) { + break; + } + } + } // check region + starCount = 0; + List reg; + /* + for (go through list of regions) { + check all spots in region + } + */ + return super.getNoContradictionMessage(); } } \ No newline at end of file From dd8b3fef0047ce78fefb691bd5e87885ac47645b Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 19 Mar 2024 16:39:38 -0400 Subject: [PATCH 36/70] added region check to TooManyStarsContradictionRule --- .../rules/TooManyStarsContradictionRule.java | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java index 9165a2b1a..a3044a8cb 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java @@ -15,7 +15,7 @@ import java.util.List; public class TooManyStarsContradictionRule extends ContradictionRule { - private final String INVALID_USE_MESSAGE = "Contradiction must be a cell containing a star."; + private final String INVALID_USE_MESSAGE = "Contradiction must be applied to a cell containing a star."; public TooManyStarsContradictionRule() { super("STBL-CONT-0001", @@ -39,9 +39,10 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { Point location = cell.getLocation(); int starCount = 0; int puzzleNum = starbattleBoard.getPuzzleNumber(); + boolean valid = false; if (cell.getType() != StarBattleCellType.STAR) { - return super.getNoContradictionMessage(); + return INVALID_USE_MESSAGE; } // check row @@ -50,6 +51,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { if (check.getType() == StarBattleCellType.STAR) { starCount++; if (starCount >= puzzleNum) { + valid = true; break; } } @@ -60,6 +62,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { if (check.getType() == StarBattleCellType.STAR) { starCount++; if (starCount >= puzzleNum) { + valid = true; break; } } @@ -72,6 +75,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { if (check.getType() == StarBattleCellType.STAR) { starCount++; if (starCount >= puzzleNum) { + valid = true; break; } } @@ -82,6 +86,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { if (check.getType() == StarBattleCellType.STAR) { starCount++; if (starCount >= puzzleNum) { + valid = true; break; } } @@ -89,13 +94,20 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { // check region starCount = 0; - List reg; - /* - for (go through list of regions) { - check all spots in region + StarBattleRegion reg = starbattleBoard.getRegion(cell); + List cellList = reg.getCells(); // list of cells + for (int k = 0; k < cellList.size(); k++) { + if (cellList.get(k) == cell) { + continue; + } else if (cellList.get(k).getType() == StarBattleCellType.STAR) { + valid = true; + break; + } } - */ - return super.getNoContradictionMessage(); + if (valid == true) { + return super.getNoContradictionMessage(); + } + return null; } } \ No newline at end of file From 2555896041d62b86b86656145cce6fde2106492a Mon Sep 17 00:00:00 2001 From: summerhenson Date: Tue, 19 Mar 2024 16:41:27 -0400 Subject: [PATCH 37/70] Split up row/column and region containment rules into separate rules for rows and columns --- .../puzzle/starbattle/StarBattleBoard.java | 2 +- .../rules/ColumnsWithinRegionsDirectRule.java | 43 +++++++++++++++++++ .../rules/FinishWithStarsDirectRule.java | 2 +- ...va => RegionsWithinColumnsDirectRule.java} | 9 ++-- .../rules/RegionsWithinRowsDirectRule.java | 43 +++++++++++++++++++ ....java => RowsWithinRegionsDirectRule.java} | 9 ++-- .../rules/SurroundStarDirectRule.java | 2 +- .../rules/starbattle_reference_sheet.txt | 10 +++-- 8 files changed, 101 insertions(+), 19 deletions(-) create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java rename src/main/java/edu/rpi/legup/puzzle/starbattle/rules/{RegionsWithinRowsColumnsDirectRule.java => RegionsWithinColumnsDirectRule.java} (81%) create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsDirectRule.java rename src/main/java/edu/rpi/legup/puzzle/starbattle/rules/{RowsColumnsWithinRegionsDirectRule.java => RowsWithinRegionsDirectRule.java} (82%) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java index a2a93ff8e..7accc86e3 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java @@ -60,7 +60,7 @@ public StarBattleRegion getRegion(int index) { } return regions.get(index); } - + public StarBattleRegion getRegion(StarBattleCell cell) { return getRegion(cell.getGroupIndex()); } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java new file mode 100644 index 000000000..05c9a2868 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java @@ -0,0 +1,43 @@ +package edu.rpi.legup.puzzle.starbattle.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 ColumnsWithinRegionsDirectRule extends DirectRule { + public ColumnsWithinRegionsDirectRule() { + super("STBL-BASC-0002", + "Columns Within Regions", + "If a number of columns is fully contained by an equal number of regions, spaces of other columns in those regions must be black.", + "INSERT IMAGE NAME HERE"); + } + + /** + * 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; + } + + /** + * 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/starbattle/rules/FinishWithStarsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java index 53ab8d947..13050a5ac 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java @@ -13,7 +13,7 @@ public class FinishWithStarsDirectRule extends DirectRule { public FinishWithStarsDirectRule() { - super("STBL-BASC-0002", + super("STBL-BASC-0003", "Finish With Stars", "Unknown spaces must be stars if there are just enough in a row, column, or region to satisfy the puzzle number.", "INSERT IMAGE NAME HERE"); diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsColumnsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinColumnsDirectRule.java similarity index 81% rename from src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsColumnsDirectRule.java rename to src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinColumnsDirectRule.java index 81645a2ad..84787e704 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsColumnsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinColumnsDirectRule.java @@ -5,13 +5,10 @@ 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.starbattle.StarBattleBoard; -import edu.rpi.legup.puzzle.starbattle.StarBattleCell; -import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; -public class RegionsWithinRowsColumnsDirectRule extends DirectRule { - public RegionsWithinRowsColumnsDirectRule() { - super("STBL-BASC-0003", +public class RegionsWithinColumnsDirectRule extends DirectRule { + public RegionsWithinColumnsDirectRule() { + super("STBL-BASC-0004", "Regions Within Rows/Columns", "If a number of regions is fully contained by an equal number of rows or columns, spaces of other regions in those rows or columns must be black.", "INSERT IMAGE NAME HERE"); diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsDirectRule.java new file mode 100644 index 000000000..e71c97df9 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsDirectRule.java @@ -0,0 +1,43 @@ +package edu.rpi.legup.puzzle.starbattle.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 RegionsWithinRowsDirectRule extends DirectRule { + public RegionsWithinRowsDirectRule() { + super("STBL-BASC-0005", + "Regions Within Rows/Columns", + "If a number of regions is fully contained by an equal number of rows or columns, spaces of other regions in those rows or columns must be black.", + "INSERT IMAGE NAME HERE"); + } + + /** + * 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; + } + + /** + * 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/starbattle/rules/RowsColumnsWithinRegionsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinRegionsDirectRule.java similarity index 82% rename from src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsColumnsWithinRegionsDirectRule.java rename to src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinRegionsDirectRule.java index 53a7b27ee..128c44095 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsColumnsWithinRegionsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinRegionsDirectRule.java @@ -5,13 +5,10 @@ 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.starbattle.StarBattleBoard; -import edu.rpi.legup.puzzle.starbattle.StarBattleCell; -import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; -public class RowsColumnsWithinRegionsDirectRule extends DirectRule { - public RowsColumnsWithinRegionsDirectRule() { - super("STBL-BASC-0004", +public class RowsWithinRegionsDirectRule extends DirectRule { + public RowsWithinRegionsDirectRule() { + super("STBL-BASC-0006", "Rows/Columns Within Regions", "If a number of rows or columns is fully contained by an equal number of regions, spaces of other rows or columns, respectively, in those regions must be black.", "INSERT IMAGE NAME HERE"); diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java index 0c46da09c..a5533104c 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java @@ -13,7 +13,7 @@ public class SurroundStarDirectRule extends DirectRule { public SurroundStarDirectRule() { - super("STBL-BASC-0005", + super("STBL-BASC-0007", "Surround Star", "Any space adjacent to a star must be black.", "INSERT IMAGE NAME HERE"); diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/starbattle_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/starbattle_reference_sheet.txt index 70e81bb73..958440a71 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/starbattle_reference_sheet.txt +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/starbattle_reference_sheet.txt @@ -4,10 +4,12 @@ Star or Empty: STBL-CASE-0002 Basic Rules: Blackout: STBL-BASC-0001 -Finish With Stars: STBL-BASC-0002 -Regions Within Rows or Columns: STBL-BASC-0003 -Rows or Columns Within Regions: STBL-BASC-0004 -Surround Star: STBL-BASC-0005 +Columns Within Regions: STBL-BASC-0002 +Finish With Stars: STBL-BASC-0003 +Regions Within Columns: STBL-BASC-0004 +Regions Within Rows: STBL-BASC-0005 +Rows Within Regions: STBL-BASC-0006 +Surround Star: STBL-BASC-0007 Contradiction Rules: Too Many Stars: STBL-CONT-0001 From 489f31d4c53180d2fe7e0d61396fb13d8e99df51 Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Tue, 19 Mar 2024 17:09:49 -0400 Subject: [PATCH 38/70] Create StarBattleCellFactory.java --- .../edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java new file mode 100644 index 000000000..e69de29bb From 7674f2225dc23ba409b56a76f5e7ec939dc6f3e8 Mon Sep 17 00:00:00 2001 From: summerhenson Date: Tue, 19 Mar 2024 17:19:19 -0400 Subject: [PATCH 39/70] Start implementing columns within regions direct rule --- .../puzzle/starbattle/StarBattleBoard.java | 11 +++++++ .../puzzle/starbattle/StarBattleRegion.java | 9 ++++++ .../rules/ColumnsWithinRegionsDirectRule.java | 29 ++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java index 7accc86e3..764e952ea 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java @@ -69,6 +69,17 @@ public void setRegion(int regionNum, StarBattleRegion region) { regions.set(regionNum, region); } + public int columnStars(int columnIndex) { + int stars = 0; + if (columnIndex < size) { + for (StarBattleCell c: this.getCol(columnIndex)) { + if (c.getType() == StarBattleCellType.STAR) + ++stars; + } + } + return stars; + } + public StarBattleBoard copy() { StarBattleBoard copy = new StarBattleBoard(size, puzzleNum); for (int x = 0; x < this.dimension.width; x++) { diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleRegion.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleRegion.java index ebae5ce86..099cabfcd 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleRegion.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleRegion.java @@ -14,4 +14,13 @@ public StarBattleRegion copy() { } return copy; } + + public int numStars() { + int stars = 0; + for (StarBattleCell c: regionCells) { + if (c.getType() == StarBattleCellType.STAR) + ++stars; + } + return stars; + } } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java index 05c9a2868..efd8b47ca 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java @@ -1,10 +1,16 @@ package edu.rpi.legup.puzzle.starbattle.rules; import edu.rpi.legup.model.gameboard.Board; +import edu.rpi.legup.model.gameboard.GridRegion; 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.starbattle.StarBattleBoard; +import edu.rpi.legup.puzzle.starbattle.StarBattleCell; +import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; + +import java.util.HashSet; public class ColumnsWithinRegionsDirectRule extends DirectRule { public ColumnsWithinRegionsDirectRule() { @@ -25,7 +31,28 @@ public ColumnsWithinRegionsDirectRule() { */ @Override public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) { - + StarBattleBoard board = (StarBattleBoard) transition.getBoard(); + StarBattleCell cell = (StarBattleCell) board.getPuzzleElement(puzzleElement); + if (cell.getType() != StarBattleCellType.BLACK) { + return "Only black cells are allowed for this rule!"; + } + //which columns are within the region + HashSet columns = new HashSet(); + int columnStars = 0; + for (PuzzleElement r: board.getRegion(cell).getCells()) { + columns.add(((StarBattleCell) r).getLocation().x); + } + //which regions are the columns within + HashSet regions = new HashSet(); + int regionStars = 0; + for (Integer c: columns) { + for (int i = 0; i < board.getSize(); ++i) { + if (regions.add(board.getCell(c,i).getGroupIndex())) { + regionStars += board.getRegion(board.getCell(c,i)).numStars(); + } + } + } + // are the columns and regions missing an equal amount of stars return null; } From 53a5004f00ab5e81a954c89223e98c412559bf87 Mon Sep 17 00:00:00 2001 From: summerhenson Date: Tue, 19 Mar 2024 17:28:54 -0400 Subject: [PATCH 40/70] Continue columns within regions --- .../legup/puzzle/starbattle/StarBattleBoard.java | 11 +++++++++++ .../rules/ColumnsWithinRegionsDirectRule.java | 14 +++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java index 764e952ea..ce04f31a6 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java @@ -80,6 +80,17 @@ public int columnStars(int columnIndex) { return stars; } + public int rowStars(int rowIndex) { + int stars = 0; + if (rowIndex < size) { + for (StarBattleCell c: this.getRow(rowIndex)) { + if (c.getType() == StarBattleCellType.STAR) + ++stars; + } + } + return stars; + } + public StarBattleBoard copy() { StarBattleBoard copy = new StarBattleBoard(size, puzzleNum); for (int x = 0; x < this.dimension.width; x++) { diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java index efd8b47ca..086a8f82e 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java @@ -11,6 +11,7 @@ import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; import java.util.HashSet; +import java.util.Set; public class ColumnsWithinRegionsDirectRule extends DirectRule { public ColumnsWithinRegionsDirectRule() { @@ -31,19 +32,23 @@ public ColumnsWithinRegionsDirectRule() { */ @Override public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) { + //TODO: fix this StarBattleBoard board = (StarBattleBoard) transition.getBoard(); StarBattleCell cell = (StarBattleCell) board.getPuzzleElement(puzzleElement); if (cell.getType() != StarBattleCellType.BLACK) { return "Only black cells are allowed for this rule!"; } //which columns are within the region - HashSet columns = new HashSet(); + Set columns = new HashSet(); int columnStars = 0; for (PuzzleElement r: board.getRegion(cell).getCells()) { - columns.add(((StarBattleCell) r).getLocation().x); + int column = ((StarBattleCell) r).getLocation().x; + if (columns.add(column)) { + columnStars += board.columnStars(column); + } } //which regions are the columns within - HashSet regions = new HashSet(); + Set regions = new HashSet(); int regionStars = 0; for (Integer c: columns) { for (int i = 0; i < board.getSize(); ++i) { @@ -53,6 +58,9 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem } } // are the columns and regions missing an equal amount of stars + if (board.getPuzzleNumber() * columns.size() - columnStars != board.getPuzzleNumber() * regions.size() - regionStars) { + return "The number of missing stars in the "; + } return null; } From eee926b4c51e049d07e8ba30618208979bb51b24 Mon Sep 17 00:00:00 2001 From: Sarah Date: Wed, 20 Mar 2024 13:52:28 -0400 Subject: [PATCH 41/70] reworked TooManyStars logic --- .../8x8 Star Battle 1star Normal1.xml | 10 ++++++ .../rules/TooManyStarsContradictionRule.java | 33 ++++++++++--------- 2 files changed, 27 insertions(+), 16 deletions(-) create mode 100644 puzzles files/starbattle/8x8 Star Battle 1star Normal1.xml diff --git a/puzzles files/starbattle/8x8 Star Battle 1star Normal1.xml b/puzzles files/starbattle/8x8 Star Battle 1star Normal1.xml new file mode 100644 index 000000000..ba237102f --- /dev/null +++ b/puzzles files/starbattle/8x8 Star Battle 1star Normal1.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java index a3044a8cb..7777ff5a4 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java @@ -39,30 +39,30 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { Point location = cell.getLocation(); int starCount = 0; int puzzleNum = starbattleBoard.getPuzzleNumber(); - boolean valid = false; + boolean valid = true; if (cell.getType() != StarBattleCellType.STAR) { - return INVALID_USE_MESSAGE; + return this.INVALID_USE_MESSAGE; } // check row - for (int i = location.x - 1; i >= 0; i--) { // to the left of selected cell + for (int i = location.x - 1; i >= 0; i--) { StarBattleCell check = starbattleBoard.getCell(i, location.y); if (check.getType() == StarBattleCellType.STAR) { starCount++; if (starCount >= puzzleNum) { - valid = true; + valid = false; break; } } } - for (int i = location.x + 1; i < starbattleBoard.getWidth(); i++) { // to the right of selected cell + for (int i = location.x + 1; i < starbattleBoard.getWidth(); i++) { StarBattleCell check = starbattleBoard.getCell(i, location.y); if (check.getType() == StarBattleCellType.STAR) { starCount++; if (starCount >= puzzleNum) { - valid = true; + valid = false; break; } } @@ -70,23 +70,23 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { // check column starCount = 0; - for (int j = location.y - 1; j >= 0; j--) { // above selected cell + for (int j = location.y - 1; j >= 0; j--) { StarBattleCell check = starbattleBoard.getCell(location.x, j); if (check.getType() == StarBattleCellType.STAR) { starCount++; if (starCount >= puzzleNum) { - valid = true; + valid = false; break; } } } - for (int j = location.y + 1; j < starbattleBoard.getWidth(); j++) { // below selected cell + for (int j = location.y + 1; j < starbattleBoard.getWidth(); j++) { StarBattleCell check = starbattleBoard.getCell(location.x, j); if (check.getType() == StarBattleCellType.STAR) { starCount++; if (starCount >= puzzleNum) { - valid = true; + valid = false; break; } } @@ -97,15 +97,16 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { StarBattleRegion reg = starbattleBoard.getRegion(cell); List cellList = reg.getCells(); // list of cells for (int k = 0; k < cellList.size(); k++) { - if (cellList.get(k) == cell) { - continue; - } else if (cellList.get(k).getType() == StarBattleCellType.STAR) { - valid = true; - break; + if (cellList.get(k).getType() == StarBattleCellType.STAR) { + starCount++; + if (starCount >= puzzleNum) { + valid = false; + break; + } } } - if (valid == true) { + if (valid == false) { return super.getNoContradictionMessage(); } return null; From 59c8d6f9563caff709e20e84a4bc15f8d04a5600 Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Fri, 22 Mar 2024 15:10:18 -0400 Subject: [PATCH 42/70] Exporter and Cell Factory started --- .../starbattle/StarBattleCellFactory.java | 66 +++++++++++++++++++ .../puzzle/starbattle/StarBattleExporter.java | 11 ++-- 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java index e69de29bb..06c879836 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java @@ -0,0 +1,66 @@ +package edu.rpi.legup.puzzle.starbattle; +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.puzzle.nurikabe.NurikabeCell; +import edu.rpi.legup.puzzle.starbattle.starbattleBoard; +import edu.rpi.legup.puzzle.starbattle.starbattleCell; +import edu.rpi.legup.save.InvalidFileFormatException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.awt.*; + +public class StarBattleCellFactory extends ElementFactory { + @Override + public StarBattleCell importCell(Node node, Board board) throws InvalidFileFormatException { + try { + if (!node.getNodeName().equalsIgnoreCase("cell")) { + throw new InvalidFileFormatException("starbattle Factory: unknown puzzleElement puzzleElement"); + } + + StarBattleBoard starbattleBoard = (StarBattleBoard) board; + int size = starbattleBoard.getSize(); + + 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()); + int groupIndex = Integer.valueOf(attributeList.getNamedItem("groupIndex").getNodeValue()); + if (x >= size || y >= size) { + throw new InvalidFileFormatException("starbattle Factory: cell location out of bounds"); + } + if (groupIndex >= size || groupIndex < 0) { + throw new InvalidFileFormatException("starbattle Factory: not in a valid region"); + } + if (value != 0) { //ALL INITIAL PUZZLES ARE BLANK, SUBJECT TO CHANGE + throw new InvalidFileFormatException("starbattle Factory: cell unknown value"); + } + + StarBattleCell cell = new StarBattleCell(value, new Point(x, y), groupIndex, size); + cell.setIndex(y * size + x); + return cell; + } + catch (NumberFormatException e1) { + throw new InvalidFileFormatException("starbattle Factory: unknown value where integer expected"); + } catch (NullPointerException e2) { + throw new InvalidFileFormatException("starbattle Factory: could not find attribute(s)"); + } + } + + public org.w3c.dom.Element exportCell(Document document, PuzzleElement puzzleElement) { + org.w3c.dom.Element cellElement = document.createElement("cell"); + + NurikabeCell cell = (NurikabeCell) 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/starbattle/StarBattleExporter.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleExporter.java index dcf149d0f..58fb41e63 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleExporter.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleExporter.java @@ -1,7 +1,6 @@ package edu.rpi.legup.puzzle.starbattle; import edu.rpi.legup.model.PuzzleExporter; -import edu.rpi.legup.model.gameboard.PuzzleElement; import org.w3c.dom.Document; @@ -16,14 +15,12 @@ protected org.w3c.dom.Element createBoardElement(Document newDocument) { org.w3c.dom.Element boardElement = newDocument.createElement("board"); boardElement.setAttribute("size", String.valueOf(board.getSize())); boardElement.setAttribute("puzzle_num", String.valueOf(board.getPuzzleNumber())); - for (PuzzleElement puzzleElement : board.getPuzzleElements()) { + for (StarBattleRegion sb_region : board.regions) { org.w3c.dom.Element regionsElement = newDocument.createElement("region"); - StarBattleRegion region = (StarBattleRegion) puzzleElement; org.w3c.dom.Element cellsElement = newDocument.createElement("cells"); - for (PuzzleElement puzzleElement : region.getPuzzleElements()) { - StarBattleCell cell = (StarBattleCell) puzzleElement; - if (cell.getData() != -2) { - org.w3c.dom.Element cellElement = puzzle.getFactory().exportCell(newDocument, puzzleElement); + for (StarBattleCell cell : sb_region.getCells()) { + if (cell.getData() == 0) { + org.w3c.dom.Element cellElement = puzzle.getFactory().exportCell(newDocument, cell); cellsElement.appendChild(cellElement); } regionsElement.appendChild(cellsElement); From 9d5362b94680e212e7c0521e48de106e12ab021b Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Fri, 22 Mar 2024 16:12:50 -0400 Subject: [PATCH 43/70] Update StarBattleCellFactory.java --- .../rpi/legup/puzzle/starbattle/StarBattleCellFactory.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java index 06c879836..827934111 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java @@ -2,9 +2,8 @@ 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.puzzle.nurikabe.NurikabeCell; -import edu.rpi.legup.puzzle.starbattle.starbattleBoard; -import edu.rpi.legup.puzzle.starbattle.starbattleCell; +import edu.rpi.legup.puzzle.starbattle.StarBattleBoard; +import edu.rpi.legup.puzzle.starbattle.StarBattleCell; import edu.rpi.legup.save.InvalidFileFormatException; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -54,7 +53,7 @@ public StarBattleCell importCell(Node node, Board board) throws InvalidFileForma public org.w3c.dom.Element exportCell(Document document, PuzzleElement puzzleElement) { org.w3c.dom.Element cellElement = document.createElement("cell"); - NurikabeCell cell = (NurikabeCell) puzzleElement; + StarBattleCell cell = (StarBattleCell) puzzleElement; Point loc = cell.getLocation(); cellElement.setAttribute("value", String.valueOf(cell.getData())); From 0deae52edcb4cc5315db11626dc46f4d0d6697fe Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Fri, 22 Mar 2024 16:26:53 -0400 Subject: [PATCH 44/70] Deleted extraneous libraries, and finished going thru guide of implementing puzzles Hopefully we get puzzles up soon. --- .../java/edu/rpi/legup/puzzle/starbattle/StarBattle.java | 8 ++++---- .../legup/puzzle/starbattle/StarBattleCellFactory.java | 4 ---- .../rpi/legup/puzzle/starbattle/StarBattleImporter.java | 9 --------- .../edu/rpi/legup/puzzle/starbattle/StarBattleView.java | 2 +- 4 files changed, 5 insertions(+), 18 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattle.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattle.java index 78800916e..760fa88b2 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattle.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattle.java @@ -5,12 +5,12 @@ public class StarBattle extends Puzzle { public StarBattle() { super(); - //this.name = "StarBattle"; + this.name = "StarBattle"; - //this.importer = new StarBattleImporter(this); - //this.exporter = new StarBattleExporter(this); + this.importer = new StarBattleImporter(this); + this.exporter = new StarBattleExporter(this); - //this.factory = new StarBattleCellFactory(); + this.factory = new StarBattleCellFactory(); } @Override diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java index 827934111..92ea8abf6 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java @@ -2,14 +2,10 @@ 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.puzzle.starbattle.StarBattleBoard; -import edu.rpi.legup.puzzle.starbattle.StarBattleCell; import edu.rpi.legup.save.InvalidFileFormatException; import org.w3c.dom.Document; -import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; -import org.w3c.dom.NodeList; import java.awt.*; diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleImporter.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleImporter.java index 32090172e..fa0e065ee 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleImporter.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleImporter.java @@ -5,12 +5,7 @@ import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import java.awt.*; import java.awt.Point; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; public class StarBattleImporter extends PuzzleImporter{ @@ -20,8 +15,6 @@ public StarBattleImporter(StarBattle starbattle) { super(starbattle); } - private Map regionsMap; - /** * Puzzle setting to support row and column inputs */ @@ -49,8 +42,6 @@ public void initializeBoard(int rows, int columns) { puzzle.setCurrentBoard(StarBattleBoard); } - - /** * Constructs StarBattle gameboard * @param node xml document node diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java index fdf0df221..a39770d85 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java @@ -31,7 +31,7 @@ public class StarBattleView extends GridBoardView { STAR = ImageIO.read(ClassLoader.getSystemResourceAsStream("edu/rpi/legup/images/starbattle/star.png")); } catch (IOException e) { - LOGGER.error("Failed to open StarBattle images"); + LOGGER.error("Failed to open starbattle image."); } } From 2ba4382b9243a73a7bf1b58d91c8d1d79349bc07 Mon Sep 17 00:00:00 2001 From: summerhenson Date: Fri, 22 Mar 2024 17:12:02 -0400 Subject: [PATCH 45/70] Implemented rule check function for region/row/column overlap rules --- .../rules/ColumnsWithinRegionsDirectRule.java | 46 ++++++--- .../rules/ColumnsWithinRowsDirectRule.java | 97 +++++++++++++++++++ .../rules/RegionsWithinColumnsDirectRule.java | 8 +- .../rules/RegionsWithinRowsDirectRule.java | 7 +- .../rules/RowsWithinColumnsDirectRule.java | 51 ++++++++++ .../rules/RowsWithinRegionsDirectRule.java | 55 ++++++++++- 6 files changed, 240 insertions(+), 24 deletions(-) create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRowsDirectRule.java create mode 100644 src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinColumnsDirectRule.java diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java index 086a8f82e..980f6db19 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java @@ -32,34 +32,50 @@ public ColumnsWithinRegionsDirectRule() { */ @Override public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) { - //TODO: fix this + //assumption: the rule has been applied to its fullest extent and the rows and regions + //are now mutually encompassing StarBattleBoard board = (StarBattleBoard) transition.getBoard(); StarBattleCell cell = (StarBattleCell) board.getPuzzleElement(puzzleElement); if (cell.getType() != StarBattleCellType.BLACK) { return "Only black cells are allowed for this rule!"; } - //which columns are within the region + //the columns that are contained Set columns = new HashSet(); - int columnStars = 0; - for (PuzzleElement r: board.getRegion(cell).getCells()) { - int column = ((StarBattleCell) r).getLocation().x; - if (columns.add(column)) { - columnStars += board.columnStars(column); - } - } - //which regions are the columns within + //the regions that contain them Set regions = new HashSet(); + //columns and regions to process + Set columnsToCheck = new HashSet(); + Set regionsToCheck = new HashSet(); + int columnStars = 0; int regionStars = 0; - for (Integer c: columns) { - for (int i = 0; i < board.getSize(); ++i) { - if (regions.add(board.getCell(c,i).getGroupIndex())) { - regionStars += board.getRegion(board.getCell(c,i)).numStars(); + regions.add(cell.getGroupIndex()); + regionsToCheck.add(cell.getGroupIndex()); + + while (!columnsToCheck.isEmpty() || !regionsToCheck.isEmpty()) { + for (int r: regionsToCheck) { + regionStars += board.getRegion(r).numStars(); + for (PuzzleElement c: board.getRegion(r).getCells()) { + int column = ((StarBattleCell) c).getLocation().x; + if (columns.add(column)) { + columnsToCheck.add(column); + } + } + regionsToCheck.remove(r); + } + for (int c: columnsToCheck) { + columnStars += board.columnStars(c); + for (int i = 0; i < board.getSize(); ++i) { + int region = board.getCell(c,i).getGroupIndex(); + if (regions.add(region)) { + regionsToCheck.add(region); + } } + columnsToCheck.remove(c); } } // are the columns and regions missing an equal amount of stars if (board.getPuzzleNumber() * columns.size() - columnStars != board.getPuzzleNumber() * regions.size() - regionStars) { - return "The number of missing stars in the "; + return "The number of missing stars in the columns and regions must be equal and every extraneous cell must be black!"; } return null; } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRowsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRowsDirectRule.java new file mode 100644 index 000000000..4c8eb6915 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRowsDirectRule.java @@ -0,0 +1,97 @@ +package edu.rpi.legup.puzzle.starbattle.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.starbattle.StarBattleBoard; +import edu.rpi.legup.puzzle.starbattle.StarBattleCell; +import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; + +import java.util.HashSet; +import java.util.Set; + +public class ColumnsWithinRowsDirectRule extends DirectRule { + + public ColumnsWithinRowsDirectRule() { + super("STBL-BASC-XXXX", + "Columns Within Rows", + "If a number of columns is fully contained by an equal number of rows, spaces of other columns in those rows must be black.", + "INSERT IMAGE NAME HERE"); + } + + /** + * 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) { + + //assumption: the rule has been applied to its fullest extent and the rows and columns + //are now mutually encompassing + StarBattleBoard board = (StarBattleBoard) transition.getBoard(); + StarBattleCell cell = (StarBattleCell) board.getPuzzleElement(puzzleElement); + if (cell.getType() != StarBattleCellType.BLACK) { + return "Only black cells are allowed for this rule!"; + } + + //the columns that are contained + Set columns = new HashSet(); + //the rows that contain them + Set rows = new HashSet(); + //columns and rows to process + Set columnsToCheck = new HashSet(); + Set rowsToCheck = new HashSet(); + int columnStars = 0; + int rowStars = 0; + int firstRow = cell.getLocation().y; + rows.add(firstRow); + rowsToCheck.add(firstRow); + + while (!columnsToCheck.isEmpty() || !rowsToCheck.isEmpty()) { + for (int r: rowsToCheck) { + rowStars += board.rowStars(r); + for (PuzzleElement c: board.getRow(r)) { + int column = ((StarBattleCell) c).getLocation().x; + if (columns.add(column)) { + columnsToCheck.add(column); + } + } + rowsToCheck.remove(r); + } + for (int c: columnsToCheck) { + columnStars += board.columnStars(c); + for (PuzzleElement r: board.getCol(c)) { + int row = ((StarBattleCell) r).getLocation().y; + if (rows.add(row)) { + rowsToCheck.add(row); + } + } + columnsToCheck.remove(c); + } + } + // are the columns and regions missing an equal amount of stars + if (board.getPuzzleNumber() * columns.size() - columnStars != board.getPuzzleNumber() * rows.size() - rowStars) { + return "The number of missing stars in the columns and rows must be equal and every extraneous cell must be black!"; + } + 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/starbattle/rules/RegionsWithinColumnsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinColumnsDirectRule.java index 84787e704..74e296522 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinColumnsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinColumnsDirectRule.java @@ -9,8 +9,8 @@ public class RegionsWithinColumnsDirectRule extends DirectRule { public RegionsWithinColumnsDirectRule() { super("STBL-BASC-0004", - "Regions Within Rows/Columns", - "If a number of regions is fully contained by an equal number of rows or columns, spaces of other regions in those rows or columns must be black.", + "Regions Within Columns", + "If a number of regions is fully contained by an equal number of columns, spaces of other regions in those columns must be black.", "INSERT IMAGE NAME HERE"); } @@ -25,8 +25,8 @@ public RegionsWithinColumnsDirectRule() { */ @Override public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) { - - return null; + ColumnsWithinRegionsDirectRule correspondingRule = new ColumnsWithinRegionsDirectRule(); + return correspondingRule.checkRuleRawAt(transition, puzzleElement); } /** diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsDirectRule.java index e71c97df9..f89e0d63f 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsDirectRule.java @@ -9,8 +9,8 @@ public class RegionsWithinRowsDirectRule extends DirectRule { public RegionsWithinRowsDirectRule() { super("STBL-BASC-0005", - "Regions Within Rows/Columns", - "If a number of regions is fully contained by an equal number of rows or columns, spaces of other regions in those rows or columns must be black.", + "Regions Within Rows", + "If a number of regions is fully contained by an equal number of rows, spaces of other regions in those rows must be black.", "INSERT IMAGE NAME HERE"); } @@ -26,7 +26,8 @@ public RegionsWithinRowsDirectRule() { @Override public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) { - return null; + RowsWithinRegionsDirectRule correspondingRule = new RowsWithinRegionsDirectRule(); + return correspondingRule.checkRuleRawAt(transition, puzzleElement); } /** diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinColumnsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinColumnsDirectRule.java new file mode 100644 index 000000000..48fb1cd81 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinColumnsDirectRule.java @@ -0,0 +1,51 @@ +package edu.rpi.legup.puzzle.starbattle.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.starbattle.StarBattleBoard; +import edu.rpi.legup.puzzle.starbattle.StarBattleCell; +import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; + +import java.util.HashSet; +import java.util.Set; + +public class RowsWithinColumnsDirectRule extends DirectRule { + + public RowsWithinColumnsDirectRule() { + super("STBL-BASC-XXXX", + "Rows Withing Columns", + "If a number of rows is fully contained by an equal number of columns, spaces of other rows in those columns must be black.", + "INSERT IMAGE NAME HERE"); + } + + /** + * 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) { + + ColumnsWithinRowsDirectRule correspondingRule = new ColumnsWithinRowsDirectRule(); + return correspondingRule.checkRuleRawAt(transition, puzzleElement); + } + + /** + * 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/starbattle/rules/RowsWithinRegionsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinRegionsDirectRule.java index 128c44095..8cc68d292 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinRegionsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinRegionsDirectRule.java @@ -5,12 +5,18 @@ 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.starbattle.StarBattleBoard; +import edu.rpi.legup.puzzle.starbattle.StarBattleCell; +import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; + +import java.util.HashSet; +import java.util.Set; public class RowsWithinRegionsDirectRule extends DirectRule { public RowsWithinRegionsDirectRule() { super("STBL-BASC-0006", - "Rows/Columns Within Regions", - "If a number of rows or columns is fully contained by an equal number of regions, spaces of other rows or columns, respectively, in those regions must be black.", + "Rows Within Regions", + "If a number of rows is fully contained by an equal number of regions, spaces of other rows in those regions must be black.", "INSERT IMAGE NAME HERE"); } @@ -26,6 +32,51 @@ public RowsWithinRegionsDirectRule() { @Override public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) { + //assumption: the rule has been applied to its fullest extent and the rows and regions + //are now mutually encompassing + StarBattleBoard board = (StarBattleBoard) transition.getBoard(); + StarBattleCell cell = (StarBattleCell) board.getPuzzleElement(puzzleElement); + if (cell.getType() != StarBattleCellType.BLACK) { + return "Only black cells are allowed for this rule!"; + } + //the rows that are contained + Set rows = new HashSet(); + //the regions that contain them + Set regions = new HashSet(); + //rows and regions to process + Set rowsToCheck = new HashSet(); + Set regionsToCheck = new HashSet(); + int rowStars = 0; + int regionStars = 0; + regions.add(cell.getGroupIndex()); + regionsToCheck.add(cell.getGroupIndex()); + + while (!rowsToCheck.isEmpty() || !regionsToCheck.isEmpty()) { + for (int r: regionsToCheck) { + regionStars += board.getRegion(r).numStars(); + for (PuzzleElement ro: board.getRegion(r).getCells()) { + int row = ((StarBattleCell) ro).getLocation().y; + if (rows.add(row)) { + rowsToCheck.add(row); + } + } + regionsToCheck.remove(r); + } + for (int r: rowsToCheck) { + rowStars += board.rowStars(r); + for (int i = 0; i < board.getSize(); ++i) { + int region = board.getCell(i,r).getGroupIndex(); + if (regions.add(region)) { + regionsToCheck.add(region); + } + } + rowsToCheck.remove(r); + } + } + // are the columns and regions missing an equal amount of stars + if (board.getPuzzleNumber() * rows.size() - rowStars != board.getPuzzleNumber() * regions.size() - regionStars) { + return "The number of missing stars in the rows and regions must be equal and every extraneous cell must be black!"; + } return null; } From 49cd17e88546c0f43a14c9c5a4101c6e5a9bb84c Mon Sep 17 00:00:00 2001 From: summerhenson Date: Fri, 22 Mar 2024 17:17:56 -0400 Subject: [PATCH 46/70] Minor changes to direct rules --- .../rules/ColumnsWithinRegionsDirectRule.java | 2 +- .../rules/ColumnsWithinRowsDirectRule.java | 4 ++-- .../starbattle/rules/FinishWithStarsDirectRule.java | 2 +- .../rules/RegionsWithinColumnsDirectRule.java | 4 ++-- .../rules/RegionsWithinRowsDirectRule.java | 4 ++-- .../rules/RowsWithinColumnsDirectRule.java | 4 ++-- .../rules/RowsWithinRegionsDirectRule.java | 4 ++-- .../starbattle/rules/SurroundStarDirectRule.java | 2 +- .../starbattle/rules/starbattle_reference_sheet.txt | 12 +++++++----- 9 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java index 980f6db19..93fb86dc5 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java @@ -17,7 +17,7 @@ public class ColumnsWithinRegionsDirectRule extends DirectRule { public ColumnsWithinRegionsDirectRule() { super("STBL-BASC-0002", "Columns Within Regions", - "If a number of columns is fully contained by an equal number of regions, spaces of other columns in those regions must be black.", + "If a number of columns is fully contained by a number of regions with an equal number of missing stars, spaces of other columns in those regions must be black.", "INSERT IMAGE NAME HERE"); } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRowsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRowsDirectRule.java index 4c8eb6915..389ba02c2 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRowsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRowsDirectRule.java @@ -15,9 +15,9 @@ public class ColumnsWithinRowsDirectRule extends DirectRule { public ColumnsWithinRowsDirectRule() { - super("STBL-BASC-XXXX", + super("STBL-BASC-0003", "Columns Within Rows", - "If a number of columns is fully contained by an equal number of rows, spaces of other columns in those rows must be black.", + "If a number of columns is fully contained by a number of rows with an equal number of missing stars, spaces of other columns in those rows must be black.", "INSERT IMAGE NAME HERE"); } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java index 13050a5ac..ed6a8a986 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java @@ -13,7 +13,7 @@ public class FinishWithStarsDirectRule extends DirectRule { public FinishWithStarsDirectRule() { - super("STBL-BASC-0003", + super("STBL-BASC-0004", "Finish With Stars", "Unknown spaces must be stars if there are just enough in a row, column, or region to satisfy the puzzle number.", "INSERT IMAGE NAME HERE"); diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinColumnsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinColumnsDirectRule.java index 74e296522..d2fa4fbe3 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinColumnsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinColumnsDirectRule.java @@ -8,9 +8,9 @@ public class RegionsWithinColumnsDirectRule extends DirectRule { public RegionsWithinColumnsDirectRule() { - super("STBL-BASC-0004", + super("STBL-BASC-0005", "Regions Within Columns", - "If a number of regions is fully contained by an equal number of columns, spaces of other regions in those columns must be black.", + "If a number of regions is fully contained by a number of columns with an equal number of missing stars, spaces of other regions in those columns must be black.", "INSERT IMAGE NAME HERE"); } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsDirectRule.java index f89e0d63f..15993b85d 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsDirectRule.java @@ -8,9 +8,9 @@ public class RegionsWithinRowsDirectRule extends DirectRule { public RegionsWithinRowsDirectRule() { - super("STBL-BASC-0005", + super("STBL-BASC-0006", "Regions Within Rows", - "If a number of regions is fully contained by an equal number of rows, spaces of other regions in those rows must be black.", + "If a number of regions is fully contained by a number of rows with an equal number of missing stars, spaces of other regions in those rows must be black.", "INSERT IMAGE NAME HERE"); } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinColumnsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinColumnsDirectRule.java index 48fb1cd81..2d6c148d0 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinColumnsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinColumnsDirectRule.java @@ -15,9 +15,9 @@ public class RowsWithinColumnsDirectRule extends DirectRule { public RowsWithinColumnsDirectRule() { - super("STBL-BASC-XXXX", + super("STBL-BASC-0007", "Rows Withing Columns", - "If a number of rows is fully contained by an equal number of columns, spaces of other rows in those columns must be black.", + "If a number of rows is fully contained by a number of columns with an equal number of missing stars, spaces of other rows in those columns must be black.", "INSERT IMAGE NAME HERE"); } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinRegionsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinRegionsDirectRule.java index 8cc68d292..7dfaae59f 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinRegionsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinRegionsDirectRule.java @@ -14,9 +14,9 @@ public class RowsWithinRegionsDirectRule extends DirectRule { public RowsWithinRegionsDirectRule() { - super("STBL-BASC-0006", + super("STBL-BASC-0008", "Rows Within Regions", - "If a number of rows is fully contained by an equal number of regions, spaces of other rows in those regions must be black.", + "If a number of rows is fully contained by a number of regions with an equal number of missing stars, spaces of other rows in those regions must be black.", "INSERT IMAGE NAME HERE"); } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java index a5533104c..0608d388f 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java @@ -13,7 +13,7 @@ public class SurroundStarDirectRule extends DirectRule { public SurroundStarDirectRule() { - super("STBL-BASC-0007", + super("STBL-BASC-0009", "Surround Star", "Any space adjacent to a star must be black.", "INSERT IMAGE NAME HERE"); diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/starbattle_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/starbattle_reference_sheet.txt index 958440a71..f18965fd6 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/starbattle_reference_sheet.txt +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/starbattle_reference_sheet.txt @@ -5,11 +5,13 @@ Star or Empty: STBL-CASE-0002 Basic Rules: Blackout: STBL-BASC-0001 Columns Within Regions: STBL-BASC-0002 -Finish With Stars: STBL-BASC-0003 -Regions Within Columns: STBL-BASC-0004 -Regions Within Rows: STBL-BASC-0005 -Rows Within Regions: STBL-BASC-0006 -Surround Star: STBL-BASC-0007 +Columns Within Rows: STBL-BASC-0003 +Finish With Stars: STBL-BASC-0004 +Regions Within Columns: STBL-BASC-0005 +Regions Within Rows: STBL-BASC-0006 +Rows Within Columns: STBL-BASC-0007 +Rows Within Regions: STBL-BASC-0008 +Surround Star: STBL-BASC-0009 Contradiction Rules: Too Many Stars: STBL-CONT-0001 From 096f070b8482cef0942aad5258f9e94f6ee1e238 Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Fri, 22 Mar 2024 17:33:28 -0400 Subject: [PATCH 47/70] Added StarBattle to config Showed how to run in allfiles Changed puzzles to be more standardized with each other --- bin/main/edu/rpi/legup/legup/config | 6 ++++- .../6x6 Star Battle 1star Normal1.xml | 3 +-- .../6x6 Star Battle 1star Normal2.xml | 3 +-- .../8x8 Star Battle 1star Normal1.xml | 23 ++++++++++++++++++- .../starbattle/StarBattleCellFactory.java | 7 +++++- .../puzzle/starbattle/StarBattleView.java | 2 +- .../rpi/legup/puzzle/starbattle/allfiles.txt | 7 +++++- src/main/resources/edu/rpi/legup/legup/config | 6 ++++- 8 files changed, 47 insertions(+), 10 deletions(-) diff --git a/bin/main/edu/rpi/legup/legup/config b/bin/main/edu/rpi/legup/legup/config index 19e63a2a3..05f4e9e40 100644 --- a/bin/main/edu/rpi/legup/legup/config +++ b/bin/main/edu/rpi/legup/legup/config @@ -31,6 +31,10 @@ + - + diff --git a/puzzles files/starbattle/6x6 Star Battle 1star Normal1.xml b/puzzles files/starbattle/6x6 Star Battle 1star Normal1.xml index 4163e15a9..110dd9abe 100644 --- a/puzzles files/starbattle/6x6 Star Battle 1star Normal1.xml +++ b/puzzles files/starbattle/6x6 Star Battle 1star Normal1.xml @@ -1,8 +1,7 @@ - - + diff --git a/puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml b/puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml index 29307fb58..49efeba59 100644 --- a/puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml +++ b/puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml @@ -1,8 +1,7 @@ - - + diff --git a/puzzles files/starbattle/8x8 Star Battle 1star Normal1.xml b/puzzles files/starbattle/8x8 Star Battle 1star Normal1.xml index ba237102f..e429c3ad1 100644 --- a/puzzles files/starbattle/8x8 Star Battle 1star Normal1.xml +++ b/puzzles files/starbattle/8x8 Star Battle 1star Normal1.xml @@ -1,7 +1,28 @@ - + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java index 92ea8abf6..9f7fd0fee 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellFactory.java @@ -39,9 +39,14 @@ public StarBattleCell importCell(Node node, Board board) throws InvalidFileForma cell.setIndex(y * size + x); return cell; } + catch (NumberFormatException e1) { + e1.printStackTrace(); throw new InvalidFileFormatException("starbattle Factory: unknown value where integer expected"); - } catch (NullPointerException e2) { + } + + catch (NullPointerException e2) { + e2.printStackTrace(); throw new InvalidFileFormatException("starbattle Factory: could not find attribute(s)"); } } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java index a39770d85..cc6d39677 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java @@ -22,7 +22,7 @@ import java.util.ArrayList; public class StarBattleView extends GridBoardView { - private final static Logger LOGGER = LogManager.getLogger(StarBattleView.class.getName()); + private static final Logger LOGGER = LogManager.getLogger(StarBattleView.class.getName()); static Image STAR; diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt b/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt index 7970eadbf..5a9ec0f0a 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/allfiles.txt @@ -227,4 +227,9 @@ public enum StarBattleType { //StarBattleExporter.java //StarBattleImporter.java -//StarBattleView.java \ No newline at end of file +//StarBattleView.java + +How to run Legup: + +./gradlew build +Java -jar build/libs/Legup.jar \ No newline at end of file diff --git a/src/main/resources/edu/rpi/legup/legup/config b/src/main/resources/edu/rpi/legup/legup/config index 19e63a2a3..05f4e9e40 100644 --- a/src/main/resources/edu/rpi/legup/legup/config +++ b/src/main/resources/edu/rpi/legup/legup/config @@ -31,6 +31,10 @@ + - + From b713212c73cdb07adcf209fcd8c773ba9b856455 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 26 Mar 2024 16:46:20 -0400 Subject: [PATCH 48/70] Reorganized puzzle files (put in subdirectories) --- .../6x6 Star Battle 1star Normal1.xml | 0 .../6x6 Star Battle 1star Normal2.xml | 0 .../rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java | 1 - 3 files changed, 1 deletion(-) rename puzzles files/starbattle/{ => 6x6 Star Battle Normal}/6x6 Star Battle 1star Normal1.xml (100%) rename puzzles files/starbattle/{ => 6x6 Star Battle Normal}/6x6 Star Battle 1star Normal2.xml (100%) diff --git a/puzzles files/starbattle/6x6 Star Battle 1star Normal1.xml b/puzzles files/starbattle/6x6 Star Battle Normal/6x6 Star Battle 1star Normal1.xml similarity index 100% rename from puzzles files/starbattle/6x6 Star Battle 1star Normal1.xml rename to puzzles files/starbattle/6x6 Star Battle Normal/6x6 Star Battle 1star Normal1.xml diff --git a/puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml b/puzzles files/starbattle/6x6 Star Battle Normal/6x6 Star Battle 1star Normal2.xml similarity index 100% rename from puzzles files/starbattle/6x6 Star Battle 1star Normal2.xml rename to puzzles files/starbattle/6x6 Star Battle Normal/6x6 Star Battle 1star Normal2.xml diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java index 57a5688f2..ceea86164 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java @@ -57,7 +57,6 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem */ @Override public Board getDefaultBoard(TreeNode node) { - return null; } } From 52220ca56382cc0552b8660137a20f5f756151bf Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 26 Mar 2024 16:47:05 -0400 Subject: [PATCH 49/70] Created 8x8 1 star puzzle --- .../8x8 Star Battle 1star Normal1.xml | 31 ------ .../8x8 Star Battle 1star Normal1.xml | 104 ++++++++++++++++++ 2 files changed, 104 insertions(+), 31 deletions(-) delete mode 100644 puzzles files/starbattle/8x8 Star Battle 1star Normal1.xml create mode 100644 puzzles files/starbattle/8x8 Star Battle Normal/8x8 Star Battle 1star Normal1.xml diff --git a/puzzles files/starbattle/8x8 Star Battle 1star Normal1.xml b/puzzles files/starbattle/8x8 Star Battle 1star Normal1.xml deleted file mode 100644 index e429c3ad1..000000000 --- a/puzzles files/starbattle/8x8 Star Battle 1star Normal1.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/puzzles files/starbattle/8x8 Star Battle Normal/8x8 Star Battle 1star Normal1.xml b/puzzles files/starbattle/8x8 Star Battle Normal/8x8 Star Battle 1star Normal1.xml new file mode 100644 index 000000000..977a62e1f --- /dev/null +++ b/puzzles files/starbattle/8x8 Star Battle Normal/8x8 Star Battle 1star Normal1.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From e2db3f2ff2f11c8ed7e3872473d6a11b406647c5 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 26 Mar 2024 17:44:35 -0400 Subject: [PATCH 50/70] Created more puzzles --- .../6x6 Star Battle 1star Normal1.xml | 0 .../6x6 Star Battle 1star Normal2.xml | 0 .../6x6 StarBattle 1star Normal3.xml | 67 ++++++++++++ .../7x7 puzzle1.xml | 42 +++++++ .../8x8 Star Battle 1star Normal1.xml | 0 .../8x8 Star Battle 1star Normal2.xml | 103 ++++++++++++++++++ .../8x8 Star Battle 1star Normal3.xml | 103 ++++++++++++++++++ 7 files changed, 315 insertions(+) rename puzzles files/starbattle/{6x6 Star Battle Normal => 6x6 Star Battle 1 star Normal}/6x6 Star Battle 1star Normal1.xml (100%) rename puzzles files/starbattle/{6x6 Star Battle Normal => 6x6 Star Battle 1 star Normal}/6x6 Star Battle 1star Normal2.xml (100%) create mode 100644 puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 StarBattle 1star Normal3.xml create mode 100644 puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 puzzle1.xml rename puzzles files/starbattle/{8x8 Star Battle Normal => 8x8 Star Battle 1 star Normal}/8x8 Star Battle 1star Normal1.xml (100%) create mode 100644 puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal2.xml create mode 100644 puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal3.xml diff --git a/puzzles files/starbattle/6x6 Star Battle Normal/6x6 Star Battle 1star Normal1.xml b/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 Star Battle 1star Normal1.xml similarity index 100% rename from puzzles files/starbattle/6x6 Star Battle Normal/6x6 Star Battle 1star Normal1.xml rename to puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 Star Battle 1star Normal1.xml diff --git a/puzzles files/starbattle/6x6 Star Battle Normal/6x6 Star Battle 1star Normal2.xml b/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 Star Battle 1star Normal2.xml similarity index 100% rename from puzzles files/starbattle/6x6 Star Battle Normal/6x6 Star Battle 1star Normal2.xml rename to puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 Star Battle 1star Normal2.xml diff --git a/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 StarBattle 1star Normal3.xml b/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 StarBattle 1star Normal3.xml new file mode 100644 index 000000000..80f8658d3 --- /dev/null +++ b/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 StarBattle 1star Normal3.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 puzzle1.xml b/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 puzzle1.xml new file mode 100644 index 000000000..b4c56807a --- /dev/null +++ b/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 puzzle1.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/puzzles files/starbattle/8x8 Star Battle Normal/8x8 Star Battle 1star Normal1.xml b/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal1.xml similarity index 100% rename from puzzles files/starbattle/8x8 Star Battle Normal/8x8 Star Battle 1star Normal1.xml rename to puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal1.xml diff --git a/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal2.xml b/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal2.xml new file mode 100644 index 000000000..e9c734546 --- /dev/null +++ b/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal2.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal3.xml b/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal3.xml new file mode 100644 index 000000000..1f050440b --- /dev/null +++ b/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal3.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From f747aa8ac836f3a0bba4a4587a3d6ffbe76f381b Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Fri, 29 Mar 2024 16:01:43 -0400 Subject: [PATCH 51/70] Update StarBattleView.java --- .../edu/rpi/legup/puzzle/starbattle/StarBattleView.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java index cc6d39677..e0914215a 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java @@ -6,20 +6,12 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; - -import edu.rpi.legup.puzzle.starbattle.StarBattleBoard; -import edu.rpi.legup.puzzle.starbattle.StarBattleCell; -import edu.rpi.legup.puzzle.starbattle.StarBattleController; -import edu.rpi.legup.puzzle.starbattle.StarBattleElementView; import edu.rpi.legup.puzzle.starbattle.StarBattleView; import edu.rpi.legup.ui.boardview.GridBoardView; import edu.rpi.legup.controller.BoardController; -import edu.rpi.legup.model.gameboard.CaseBoard; import edu.rpi.legup.model.gameboard.PuzzleElement; -import edu.rpi.legup.ui.boardview.ElementView; import java.awt.*; -import java.util.ArrayList; public class StarBattleView extends GridBoardView { private static final Logger LOGGER = LogManager.getLogger(StarBattleView.class.getName()); From 23c3d92a9d7ccc7538234f8e80ed856f268df73b Mon Sep 17 00:00:00 2001 From: summerhenson Date: Fri, 29 Mar 2024 16:47:14 -0400 Subject: [PATCH 52/70] Wrote 5x5 puzzle file 1 --- .../5x5 Star Battle 1 star Normal 1.xml | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml diff --git a/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml b/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml new file mode 100644 index 000000000..8cd026437 --- /dev/null +++ b/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 99e431fd3d452b0edb04f980976b188895264f5d Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Fri, 29 Mar 2024 16:51:07 -0400 Subject: [PATCH 53/70] StarBattle Runs --- .../legup/puzzle/starbattle/StarBattleController.java | 6 ++---- .../edu/rpi/legup/puzzle/starbattle/StarBattleView.java | 6 ++---- src/main/java/edu/rpi/legup/utility/LegupUtils.java | 9 ++++++++- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleController.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleController.java index f7a094397..6b2a9352d 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleController.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleController.java @@ -14,12 +14,10 @@ public void changeCell(MouseEvent e, PuzzleElement data) { this.boardView.getSelectionPopupMenu().show(boardView, this.boardView.getCanvas().getX() + e.getX(), this.boardView.getCanvas().getY() + e.getY()); } else { - if (cell.getData() == 0) { + data.setData(cell.getData() + 1); + if (cell.getData() >= 0) { data.setData(-3); } - else { - data.setData(cell.getData() + 1); - } } } else { diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java index e0914215a..ceb0eec19 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleView.java @@ -14,16 +14,14 @@ import java.awt.*; public class StarBattleView extends GridBoardView { - private static final Logger LOGGER = LogManager.getLogger(StarBattleView.class.getName()); - static Image STAR; static { try { - STAR = ImageIO.read(ClassLoader.getSystemResourceAsStream("edu/rpi/legup/images/starbattle/star.png")); + STAR = ImageIO.read(ClassLoader.getSystemClassLoader().getResource("edu/rpi/legup/images/starbattle/star.gif")); } catch (IOException e) { - LOGGER.error("Failed to open starbattle image."); + // pass } } diff --git a/src/main/java/edu/rpi/legup/utility/LegupUtils.java b/src/main/java/edu/rpi/legup/utility/LegupUtils.java index dbdd24e7f..317fb787e 100644 --- a/src/main/java/edu/rpi/legup/utility/LegupUtils.java +++ b/src/main/java/edu/rpi/legup/utility/LegupUtils.java @@ -85,7 +85,14 @@ private static List findClassesZip(String path, String packageName) throw for (ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip.getNextEntry()) { if (!entry.isDirectory() && entry.getName().endsWith(".class") && entry.getName().startsWith(packageName)) { String className = entry.getName().replace('/', '.'); - classes.add(Class.forName(className.substring(0, className.length() - ".class".length()))); + String substr = className.substring(0, className.length() - ".class".length()); + try { + Class c = Class.forName(substr); + classes.add(c); + } + catch (LinkageError | ClassNotFoundException e) { + System.out.println("Failed on " + substr); + } } } return classes; From 63ea4911079b43136c3ea1f272d3663e85cc6d44 Mon Sep 17 00:00:00 2001 From: summerhenson Date: Fri, 29 Mar 2024 17:27:36 -0400 Subject: [PATCH 54/70] Fix spelling error --- .../5x5 Star Battle 1 star Normal 1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml b/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml index 8cd026437..5fefc844f 100644 --- a/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml +++ b/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml @@ -1,4 +1,4 @@ - + From 617b0acabfb25b7a3abf4dc0300c56e6c74e4221 Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Fri, 29 Mar 2024 17:35:39 -0400 Subject: [PATCH 55/70] Update StarBattleController.java Fixed the right click issue. --- .../edu/rpi/legup/puzzle/starbattle/StarBattleController.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleController.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleController.java index 6b2a9352d..9566a3f52 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleController.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleController.java @@ -22,12 +22,10 @@ public void changeCell(MouseEvent e, PuzzleElement data) { } else { if (e.getButton() == MouseEvent.BUTTON3) { + data.setData(cell.getData() - 1); if (cell.getData() == -3) { data.setData(0); } - else { - data.setData(cell.getData() - 1); - } } } } From b3452a8262338a721c84ab3fb0058359b1e50d0b Mon Sep 17 00:00:00 2001 From: Sarah Date: Fri, 29 Mar 2024 18:03:45 -0400 Subject: [PATCH 56/70] Created more puzzles --- .../6x6 StarBattle 1star Normal3.xml | 1 + .../7x7 Star Battle 1star Hard1.xml | 60 +++++++++++++ .../7x7 Star Battle 1star Normal1.xml | 85 +++++++++++++++++++ .../7x7 Star Battle 1star Normal2.xml | 85 +++++++++++++++++++ .../7x7 puzzle1.xml | 42 --------- .../8x8 Star Battle 1star Normal1.xml | 1 + .../8x8 Star Battle 1star Normal2.xml | 1 + .../8x8 Star Battle 1star Normal3.xml | 1 + 8 files changed, 234 insertions(+), 42 deletions(-) create mode 100644 puzzles files/starbattle/7x7 Star Battle 1 star Hard/7x7 Star Battle 1star Hard1.xml create mode 100644 puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal1.xml create mode 100644 puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal2.xml delete mode 100644 puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 puzzle1.xml diff --git a/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 StarBattle 1star Normal3.xml b/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 StarBattle 1star Normal3.xml index 80f8658d3..855943612 100644 --- a/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 StarBattle 1star Normal3.xml +++ b/puzzles files/starbattle/6x6 Star Battle 1 star Normal/6x6 StarBattle 1star Normal3.xml @@ -64,4 +64,5 @@ + \ No newline at end of file diff --git a/puzzles files/starbattle/7x7 Star Battle 1 star Hard/7x7 Star Battle 1star Hard1.xml b/puzzles files/starbattle/7x7 Star Battle 1 star Hard/7x7 Star Battle 1star Hard1.xml new file mode 100644 index 000000000..bacc00b11 --- /dev/null +++ b/puzzles files/starbattle/7x7 Star Battle 1 star Hard/7x7 Star Battle 1star Hard1.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal1.xml b/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal1.xml new file mode 100644 index 000000000..70b81e376 --- /dev/null +++ b/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal1.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal2.xml b/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal2.xml new file mode 100644 index 000000000..c541ece06 --- /dev/null +++ b/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal2.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 puzzle1.xml b/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 puzzle1.xml deleted file mode 100644 index b4c56807a..000000000 --- a/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 puzzle1.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal1.xml b/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal1.xml index 977a62e1f..02dd5d6c0 100644 --- a/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal1.xml +++ b/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal1.xml @@ -101,4 +101,5 @@ + \ No newline at end of file diff --git a/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal2.xml b/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal2.xml index e9c734546..0df84ef62 100644 --- a/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal2.xml +++ b/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal2.xml @@ -100,4 +100,5 @@ + \ No newline at end of file diff --git a/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal3.xml b/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal3.xml index 1f050440b..725c91d7f 100644 --- a/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal3.xml +++ b/puzzles files/starbattle/8x8 Star Battle 1 star Normal/8x8 Star Battle 1star Normal3.xml @@ -100,4 +100,5 @@ + \ No newline at end of file From 85c9b7c9d3e84b9d6e3eeb3374e72103073407f1 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 2 Apr 2024 16:40:19 -0400 Subject: [PATCH 57/70] created image for star or empty case rule --- .../rpi/legup/images/starbattle/UnknownTile.png | Bin 0 -> 9733 bytes .../starbattle/cases/StarOrEmptyCaseRule.png | Bin 0 -> 4437 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/resources/edu/rpi/legup/images/starbattle/UnknownTile.png create mode 100644 src/main/resources/edu/rpi/legup/images/starbattle/cases/StarOrEmptyCaseRule.png diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/UnknownTile.png b/src/main/resources/edu/rpi/legup/images/starbattle/UnknownTile.png new file mode 100644 index 0000000000000000000000000000000000000000..850fbf127f04020fe83c6a4f6db75078967916ea GIT binary patch literal 9733 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 QTOg2`(SBUvUiYy70dQO53jhEB literal 0 HcmV?d00001 diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/cases/StarOrEmptyCaseRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/cases/StarOrEmptyCaseRule.png new file mode 100644 index 0000000000000000000000000000000000000000..0383711bb7fb4d881c78c0d5c61227ac7c05cb49 GIT binary patch literal 4437 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 literal 0 HcmV?d00001 From 84827707929cb2992d9cbdedd30ec7cac52903fc Mon Sep 17 00:00:00 2001 From: EmilioBejasa <69165764+EmilioBejasa@users.noreply.github.com> Date: Tue, 2 Apr 2024 17:10:42 -0400 Subject: [PATCH 58/70] Deleted WHITE element It was unnecessary, we were switching between unknown star and blank anyways. --- .../legup/puzzle/starbattle/StarBattleCellType.java | 2 +- .../puzzle/starbattle/StarBattleController.java | 12 ++++++++---- .../puzzle/starbattle/StarBattleElementView.java | 7 +------ .../puzzle/starbattle/rules/StarOrEmptyCaseRule.java | 4 ++-- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellType.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellType.java index f3524034e..565f608d7 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellType.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCellType.java @@ -2,7 +2,7 @@ package edu.rpi.legup.puzzle.starbattle; public enum StarBattleCellType { - WHITE(-3), STAR(-2), BLACK(-1), UNKNOWN(0); + STAR(-2), BLACK(-1), UNKNOWN(0); public int value; diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleController.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleController.java index 9566a3f52..4ebeb39ba 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleController.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleController.java @@ -14,18 +14,22 @@ public void changeCell(MouseEvent e, PuzzleElement data) { this.boardView.getSelectionPopupMenu().show(boardView, this.boardView.getCanvas().getX() + e.getX(), this.boardView.getCanvas().getY() + e.getY()); } else { - data.setData(cell.getData() + 1); if (cell.getData() >= 0) { - data.setData(-3); + data.setData(-2); + } + else { + data.setData(cell.getData() + 1); } } } else { if (e.getButton() == MouseEvent.BUTTON3) { - data.setData(cell.getData() - 1); - if (cell.getData() == -3) { + if (cell.getData() == -2) { data.setData(0); } + else { + data.setData(cell.getData() - 1); + } } } } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleElementView.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleElementView.java index a88773a06..ff5d54d1c 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleElementView.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleElementView.java @@ -29,12 +29,6 @@ public void drawElement(Graphics2D graphics2D) { graphics2D.setStroke(new BasicStroke(1)); graphics2D.setColor(Color.BLACK); graphics2D.fillRect(location.x, location.y, size.width, size.height); - } else if (type == StarBattleCellType.WHITE) { - graphics2D.setStroke(new BasicStroke(1)); - graphics2D.setColor(Color.WHITE); - graphics2D.fillRect(location.x, location.y, size.width, size.height); - graphics2D.setColor(Color.BLACK); - graphics2D.drawRect(location.x, location.y, size.width, size.height); } else if (type == StarBattleCellType.UNKNOWN) { graphics2D.setStroke(new BasicStroke(1)); graphics2D.setColor(Color.LIGHT_GRAY); @@ -42,5 +36,6 @@ public void drawElement(Graphics2D graphics2D) { graphics2D.setColor(Color.BLACK); graphics2D.drawRect(location.x, location.y, size.width, size.height); } + } } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java index 1bbbe3e92..035e55073 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java @@ -20,7 +20,7 @@ public StarOrEmptyCaseRule() { super("STBL-CASE-0002", "Star or Empty", "Each unknown space is either a star or empty.", - "INSERT IMAGE NAME HERE"); + "edu/rpi/legup/images/starbattle/cases/StarOrEmptyCaseRule.png"); } /** @@ -98,6 +98,6 @@ public ArrayList getCases(Board board, PuzzleElement puzzleElement) { @Override public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) { - return null; + return checkRuleRaw(transition); } } From 09263e681d8e316deea41a3ce920783caad9dead Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 2 Apr 2024 17:35:17 -0400 Subject: [PATCH 59/70] More rule images --- .../ClashingOrbitContradictionRule.png | Bin 0 -> 5397 bytes .../TooFewStarsContradictionRule.png | Bin 0 -> 3571 bytes .../TooManyStarsContradictionRule.png | Bin 0 -> 5815 bytes .../starbattle/rules/BlackOutDirectRule.png | Bin 0 -> 5209 bytes .../rules/FinishWithStarDirectRule.png | Bin 0 -> 4399 bytes .../images/starbattle/rules/SurroundStar.png | Bin 0 -> 5102 bytes 6 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/resources/edu/rpi/legup/images/starbattle/contradictions/ClashingOrbitContradictionRule.png create mode 100644 src/main/resources/edu/rpi/legup/images/starbattle/contradictions/TooFewStarsContradictionRule.png create mode 100644 src/main/resources/edu/rpi/legup/images/starbattle/contradictions/TooManyStarsContradictionRule.png create mode 100644 src/main/resources/edu/rpi/legup/images/starbattle/rules/BlackOutDirectRule.png create mode 100644 src/main/resources/edu/rpi/legup/images/starbattle/rules/FinishWithStarDirectRule.png create mode 100644 src/main/resources/edu/rpi/legup/images/starbattle/rules/SurroundStar.png diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/ClashingOrbitContradictionRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/ClashingOrbitContradictionRule.png new file mode 100644 index 0000000000000000000000000000000000000000..3cdbfd4e1ebb0dc820f59cfd90297d35795e93df GIT binary patch literal 5397 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 Wa{k=8Y32$D_&C}V?XKD$i2e@+u;#@8 literal 0 HcmV?d00001 diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/TooManyStarsContradictionRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/TooManyStarsContradictionRule.png new file mode 100644 index 0000000000000000000000000000000000000000..724f8aa64d9733c30ca7fe5d1d52fe92cb539e8d GIT binary patch literal 5815 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/rules/BlackOutDirectRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/rules/BlackOutDirectRule.png new file mode 100644 index 0000000000000000000000000000000000000000..53fac213291591a0318f46e049ad083a25315527 GIT binary patch literal 5209 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/rules/FinishWithStarDirectRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/rules/FinishWithStarDirectRule.png new file mode 100644 index 0000000000000000000000000000000000000000..24eddc3b058a4a390b9e9344d4aa012c85f415be GIT binary patch literal 4399 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/rules/SurroundStar.png b/src/main/resources/edu/rpi/legup/images/starbattle/rules/SurroundStar.png new file mode 100644 index 0000000000000000000000000000000000000000..13287f779e74d6c70489f32013ec3675b07dfe4c GIT binary patch literal 5102 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 literal 0 HcmV?d00001 From 999fa1780ad12f8ecbe0912d3da285b7b7c902ee Mon Sep 17 00:00:00 2001 From: summerhenson Date: Fri, 5 Apr 2024 16:42:27 -0400 Subject: [PATCH 60/70] Made small test board --- .../rules/BlackoutDirectRuleTest.java | 19 ++++++++++ .../BlackoutDirectRule/ColumnBlackout | 36 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 src/test/java/puzzles/starbattle/rules/BlackoutDirectRuleTest.java create mode 100644 src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/ColumnBlackout diff --git a/src/test/java/puzzles/starbattle/rules/BlackoutDirectRuleTest.java b/src/test/java/puzzles/starbattle/rules/BlackoutDirectRuleTest.java new file mode 100644 index 000000000..b87b88de5 --- /dev/null +++ b/src/test/java/puzzles/starbattle/rules/BlackoutDirectRuleTest.java @@ -0,0 +1,19 @@ +package puzzles.starbattle.rules; + +import legup.MockGameBoardFacade; +import legup.TestUtilities; +import edu.rpi.legup.model.tree.TreeNode; +import edu.rpi.legup.model.tree.TreeTransition; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import edu.rpi.legup.puzzle.starbattle.StarBattle; +import edu.rpi.legup.puzzle.starbattle.StarBattleBoard; +import edu.rpi.legup.puzzle.starbattle.StarBattleCell; +import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; +import edu.rpi.legup.puzzle.starbattle.rules.BlackoutDirectRule; +import edu.rpi.legup.save.InvalidFileFormatException; + +public class BlackoutDirectRuleTest { +} diff --git a/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/ColumnBlackout b/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/ColumnBlackout new file mode 100644 index 000000000..f2a5b42d9 --- /dev/null +++ b/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/ColumnBlackout @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 15e19d39a03c41b0807233927bac1b7eb63d454b Mon Sep 17 00:00:00 2001 From: summerhenson Date: Fri, 5 Apr 2024 16:52:31 -0400 Subject: [PATCH 61/70] Add image paths to rule constructors --- .../rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java | 2 +- .../puzzle/starbattle/rules/ClashingOrbitContradictionRule.java | 2 +- .../puzzle/starbattle/rules/FinishWithStarsDirectRule.java | 2 +- .../legup/puzzle/starbattle/rules/SurroundStarDirectRule.java | 2 +- .../puzzle/starbattle/rules/TooFewStarsContradictionRule.java | 2 +- .../puzzle/starbattle/rules/TooManyStarsContradictionRule.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java index ceea86164..45c550bde 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java @@ -16,7 +16,7 @@ public BlackoutDirectRule() { super("STBL-BASC-0001", "Blackout", "If a row, column, or region has enough stars, its unknown spaces are black.", - "INSERT IMAGE NAME HERE"); + "edu/rpi/legup/images/starbattle/rules/BlackOutDirectRule.png"); } /** diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule.java index 28398143e..0ca27ab4a 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ClashingOrbitContradictionRule.java @@ -17,7 +17,7 @@ public ClashingOrbitContradictionRule() { super("STBL-CONT-0003", "Clashing Orbit", "No two stars can be adjacent to each other.", - "INSERT IMAGE NAME HERE"); + "edu/rpi/legup/images/starbattle/contradictions/ClashingOrbitContradictionRule.png"); } /** diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java index ed6a8a986..f6b7eef86 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java @@ -16,7 +16,7 @@ public FinishWithStarsDirectRule() { super("STBL-BASC-0004", "Finish With Stars", "Unknown spaces must be stars if there are just enough in a row, column, or region to satisfy the puzzle number.", - "INSERT IMAGE NAME HERE"); + "edu/rpi/legup/images/starbattle/rules/FinishWithStarDirectRule.png"); } /** diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java index 0608d388f..5d42e895e 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java @@ -16,7 +16,7 @@ public SurroundStarDirectRule() { super("STBL-BASC-0009", "Surround Star", "Any space adjacent to a star must be black.", - "INSERT IMAGE NAME HERE"); + "edu/rpi/legup/images/starbattle/rules/SurroundStar.png"); } /** diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooFewStarsContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooFewStarsContradictionRule.java index af30a5e18..d1ed62107 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooFewStarsContradictionRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooFewStarsContradictionRule.java @@ -18,7 +18,7 @@ public TooFewStarsContradictionRule() { super("STBL-CONT-0002", "Too Few Stars", "There are too few stars in this region/row/column and there are not enough places to put the remaining stars.", - "INSERT IMAGE NAME HERE"); + "edu/rpi/legup/images/starbattle/contradictions/TooFewStarsContradictionRule.png"); } /** diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java index 7777ff5a4..880e3b8ac 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java @@ -21,7 +21,7 @@ public TooManyStarsContradictionRule() { super("STBL-CONT-0001", "Too Many Stars", "There are too many stars in this region/row/column.", - "INSERT IMAGE NAME HERE"); + "edu/rpi/legup/images/starbattle/contradictions/TooManyStarsContradictionRule.png"); } /** From 729d6b7fe2908851f8cd9915be63883b9de88fcd Mon Sep 17 00:00:00 2001 From: summerhenson Date: Fri, 5 Apr 2024 17:18:02 -0400 Subject: [PATCH 62/70] Write first test for blackout direct rule --- .../rules/BlackoutDirectRuleTest.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/test/java/puzzles/starbattle/rules/BlackoutDirectRuleTest.java b/src/test/java/puzzles/starbattle/rules/BlackoutDirectRuleTest.java index b87b88de5..d42f40c87 100644 --- a/src/test/java/puzzles/starbattle/rules/BlackoutDirectRuleTest.java +++ b/src/test/java/puzzles/starbattle/rules/BlackoutDirectRuleTest.java @@ -1,5 +1,9 @@ package puzzles.starbattle.rules; +import edu.rpi.legup.puzzle.nurikabe.Nurikabe; +import edu.rpi.legup.puzzle.nurikabe.NurikabeBoard; +import edu.rpi.legup.puzzle.nurikabe.NurikabeCell; +import edu.rpi.legup.puzzle.nurikabe.NurikabeType; import legup.MockGameBoardFacade; import legup.TestUtilities; import edu.rpi.legup.model.tree.TreeNode; @@ -15,5 +19,51 @@ import edu.rpi.legup.puzzle.starbattle.rules.BlackoutDirectRule; import edu.rpi.legup.save.InvalidFileFormatException; +import java.awt.*; + public class BlackoutDirectRuleTest { + + private static final BlackoutDirectRule RULE = new BlackoutDirectRule(); + private static StarBattle starbattle; + + @BeforeClass + public static void setUp() { + MockGameBoardFacade.getInstance(); + starbattle = new StarBattle(); + } + + @Test + public void BlackoutDirectRuleTest_ColumnBlackout() throws InvalidFileFormatException { + TestUtilities.importTestBoard("puzzles/starbattle/rules/BlackoutDirectRule/ColumnBlackout", starbattle); + TreeNode rootNode = starbattle.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + StarBattleBoard board = (StarBattleBoard) transition.getBoard(); + + StarBattleCell cell1 = board.getCell(1, 1); + cell1.setData(StarBattleCellType.BLACK.value); + StarBattleCell cell2 = board.getCell(1, 2); + cell2.setData(StarBattleCellType.BLACK.value); + StarBattleCell cell3 = board.getCell(1, 3); + cell3.setData(StarBattleCellType.BLACK.value); + + board.addModifiedData(cell1); + board.addModifiedData(cell2); + board.addModifiedData(cell3); + + Assert.assertNull(RULE.checkRule(transition)); + + for (int i = 0; i < board.getHeight(); i++) { + for (int k = 0; k < board.getWidth(); k++) { + Point point = new Point(k, i); + if (point.equals(cell1.getLocation()) || point.equals(cell2.getLocation()) || point.equals(cell3.getLocation())) { + Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(k, i))); + } + else { + Assert.assertNotNull(RULE.checkRuleAt(transition, board.getCell(k, i))); + } + } + } + } } From ee074b1b63917e8cfea295d72ddb6a87731a2713 Mon Sep 17 00:00:00 2001 From: summerhenson Date: Fri, 5 Apr 2024 17:24:06 -0400 Subject: [PATCH 63/70] Test puzzle files --- .../BlackoutDirectRule/RegionBlackout | 36 +++++++++++++++++++ .../BlackoutDirectRule/RowBlackout | 36 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/RegionBlackout create mode 100644 src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/RowBlackout diff --git a/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/RegionBlackout b/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/RegionBlackout new file mode 100644 index 000000000..f2a5b42d9 --- /dev/null +++ b/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/RegionBlackout @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/RowBlackout b/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/RowBlackout new file mode 100644 index 000000000..f2a5b42d9 --- /dev/null +++ b/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/RowBlackout @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From c789e5b049b31dc793de92016a594cb8d1969f86 Mon Sep 17 00:00:00 2001 From: Sarah Date: Fri, 5 Apr 2024 17:44:05 -0400 Subject: [PATCH 64/70] remade images to be 3x3 --- .../7x7 Star Battle 1star Hard1.xml | 33 ++++++- .../7x7 Star Battle 1star Normal.xml | 85 ++++++++++++++++++ .../ClashingOrbitContradictionRule.png | Bin 5397 -> 5135 bytes .../TooFewStarsContradictionRule.png | Bin 3571 -> 3218 bytes .../TooManyStarsContradictionRule.png | Bin 5815 -> 6199 bytes .../starbattle/rules/BlackOutDirectRule.png | Bin 5209 -> 4717 bytes .../rules/ColumnsWithinRegionsDirectRule.png | Bin 0 -> 3781 bytes .../rules/FinishWithStarDirectRule.png | Bin 4399 -> 4326 bytes .../rules/RowsWithinRegionsDirectRule.png | Bin 0 -> 3761 bytes 9 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal.xml create mode 100644 src/main/resources/edu/rpi/legup/images/starbattle/rules/ColumnsWithinRegionsDirectRule.png create mode 100644 src/main/resources/edu/rpi/legup/images/starbattle/rules/RowsWithinRegionsDirectRule.png diff --git a/puzzles files/starbattle/7x7 Star Battle 1 star Hard/7x7 Star Battle 1star Hard1.xml b/puzzles files/starbattle/7x7 Star Battle 1 star Hard/7x7 Star Battle 1star Hard1.xml index bacc00b11..c1d7770f6 100644 --- a/puzzles files/starbattle/7x7 Star Battle 1 star Hard/7x7 Star Battle 1star Hard1.xml +++ b/puzzles files/starbattle/7x7 Star Battle 1 star Hard/7x7 Star Battle 1star Hard1.xml @@ -36,22 +36,47 @@ - + + + + + + + + + + + + - + + + + - + + + + + + + + + - + + + + diff --git a/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal.xml b/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal.xml new file mode 100644 index 000000000..cab0a0a5e --- /dev/null +++ b/puzzles files/starbattle/7x7 Star Battle 1 star Normal/7x7 Star Battle 1star Normal.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/ClashingOrbitContradictionRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/ClashingOrbitContradictionRule.png index 3cdbfd4e1ebb0dc820f59cfd90297d35795e93df..d25340b407edf02eebfdbc35764b0527ecea59b7 100644 GIT binary patch delta 4008 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 H!|4A3=DL=1 delta 4272 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 diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/TooFewStarsContradictionRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/TooFewStarsContradictionRule.png index 8d4c7bf3520f49394a88c0a5922779aa589b1674..cc019752f8531a366fd784d6772182e185a8d8df 100644 GIT binary patch delta 2078 zcmb7Fdpy$%8{gJaj{7CX!g!mgOzws=*OE#uFJ~@mvYAW02sv)EABol?%DN!;$fe{~ zOfF}ViatZBjoM_=+{tB|96CGiAMfAqdH#F;d7kI{e8124S%crwXsiZ6ltCkh;AOt|!XNo|eJy(J^ST&#JqBs>Mi||n(#g&+DO^)V|rp#je=#WvPJ)a z^QyHnr~^o<6BF5=I!O3jS)oT=UUY71ou2=*r$id-c0@0ZWwfom!?<7IykoXz8y6~1 zo-D*xD6a0egED$|DcEdVDrpyxidL?^#Z#=L!~qNbGxIKmX@lll%evqM#08B zo56Y@njXA6D_s248u`g`X^sE#`s~j3)}`5Z$V#4gVx>Dpg!1+AX-psz|Ft0$#xgSP z!(Fgg_1kyutV-{Z-(SXJok6*Fxs~5sTwL6CK;b)IdjhAodIcXJ2e!t~|F#rIA|bhq zxT`2!`xmMe=xwQeX;;Dmhp7UZRy#D@*xijOw241dIy^o;@XA_xqZ%57GrXr%?n!NK zX&F<&Hn;`t#dwt1l~-5mFRe9`24^o z%Uq|?#IWfat6Kk-(2@1o_eojpXapLK2Fw$daIQaO6%t7#Qd5GtW)(W_+r>>=wj#Z# zyObcuWDzB_G~ga%N^^m`sIzk%&C5>-!xkZpXVq>LkCTegan(B1_wO9;^GLx{re9DO z8U>0tLjwtlN%U7q_ZaY33FPe|UHz(3XY)L(5@-G-Q*lT)Y8Nvj_=qCF)|TB(1t}pQ zE@^ue!FmqR|2s(n5aFQ9FQRyzZb&4O+$)j7=HC#J(5&+Ghi8f_RN>U2DcvVO;!jFj zD!M2UJXxjo(XB&@c8dFKqIq`0<9QYkK*faj@x@gIwAb!nI<@Jg^s8JQ0g+zGqifqG z{-I0f)|oio4W&+RtVYMjTXZFF(4OG(Q?rh$1a*_&w0L`@sT<>05(Ddhdt7n*FxK1M zT}}}81q$8KJFSz0Ya(QNF?*WpXsh}8wMSqNmYsB6eXGemUa33h-@@wrTe9kayT(?$ zuOJ3D)3Aa&>%IfzWaeISi0TZx$M^z;c!dXkhLD~-E*yly7gylcLZ{-TRSky3BP3( z2;Q`iPebG=j7fD4(o*FMOi46Qj3Y-VFFprTaG*sZ@EIlA|0NsvXVm8@?B=_Sz5yV6 z`Iq_N6SZ>CT_K0~+~|~VQji!h^oe$EAY$ZP1(BzL3BtLcy1`JT>n92wVMKrbG5d@V z!D(yV9<7N083ZF~v{0$KV-koMr3+0gVBVG9sR5eX_exkzU0e{M?ZuR54>98rTvOBf z7&z!!V}B0Zb@+<3ih-{jEf9N6YSrc-yJ<$$LuW6a1o0DUCp__Z?R~1MNB77)XkC{U zx1WrSHI>Lx1KaFAB-3zfrISJnmEk>(~sJc%Ct_kuuzH$sN6tf!(r@gvB4ysD{7;ENdh_#imvH66Ouwdc;E9f#_^@V)l=Gsg z#-4w`Crp_pb4Sb}BGe<@WG{QN_^3|h{tMZLOgJO{HDk*Fnb}p$GLhxXPv1hGvgV#X zSW&oOCZ#h=24qH$ftHJH6Jif(4Hy;gqn*98W7Esb*dsZmpF+Z>f>LM|MFXJ8^+mkw z&eqA`_YI0C)9>%!Hl-YyI|0e5Zw+rt?{g1m{bxM>@6v%~1!xAw6Q>5@3|o&DDU+45 z)jeYT6G;tkFwQFu2*Q7GYWkr5PY|layeUeZHz@YMFTjF~BnD#$wrP+x?~6qE`uhH9 z8sVZYfdtKU&D9?1&6F8?&R`T&>YMP?q<+qfRE~c9czh(B?!oCyGSksP$6lGdr%VnE z2oMAFAm;@R{%f_hq1Flxk7t?m@2#{L3)?%D%7Dy6q$IiGkIGwxv7v_`4;{X5v delta 2434 zcma)-S5(u962=KlP%%_B)WijZ&;lg%k|m%(Ahg{@gcS+Jf*5HEMEKK-bi@S-MFbK- zKuT6n2~8lh4Iro?xO53%)(ssIJ9; zsM5d6Jg@%jC7bF}Knl_=F~dK8h_u(o{|#gG<)mCba%}g+dQz;kI@oF&n^=&}lsk4$ z4=%-_?Mb8Lg9LlK5mlq3lOvau-Us8;q29k zs`JR$gNUPGFr^i^GWOqbTMRbAo$YZf8Vy7N`H37l4c6IY4dZPvBdRRn)#nEBQs~H zj8an!SlQyywMnvm-Xz5(oHE{&tn1t9M9)=W<8*x5^F9N!w2^VOjs+oWA>q&}59!(V ztBt;0xS8i6OU(C;zm5oL$e9ZR0&DLY6#i@vO`4&i$z*cs3Zo1wB_;JiL!hz>7s+NQ z#q4wal%ijG^!N8~ufNsmlvh0r?f=Eo)5FgXR#RO)P9yH^mnI`lSc`8|bmyr18w zWRF#B0e@EytgKB^rfNOT4v&mf)z!hRuE@#Cj&~;rY3k@?CnhC{(_;^|D`#oMOtDL} zn4LvjU|`@xJV>ZrLY%PQ{fuwZ@=naP)$vMXz@Vg*gtA5Pk8CzOoYP+Lb?4LBljg!* ztE*S>!@|S+J7D|$0|PBx zq}~GN%gEpf=ED1G2bs>|thN*d7t5Yq3BT*%f zoy7qQ#APoC>bmULw3L($?IL%3doiH*6_r|8>_HH-8k|C)Z7>+Swp*}eNVh_?*J-p*w{$a5EGkSWZM`MZ6}9o$ z&qYZ{>>~4zFgP+DBoq*F{mbUZZO*h|IZB$xOp4oF7SC3;Wc~io@26jW8PF1E70N3( zCFdxayN{JyPAjnM%gpb*Y4)dIT?Pj8OI4fv=_goi1eL#LX{24w^pZUneaXYlPUOz@ z;X=)b?Nv7$5{_2MH+v%ghw~<}1JwxFM|(%^>v-5M{}$dXyiR-JoWayLIs#T+cDjH2 zFIKZL!|Up(6LzbWdiNPJT>E3Nm8CM6ZR`NIvMMh@1;5kqpX6>0KhQD-w7^4Q7m`A= zs6%g`dQS3disH)ckj4wmi3+c^KXgPJHeCFDxY<}(MO$s~Fq}A4Vj8Ya5p?L!X`XHm z{h@|J+0ve-UX!V4Z7Qe5eJfcRefWA$vff`^P3BXVOpnkf)wy~OPEJm4Vx&m#i|ERf zLLxY9cpwY1bl`DPSM>w%T@`P%HVQWjxKYaCcPI2H?~3A&zR^ zRsOG2CBl``BU(@cqF}LhprhzU!yM+2L;OEx&ff+f&|`qY3q-5pzc2QJ+_R0;^PokS zk#Na5;Nn?<#QRK7dNf7w0y1WOO7rtnff_a{+7>O%E9Nm7NcT))(NKtuvzF||{LR$) zQv|y5#|_sRDstGtS{HjaCLAxPQ&ub;|LF&09FNV=iNKP^Y@>AYtYa;)BBc5GA7_+zwS0XElTBRII7x+z$YF?|hRRUb*zAbGgHD%%zHDdi|YfNH_zws$} zkmzR>iEHR~eMY&Z`J;rw0s7>N>fa7q>6N_=FR2VcV$c*QBSJ|`Ic}E7v0K4E5;FA$ z_idox0)ol^b)^7b#X&_Dued|w)c;o^6K+~Bdr#{N=MnI9$pG#O^~)B!YcE&OE-0^w z!V7kU>)gw!tia=yY6nl=9hT{=>Y6lMr5{*Eu65{n+!7_OYqa*%pqw@!9S@Fo^4cb$&c7B6ih8@s zC-w{1Q%A3xN?EubZ|LYKRUlbJ8=O+ad9Z(M`%JNY z{LL)R-Z`zrT0mv6h14=xJpN(zWgZ8`zmjaV#c2HkXjJq86u#>*B$41*Ao zivE&6N?$G&Q)bFNt*^gP42#cAEsG&#ikjz<>By_S`( zB=86mke6M6zaiTM5m1JDhE!&E>>@0LU+flmGw# diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/TooManyStarsContradictionRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/contradictions/TooManyStarsContradictionRule.png index 724f8aa64d9733c30ca7fe5d1d52fe92cb539e8d..b468ae6f6fb70271fd594e8cb6b5148dbd9153c5 100644 GIT binary patch delta 5082 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 YfPTG|sWX}iqkzlMxo@adbI&2>Kgw3Y`v3p{ delta 4095 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 Jt$bo1{eO3p=0E@d diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/rules/ColumnsWithinRegionsDirectRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/rules/ColumnsWithinRegionsDirectRule.png new file mode 100644 index 0000000000000000000000000000000000000000..3493810b78122654a0f7091cf605ef0cf9dc9c84 GIT binary patch literal 3781 zcmb_fc|4SR7awJd>{+TSgCd$S3kHM9*rFm?3RjrTItw#ni;2iyx0EIORFd9AWPdYC zwo)!FvMWo9G}Mh;%YC15yGnQY<9*-xJkLDOe9!rv-#Op&ea_4z+S%?C6WJyL0)fP= zt<3F#E0K2!3j*%}BWaGnWmABa3j+iaZ{nSNX?w)C1E3Mp!kKACqfkgxCMcASCZf%; z`%K9Mr2c+qYcv7@@k8q)_4MI7a5%~Up{J*Z($~?3Lzrl!4uI(*5qT_pF9^gx=j-Uq zbhbH&CeSEaI3f*C(h8*n02=^Xgrb343WH?20GMOeboaE-1A_VIz|NiFd+q7|a8MWcJe5C#SYFgOy1L_z@%C?kx@#Dzks3{@b~ z`cUR127&Gy!1Se2!MxBoJS~W6tggQ1^?OQ0!rC?gL3Hx!CPV^^L?-cwVZabth;>;K z323G-lT7+9aV(kn9YXfyRe~ntsNTlvp->{p3l~IYs$z zsRi^Ih9mNrfv;oc_f=>tk?~F9yh_G z6s4oBr;mi|ArN@@TCCrf{3((p9tfn1)J39n4G=mAJp*0+uWMF~e_G;53nKXN%EBPm zqJPD{y8lg^*VFY!sq1O|KQ%hwn}>|o<<+N`*I&Q@^jCXbe*p}Q4PyGx=okka9p?kK z@ueE^JpVwytL%T*Auv4FiEu5wP+Y*DD+L#!wbdMh7+wjl~IMtT%EURH4I=&;d;42H!f>TO_ZJ9z=Ej&btNT zDxe{T)e^(0ZD1vjoqHKH&E<$Z9VdW5zV7Zr8M>k)e4z7Pd~I=Pf$3*2?}Fb28%j&d z@SpLo?nmgug|FHt>O1AI%P3{mlC4maBsKBG3+RN1((

H#jbB8k%5>BN}m;F3#a zd}>!Vp>ws^9VjG!EK*Q9^Yr{m>pmqDIb9)qB5{9hmybDtpjuvD&VKH9?HOY8#^hR| ze+g*Z8QrkC*lb?v$_WU&@IjO3!L+1|rs`Wp@0CFf7wQslY9Uzh`-Rjy^ZPe-Ol!8* zJbvh}B*&1jU1ke=yB~|6?GnoAgP#_S48O5WJ?Llla`&}6BXv2pI-E)&+EJgt>Q9>2 zQ05*avAN)v@BF6_fJ&Eq77p&nb+^st+jI_9{ygsWEm$w4oRK^P~#q(48Fvac9yRpV$e7RgEl7 zrQxRA@$c{TzUU^f7u`(;+gJ{5bEn%k9q>46QoHn?bh5l9o_Z0YBB%S+56Pi zgkFW7HX*!#wfpBS-P~~bq&GcLbpdnZ{thce7oL<|FWm9a*{QP%pSXoYTiS8G_mI%D z*xN9V><{~PN?&2NX15*tn9HWr&${?~UwpJ=nyQ2rP1Kp0)J$aw+}4noEMPkRfRS)A z)%17ER1uNgH+e3l0m;@XUd|H=GjP0P;N`YUkph^h^E-&4Y}( zy5GuTybBFvVbGkWaoH~TC5t#FFZgVsUq0IgyVG)ZZe!b?N%{?E+ z3Hv*|TG_hNme$o1aBh&(M{^hTcM$O3!na!!Vo45qOZm_^^YUz{E_Xn_|3qmH zS~$5@eGK&*=Y#i9E$ps`WQ*>?gYd}TLV5&QoSDb0*l0@Ugy`@bH>WgcCZO(jz|`ZGJv`u3od32cT_*+pf`7 z41?TzuHMZ7!$XCL&qF%WMYz#wqS!G^W&F+k65xqUmxvfm;}C;~;w$3iyLWL1QcGFarS0tke=&8&$};eF zfnytO&sUg(HxrQ#Lj!l&34;c2y*V0J-&`2ALciZ~- z$ITK*i!E|;nD(&n%h0LAr!Gb&KrkE2K62vz{gX3R+gJ7QX1si9Q`6Ey&4gz|>j$S% zyPDfIGI#^fe3Vnc)3k^L}wjUj`=c^@=!7NsN zNZQo(r&9LvugY{`qJ0{Xb)UjtX1%{*?~S-TIq6plo}QlWoch%1R|y=^!39-Sa=E#= zMI|MxzatoQx}B@5rVsgN1g*bHOfyXc1cqv8%u+l1`b6s8&lVR$KBtRf&CE8U4Gjg( rP8qyTO-8PDWsA>n7WIe-N!LY|TqdJ){2v{O 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 delta 3273 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 Date: Tue, 9 Apr 2024 16:38:38 -0400 Subject: [PATCH 65/70] Added direct rule images, updated image locations --- .../rules/ColumnsWithinRegionsDirectRule.java | 2 +- .../rules/ColumnsWithinRowsDirectRule.java | 2 +- .../rules/RegionsWithinColumnsDirectRule.java | 2 +- .../rules/RegionsWithinRowsDirectRule.java | 2 +- .../rules/RowsWithinColumnsDirectRule.java | 2 +- .../rules/RowsWithinRegionsDirectRule.java | 2 +- .../rules/ColumnsWithinRegionsDirectRule.png | Bin 3781 -> 6456 bytes .../rules/ColumnsWithinRowsDirectRule.png | Bin 0 -> 5331 bytes .../rules/RegionsWithinColumnsDirectRule.png | Bin 0 -> 6402 bytes .../rules/RegionsWithinRowsDirectRule.png | Bin 0 -> 6269 bytes .../rules/RowsWithinColumnsDirectRule.png | Bin 0 -> 5117 bytes .../rules/RowsWithinRegionsDirectRule.png | Bin 3761 -> 6477 bytes 12 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 src/main/resources/edu/rpi/legup/images/starbattle/rules/ColumnsWithinRowsDirectRule.png create mode 100644 src/main/resources/edu/rpi/legup/images/starbattle/rules/RegionsWithinColumnsDirectRule.png create mode 100644 src/main/resources/edu/rpi/legup/images/starbattle/rules/RegionsWithinRowsDirectRule.png create mode 100644 src/main/resources/edu/rpi/legup/images/starbattle/rules/RowsWithinColumnsDirectRule.png diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java index 93fb86dc5..b42bfd1c0 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRegionsDirectRule.java @@ -18,7 +18,7 @@ public ColumnsWithinRegionsDirectRule() { super("STBL-BASC-0002", "Columns Within Regions", "If a number of columns is fully contained by a number of regions with an equal number of missing stars, spaces of other columns in those regions must be black.", - "INSERT IMAGE NAME HERE"); + "edu/rpi/legup/images/starbattle/rules/ColumnsWithinRegionsDirectRule.png"); } /** diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRowsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRowsDirectRule.java index 389ba02c2..0a78c8868 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRowsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/ColumnsWithinRowsDirectRule.java @@ -18,7 +18,7 @@ public ColumnsWithinRowsDirectRule() { super("STBL-BASC-0003", "Columns Within Rows", "If a number of columns is fully contained by a number of rows with an equal number of missing stars, spaces of other columns in those rows must be black.", - "INSERT IMAGE NAME HERE"); + "edu/rpi/legup/images/starbattle/rules/ColumnsWithinRowsDirectRule.png"); } /** diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinColumnsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinColumnsDirectRule.java index d2fa4fbe3..16951fb2a 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinColumnsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinColumnsDirectRule.java @@ -11,7 +11,7 @@ public RegionsWithinColumnsDirectRule() { super("STBL-BASC-0005", "Regions Within Columns", "If a number of regions is fully contained by a number of columns with an equal number of missing stars, spaces of other regions in those columns must be black.", - "INSERT IMAGE NAME HERE"); + "edu/rpi/legup/images/starbattle/rules/RegionsWithinColumnsDirectRule.png"); } /** diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsDirectRule.java index 15993b85d..27dc001a0 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RegionsWithinRowsDirectRule.java @@ -11,7 +11,7 @@ public RegionsWithinRowsDirectRule() { super("STBL-BASC-0006", "Regions Within Rows", "If a number of regions is fully contained by a number of rows with an equal number of missing stars, spaces of other regions in those rows must be black.", - "INSERT IMAGE NAME HERE"); + "edu/rpi/legup/images/starbattle/rules/RegionsWithinRowsDirectRule.png"); } /** diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinColumnsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinColumnsDirectRule.java index 2d6c148d0..4054ec017 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinColumnsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinColumnsDirectRule.java @@ -18,7 +18,7 @@ public RowsWithinColumnsDirectRule() { super("STBL-BASC-0007", "Rows Withing Columns", "If a number of rows is fully contained by a number of columns with an equal number of missing stars, spaces of other rows in those columns must be black.", - "INSERT IMAGE NAME HERE"); + "edu/rpi/legup/images/starbattle/rules/RowsWithinColumnsDirectRule.png"); } /** diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinRegionsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinRegionsDirectRule.java index 7dfaae59f..7af2c79ed 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinRegionsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/RowsWithinRegionsDirectRule.java @@ -17,7 +17,7 @@ public RowsWithinRegionsDirectRule() { super("STBL-BASC-0008", "Rows Within Regions", "If a number of rows is fully contained by a number of regions with an equal number of missing stars, spaces of other rows in those regions must be black.", - "INSERT IMAGE NAME HERE"); + "edu/rpi/legup/images/starbattle/rules/RowsWithinRegionsDirectRule.png"); } /** diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/rules/ColumnsWithinRegionsDirectRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/rules/ColumnsWithinRegionsDirectRule.png index 3493810b78122654a0f7091cf605ef0cf9dc9c84..1a88e9d07c6a0e4a1425d9725be9d1fc130058ee 100644 GIT binary patch delta 5806 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 delta 2978 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/rules/RegionsWithinColumnsDirectRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/rules/RegionsWithinColumnsDirectRule.png new file mode 100644 index 0000000000000000000000000000000000000000..fde683dcde26e2d717999fe759d97d3f3f524dee GIT binary patch literal 6402 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 E0_Y@20RR91 literal 0 HcmV?d00001 diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/rules/RowsWithinColumnsDirectRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/rules/RowsWithinColumnsDirectRule.png new file mode 100644 index 0000000000000000000000000000000000000000..bac64a87c9ae9df53b8be031c17306773ccfba7d GIT binary patch literal 5117 zcmbtYXH-+$whmPcRivswL?nPfAV8?0D@8g{Kv0NDkdg#Q0)!|iML{}J6r+er6Tw22 z-jrUXDP55w(nLUdxdDBibMCl5-hFS3-R4@~{MM{%XXmzsnE^ZS2oL}Oup1fbThZ?5 zy_1ERcJ=&{h@jmLdK%gh0RWD-dnaAuDUPE60OK`Rge}R|)I<&Cfs;j|JuYKp$v96M z8UWDHB6}iH?idp2GUkda9uEFqRs{yRqTyg0B~v+5Pd$u_t09Gev8I?IP!xBRDjKY% z3Dh8~(FkxD5)wqlVev#YG90|mt44d?8-{>sAOhN1%}W2wZwO6-gI!1@Pc;a{*Vk9p zS3%Z;a0Mc-s;UZ+gF>KC85%-{=!YjE$ufB22^s?sw9lcBA)*Mbo+MWfJZO&-dD+98 z1P6nGpx@LwBoe{(@*j3QQ5LyB;=QLLOLH26L=z$MvT}Q7fj}C+@M=0};-2_x5o?Us zzVJ)Jy6&&!i6js)2tQ8@9BhRldUz91n0oBv>?kad@J>D*=NdS$ShIAQ_PSe{k|Q zuLk6AOa4Dx^!!_)@0H?yzwH$vZGz^X!f*d*lA4Y;$;E@9X^kWxT|lO;c#S>G|BTYA ze?JHRr#REv^G~4vVFVfJ`L|A>!PNFE*n@!Z@W5*7A@M#)4amO_|3_1PSx0MdTB}3; zYzQ>r&z6G0)AkVpZNp%Xb~*?EaDt8Wbr9qSa~EAb5$E^3hkOEygJ_+9ZsIj%Y&{g+e-5>C!A;8VP|JYAP{fI+a2W|T{G2$+7}l0Urxj* z!z>176~#9fM(c8Xb-~}Z)|U|0)^*zb$*<$j*{WPWZb#x%^PN1_d+p*=$#XX6yKiQ* zCTM6TH)#^aS!R+83kw;C3q<=OGrd>mhfU@m2of6+SDs{tOSR!{vFYUoW|$|pqw8?B z*4ki6S=nfnQ9X;=SB%rjr6O>->A*0HPo4gfJELTAbu+haFn3y?hGHH}@BEg>7vA-7 zO>?bn#lSmYvF@yfGjYo|97exGx9u}T&>NPgYj#&dg8Z&Qx;vnP=ydKcF0&pDR#sNr zUKIstY2#u?-~>gZZS_~{n`KVEa-8^lvkda>lxts%GFVA>-e}$2ZEZ?8@UwCUG7R1o zD-^dhb_bp;7Vi%Ea4=y5C3W&Tcz1g{WIle&e}OJ0?fV^DL2`_Tkok|rnDIN9m68~< z#FWdy&wJf^1K8rW*D5PEw{A4D`&4b!;cf*O?HWIMwwr7$sg<_ehws~HHSdtnu(G!v z#QGTboO;YJq~RG`&R*QWb+UPpBH?b3Bocf6HuLZieYN=LS&F)y>G?eB9KzYo>hacm*r^O;hx@5{a&7xkM*~nWsoBc8uoY`i? z@i15_rx;gc#Pf*De6woE-0ZG`#Oyf+QQv1eRcud|CYR8#`+^jYil2P!eq$W) z!P?Z0UB?Q zf$#k|lq}E;V`Q*GJ5xpBVR|$JADR7 zNlHD=pU=mZhcjt2?`XtI3$xCxEpeRwbg6w zSO<#()?Gn%73T-?T+gaM^b2lJfm2I*EK)t?^78WN0p|uEY?L9?Fsi+#+UUDV3m>$h zD(ncmOGb4fM}?~k6fCMa;d*l!Z;)H7c@r&-?yFYGg{`0bQ2?$tITuheO3JYA4>TJcs-@=POk;Q*AX?7_hrKH&e2R2qvn9yW^yn>(YjTfVp{ zXZZ?p344L)Rfv;pQ3CR!SaVg%vINnxQST17WK?Tptk%NhFHIPMUb;~HCdq9pUK+uJ-srMaHHC*f`C_TzVs|F8?FL< z9gjtN8Z)o5jl4gTFF#4A1LrV)wFx}HvHPe@a+&R#R@xqt)3rC1?I=uITA*AS4u8nL z<|fzoX%zsfSz^_~b_Z1mhidU8pi`_qHP9-(ltp~#&V^iNhYYvMJ%J6NK1YfXi}Gie76CsMjH zIWFjy%v!`Zl#S?>LcduD*IW;6_8(@wK}w)byJ&OX-7IytLg{=L!SC9Vv~bX9zOqkNxK60Gr=PxeuH1~K!#4CecuKTqTwZ1MW_@*g zk}YFME}zeF<#%BJuu7WIz4NTk4vX<$O=z*=%PQBrQ1v)CC)cejbA<7O>-@QR@^X8U+O5qx(4Q(u=zzJ!{lDqBrhdT`&>Y_gHfDk#$(Ev1@WNI zDYe7=2T(umyc>V**C)Uo!HS?37bv+%DDwi@lq4P#93`JgV%f7ASP{J$ZXXuXC(@T2 zUl|B=r=Lo?(>*2@+^~=4GX`#x-XV zzewT5-p#B5DX^F1wZ?C@`zCGDS(ZK2tD2dq=V}SPO2be#FNjS~(OtoSg76!GOtzRbr58 zYL_CtQl|dakLS{<<)sB@%M@@7Oc}r8>lh&ti!z9QJv_>C@-g*1BXy2LeXePE>{H2F zj5f8T{VL>p`h)rh!u_p&op8#j3{4)(0ld?JXaY2>Ft}=CVP602k80f@XyO`GqH#awR4Nc|@ zNe?`%qNW&A!kf+z2;WC4b`(+!mysb=gbCop*RQAID?KXLZ%w2xlq7{19@uosG<(>L z4z(BV4PP6Ye#h^a)?y=@U-W*+*-xsot4o(S*^112ZU40^{j5n*NG$&$_MQGhcmC(E zTslRQ+#0fCIts2=HpZ(KxoDe>7F5porg6*lKa>{ntQ-1GX@M3EWbwgh)h+ zqN^3+Y9sCECxh9jn=3K2;RzFno{KIFpbroQ9J;}x&G=u6vGWYIocHuMp*t>gPe$(Y zmfii4nVB#2MdIV4E^2{UNA(zggfnMNg$8s1nW8|S+-%@K4pIC5N3@+T=p zbR*Y_R&(MBoB$#(f4f)}m9ND7hLvB|g_09_*x_`6vi%qyQb0GL>wfk1(UJ4olE?lrDUZQ*AhWSUa>dWD08 zc3l{99qCicSw7dZQ|3#)-rM_xDGk_O!EDj$Qasn8Z@f<628*JSWG^-Yy~xhA&$XOmkK9j-_%9ziQLgPi-WX>BOR-AuU#K}Sdxt`6 z(I3%SHje&@O+s1$8tx2zZ0i>WBb7^{gw&IoZiQAyNLtDwA5?ouIaE5@+BQn%*uD;0 zw`QB|BSooQ;35Zm%5Nt~THl+^&X!uy@_FKZ^6p@yjn|lp;P{uq*DeeR?l=W(FjiAP zAt@=(i)UgMx?}NGZw<2*2DC6>{bG5bXlm&M4s7@~ literal 0 HcmV?d00001 diff --git a/src/main/resources/edu/rpi/legup/images/starbattle/rules/RowsWithinRegionsDirectRule.png b/src/main/resources/edu/rpi/legup/images/starbattle/rules/RowsWithinRegionsDirectRule.png index a9f22f16f5042b5bd5b9294f9fb465b15f1eeb0a..8907e047521d5310676821ddb141672f2b5e4d7c 100644 GIT binary patch delta 5692 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 E9~7y-K>z>% delta 2945 zcmbVLdpr|*8=p}w(UIns+svi8ZiZpzvfM^FC)Pz*X2{*F#Sn8p?#xtm1HCQ9wh1s8 zP4eb9|tF|F|je6J*YxXx|Ix8s^bdOfaYd$} z{ENSfpI(ze)~0$+FdA1Q{`lXq{Vw(Vn#`(EQ* z_nf=#(&1R1sm6ND@%WG+ry=Zn?J1SqR_B8%;^fCAQhrOJ&uT;#x0QA`{!9cnewre^ zYMQ^(7@jf5S^K#0P_f^#e`Ta;(PAvRc#Jn%d-<}=o-sU04pLgX7f%p90K(2%W zvZSd=Nl#C&pyPtdc^8*G+B!PMnLNvvESBbV77GXvFIW(`Dk6H#&<%&9cT#KF%@1M; zgHAd5c^UJ5;*c_$h^C9?(f<8;A-~L?s%m@9#iTSkobp3! zhDZnkG8!5hiY3%IqQko|RO{;%edVb`4z};s=gzc!xR|!g9BFQj$uKV(E8+s@(n!%O zmaUsfQqfz?tO`5zrihx<EDw&1I#W-TiBm2n7NqX{>9WCHdL2iH$A-7kQnS9Ph=Ft?k2^FJxZ0z9I; zH4r}P0wr|z0vJQyxn&VnvIrADD=uYwE(eTC5PB@Hp2GRRQ^~aY36^B#OiXOMhAP@+ z2)*FzCQfbLo2%NP?z``bunr8yKMf3A1quw$OuFe0_6bl7ME!}3-^tW?< zmfMp#qjVITmAwNXx3atp)Ml|*2Y%fMmXehf1{8EkOW@bU0fgT3Q{L7}7=YoSpiQ+j zpxg?tv}b}n5^(mI%!{m&%Q{6BH&4_n3a*x`^6_*2HqH^M>s4o5ZXb;A8u;XG{$`9K zI!uK{C;bp}iuFd~eP>vu#06>CIQu&p;yL&ey zHpq3g{f-u(tLsGKCG#I3=rq_)>v*UXvoP6sG3KVPyA$%Bf4CBaFbSHXfwd14sP4EL ztq`o_CFrx^BZ1utQtBep^F2(DuMoQhovV>E5~5PTM<(;ccVpwhDzgn@oz@}PXgU}J zF=3Dlhe{t%rZMqCaolVD%)=yifatY-AMD0F|4et#z)DI(Ve7lgPojT~6LPT*3f3Ot zUa?Y75r6oS72g-_h>52XMT|{uAo=YHLNsfT-NqE`lIkl~-u&Fk-o^7HxnL=H$5N|G z04)dAQ-;pxg8G|%IPNJoT1H!g9O8*stYhcFqY~Id3<>aEZeB}tU*v}4?TA-U2%)7j z=uuPM6@b(rqB=5Ll*u$rj9;!$ondiT{|uXyjHz9}keJltPHj9C56#KH95Q{kqH)o!|2N5_e? zl#BISkZ7v7G^(OU%s^RG;aqV>nSJ?lkEKVgI{Fv*4$4Km*+eaZg`6$OKDzwNhaXgx zD_vqx-}bin7jZ` zQ}eFm>gtkpITfXcwC;QN11%FagLRycEqYN^qM4Grr%Kh>z3y3m&SIiY>lO_!VmR4urF6ia19_HjbO6+)wXwqqxp?d@OoMT@0)-cz4h2ek0@PFd^X3nV-9yd{`e>U+w5V>W z5F+44bG|&=kEFe~og-}G6RoLFa;2U{*&;|X6Ev0SpNC9DrPLRm9jW341S=h!Ymt`C zMq_ipIj7!z*z2^gtK`IG|2&!KYhY{8CE0AJ0TGwD0y}rdq~%E$i7lD;3Ap9-=4WQ< zAlYmU#@Mk9%OoM1>QnBK>IRrrSFLGc0mGH?aS{`c1*btQxivo`lc@UjvpA<0pI>=M z*XxNw1PJ0M4yFlM1%!?amF~I%U8UjN(xgv)Rs^RRAjHN#PauNLr4ns|UF4m#!=ip{ zy*ka>;ORh6GTx1&oxPpK<8@c*DB%vdVyJ#XoIH{3v)@Ul+@{;P0mtwAScjkC@Rx`S z*&Ln#6SB5%P!xhHEF zKxM#-XoDwDo_Pfg}zpqYEi-C z?R&>Q?|`t%2oFr&xmWE@N_qWS(%xa4 z*xP%kkC`>V<%%= Date: Tue, 9 Apr 2024 16:47:58 -0400 Subject: [PATCH 66/70] Fix a puzzle file --- .../5x5 Star Battle 1 star Normal 1.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml b/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml index 5fefc844f..cccf07c95 100644 --- a/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml +++ b/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml @@ -1,7 +1,7 @@ - + @@ -9,6 +9,7 @@ + @@ -26,6 +27,7 @@ + @@ -45,9 +47,6 @@ - - - \ No newline at end of file From 1db4a7a426a50b7b7b6947435be2c458d8af778e Mon Sep 17 00:00:00 2001 From: summerhenson Date: Tue, 9 Apr 2024 17:46:10 -0400 Subject: [PATCH 67/70] Fixed some bugs with the rules --- .../5x5 Star Battle 1 star Normal 1.xml | 1 + .../edu/rpi/legup/puzzle/starbattle/StarBattleCell.java | 2 +- .../legup/puzzle/starbattle/rules/BlackoutDirectRule.java | 2 +- .../starbattle/rules/FinishWithStarsDirectRule.java | 2 +- .../puzzle/starbattle/rules/StarOrEmptyCaseRule.java | 4 ++-- .../puzzle/starbattle/rules/SurroundStarDirectRule.java | 2 +- .../starbattle/rules/TooManyStarsContradictionRule.java | 4 ++-- .../starbattle.rules/BlackoutDirectRule/ColumnBlackout | 8 ++++++-- 8 files changed, 15 insertions(+), 10 deletions(-) diff --git a/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml b/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml index cccf07c95..b86e16ff2 100644 --- a/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml +++ b/puzzles files/starbattle/5x5 Star Battle 1 star Normal/5x5 Star Battle 1 star Normal 1.xml @@ -49,4 +49,5 @@ + \ No newline at end of file diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java index 4296c8230..a316872d9 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleCell.java @@ -13,7 +13,7 @@ public class StarBattleCell extends GridCell { /** * StarBattleCell Constructor - creates a new StarBattle cell to hold the puzzleElement * - * @param valueInt value of the star battle cell denoting its state + * @param value value of the star battle cell denoting its state * @param location location of the cell on the board * @param groupIndex indicates what group # the cell is in. * @param size size of the star battle cell diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java index 45c550bde..75fbaadb6 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/BlackoutDirectRule.java @@ -42,7 +42,7 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem } StarBattleBoard modified = (StarBattleBoard) origBoard.copy(); - modified.getPuzzleElement(puzzleElement).setData(StarBattleCellType.STAR); + modified.getPuzzleElement(puzzleElement).setData(StarBattleCellType.STAR.value); if (contraRule.checkContradictionAt(modified, puzzleElement) != null) { return "Black cells must be placed in a row, region, or column with enough stars!"; } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java index f6b7eef86..36e691e74 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/FinishWithStarsDirectRule.java @@ -42,7 +42,7 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem } StarBattleBoard modified = (StarBattleBoard) origBoard.copy(); - modified.getPuzzleElement(puzzleElement).setData(StarBattleCellType.BLACK); + modified.getPuzzleElement(puzzleElement).setData(StarBattleCellType.BLACK.value); if (contraRule.checkContradictionAt(modified, puzzleElement) != null) { return "Star cells must be placed in a row, region, or column without extra spaces!"; } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java index 035e55073..0aa147c6f 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/StarOrEmptyCaseRule.java @@ -83,13 +83,13 @@ public ArrayList getCases(Board board, PuzzleElement puzzleElement) { ArrayList cases = new ArrayList<>(); Board case1 = board.copy(); PuzzleElement data1 = case1.getPuzzleElement(puzzleElement); - data1.setData(StarBattleCellType.STAR); + data1.setData(StarBattleCellType.STAR.value); case1.addModifiedData(data1); cases.add(case1); Board case2 = board.copy(); PuzzleElement data2 = case2.getPuzzleElement(puzzleElement); - data2.setData(StarBattleCellType.BLACK); + data2.setData(StarBattleCellType.BLACK.value); case2.addModifiedData(data2); cases.add(case2); diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java index 5d42e895e..e1c6f3084 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/SurroundStarDirectRule.java @@ -41,7 +41,7 @@ public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElem } StarBattleBoard modified = (StarBattleBoard) origBoard.copy(); - modified.getPuzzleElement(puzzleElement).setData(StarBattleCellType.STAR); + modified.getPuzzleElement(puzzleElement).setData(StarBattleCellType.STAR.value); if (contraRule.checkContradictionAt(modified, puzzleElement) != null) { return "Black cells must be placed adjacent to a star!"; } diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java index 880e3b8ac..2ae424d45 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/rules/TooManyStarsContradictionRule.java @@ -99,14 +99,14 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) { for (int k = 0; k < cellList.size(); k++) { if (cellList.get(k).getType() == StarBattleCellType.STAR) { starCount++; - if (starCount >= puzzleNum) { + if (starCount > puzzleNum) { valid = false; break; } } } - if (valid == false) { + if (valid) { return super.getNoContradictionMessage(); } return null; diff --git a/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/ColumnBlackout b/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/ColumnBlackout index f2a5b42d9..ddcc4dc9a 100644 --- a/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/ColumnBlackout +++ b/src/test/resources/puzzles/starbattle.rules/BlackoutDirectRule/ColumnBlackout @@ -1,5 +1,6 @@ - - + + + @@ -25,12 +26,15 @@ + + + \ No newline at end of file From 4a502d5330a122c20e2fe01cfff5373831ead9db Mon Sep 17 00:00:00 2001 From: Chase-Grajeda Date: Tue, 16 Apr 2024 17:26:22 -0400 Subject: [PATCH 68/70] Checkstyle update Silly checkstyle change --- .../java/edu/rpi/legup/puzzle/starbattle/StarBattleRegion.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleRegion.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleRegion.java index 099cabfcd..730f9291f 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleRegion.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleRegion.java @@ -18,8 +18,9 @@ public StarBattleRegion copy() { public int numStars() { int stars = 0; for (StarBattleCell c: regionCells) { - if (c.getType() == StarBattleCellType.STAR) + if (c.getType() == StarBattleCellType.STAR) { ++stars; + } } return stars; } From e7ea94483b15feec13e44a65cb8af7e738aaa4e3 Mon Sep 17 00:00:00 2001 From: Chase-Grajeda Date: Tue, 16 Apr 2024 17:31:04 -0400 Subject: [PATCH 69/70] Update StarBattleBoard.java Another checkstyle fix --- .../edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java index ce04f31a6..2c4a20ebc 100644 --- a/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java +++ b/src/main/java/edu/rpi/legup/puzzle/starbattle/StarBattleBoard.java @@ -73,8 +73,9 @@ public int columnStars(int columnIndex) { int stars = 0; if (columnIndex < size) { for (StarBattleCell c: this.getCol(columnIndex)) { - if (c.getType() == StarBattleCellType.STAR) + if (c.getType() == StarBattleCellType.STAR) { ++stars; + } } } return stars; @@ -84,8 +85,9 @@ public int rowStars(int rowIndex) { int stars = 0; if (rowIndex < size) { for (StarBattleCell c: this.getRow(rowIndex)) { - if (c.getType() == StarBattleCellType.STAR) + if (c.getType() == StarBattleCellType.STAR) { ++stars; + } } } return stars; @@ -97,8 +99,9 @@ public StarBattleBoard copy() { for (int y = 0; y < this.dimension.height; y++) { copy.setCell(x, y, getCell(x, y).copy()); } - if (x < this.regions.size()) + if (x < this.regions.size()) { copy.regions.add(this.getRegion(x).copy()); + } } for (PuzzleElement e : modifiedData) { copy.getPuzzleElement(e).setModifiable(false); From 8b2397ab1abbd3ffe203406d7a6bad0995254913 Mon Sep 17 00:00:00 2001 From: Jaden Tian <56417002+jadeandtea@users.noreply.github.com> Date: Sun, 5 May 2024 13:38:18 -0400 Subject: [PATCH 70/70] Tree Tent Test Suite (#775) * TentForTree test cases One valid case of connecting a tree to a tent One invalid case of connecting a tree to a tent when there is another valid tent * Incomplete test for already connected tree * Test for Fill in Row Case Rule Looks like the case rule was implemented incorrectly :/ * Fill in Row Test Cases Actually case generator works properly * Fill in Row Test Cases When the clue is that there are 0 tents, the case returned should be equivalent to FinishWithGrass. * Comments * Fix TreeTent Puzzle Editor * LinkTentCaseRule Four Trees Test Case Expected to create four cases, each one connecting a line between the tree in the center and one of the four surrounding trees. * LinkTentCaseRule Various Test Cases With one tree, one case is created. With no trees, no cases are created. With diagonal trees, no cases are created. * TreeTent Puzzle Editor Fix Removed double-calling setCell due to custom and super mouseReleased * LinkTreeCaseRule Test Cases Similar test cases to LinkTentCaseRule - Make sure diagonal tents have no bearing on cases - Make sure no tents around the tree fails - One tent should connect to the correct tree - Two tents should create two cases - No other cases to check, as there cannot be more than two tents around a tree; otherwise, the tents would touch * Reset puzzle * Improved FillInRowCaseRule Rewrote recursive generate board function to be slightly more optimized * Fix FillInRowCaseRule * Implement Copy Clue function Fixes a bug where you couldn't apply the FillInRow Case Rule on a child node * Allow Importing Puzzle-Specific Puzzle Elements When checking the proof tree, the Puzzle Importer only checks for changed cells. However, for TreeTent, the user can create lines, which cannot be saved as a "cell" object. Now, an importer class can override the getImporterElements function to specify what types of changes the board may experience. * Fix Puzzles Uneven Sides Simple mistake in calculation of index * Check Rule on Columns Adjust all simple cases to also check the central column rule * Change test puzzle names * FillInRowCaseRule Test Checks that the rule works on an empty 5x5 board * TreeForTent tests and TentForTree tests * Minor formatting changes * Fix boards with uneven side lengths * Comments * Standardizing Comments * Standardizing Comments All Direct Rules * Fix Build Issues The Ubuntu and Checkstyle Autocompilers have trouble opening this file for some reason * Comment out problematic file * Uncommenting problematic test * Update file name * Commented out Star Battle test --------- Co-authored-by: Charles Tian <46334090+charlestian23@users.noreply.github.com> Co-authored-by: charlestian23 --- .../treetent/8x8 TreeTent Easy/1646651 | 5 +- .../edu/rpi/legup/model/PuzzleImporter.java | 18 +- .../legup/puzzle/treetent/TreeTentBoard.java | 46 +- .../puzzle/treetent/TreeTentCellFactory.java | 2 +- .../legup/puzzle/treetent/TreeTentClue.java | 2 +- .../puzzle/treetent/TreeTentController.java | 8 +- .../puzzle/treetent/TreeTentExporter.java | 2 +- .../puzzle/treetent/TreeTentImporter.java | 13 +- .../treetent/rules/FillinRowCaseRule.java | 106 ++-- .../rules/BlackoutDirectRuleTest.java | 140 +++--- .../rules/EmptyFieldDirectRuleTest.java | 169 ++----- .../treetent/rules/FillinRowCaseRuleTest.java | 464 ++++++++++++++++++ .../rules/FinishWithGrassDirectRuleTest.java | 136 +++-- .../rules/FinishWithTentsDirectRuleTest.java | 143 +++--- .../rules/LastCampingSpotDirectRuleTest.java | 72 +-- .../treetent/rules/LinkTentCaseRuleTest.java | 191 +++++++ .../treetent/rules/LinkTreeCaseRuleTest.java | 192 ++++++++ .../SurroundTentWithGrassDirectRuleTest.java | 54 +- .../rules/TentForTreeDirectRuleTest.java | 171 ++++++- .../TooManyTentsContradictionRuleTest.java | 2 +- .../TouchingTentsContradictionRuleTest.java | 86 +--- .../rules/TreeForTentDirectRuleTest.java | 163 +++++- .../EmptyRow3x3OneTent} | 5 +- .../EmptyRow3x3ThreeTent} | 5 +- .../EmptyRow3x3TwoTent} | 11 +- .../EmptyRow3x3ZeroTent} | 1 - .../FillinRowCaseRule/EmptyRow5x5TwoTent | 23 + .../FillinRowCaseRule/PartialFillOneTent | 29 ++ .../treetent/rules/LinkTentCaseRule/DiagTrees | 26 + .../rules/LinkTentCaseRule/FourTreesOneTent | 26 + .../treetent/rules/LinkTentCaseRule/NoTrees | 22 + .../rules/LinkTentCaseRule/OneTreeOneTent | 23 + .../treetent/rules/LinkTreeCaseRule/DiagTents | 26 + .../treetent/rules/LinkTreeCaseRule/NoTents | 22 + .../treetent/rules/LinkTreeCaseRule/OneTent | 23 + .../treetent/rules/LinkTreeCaseRule/TwoTents | 24 + .../rules/TentForTreeDirectRule/ArbitraryTree | 28 ++ .../rules/TentForTreeDirectRule/ConnectedTent | 31 ++ .../TentForTreeDirectRule/OneTreeOneTent | 28 ++ .../OneTreeTwoAdjacentTent | 28 ++ .../TouchingTentsMixedDownRight | 20 - .../TouchingTentsMixedUpLeft | 20 - .../TouchingTentsMixedUpRight | 20 - .../TouchingTentsTreeDiagonal | 2 +- .../rules/TreeForTentDirectRule/ArbitraryTent | 28 ++ .../rules/TreeForTentDirectRule/ConnectedTree | 31 ++ .../TreeForTentDirectRule/OneTentOneTree | 28 ++ .../OneTentTwoAdjacentTrees | 28 ++ 48 files changed, 2155 insertions(+), 588 deletions(-) create mode 100644 src/test/java/puzzles/treetent/rules/FillinRowCaseRuleTest.java create mode 100644 src/test/java/puzzles/treetent/rules/LinkTentCaseRuleTest.java create mode 100644 src/test/java/puzzles/treetent/rules/LinkTreeCaseRuleTest.java rename src/test/resources/puzzles/treetent/rules/{EmptyFieldDirectRule/EmptyFieldFailLeft => FillinRowCaseRule/EmptyRow3x3OneTent} (78%) rename src/test/resources/puzzles/treetent/rules/{EmptyFieldDirectRule/EmptyFieldFailRight => FillinRowCaseRule/EmptyRow3x3ThreeTent} (78%) rename src/test/resources/puzzles/treetent/rules/{TouchingTentsContradictionRule/TouchingTentsMixedDownLeft => FillinRowCaseRule/EmptyRow3x3TwoTent} (57%) rename src/test/resources/puzzles/treetent/rules/{EmptyFieldDirectRule/EmptyFieldFailBottom => FillinRowCaseRule/EmptyRow3x3ZeroTent} (92%) create mode 100644 src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow5x5TwoTent create mode 100644 src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/PartialFillOneTent create mode 100644 src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/DiagTrees create mode 100644 src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/FourTreesOneTent create mode 100644 src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/NoTrees create mode 100644 src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/OneTreeOneTent create mode 100644 src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/DiagTents create mode 100644 src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/NoTents create mode 100644 src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/OneTent create mode 100644 src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/TwoTents create mode 100644 src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/ArbitraryTree create mode 100644 src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/ConnectedTent create mode 100644 src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/OneTreeOneTent create mode 100644 src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/OneTreeTwoAdjacentTent delete mode 100644 src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedDownRight delete mode 100644 src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedUpLeft delete mode 100644 src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedUpRight create mode 100644 src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/ArbitraryTent create mode 100644 src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/ConnectedTree create mode 100644 src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/OneTentOneTree create mode 100644 src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/OneTentTwoAdjacentTrees diff --git a/puzzles files/treetent/8x8 TreeTent Easy/1646651 b/puzzles files/treetent/8x8 TreeTent Easy/1646651 index 36dbc7f1e..db70ca164 100644 --- a/puzzles files/treetent/8x8 TreeTent Easy/1646651 +++ b/puzzles files/treetent/8x8 TreeTent Easy/1646651 @@ -1,5 +1,6 @@ - + + @@ -38,5 +39,5 @@ - + diff --git a/src/main/java/edu/rpi/legup/model/PuzzleImporter.java b/src/main/java/edu/rpi/legup/model/PuzzleImporter.java index 0cc163200..c22831c8d 100644 --- a/src/main/java/edu/rpi/legup/model/PuzzleImporter.java +++ b/src/main/java/edu/rpi/legup/model/PuzzleImporter.java @@ -6,6 +6,8 @@ import edu.rpi.legup.model.rules.Rule; import edu.rpi.legup.model.tree.*; import edu.rpi.legup.save.InvalidFileFormatException; + +import java.lang.reflect.Array; import java.util.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -130,6 +132,19 @@ public void initializePuzzle(Node node) throws InvalidFileFormatException { public abstract void initializeBoard(String[] statements) throws UnsupportedOperationException, IllegalArgumentException; + /** + * Used to check that elements in the proof tree are saved properly. + *

Make sure the list elements are lowercase + * + * @return A list of elements that will change when solving the puzzle + * * e.g. {"cell"}, {"cell", "line"} + */ + public List getImporterElements() { + List elements = new ArrayList<>(); + elements.add("cell"); + return elements; + } + /** * Creates the proof for building * @@ -379,7 +394,8 @@ protected void makeTransitionChanges(TreeTransition transition, Node transElemen NodeList cellList = transElement.getChildNodes(); for (int i = 0; i < cellList.getLength(); i++) { Node node = cellList.item(i); - if (node.getNodeName().equalsIgnoreCase("cell")) { + List elements = getImporterElements(); + if (elements.contains(node.getNodeName().toLowerCase())) { Board board = transition.getBoard(); PuzzleElement cell = puzzle.getFactory().importCell(node, board); diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentBoard.java b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentBoard.java index 09706f92a..6ded23a18 100644 --- a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentBoard.java +++ b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentBoard.java @@ -3,6 +3,8 @@ import edu.rpi.legup.model.gameboard.Board; import edu.rpi.legup.model.gameboard.GridBoard; import edu.rpi.legup.model.gameboard.PuzzleElement; +import edu.rpi.legup.model.tree.Tree; + import java.awt.*; import java.util.ArrayList; import java.util.List; @@ -53,21 +55,29 @@ public TreeTentCell getCell(int x, int y) { @Override public PuzzleElement getPuzzleElement(PuzzleElement element) { - switch (element.getIndex()) { - case -2: - return element; - case -1: - TreeTentLine line = (TreeTentLine) element; - TreeTentLine thisLine = null; - for (TreeTentLine l : lines) { - if (line.compare(l)) { - thisLine = l; - break; - } - } - return thisLine; - default: - return super.getPuzzleElement(element); + return switch (element.getIndex()) { + case -2 -> element; + case -1 -> element; + default -> super.getPuzzleElement(element); + }; + } + + @Override + public void setPuzzleElement(int index, PuzzleElement puzzleElement) { + if (index == -1) { + lines.add((TreeTentLine) puzzleElement); + } else if (index < puzzleElements.size()) { + puzzleElements.set(index, puzzleElement); + } + } + + @Override + public void notifyChange(PuzzleElement puzzleElement) { + int index = puzzleElement.getIndex(); + if (index == -1) { + lines.add((TreeTentLine) puzzleElement); + } else if (index < puzzleElements.size()) { + puzzleElements.set(index, puzzleElement); } } @@ -168,20 +178,20 @@ public List getDiagonals(TreeTentCell cell, TreeTentType type) { * * @param index the row or column number * @param type type of TreeTent element - * @param isRow boolean value beased on whether a row of column is being checked + * @param isRow boolean value based on whether a row of column is being checked * @return List of TreeTentCells that match the given TreeTentType */ public List getRowCol(int index, TreeTentType type, boolean isRow) { List list = new ArrayList<>(); if (isRow) { - for (int i = 0; i < dimension.height; i++) { + for (int i = 0; i < dimension.width; i++) { TreeTentCell cell = getCell(i, index); if (cell.getType() == type) { list.add(cell); } } } else { - for (int i = 0; i < dimension.width; i++) { + for (int i = 0; i < dimension.height; i++) { TreeTentCell cell = getCell(index, i); if (cell.getType() == type) { list.add(cell); diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentCellFactory.java b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentCellFactory.java index 1697b8bd5..a3553940d 100644 --- a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentCellFactory.java +++ b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentCellFactory.java @@ -39,7 +39,7 @@ public PuzzleElement importCell(Node node, Board board) throws InvalidFileFormat } TreeTentCell cell = new TreeTentCell(TreeTentType.valueOf(value), new Point(x, y)); - cell.setIndex(y * height + x); + cell.setIndex(y * width + x); return cell; } else { if (node.getNodeName().equalsIgnoreCase("line")) { diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentClue.java b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentClue.java index bcba7dc94..7b93f1301 100644 --- a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentClue.java +++ b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentClue.java @@ -50,6 +50,6 @@ public void setType(TreeTentType type) { } public TreeTentClue copy() { - return null; + return new TreeTentClue(data, clueIndex, type); } } diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentController.java b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentController.java index 79e074657..667c2ba7d 100644 --- a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentController.java +++ b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentController.java @@ -32,8 +32,10 @@ public TreeTentController() { public void mousePressed(MouseEvent e) { if (e.getButton() != MouseEvent.BUTTON2) { BoardView boardView = getInstance().getLegupUI().getBoardView(); - dragStart = boardView.getElement(e.getPoint()); - lastCellPressed = boardView.getElement(e.getPoint()); + if (boardView != null) { + dragStart = boardView.getElement(e.getPoint()); + lastCellPressed = boardView.getElement(e.getPoint()); + } } } @@ -105,6 +107,8 @@ public void mouseReleased(MouseEvent e) { } dragStart = null; lastCellPressed = null; + } else { + super.mouseReleased(e); } } diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentExporter.java b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentExporter.java index 475aaab1e..82c1b373d 100644 --- a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentExporter.java +++ b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentExporter.java @@ -52,7 +52,7 @@ protected org.w3c.dom.Element createBoardElement(Document newDocument) { org.w3c.dom.Element axisSouth = newDocument.createElement("axis"); axisSouth.setAttribute("side", "south"); - for (TreeTentClue clue : board.getRowClues()) { + for (TreeTentClue clue : board.getColClues()) { org.w3c.dom.Element clueElement = newDocument.createElement("clue"); clueElement.setAttribute("value", String.valueOf(clue.getData())); clueElement.setAttribute("index", String.valueOf(clue.getClueIndex())); diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentImporter.java b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentImporter.java index 0117f41ce..c791617ce 100644 --- a/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentImporter.java +++ b/src/main/java/edu/rpi/legup/puzzle/treetent/TreeTentImporter.java @@ -3,6 +3,9 @@ import edu.rpi.legup.model.PuzzleImporter; import edu.rpi.legup.save.InvalidFileFormatException; import java.awt.*; +import java.util.ArrayList; +import java.util.List; + import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @@ -113,7 +116,7 @@ public void initializeBoard(Node node) throws InvalidFileFormatException { for (int x = 0; x < width; x++) { if (treeTentBoard.getCell(x, y) == null) { TreeTentCell cell = new TreeTentCell(TreeTentType.UNKNOWN, new Point(x, y)); - cell.setIndex(y * height + x); + cell.setIndex(y * width + x); cell.setModifiable(true); treeTentBoard.setCell(x, y, cell); } @@ -216,4 +219,12 @@ public void initializeBoard(Node node) throws InvalidFileFormatException { public void initializeBoard(String[] statements) throws UnsupportedOperationException { throw new UnsupportedOperationException("Tree Tent cannot accept text input"); } + + @Override + public List getImporterElements() { + List elements = new ArrayList<>(); + elements.add("cell"); + elements.add("line"); + return elements; + } } diff --git a/src/main/java/edu/rpi/legup/puzzle/treetent/rules/FillinRowCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/treetent/rules/FillinRowCaseRule.java index 0116c0dcd..a796c992a 100644 --- a/src/main/java/edu/rpi/legup/puzzle/treetent/rules/FillinRowCaseRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/treetent/rules/FillinRowCaseRule.java @@ -1,9 +1,11 @@ package edu.rpi.legup.puzzle.treetent.rules; +import edu.rpi.legup.model.Puzzle; import edu.rpi.legup.model.gameboard.Board; import edu.rpi.legup.model.gameboard.CaseBoard; import edu.rpi.legup.model.gameboard.PuzzleElement; import edu.rpi.legup.model.rules.CaseRule; +import edu.rpi.legup.model.tree.Tree; import edu.rpi.legup.model.tree.TreeTransition; import edu.rpi.legup.puzzle.treetent.TreeTentBoard; import edu.rpi.legup.puzzle.treetent.TreeTentCell; @@ -11,7 +13,9 @@ import edu.rpi.legup.puzzle.treetent.TreeTentType; import java.awt.*; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; +import java.util.ListIterator; public class FillinRowCaseRule extends CaseRule { @@ -61,7 +65,7 @@ public CaseBoard getCaseBoard(Board board) { */ @Override public ArrayList getCases(Board board, PuzzleElement puzzleElement) { - ArrayList cases = new ArrayList(); + ArrayList cases; List group; int tentsLeft; TreeTentClue clue = ((TreeTentClue) puzzleElement); @@ -70,7 +74,7 @@ public ArrayList getCases(Board board, PuzzleElement puzzleElement) { if (clue.getType() == TreeTentType.CLUE_SOUTH) { group = tBoard.getRowCol(clueIndex, TreeTentType.UNKNOWN, false); tentsLeft = - tBoard.getRowClues().get(clueIndex).getData() + tBoard.getColClues().get(clueIndex).getData() - tBoard.getRowCol(clueIndex, TreeTentType.TENT, false).size(); cases = genCombinations(tBoard, group, tentsLeft, clueIndex, false); } else { @@ -83,60 +87,100 @@ public ArrayList getCases(Board board, PuzzleElement puzzleElement) { // generate every combination (nCr) // call goodBoard for each generated combination - // alternitive would be to implement collision avoidance while generating instead of after + // alternative would be to implement collision avoidance while generating instead of after if (cases.size() > 0) { return cases; } return null; } + /** + * + * @param iBoard the board to place tents onto + * @param tiles the locations where tents can be placed + * @param target the target number of tents to place + * @param index the index of tiles which is trying to be placed + * @param isRow Used to check validity of board + * @return the list of boards created + */ private ArrayList genCombinations( TreeTentBoard iBoard, List tiles, int target, Integer index, boolean isRow) { - return genCombRecursive( - iBoard, tiles, tiles, target, 0, new ArrayList(), index, isRow); + ArrayList generatedBoards = new ArrayList<>(); + genCombRecursive( + iBoard, tiles, target, 0, new ArrayList(), 0, index, generatedBoards, isRow); + return generatedBoards; } - private ArrayList genCombRecursive( + /** + * + * Recursive function to generate all ways of placing the target number of tents + * from the list of tiles to fill. + * + * @param iBoard The board + * @param tiles Unknown Tiles to fill + * @param target number of tents to place + * @param current number of tents already placed + * @param currentTile index of the next tile to add + * @param selected the cells which have tents + * @param index The index of the clue + * @param isRow Used for checking if the board is good + * + * The generated boards are placed into generatedBoards (passed by reference) + */ + + private void genCombRecursive( TreeTentBoard iBoard, - List original, List tiles, int target, int current, List selected, + int currentTile, Integer index, + ArrayList generatedBoards, boolean isRow) { - ArrayList b = new ArrayList<>(); + // Base Case: Enough tents have been placed if (target == current) { - TreeTentBoard temp = iBoard.copy(); - for (TreeTentCell c : original) { - if (selected.contains(c)) { - PuzzleElement change = temp.getPuzzleElement(c); - change.setData(TreeTentType.TENT); - temp.addModifiedData(change); - } else { - PuzzleElement change = temp.getPuzzleElement(c); - change.setData(TreeTentType.GRASS); - temp.addModifiedData(change); + TreeTentBoard boardCopy = iBoard.copy(); + // Selected Tiles should already be filled + // Fill in other tiles with Grass + for (TreeTentCell tile : tiles) { + if (!selected.contains(tile)) { + PuzzleElement element = boardCopy.getPuzzleElement(tile); + element.setData(TreeTentType.GRASS); + boardCopy.addModifiedData(element); } } - if (goodBoard(temp, index, isRow)) { - b.add(temp); - } - return b; + // board validity is checked after placing every tent + // because the base case doesn't place any tents, the board + // should still be valid + generatedBoards.add(boardCopy); + return; } - for (int i = 0; i < tiles.size(); ++i) { - List sub = tiles.subList(i + 1, tiles.size()); - List next = new ArrayList(selected); - next.add(tiles.get(i)); - b.addAll( - genCombRecursive( - iBoard, original, sub, target, current + 1, next, index, isRow)); + + // Recursive Case: + // Looking at the group of possible tiles, save one of the tiles into selected, + // Place it on the board, + // Check if the board is good and recurse + // + // Backtracking: + // Remove the placed tent from the board and selected + for (int i = currentTile; i < tiles.size(); ++i){ + TreeTentCell tile = tiles.get(i); + selected.add(tile); + PuzzleElement element = iBoard.getPuzzleElement(tile); + element.setData(TreeTentType.TENT); + iBoard.addModifiedData(element); + if (goodBoard(iBoard, index, isRow)) { + genCombRecursive(iBoard, tiles, target, current + 1, selected, i + 1, index, generatedBoards, isRow); + } + element.setData(TreeTentType.UNKNOWN); + iBoard.addModifiedData(element); + selected.remove(tile); } - return b; } // Effectively runs TouchingTents check on all the added tents to make sure that the proposed @@ -153,7 +197,7 @@ private boolean goodBoard(TreeTentBoard board, Integer index, boolean isRow) { for (TreeTentCell t : tents) { List adj = board.getAdjacent(t, TreeTentType.TENT); List diag = board.getDiagonals(t, TreeTentType.TENT); - if (adj.size() > 0 || diag.size() > 0) { + if (!adj.isEmpty() || !diag.isEmpty()) { return false; } } diff --git a/src/test/java/puzzles/starbattle/rules/BlackoutDirectRuleTest.java b/src/test/java/puzzles/starbattle/rules/BlackoutDirectRuleTest.java index d42f40c87..7789b273b 100644 --- a/src/test/java/puzzles/starbattle/rules/BlackoutDirectRuleTest.java +++ b/src/test/java/puzzles/starbattle/rules/BlackoutDirectRuleTest.java @@ -1,69 +1,73 @@ -package puzzles.starbattle.rules; +// This test is for a puzzle that is not fully implemented yet and is causing issues. +// Commenting this out for now, but once Star Battle is fully implemented this should +// be uncommented and finished. -import edu.rpi.legup.puzzle.nurikabe.Nurikabe; -import edu.rpi.legup.puzzle.nurikabe.NurikabeBoard; -import edu.rpi.legup.puzzle.nurikabe.NurikabeCell; -import edu.rpi.legup.puzzle.nurikabe.NurikabeType; -import legup.MockGameBoardFacade; -import legup.TestUtilities; -import edu.rpi.legup.model.tree.TreeNode; -import edu.rpi.legup.model.tree.TreeTransition; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -import edu.rpi.legup.puzzle.starbattle.StarBattle; -import edu.rpi.legup.puzzle.starbattle.StarBattleBoard; -import edu.rpi.legup.puzzle.starbattle.StarBattleCell; -import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; -import edu.rpi.legup.puzzle.starbattle.rules.BlackoutDirectRule; -import edu.rpi.legup.save.InvalidFileFormatException; - -import java.awt.*; - -public class BlackoutDirectRuleTest { - - private static final BlackoutDirectRule RULE = new BlackoutDirectRule(); - private static StarBattle starbattle; - - @BeforeClass - public static void setUp() { - MockGameBoardFacade.getInstance(); - starbattle = new StarBattle(); - } - - @Test - public void BlackoutDirectRuleTest_ColumnBlackout() throws InvalidFileFormatException { - TestUtilities.importTestBoard("puzzles/starbattle/rules/BlackoutDirectRule/ColumnBlackout", starbattle); - TreeNode rootNode = starbattle.getTree().getRootNode(); - TreeTransition transition = rootNode.getChildren().get(0); - transition.setRule(RULE); - - StarBattleBoard board = (StarBattleBoard) transition.getBoard(); - - StarBattleCell cell1 = board.getCell(1, 1); - cell1.setData(StarBattleCellType.BLACK.value); - StarBattleCell cell2 = board.getCell(1, 2); - cell2.setData(StarBattleCellType.BLACK.value); - StarBattleCell cell3 = board.getCell(1, 3); - cell3.setData(StarBattleCellType.BLACK.value); - - board.addModifiedData(cell1); - board.addModifiedData(cell2); - board.addModifiedData(cell3); - - Assert.assertNull(RULE.checkRule(transition)); - - for (int i = 0; i < board.getHeight(); i++) { - for (int k = 0; k < board.getWidth(); k++) { - Point point = new Point(k, i); - if (point.equals(cell1.getLocation()) || point.equals(cell2.getLocation()) || point.equals(cell3.getLocation())) { - Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(k, i))); - } - else { - Assert.assertNotNull(RULE.checkRuleAt(transition, board.getCell(k, i))); - } - } - } - } -} +//package puzzles.starbattle.rules; +// +//import edu.rpi.legup.puzzle.nurikabe.Nurikabe; +//import edu.rpi.legup.puzzle.nurikabe.NurikabeBoard; +//import edu.rpi.legup.puzzle.nurikabe.NurikabeCell; +//import edu.rpi.legup.puzzle.nurikabe.NurikabeType; +//import legup.MockGameBoardFacade; +//import legup.TestUtilities; +//import edu.rpi.legup.model.tree.TreeNode; +//import edu.rpi.legup.model.tree.TreeTransition; +//import org.junit.Assert; +//import org.junit.BeforeClass; +//import org.junit.Test; +// +//import edu.rpi.legup.puzzle.starbattle.StarBattle; +//import edu.rpi.legup.puzzle.starbattle.StarBattleBoard; +//import edu.rpi.legup.puzzle.starbattle.StarBattleCell; +//import edu.rpi.legup.puzzle.starbattle.StarBattleCellType; +//import edu.rpi.legup.puzzle.starbattle.rules.BlackoutDirectRule; +//import edu.rpi.legup.save.InvalidFileFormatException; +// +//import java.awt.*; +// +//public class BlackoutDirectRuleTest { +// +// private static final BlackoutDirectRule RULE = new BlackoutDirectRule(); +// private static StarBattle starbattle; +// +// @BeforeClass +// public static void setUp() { +// MockGameBoardFacade.getInstance(); +// starbattle = new StarBattle(); +// } +// +// @Test +// public void BlackoutDirectRuleTest_ColumnBlackout() throws InvalidFileFormatException { +// TestUtilities.importTestBoard("puzzles/starbattle/rules/BlackoutDirectRule/ColumnBlackout", starbattle); +// TreeNode rootNode = starbattle.getTree().getRootNode(); +// TreeTransition transition = rootNode.getChildren().get(0); +// transition.setRule(RULE); +// +// StarBattleBoard board = (StarBattleBoard) transition.getBoard(); +// +// StarBattleCell cell1 = board.getCell(1, 1); +// cell1.setData(StarBattleCellType.BLACK.value); +// StarBattleCell cell2 = board.getCell(1, 2); +// cell2.setData(StarBattleCellType.BLACK.value); +// StarBattleCell cell3 = board.getCell(1, 3); +// cell3.setData(StarBattleCellType.BLACK.value); +// +// board.addModifiedData(cell1); +// board.addModifiedData(cell2); +// board.addModifiedData(cell3); +// +// Assert.assertNull(RULE.checkRule(transition)); +// +// for (int i = 0; i < board.getHeight(); i++) { +// for (int k = 0; k < board.getWidth(); k++) { +// Point point = new Point(k, i); +// if (point.equals(cell1.getLocation()) || point.equals(cell2.getLocation()) || point.equals(cell3.getLocation())) { +// Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(k, i))); +// } +// else { +// Assert.assertNotNull(RULE.checkRuleAt(transition, board.getCell(k, i))); +// } +// } +// } +// } +//} diff --git a/src/test/java/puzzles/treetent/rules/EmptyFieldDirectRuleTest.java b/src/test/java/puzzles/treetent/rules/EmptyFieldDirectRuleTest.java index 38284c410..8ffb2ee4f 100644 --- a/src/test/java/puzzles/treetent/rules/EmptyFieldDirectRuleTest.java +++ b/src/test/java/puzzles/treetent/rules/EmptyFieldDirectRuleTest.java @@ -26,11 +26,17 @@ public static void setUp() { treetent = new TreeTent(); } - // creates a 3x3 puzzle with no trees - // make the (1,1) tile GRASS - // checks if tiles logically follow the EmptyFieldDirectRule - @Test - public void EmptyFieldTest() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests EmptyFieldDirectRule + *

Empty + * XXX + * XGX + * XXX + *

Makes the (1, 1) tile GRASS + * Checks if the rule correctly detects no trees around the grass tile + */ + @Test + public void EmptyFieldTest() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/EmptyFieldDirectRule/EmptyField", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); @@ -64,12 +70,17 @@ public void EmptyFieldTest() throws InvalidFileFormatException { } } - // creates a 3x3 puzzle with 4 trees - // trees are at (0,0), (2,0), (0,2), and (2,2) - // make the (1,1) tile GRASS. - // checks if tiles logically follow the EmptyFieldDirectRule - @Test - public void DiagonalTreeTest() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests EmptyFieldDirectRule + *

Trees are at (0, 0), (2, 0), (0, 2), and (2, 2) + * RXR + * XGX + * RXR + *

Makes the (1, 1) tile GRASS + * Checks if the rule correctly ignores the trees on the diagonals + */ + @Test + public void DiagonalTreeTest() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/EmptyFieldDirectRule/DiagonalTree", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); @@ -103,12 +114,17 @@ public void DiagonalTreeTest() throws InvalidFileFormatException { } } - // creates a 3x3 puzzle with 4 trees - // trees are at (0,1), (1,0), (1,2), and (2,1) - // make the (1,1) tile GRASS. - // checks if tiles don't logically follow the EmptyFieldDirectRule - @Test - public void EmptyFieldTestFail() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests EmptyFieldDirectRule + *

Trees are at (0, 1), (1, 0), (1, 2), and (2, 1) + * XRX + * RGR + * XRX + *

Makes the (1, 1) tile GRASS + * Checks if the rule is not valid when there are adjacent trees + */ + @Test + public void EmptyFieldTestFail() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFail", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); @@ -137,12 +153,17 @@ public void EmptyFieldTestFail() throws InvalidFileFormatException { } } - // creates a 3x3 puzzle with 1 tree - // tree is at (1,0) - // make the (1,1) tile GRASS. - // checks if tiles don't logically follow the EmptyFieldDirectRule - @Test - public void EmptyFieldTestFailTop() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests EmptyFieldDirectRule + *

Tree at (1, 0) + * XRX + * XGX + * XXX + *

Makes the (1, 1) tile GRASS + * Checks if the rule is not valid when there is one adjacent tree + */ + @Test + public void EmptyFieldTestFailTop() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailTop", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); @@ -170,106 +191,4 @@ public void EmptyFieldTestFailTop() throws InvalidFileFormatException { } } } - - // creates a 3x3 puzzle with 1 tree - // tree is at (1,2) - // make the (1,1) tile GRASS. - // checks if tiles don't logically follow the EmptyFieldDirectRule - @Test - public void EmptyFieldTestFailTopBottom() throws InvalidFileFormatException { - TestUtilities.importTestBoard( - "puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailBottom", treetent); - TreeNode rootNode = treetent.getTree().getRootNode(); - TreeTransition transition = rootNode.getChildren().get(0); - transition.setRule(RULE); - - // get board state - TreeTentBoard board = (TreeTentBoard) transition.getBoard(); - - // change the board's cells considering breaking the EmptyField rule - TreeTentCell cell1 = board.getCell(1, 1); - cell1.setData(TreeTentType.GRASS); - board.addModifiedData(cell1); - - // confirm there is not a logical following of the EmptyField rule - Assert.assertNotNull(RULE.checkRule(transition)); - - // the cells should not follow the rule - TreeTentCell c; - for (int i = 0; i < board.getWidth(); i++) { - for (int j = 0; j < board.getHeight(); j++) { - c = board.getCell(j, i); - // does not use the rule to logically follow - Assert.assertNotNull(RULE.checkRuleAt(transition, c)); - } - } - } - - // creates a 3x3 puzzle with 1 tree - // tree is at (0,1) - // make the (1,1) tile GRASS. - // checks if tiles don't logically follow the EmptyFieldDirectRule - @Test - public void EmptyFieldTestFailLeft() throws InvalidFileFormatException { - TestUtilities.importTestBoard( - "puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailLeft", treetent); - TreeNode rootNode = treetent.getTree().getRootNode(); - TreeTransition transition = rootNode.getChildren().get(0); - transition.setRule(RULE); - - // get board state - TreeTentBoard board = (TreeTentBoard) transition.getBoard(); - - // change the board's cells considering breaking the EmptyField rule - TreeTentCell cell1 = board.getCell(1, 1); - cell1.setData(TreeTentType.GRASS); - board.addModifiedData(cell1); - - // confirm there is not a logical following of the EmptyField rule - Assert.assertNotNull(RULE.checkRule(transition)); - - // the cells should not follow the rule - TreeTentCell c; - for (int i = 0; i < board.getWidth(); i++) { - for (int j = 0; j < board.getHeight(); j++) { - c = board.getCell(j, i); - // does not use the rule to logically follow - Assert.assertNotNull(RULE.checkRuleAt(transition, c)); - } - } - } - - // creates a 3x3 puzzle with 1 tree - // tree is at (2,1) - // make the (1,1) tile GRASS. - // checks if tiles don't logically follow the EmptyFieldDirectRule - @Test - public void EmptyFieldTestFailRight() throws InvalidFileFormatException { - TestUtilities.importTestBoard( - "puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailRight", treetent); - TreeNode rootNode = treetent.getTree().getRootNode(); - TreeTransition transition = rootNode.getChildren().get(0); - transition.setRule(RULE); - - // get board state - TreeTentBoard board = (TreeTentBoard) transition.getBoard(); - - // change the board's cells considering breaking the EmptyField rule - TreeTentCell cell1 = board.getCell(1, 1); - cell1.setData(TreeTentType.GRASS); - board.addModifiedData(cell1); - - // confirm there is not a logical following of the EmptyField rule - Assert.assertNotNull(RULE.checkRule(transition)); - - // the cells should not follow the rule - TreeTentCell c; - for (int i = 0; i < board.getWidth(); i++) { - for (int j = 0; j < board.getHeight(); j++) { - c = board.getCell(j, i); - // does not use the rule to logically follow - Assert.assertNotNull(RULE.checkRuleAt(transition, c)); - } - } - } } diff --git a/src/test/java/puzzles/treetent/rules/FillinRowCaseRuleTest.java b/src/test/java/puzzles/treetent/rules/FillinRowCaseRuleTest.java new file mode 100644 index 000000000..71b478e7a --- /dev/null +++ b/src/test/java/puzzles/treetent/rules/FillinRowCaseRuleTest.java @@ -0,0 +1,464 @@ +package puzzles.treetent.rules; + +import edu.rpi.legup.model.gameboard.Board; +import edu.rpi.legup.model.tree.TreeNode; +import edu.rpi.legup.model.tree.TreeTransition; +import edu.rpi.legup.puzzle.treetent.*; +import edu.rpi.legup.puzzle.treetent.rules.FillinRowCaseRule; +import edu.rpi.legup.save.InvalidFileFormatException; +import legup.MockGameBoardFacade; +import legup.TestUtilities; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.lang.reflect.Array; +import java.util.ArrayList; + +public class FillinRowCaseRuleTest { + private static final FillinRowCaseRule RULE = new FillinRowCaseRule(); + private static TreeTent treetent; + + @BeforeClass + public static void setUp() { + MockGameBoardFacade.getInstance(); + treetent = new TreeTent(); + } + + /** + * empty 3x3 TreeTent puzzle Tests FillinRowCaseRule on row with 3 UNKNOWN tiles + * and a clue of 0 tents in the row. + * + *

checks that 1 case is created and that it is equivalent to FinishWithGrass rule + * May need to change checks due to issue #777 + * + * @throws InvalidFileFormatException + */ + @Test + public void TentOrTreeTestZeroTentClue() throws InvalidFileFormatException { + TestUtilities.importTestBoard( + "puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3ZeroTent", treetent); + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + + /* Test the Row */ + TreeTentClue testing_row = board.getClue(3, 1); + ArrayList cases = RULE.getCases(board, testing_row); + + // assert that one case was found + Assert.assertEquals(1, cases.size()); + + // assert the case filled the row with grass + TreeTentBoard testCase = (TreeTentBoard) cases.getFirst(); + Assert.assertEquals(3, testCase.getRowCol(1, TreeTentType.GRASS, true).size()); + + // checks other cells have not been modified + TreeTentCell original_cell; + TreeTentCell case_cell; + + for (int w = 0; w < board.getWidth(); w++) { + for (int h = 0; h < board.getHeight(); h++) { + if (h == 1) { + continue; + } + + original_cell = board.getCell(w, h); + case_cell = testCase.getCell(w, h); + Assert.assertEquals(original_cell.getType(), case_cell.getType()); + } + } + + /* Test the Column */ + TreeTentClue testing_col = board.getClue(1, 3); + cases = RULE.getCases(board, testing_col); + + // assert one case was created + Assert.assertEquals(1, cases.size()); + + // assert the case filled the column with grass + testCase = (TreeTentBoard) cases.getFirst(); + Assert.assertEquals(3, testCase.getRowCol(1, TreeTentType.GRASS, false).size()); + + // checks other cells have not been modified + for (int w = 0; w < board.getWidth(); w++) { + for (int h = 0; h < board.getHeight(); h++) { + if (w == 1) { + continue; + } + + original_cell = board.getCell(w, h); + + case_cell = testCase.getCell(w, h); + Assert.assertEquals(original_cell.getType(), case_cell.getType()); + } + } + } + + /** + * empty 3x3 TreeTent puzzle Tests FillinRowCaseRule on row with 3 UNKNOWN tiles + * and a clue of 1 tent in the row. The column rules make the board impossible, but + * they are not checked here. + * + *

checks 3 cases are created checks; + * first case is TENT tile at x=0, + * second case is TENT tile at x=1, + * and a third case is TENT tile at x=2. + * The cases can be in any order. + * Then, it checks that other cells have not been modified + * + * @throws InvalidFileFormatException + */ + @Test + public void FillInRowEmptyOneTentClue() throws InvalidFileFormatException { + TestUtilities.importTestBoard( + "puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3OneTent", treetent); + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + + /* Test the Row */ + TreeTentClue testing_row = board.getClue(3, 1); + ArrayList cases = RULE.getCases(board, testing_row); + + // assert correct number of cases created + Assert.assertEquals(3, cases.size()); + + for (Board testCaseBoard : cases) { + TreeTentBoard testCase = (TreeTentBoard) testCaseBoard; + + // Each case must have 1 tent in the row + Assert.assertEquals(1, testCase.getRowCol(1, TreeTentType.TENT, true).size()); + + // and they must have 2 grass tiles in the row + Assert.assertEquals(2, testCase.getRowCol(1, TreeTentType.GRASS, true).size()); + } + + // checks other cells have not been modified + TreeTentCell original_cell; + TreeTentCell case_cell; + + for (int w = 0; w < board.getWidth(); w++) { + for (int h = 0; h < board.getHeight(); h++) { + if (h == 1) { + continue; + } + + original_cell = board.getCell(w, h); + + for (Board testCaseBoard : cases) { + TreeTentBoard testCase = (TreeTentBoard) testCaseBoard; + + case_cell = testCase.getCell(w, h); + Assert.assertEquals(original_cell.getType(), case_cell.getType()); + + } + } + } + + /* Test the Column */ + TreeTentClue testing_col = board.getClue(1, 3); + cases = RULE.getCases(board, testing_col); + + // assert correct number of cases created + Assert.assertEquals(3, cases.size()); + // Only one arrangement is possible when taking into account the + // touching tents contradiction rule. + + for (Board testCaseBoard : cases) { + TreeTentBoard testCase = (TreeTentBoard) testCaseBoard; + + // Each case must have 1 tent in the column + Assert.assertEquals(1, testCase.getRowCol(1, TreeTentType.TENT, false).size()); + + // and they must have 2 grass tiles in the column + Assert.assertEquals(2, testCase.getRowCol(1, TreeTentType.GRASS, false).size()); + } + + // checks other cells have not been modified + for (int w = 0; w < board.getWidth(); w++) { + for (int h = 0; h < board.getHeight(); h++) { + if (w == 1) { + continue; + } + + original_cell = board.getCell(w, h); + + for (Board testCaseBoard : cases) { + TreeTentBoard testCase = (TreeTentBoard) testCaseBoard; + + case_cell = testCase.getCell(w, h); + Assert.assertEquals(original_cell.getType(), case_cell.getType()); + } + } + } + } + + /** + * empty 3x3 TreeTent puzzle Tests FillinRowCaseRule on row with 3 UNKNOWN tiles + * and a clue of 2 tent in the row. The column rules make the board impossible, but + * they are not checked here. + * + *

checks 1 case is created. Checks that the case is when + * there are TENT tiles at x=0 and x=2. + * Then, it checks that other cells have not been modified + * + * @throws InvalidFileFormatException + */ + @Test + public void FillInRowEmptyTwoTentClue() throws InvalidFileFormatException { + TestUtilities.importTestBoard( + "puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3TwoTent", treetent); + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + /* Test the Row */ + TreeTentClue testing_row = board.getClue(3, 1); + ArrayList cases = RULE.getCases(board, testing_row); + + // assert correct number of cases created + Assert.assertEquals(1, cases.size()); + // Only one arrangement is possible when taking into account the + // touching tents contradiction rule. + + TreeTentBoard testCase = (TreeTentBoard) cases.getFirst(); + + // The two side tiles are tents, + Assert.assertEquals(TreeTentType.TENT, testCase.getCell(0, 1).getType()); + Assert.assertEquals(TreeTentType.TENT, testCase.getCell(2, 1).getType()); + + // and the center tile is grass. + Assert.assertEquals(TreeTentType.GRASS, testCase.getCell(1, 1).getType()); + + // checks other cells have not been modified + TreeTentCell original_cell; + TreeTentCell case_cell; + + for (int w = 0; w < board.getWidth(); w++) { + for (int h = 0; h < board.getHeight(); h++) { + if (h == 1) { + continue; + } + + original_cell = board.getCell(w, h); + + case_cell = testCase.getCell(w, h); + Assert.assertEquals(original_cell.getType(), case_cell.getType()); + } + } + + /* Test the Column */ + TreeTentClue testing_col = board.getClue(1, 3); + cases = RULE.getCases(board, testing_col); + + // assert correct number of cases created + Assert.assertEquals(1, cases.size()); + // Only one arrangement is possible when taking into account the + // touching tents contradiction rule. + + testCase = (TreeTentBoard) cases.getFirst(); + + // The two side tiles are tents, + Assert.assertEquals(TreeTentType.TENT, testCase.getCell(1, 0).getType()); + Assert.assertEquals(TreeTentType.TENT, testCase.getCell(1, 2).getType()); + + // and the center tile is grass. + Assert.assertEquals(TreeTentType.GRASS, testCase.getCell(1, 1).getType()); + + // checks other cells have not been modified + for (int w = 0; w < board.getWidth(); w++) { + for (int h = 0; h < board.getHeight(); h++) { + if (w == 1) { + continue; + } + + original_cell = board.getCell(w, h); + + case_cell = testCase.getCell(w, h); + Assert.assertEquals(original_cell.getType(), case_cell.getType()); + } + } + } + + /** + * empty 3x3 TreeTent puzzle Tests FillinRowCaseRule on row with 3 UNKNOWN tiles + * and a clue of 3 tent in the row. + * + *

checks that 0 cases are created + * + * @throws InvalidFileFormatException + */ + @Test + public void FillInRowEmptyThreeTentClue() throws InvalidFileFormatException { + TestUtilities.importTestBoard( + "puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3ThreeTent", treetent); + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + + /* Test the Row */ + TreeTentClue testing_row = board.getClue(3, 1); + ArrayList cases = RULE.getCases(board, testing_row); + + // assert there were no cases found, as filling in all tiles causes the tents to touch + Assert.assertNull(cases); + + /* Test the Column */ + TreeTentClue testing_col = board.getClue(1, 3); + cases = RULE.getCases(board, testing_row); + + Assert.assertNull(cases); + } + + /** + * empty 5x5 TreeTent puzzle Tests FillinRowCaseRule on row with 5 UNKNOWN tiles + * and a clue of 2 tents in the row. + * + *

checks that 6 cases are created and each case has the right number of tents + * + * @throws InvalidFileFormatException + */ + @Test + public void FillInRowEmpty5x5TwoTentClue() throws InvalidFileFormatException { + TestUtilities.importTestBoard( + "puzzles/treetent/rules/FillinRowCaseRule/EmptyRow5x5TwoTent", treetent); + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + + // Test the Row + TreeTentClue testing_row = board.getClue(5, 2); + ArrayList cases = RULE.getCases(board, testing_row); + + // assert correct number of cases created + Assert.assertEquals(6, cases.size()); + // Only one arrangement is possible when taking into account the + // touching tents contradiction rule. + + for (Board testCaseBoard : cases) { + TreeTentBoard testCase = (TreeTentBoard) testCaseBoard; + + // Each case must have 2 tens in the row + Assert.assertEquals(2, testCase.getRowCol(2, TreeTentType.TENT, true).size()); + + // and they must have 3 grass tiles in the row + Assert.assertEquals(3, testCase.getRowCol(2, TreeTentType.GRASS, true).size()); + } + + TreeTentCell original_cell; + TreeTentCell case_cell; + + // checks other cells have not been modified + for (int w = 0; w < board.getWidth(); w++) { + for (int h = 0; h < board.getHeight(); h++) { + if (h == 2) { + continue; + } + + original_cell = board.getCell(w, h); + + for (Board testCaseBoard : cases) { + TreeTentBoard testCase = (TreeTentBoard) testCaseBoard; + + case_cell = testCase.getCell(w, h); + Assert.assertEquals(original_cell.getType(), case_cell.getType()); + } + } + } + + // Test the Column + TreeTentClue testing_col = board.getClue(2, 5); + cases = RULE.getCases(board, testing_col); + + // assert correct number of cases created + Assert.assertEquals(6, cases.size()); + // Only one arrangement is possible when taking into account the + // touching tents contradiction rule. + + for (Board testCaseBoard : cases) { + TreeTentBoard testCase = (TreeTentBoard) testCaseBoard; + + // Each case must have 2 tents in the column + Assert.assertEquals(2, testCase.getRowCol(2, TreeTentType.TENT, false).size()); + + // and they must have 4 grass tiles in the column + Assert.assertEquals(3, testCase.getRowCol(2, TreeTentType.GRASS, false).size()); + } + + // checks other cells have not been modified + for (int w = 0; w < board.getWidth(); w++) { + for (int h = 0; h < board.getHeight(); h++) { + if (w == 2) { + continue; + } + + original_cell = board.getCell(w, h); + + for (Board testCaseBoard : cases) { + TreeTentBoard testCase = (TreeTentBoard) testCaseBoard; + + case_cell = testCase.getCell(w, h); + Assert.assertEquals(original_cell.getType(), case_cell.getType()); + } + } + } + } + + /** + * 7x3 TreeTent puzzle Tests FillinRowCaseRule on col with 3 UNKNOWN tiles separated by grass + * tiles and a clue of 3 tents in the col. + * + *

checks that 1 case is created and that all three UNKNOWN tiles have become tents + * + * @throws InvalidFileFormatException + */ + @Test + public void FillInRowPartialFillThreeTent() throws InvalidFileFormatException { + TestUtilities.importTestBoard( + "puzzles/treetent/rules/FillinRowCaseRule/PartialFillOneTent", treetent); + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + TreeTentClue testing_col = board.getClue(1, 7); + ArrayList cases = RULE.getCases(board, testing_col); + + // assert that one case was found + Assert.assertEquals(1, cases.size()); + + // assert the case has three tents in the column + TreeTentBoard testCase = (TreeTentBoard) cases.getFirst(); + Assert.assertEquals(3, testCase.getRowCol(1, TreeTentType.TENT, false).size()); + + Assert.assertEquals(TreeTentType.TENT, testCase.getCell(1, 1).getType()); + Assert.assertEquals(TreeTentType.TENT, testCase.getCell(1, 3).getType()); + Assert.assertEquals(TreeTentType.TENT, testCase.getCell(1, 5).getType()); + + // checks other cells have not been modified + TreeTentCell original_cell; + TreeTentCell case_cell; + + for (int w = 0; w < board.getWidth(); w++) { + if (w == 1) { + continue; + } + for (int h = 0; h < board.getHeight(); h++) { + + original_cell = board.getCell(w, h); + case_cell = testCase.getCell(w, h); + Assert.assertEquals(original_cell.getType(), case_cell.getType()); + } + } + } +} diff --git a/src/test/java/puzzles/treetent/rules/FinishWithGrassDirectRuleTest.java b/src/test/java/puzzles/treetent/rules/FinishWithGrassDirectRuleTest.java index 0783ab8b8..f37761e26 100644 --- a/src/test/java/puzzles/treetent/rules/FinishWithGrassDirectRuleTest.java +++ b/src/test/java/puzzles/treetent/rules/FinishWithGrassDirectRuleTest.java @@ -28,14 +28,18 @@ public static void setUp() { treetent = new TreeTent(); } - /** - * 3x3 TreeTent puzzle with a tent at (0,0) Tests FinishWithGrassDirectRule on GRASS tiles - * horizontal of the tent at (1,0) and (2,0) - * - * @throws InvalidFileFormatException - */ - @Test - public void FinishWithGrassHorizontalTest() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests FinishWithGrassDirectRule + *

Tent at (1, 1) + * XXX x + * GTG 1 + * XXX x + * xxx + *

Makes (0, 1) and (2, 1) GRASS + * Checks if the rule detects the middle row to be filled in correctly + */ + @Test + public void FinishWithGrassHorizontalTest() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/FinishWithGrassDirectRule/CornerTent", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); @@ -74,14 +78,18 @@ public void FinishWithGrassHorizontalTest() throws InvalidFileFormatException { } } - /** - * 3x3 TreeTent puzzle with a tent at (0,0) Tests FinishWithGrassDirectRule on GRASS tiles - * vertical of the tent at (0,1) and (0,2) - * - * @throws InvalidFileFormatException - */ - @Test - public void FinishWithGrassVerticalTest() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests FinishWithGrassDirectRule + *

Tent at (0, 0) + * TXX x + * GXX x + * GXX x + * 1xx + *

Makes (0, 1) and (0, 2) GRASS + * Checks if the rule detects the leftmost column to be filled in correctly + */ + @Test + public void FinishWithGrassVerticalTest() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/FinishWithGrassDirectRule/CornerTent", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); @@ -121,10 +129,14 @@ public void FinishWithGrassVerticalTest() throws InvalidFileFormatException { } /** - * 3x3 TreeTent puzzle with a tent at (0,0) Tests FinishWithGrassDirectRule on GRASS tiles at - * (1,0), (2,0), (0,1), and (0,2) - * - * @throws InvalidFileFormatException + * 3x3 TreeTent puzzle Tests FinishWithGrassDirectRule + *

Tent at (0, 0) + * TGG 1 + * GXX x + * GXX x + * 1xx + *

Makes (0, 1), (0, 2), (1, 0), and (2, 0) GRASS + * Checks if the rule detects the top row and leftmost column to be filled in correctly */ @Test public void FinishWithGrassTest() throws InvalidFileFormatException { @@ -174,14 +186,18 @@ public void FinishWithGrassTest() throws InvalidFileFormatException { } } - /** - * 3x3 TreeTent puzzle with no tents Tests FinishWithGrassDirectRule on GRASS tiles GRASS tiles - * fill entire board - * - * @throws InvalidFileFormatException - */ - @Test - public void NoTentTest() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests FinishWithGrassDirectRule + *

Empty + * GGG 0 + * GGG 0 + * GGG 0 + * 000 + *

Fill Board with GRASS + * Checks if the rule allows all cells to be filled when the clue for all rows and columns is zero. + */ + @Test + public void NoTentTest() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/FinishWithGrassDirectRule/NoTent", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); @@ -215,14 +231,18 @@ public void NoTentTest() throws InvalidFileFormatException { } } - /** - * 3x3 TreeTent puzzle with a tent at (1,1) Tests FinishWithGrassDirectRule on GRASS tiles - * surrounding the tent at (1,0), (0,1), (2,1), and (1,2) - * - * @throws InvalidFileFormatException - */ - @Test - public void MiddleTentTest() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests FinishWithGrassDirectRule + *

Tent at (1, 1) + * XGX x + * GTG 1 + * XGX x + * x1x + *

Makes (1, 0), (0, 1), (2, 1), and (1, 2) GRASS + * Checks if the rule correctly allows the central row and column to be filled with grass. + */ + @Test + public void MiddleTentTest() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/FinishWithGrassDirectRule/MiddleTent", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); @@ -270,14 +290,18 @@ public void MiddleTentTest() throws InvalidFileFormatException { } } - /** - * 3x3 TreeTent puzzle with missing tents Tests FinishWithGrassDirectRule on GRASS tiles filling - * the puzzle all GRASS tiles should fail the FinishWithGrassDirectRule - * - * @throws InvalidFileFormatException - */ - @Test - public void FailTentTest() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests FinishWithGrassDirectRule + *

Empty + * GGG 1 + * GGG 1 + * GGG 1 + * 111 + *

Fill Board with GRASS + * Checks if the rule is not valid when a row or column does not have the required number of tents but is filled with grass + */ + @Test + public void FailTentTest() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/FinishWithGrassDirectRule/FailTent", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); @@ -311,14 +335,22 @@ public void FailTentTest() throws InvalidFileFormatException { } } - /** - * 7x7 TreeTent puzzle with multiple tents spaced out Tests FinishWithGrassDirectRule on GRASS - * tiles between the tents at (0,3), (2,3), (4,3), and (6,3) - * - * @throws InvalidFileFormatException - */ - @Test - public void SpacedOutTentTest() throws InvalidFileFormatException { + /** + * 7x7 TreeTent puzzle Tests FinishWithGrassDirectRule + *

Tents at (1, 3), (3, 3), and (5, 3) + * XXXXXXX x + * XXXXXXX x + * XXXXXXX x + * TGTGTGT 4 + * XXXXXXX x + * XXXXXXX x + * XXXXXXX x + * xxxxxxx + *

Makes (0, 3), (2, 3), (4, 3), and (6, 3) GRASS + * Checks if applying the rule on row 3 is valid + */ + @Test + public void SpacedOutTentTest() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/FinishWithGrassDirectRule/SpacedOutTent", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); diff --git a/src/test/java/puzzles/treetent/rules/FinishWithTentsDirectRuleTest.java b/src/test/java/puzzles/treetent/rules/FinishWithTentsDirectRuleTest.java index 652af615f..d82be3f87 100644 --- a/src/test/java/puzzles/treetent/rules/FinishWithTentsDirectRuleTest.java +++ b/src/test/java/puzzles/treetent/rules/FinishWithTentsDirectRuleTest.java @@ -27,14 +27,18 @@ public static void setUp() { treetent = new TreeTent(); } - /** - * 3x3 TreeTent puzzle with a GRASS tile at (0,0) Tests FinishWithTentsDirectRule on TENT tiles - * horizontal of the GRASS tile at (1,0) and (2,0) - * - * @throws InvalidFileFormatException - */ - @Test - public void FinishWithHorizontalTentsTest() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests FinishWithTentsDirectRule + *

Grass at (0, 0) + * GTT 2 + * XXX x + * XXX x + * xxx + *

Makes (1, 0) and (2, 0) TENT + * Checks that the rule correctly fills in the first row + */ + @Test + public void FinishWithHorizontalTentsTest() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/FinishWithTentsDirectRule/FinishWithHorizontalTents", treetent); @@ -67,14 +71,18 @@ public void FinishWithHorizontalTentsTest() throws InvalidFileFormatException { } } - /** - * 3x3 TreeTent puzzle with a GRASS tile at (0,0) Tests FinishWithTentsDirectRule on TENT tiles - * vertical of the GRASS tile at (0,1) and (0,2) - * - * @throws InvalidFileFormatException - */ - @Test - public void FinishWithVerticalTentsTest() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests FinishWithTentsDirectRule + *

Grass at (0, 0) + * GXX x + * TXX x + * TXX x + * 2xx + *

Makes (0, 1) and (0, 2) TENT + * Checks that the rule correctly fills in the first column + */ + @Test + public void FinishWithVerticalTentsTest() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/FinishWithTentsDirectRule/FinishWithVerticalTents", treetent); @@ -107,14 +115,18 @@ public void FinishWithVerticalTentsTest() throws InvalidFileFormatException { } } - /** - * 3x3 TreeTent puzzle with a GRASS tile at (1,1) Tests FinishWithTentsDirectRule on TENT tiles - * around the GRASS tile at (1,0), (1,2), (0,1), and (2,1) - * - * @throws InvalidFileFormatException - */ - @Test - public void FinishWithTentsTest() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests FinishWithTentsDirectRule + *

Grass at (0, 0) + * GTT 2 + * TXX x + * TXX x + * 2xx + *

Makes (1, 0), (2, 0), (0, 1) and (0, 2) TENT + * Checks that the rule correctly fills both the first row and first column + */ + @Test + public void FinishWithTentsTest() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/FinishWithTentsDirectRule/FinishWithTents", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); @@ -155,14 +167,18 @@ public void FinishWithTentsTest() throws InvalidFileFormatException { } } - /** - * 3x3 TreeTent puzzle with a TENT tile at (1,1) Tests FinishWithTentsDirectRule on TENT tiles - * around the TENT tile at (1,0), (1,2), (0,1), and (2,1) - * - * @throws InvalidFileFormatException - */ - @Test - public void AdditionalTentsTest() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests FinishWithTentsDirectRule + *

Tent at (1, 1) + * XTX x + * TTT 3 + * XTX x + * x3x + *

Makes (1, 0), (0, 1), (2, 1), and (1, 2) TENT + * Checks that the rule correctly fills in the middle row and column when a tent starts at (1, 1) + */ + @Test + public void AdditionalTentsTest() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/FinishWithTentsDirectRule/AdditionalTents", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); @@ -203,14 +219,18 @@ public void AdditionalTentsTest() throws InvalidFileFormatException { } } - /** - * Empty 3x3 TreeTent puzzle Tests FinishWithTentsDirectRule on TENT tiles of entire puzzle all - * TENT tiles should fail FinishWithTentsDirectRule as no TENT tiles should be there - * - * @throws InvalidFileFormatException - */ - @Test - public void FinishWithTentsFailTest() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests FinishWithTentsDirectRule + *

Empty + * TTT 0 + * TTT 0 + * TTT 0 + * 000 + *

Fills the board with tents + * Checks that the rule does not allow for more tents in any of the rows or columns + */ + @Test + public void FinishWithTentsFailTest() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/FinishWithTentsDirectRule/FinishWithTentsFail", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); @@ -239,15 +259,18 @@ public void FinishWithTentsFailTest() throws InvalidFileFormatException { } } - /** - * 3x3 TreeTent puzzle with a TENT tile at (1,1) Tests FinishWithTentsDirectRule on TENT tiles - * around the TENT tile at (1,0), (1,2), (0,1), and (2,1) all TENT tiles should fail - * FinishWithTentsDirectRule as there were already sufficient number of TENT tiles - * - * @throws InvalidFileFormatException - */ - @Test - public void TooManyTentsTest() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests FinishWithTentsDirectRule + *

Tent at (1, 1) + * XTX x + * TTT 1 + * XTX x + * x1x + *

Makes (1, 0), (0, 1), (2, 1) and (1, 2) Tent + * Checks that the rule does not allow for more tents in the central row or central column + */ + @Test + public void TooManyTentsTest() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/FinishWithTentsDirectRule/TooManyTents", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); @@ -279,16 +302,18 @@ public void TooManyTentsTest() throws InvalidFileFormatException { } } - /** - * 3x3 TreeTent puzzle with a TENT tile at (1,1) Tests FinishWithTentsDirectRule on TENT tiles - * around the TENT tile at (1,0), (1,2), (0,1), and (2,1) all TENT tiles should fail - * FinishWithTentsDirectRule as there are multiple configurations of the placement of the TENT - * tiles - * - * @throws InvalidFileFormatException - */ - @Test - public void AmbiguousTentsTest() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests FinishWithTentsDirectRule + *

Tent at (1, 1) + * XTX x + * TTT 2 + * XTX x + * x2x + *

Makes (1, 0), (0, 1), (2, 1) and (1, 2) Tent + * Checks that the rule is not satisfied because there are multiple configurations of tents for the central row and central column + */ + @Test + public void AmbiguousTentsTest() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/FinishWithTentsDirectRule/AmbiguousTents", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); diff --git a/src/test/java/puzzles/treetent/rules/LastCampingSpotDirectRuleTest.java b/src/test/java/puzzles/treetent/rules/LastCampingSpotDirectRuleTest.java index 92d6e4a59..ad4559922 100644 --- a/src/test/java/puzzles/treetent/rules/LastCampingSpotDirectRuleTest.java +++ b/src/test/java/puzzles/treetent/rules/LastCampingSpotDirectRuleTest.java @@ -26,13 +26,17 @@ public static void setUp() { treetent = new TreeTent(); } - /** - * @throws InvalidFileFormatException - *

Checks if a test works for an empty square above a tree which is surrounded on all - * other sides. - */ - @Test - public void EmptyFieldTest_Up() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests LastCampingSpotDirectRule + *

TREE at (1, 1) and (0, 1); GRASS at (1, 2) and (2, 1) + * XTX + * RRG + * XGX + *

Makes (1, 0) TENT + * Checks that a tent must be placed above the central tree + */ + @Test + public void EmptyFieldTest_Up() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/LastCampingSpotDirectRule/LastCampingSpotUp", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); @@ -60,13 +64,17 @@ public void EmptyFieldTest_Up() throws InvalidFileFormatException { } } - /** - * @throws InvalidFileFormatException - *

Checks if a test works for an empty square below a tree which is surrounded on all - * other sides. - */ - @Test - public void EmptyFieldTest_Down() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests LastCampingSpotDirectRule + *

TREE at (1, 1) and (0, 1); GRASS at (1, 0) and (1, 2) + * XGX + * RRG + * XTX + *

Makes (1, 2) TENT + * Checks that a tent must be placed below the central tree + */ + @Test + public void EmptyFieldTest_Down() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/LastCampingSpotDirectRule/LastCampingSpotDown", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); @@ -94,13 +102,17 @@ public void EmptyFieldTest_Down() throws InvalidFileFormatException { } } - /** - * @throws InvalidFileFormatException - *

Checks if a test works for an empty square to the left of a tree which is surrounded - * on all other sides. - */ - @Test - public void EmptyFieldTest_Left() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests LastCampingSpotDirectRule + *

TREE at (1, 1) and (2, 1); GRASS at (1, 0) and (1, 2) + * XGX + * TRR + * XGX + *

Makes (0, 1) TENT + * Checks that a tent must be placed on the left of the central tree + */ + @Test + public void EmptyFieldTest_Left() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/LastCampingSpotDirectRule/LastCampingSpotLeft", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); @@ -128,13 +140,17 @@ public void EmptyFieldTest_Left() throws InvalidFileFormatException { } } - /** - * @throws InvalidFileFormatException - *

Checks if a test works for an empty square to the right of a tree which is surrounded - * on all other sides. - */ - @Test - public void EmptyFieldTest_Right() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests LastCampingSpotDirectRule + *

TREE at (1, 1) and (1, 2); GRASS at (0, 1) and (1, 0) + * XGX + * GRT + * XRX + *

Makes (2, 1) TENT + * Checks that a tent must be placed to the right of the central tree + */ + @Test + public void EmptyFieldTest_Right() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/LastCampingSpotDirectRule/LastCampingSpotRight", treetent); TreeNode rootNode = treetent.getTree().getRootNode(); diff --git a/src/test/java/puzzles/treetent/rules/LinkTentCaseRuleTest.java b/src/test/java/puzzles/treetent/rules/LinkTentCaseRuleTest.java new file mode 100644 index 000000000..3ed1fd79e --- /dev/null +++ b/src/test/java/puzzles/treetent/rules/LinkTentCaseRuleTest.java @@ -0,0 +1,191 @@ +package puzzles.treetent.rules; + +import edu.rpi.legup.model.gameboard.Board; +import edu.rpi.legup.model.tree.Tree; +import edu.rpi.legup.model.tree.TreeNode; +import edu.rpi.legup.model.tree.TreeTransition; +import edu.rpi.legup.puzzle.treetent.*; +import edu.rpi.legup.puzzle.treetent.rules.LinkTentCaseRule; +import edu.rpi.legup.save.InvalidFileFormatException; +import legup.MockGameBoardFacade; +import legup.TestUtilities; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.LinkedList; + +public class LinkTentCaseRuleTest { + private static final LinkTentCaseRule RULE = new LinkTentCaseRule(); + private static TreeTent treetent; + + @BeforeClass + public static void setUp() { + MockGameBoardFacade.getInstance(); + treetent = new TreeTent(); + } + + /** + * empty 3x3 TreeTent puzzle Tests LinkTentCaseRule on a central tent + * with one tree surrounding it. + * + *

checks that 1 cases is with the line connecting the central tent and the tree + * + * @throws InvalidFileFormatException + */ + @Test + public void LinkTentOneTreeTest() throws InvalidFileFormatException { + TestUtilities.importTestBoard( + "puzzles/treetent/rules/LinkTentCaseRule/OneTreeOneTent", treetent); + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + TreeTentCell test_location = board.getCell(1, 1); + ArrayList cases = RULE.getCases(board, test_location); + + // assert that one cases was found + Assert.assertEquals(1, cases.size()); + TreeTentBoard testCase = (TreeTentBoard) cases.getFirst(); + + TreeTentLine expectedLine = new TreeTentLine(board.getCell(1, 1), board.getCell(1, 0)); + + ArrayList lines = testCase.getLines(); + + // One line connecting the tree to the tent + Assert.assertEquals(1, lines.size()); + TreeTentLine line = lines.getFirst(); + + // Expected line + Assert.assertTrue(line.compare(expectedLine)); + + // checks other cells have not been modified + TreeTentCell original_cell; + TreeTentCell case_cell; + + for (int w = 0; w < board.getWidth(); w++) { + for (int h = 0; h < board.getHeight(); h++) { + original_cell = board.getCell(w, h); + case_cell = testCase.getCell(w, h); + Assert.assertEquals(original_cell.getType(), case_cell.getType()); + } + } + } + + /** + * empty 3x3 TreeTent puzzle Tests LinkTentCaseRule on a central tent + * with four trees surrounding it. + * + *

checks that 4 cases are created, each of which create a line + * connecting the tent to one of the four trees without repeat. + * + * @throws InvalidFileFormatException + */ + @Test + public void LinkTentFourTreesTest() throws InvalidFileFormatException { + TestUtilities.importTestBoard( + "puzzles/treetent/rules/LinkTentCaseRule/FourTreesOneTent", treetent); + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + TreeTentCell test_location = board.getCell(1, 1); + ArrayList cases = RULE.getCases(board, test_location); + + // assert that four cases were found + Assert.assertEquals(4, cases.size()); + + ArrayList expectedLines = new ArrayList<>(); + expectedLines.addFirst(new TreeTentLine(board.getCell(1, 1), board.getCell(1, 0))); + expectedLines.addFirst(new TreeTentLine(board.getCell(1, 1), board.getCell(0, 1))); + expectedLines.addFirst(new TreeTentLine(board.getCell(1, 1), board.getCell(2, 1))); + expectedLines.addFirst(new TreeTentLine(board.getCell(1, 1), board.getCell(1, 2))); + + for (Board testCaseBoard : cases) { + TreeTentBoard testCase = (TreeTentBoard) testCaseBoard ; + ArrayList lines = testCase.getLines(); + + // Each case should connect one line from the tent to + // one of the four trees next to it + Assert.assertEquals(1, lines.size()); + TreeTentLine line = lines.getFirst(); + + // Check to make sure that cases do not repeat + // and cover all four possibilities + boolean exists = false; + for (TreeTentLine expectedLine : expectedLines) { + if (line.compare(expectedLine)) { + expectedLines.remove(expectedLine); + exists = true; + break; + } + } + + Assert.assertTrue(exists); + + // checks other cells have not been modified + TreeTentCell original_cell; + TreeTentCell case_cell; + + for (int w = 0; w < board.getWidth(); w++) { + for (int h = 0; h < board.getHeight(); h++) { + original_cell = board.getCell(w, h); + case_cell = testCase.getCell(w, h); + Assert.assertEquals(original_cell.getType(), case_cell.getType()); + } + } + } + } + + /** + * empty 3x3 TreeTent puzzle Tests LinkTentCaseRule on a central tent + * with zero trees around it. + * + *

Ensures no cases are created + * + * @throws InvalidFileFormatException + */ + @Test + public void LinkTentNoTreesTest() throws InvalidFileFormatException { + TestUtilities.importTestBoard( + "puzzles/treetent/rules/LinkTentCaseRule/NoTrees", treetent); + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + TreeTentCell test_location = board.getCell(1, 1); + ArrayList cases = RULE.getCases(board, test_location); + + // assert that no cases were found + Assert.assertEquals(0, cases.size()); + } + + /** + * empty 3x3 TreeTent puzzle Tests LinkTentCaseRule on a central tent + * with trees on a diagonal. + * + *

Ensures no cases are created + * + * @throws InvalidFileFormatException + */ + @Test + public void LinkTentDiagTreesTest() throws InvalidFileFormatException { + TestUtilities.importTestBoard( + "puzzles/treetent/rules/LinkTentCaseRule/DiagTrees", treetent); + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + TreeTentCell test_location = board.getCell(1, 1); + ArrayList cases = RULE.getCases(board, test_location); + + // assert that no cases were found + Assert.assertEquals(0, cases.size()); + } +} diff --git a/src/test/java/puzzles/treetent/rules/LinkTreeCaseRuleTest.java b/src/test/java/puzzles/treetent/rules/LinkTreeCaseRuleTest.java new file mode 100644 index 000000000..fffde14b1 --- /dev/null +++ b/src/test/java/puzzles/treetent/rules/LinkTreeCaseRuleTest.java @@ -0,0 +1,192 @@ +package puzzles.treetent.rules; + +import com.sun.source.doctree.LinkTree; +import edu.rpi.legup.model.gameboard.Board; +import edu.rpi.legup.model.tree.TreeNode; +import edu.rpi.legup.model.tree.TreeTransition; +import edu.rpi.legup.puzzle.treetent.TreeTent; +import edu.rpi.legup.puzzle.treetent.TreeTentBoard; +import edu.rpi.legup.puzzle.treetent.TreeTentCell; +import edu.rpi.legup.puzzle.treetent.TreeTentLine; +import edu.rpi.legup.puzzle.treetent.rules.LinkTreeCaseRule; +import edu.rpi.legup.save.InvalidFileFormatException; +import legup.MockGameBoardFacade; +import legup.TestUtilities; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.ArrayList; + +public class LinkTreeCaseRuleTest { + private static final LinkTreeCaseRule RULE = new LinkTreeCaseRule(); + private static TreeTent treetent; + + @BeforeClass + public static void setUp() { + MockGameBoardFacade.getInstance(); + treetent = new TreeTent(); + } + + /** + * empty 3x3 TreeTent puzzle Tests LinkTentCaseRule on a central tree + * with one tent above + * + *

Ensures one case is created that connects the tree to the tent. + * + * @throws InvalidFileFormatException + */ + @Test + public void LinkTentOneTentTest() throws InvalidFileFormatException { + TestUtilities.importTestBoard( + "puzzles/treetent/rules/LinkTreeCaseRule/OneTent", treetent); + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + TreeTentCell test_location = board.getCell(1, 1); + ArrayList cases = RULE.getCases(board, test_location); + + // assert that no cases were found + Assert.assertEquals(1, cases.size()); + TreeTentBoard testCase = (TreeTentBoard) cases.getFirst(); + + TreeTentLine expectedLine = new TreeTentLine(board.getCell(1, 1), board.getCell(1, 0)); + + ArrayList lines = testCase.getLines(); + + // One line connecting the tree to the tent + Assert.assertEquals(1, lines.size()); + TreeTentLine line = lines.getFirst(); + + // Expected line + Assert.assertTrue(line.compare(expectedLine)); + + // checks other cells have not been modified + TreeTentCell original_cell; + TreeTentCell case_cell; + + for (int w = 0; w < board.getWidth(); w++) { + for (int h = 0; h < board.getHeight(); h++) { + original_cell = board.getCell(w, h); + case_cell = testCase.getCell(w, h); + Assert.assertEquals(original_cell.getType(), case_cell.getType()); + } + } + } + + /** + * empty 3x3 TreeTent puzzle Tests LinkTentCaseRule on a central tree + * with two tents, one on the left and one on the right. + * + *

Ensures two cases are created, one connecting the tree and the + * left tent, and one connecting the tree and the right tent. + * Because tents must be surrounded by grass, there can be at most + * two tents around a given tree. + * + * @throws InvalidFileFormatException + */ + @Test + public void LinkTentTwoTentsTest() throws InvalidFileFormatException { + TestUtilities.importTestBoard( + "puzzles/treetent/rules/LinkTreeCaseRule/TwoTents", treetent); + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + TreeTentCell test_location = board.getCell(1, 1); + ArrayList cases = RULE.getCases(board, test_location); + + // assert that no cases were found + Assert.assertEquals(2, cases.size()); + + ArrayList expectedLines = new ArrayList<>(); + expectedLines.addFirst(new TreeTentLine(board.getCell(1, 1), board.getCell(0, 1))); + expectedLines.addFirst(new TreeTentLine(board.getCell(1, 1), board.getCell(2, 1))); + + for (Board testCaseBoard : cases) { + TreeTentBoard testCase = (TreeTentBoard) testCaseBoard ; + ArrayList lines = testCase.getLines(); + + // Each case should connect one line from the tent to + // either the left or right tree + Assert.assertEquals(1, lines.size()); + TreeTentLine line = lines.getFirst(); + + // Check to make sure that cases do not repeat + // and cover both possibilities + boolean exists = false; + for (TreeTentLine expectedLine : expectedLines) { + if (line.compare(expectedLine)) { + expectedLines.remove(expectedLine); + exists = true; + break; + } + } + + Assert.assertTrue(exists); + + // checks other cells have not been modified + TreeTentCell original_cell; + TreeTentCell case_cell; + + for (int w = 0; w < board.getWidth(); w++) { + for (int h = 0; h < board.getHeight(); h++) { + original_cell = board.getCell(w, h); + case_cell = testCase.getCell(w, h); + Assert.assertEquals(original_cell.getType(), case_cell.getType()); + } + } + } + } + + /** + * empty 3x3 TreeTent puzzle Tests LinkTentCaseRule on a central tree + * with zero tents around it. + * + *

Ensures no cases are created + * + * @throws InvalidFileFormatException + */ + @Test + public void LinkTentNoTreesTest() throws InvalidFileFormatException { + TestUtilities.importTestBoard( + "puzzles/treetent/rules/LinkTreeCaseRule/NoTents", treetent); + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + TreeTentCell test_location = board.getCell(1, 1); + ArrayList cases = RULE.getCases(board, test_location); + + // assert that no cases were found + Assert.assertEquals(0, cases.size()); + } + + /** + * empty 3x3 TreeTent puzzle Tests LinkTentCaseRule on a central tree + * with tents on a diagonal. + * + *

Ensures no cases are created + * + * @throws InvalidFileFormatException + */ + @Test + public void LinkTentDiagTentsTest() throws InvalidFileFormatException { + TestUtilities.importTestBoard( + "puzzles/treetent/rules/LinkTreeCaseRule/NoTents", treetent); + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + TreeTentCell test_location = board.getCell(1, 1); + ArrayList cases = RULE.getCases(board, test_location); + + // assert that no cases were found + Assert.assertEquals(0, cases.size()); + } +} diff --git a/src/test/java/puzzles/treetent/rules/SurroundTentWithGrassDirectRuleTest.java b/src/test/java/puzzles/treetent/rules/SurroundTentWithGrassDirectRuleTest.java index 7ff57a052..6177bb64c 100644 --- a/src/test/java/puzzles/treetent/rules/SurroundTentWithGrassDirectRuleTest.java +++ b/src/test/java/puzzles/treetent/rules/SurroundTentWithGrassDirectRuleTest.java @@ -27,12 +27,17 @@ public static void setUp() { treetent = new TreeTent(); } - /** - * @throws InvalidFileFormatException Test to check if all adjacent and diagonals not filled - * with a tree are filled with grass - */ - @Test - public void SurroundTentWithGrassBasicRuleTest() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests SurroundTentWithGrassDirectRule + *

TREE at (0, 0), (2, 0), (0, 1), (2, 1), (1, 2), and (2, 2); TENT at (1, 1) + * RGR + * RTR + * GRR + *

Makes (1, 0) and (0, 2) GRASS + * Checks that the rule detects unknown adjacent and diagonal tiles correctly + */ + @Test + public void SurroundTentWithGrassBasicRuleTest() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/SurroundTentWithGrassDirectRule/SurroundTentWithGrass", treetent); @@ -64,14 +69,17 @@ public void SurroundTentWithGrassBasicRuleTest() throws InvalidFileFormatExcepti } } - /** - * @throws InvalidFileFormatException - *

Test with a 3x3 board with an absolutely empty area aside from a tent in the middle - * While such a situation is an illegal treetent setup, this direct rule doesn't consider - * that aspect, so its ok in this context - */ - @Test - public void SurroundTentWithGrassBasicRuleTest_BadBoard() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests SurroundTentWithGrassDirectRule + *

TENT at (1, 1) + * GGG + * GTG + * GGG + *

Makes all cells adjacent and diagonal to the tent GRASS + * Checks that the rule detects all adjacent and diagonal tiles correctly + */ + @Test + public void SurroundTentWithGrassBasicRuleTest_BadBoard() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/SurroundTentWithGrassDirectRule/SurroundTentWithGrassBad", treetent); @@ -129,13 +137,17 @@ public void SurroundTentWithGrassBasicRuleTest_BadBoard() throws InvalidFileForm } } - /** - * @throws InvalidFileFormatException - *

Test to see if the rule passes even if no grass was able to be placed due to the - * presence of trees. - */ - @Test - public void SurroundTentWithGrassBasicRuleTest_FullBoard() throws InvalidFileFormatException { + /** + * 3x3 TreeTent puzzle Tests SurroundTentWithGrassDirectRule + *

TENT at (1, 1); TREE on all adjacent and diagonal tiles + * RRR + * RTR + * RRR + *

Null + * Checks that the rule correctly detects no missing tiles + */ + @Test + public void SurroundTentWithGrassBasicRuleTest_FullBoard() throws InvalidFileFormatException { TestUtilities.importTestBoard( "puzzles/treetent/rules/SurroundTentWithGrassDirectRule/SurroundTentWithGrassTrees", treetent); diff --git a/src/test/java/puzzles/treetent/rules/TentForTreeDirectRuleTest.java b/src/test/java/puzzles/treetent/rules/TentForTreeDirectRuleTest.java index 68dbeaf48..e55704ec2 100644 --- a/src/test/java/puzzles/treetent/rules/TentForTreeDirectRuleTest.java +++ b/src/test/java/puzzles/treetent/rules/TentForTreeDirectRuleTest.java @@ -1,14 +1,167 @@ package puzzles.treetent.rules; -// This feature is no longer supported +import edu.rpi.legup.model.tree.TreeNode; +import edu.rpi.legup.model.tree.TreeTransition; +import edu.rpi.legup.puzzle.treetent.*; +import edu.rpi.legup.puzzle.treetent.rules.TentForTreeDirectRule; +import edu.rpi.legup.save.InvalidFileFormatException; +import legup.MockGameBoardFacade; +import legup.TestUtilities; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.ArrayList; + public class TentForTreeDirectRuleTest { - // private static final TentForTreeBasicRule RULE = new TentForTreeBasicRule(); - // private static TreeTent treetent; - // - // @BeforeClass - // public static void setUp() { - // MockGameBoardFacade.getInstance(); - // treetent = new TreeTent(); - // } + private static final TentForTreeDirectRule RULE = new TentForTreeDirectRule(); + private static TreeTent treetent; + + @BeforeClass + public static void setUp() { + MockGameBoardFacade.getInstance(); + treetent = new TreeTent(); + } + + /** + * 3x3 TreeTent puzzle Tests TentForTreeDirectRule + *

TREE at (1, 0); TENT at (1, 1) + * XRX + * XTX + * XXX + *

Makes a line between (1, 0) and (1, 1) + * Checks that the rule correctly detects the central tent as the only possible connection + */ + @Test + public void TentForTreeTestOneTreeOneTentTest() throws InvalidFileFormatException { + + TestUtilities.importTestBoard( + "puzzles/treetent/rules/TentForTreeDirectRule/OneTreeOneTent", + treetent); + + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + + TreeTentCell cell1 = board.getCell(1, 0); + TreeTentCell cell2 = board.getCell(1, 1); + TreeTentLine line = new TreeTentLine(cell1, cell2); + + board.addModifiedData(line); + board.getLines().add(line); + + Assert.assertNull(RULE.checkRule(transition)); + + ArrayList lines = board.getLines(); + for (TreeTentLine l : lines) { + if (l.compare((line))) { + Assert.assertNull(RULE.checkRuleAt(transition, l)); + } else { + Assert.assertNotNull(RULE.checkRuleAt(transition, l)); + } + } + } + + /** + * 3x3 TreeTent puzzle Tests TentForTreeDirectRule + *

TREE at (1, 0) and (1, 2); TENT at (1, 1) + * XRX + * XTX + * XRX + *

Makes a line between (1, 0) and (1, 1) + * Checks that the rule works when connecting a line between the tree at (1, 0) and tent at (1, 1) + */ + @Test + public void TentForTreeArbitraryTreeTest() throws InvalidFileFormatException { + + TestUtilities.importTestBoard( + "puzzles/treetent/rules/TentForTreeDirectRule/ArbitraryTree", + treetent); + + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + + TreeTentCell cell1 = board.getCell(1, 0); + TreeTentCell cell2 = board.getCell(1, 1); + TreeTentLine line = new TreeTentLine(cell1, cell2); + + board.addModifiedData(line); + board.getLines().add(line); + + Assert.assertNull(RULE.checkRule(transition)); + } + + /** + * 3x3 TreeTent puzzle Tests TentForTreeDirectRule + *

TREE at (1, 0) and (1, 2); TENT at (1, 1); LINE between (1, 0) and (1, 1) + * XRX + * XTX + * XRX + *

Makes a line between (1, 1) and (1, 2) + * Checks that the rule fails for the tree at (1, 2) because there are no valid tents to connect to + */ + @Test + public void TentForTreeConnectedTent() throws InvalidFileFormatException { + + TestUtilities.importTestBoard( + "puzzles/treetent/rules/TentForTreeDirectRule/ArbitraryTree", + treetent); + + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + + TreeTentCell cell1 = board.getCell(1, 2); + TreeTentCell cell2 = board.getCell(1, 1); + TreeTentLine line = new TreeTentLine(cell1, cell2); + + board.addModifiedData(line); + board.getLines().add(line); + + Assert.assertNull(RULE.checkRule(transition)); + + ArrayList lines = board.getLines(); + for (TreeTentLine l : lines) { + Assert.assertNotNull(RULE.checkRuleAt(transition, l)); + } + } + + /** + * 3x3 TreeTent puzzle Tests TentForTreeDirectRule + *

TREE at (1, 1); TENT at (1, 0) and (1, 2) + * XTX + * XRX + * XTX + *

Makes a line between (1, 1) and (1, 2) + * Checks that the rule fails for the tree at (1, 1) because there are two valid tents to connect to + */ + @Test + public void TentForTreeOneTreeTwoAdjacentTent() throws InvalidFileFormatException { + TestUtilities.importTestBoard( + "puzzles/treetent/rules/TentForTreeDirectRule/OneTreeTwoAdjacentTent", + treetent); + + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + + TreeTentCell cell1 = board.getCell(1, 2); + TreeTentCell cell2 = board.getCell(1, 1); + TreeTentLine line = new TreeTentLine(cell1, cell2); + + board.addModifiedData(line); + board.getLines().add(line); + + Assert.assertNotNull(RULE.checkRule(transition)); + } } diff --git a/src/test/java/puzzles/treetent/rules/TooManyTentsContradictionRuleTest.java b/src/test/java/puzzles/treetent/rules/TooManyTentsContradictionRuleTest.java index 2e542b3d2..c1dc6380a 100644 --- a/src/test/java/puzzles/treetent/rules/TooManyTentsContradictionRuleTest.java +++ b/src/test/java/puzzles/treetent/rules/TooManyTentsContradictionRuleTest.java @@ -29,7 +29,7 @@ public static void setUp() { TESTING BASIS: All test in this Rule use a 3x3 table. There is a Tree at (1,1) - There are tents at (0,1) and (2,2) + There are tents at (1,0) and (2,2) All Tent Counts are listed left to right or top to bottom */ diff --git a/src/test/java/puzzles/treetent/rules/TouchingTentsContradictionRuleTest.java b/src/test/java/puzzles/treetent/rules/TouchingTentsContradictionRuleTest.java index 9f5455a92..e44543ab6 100644 --- a/src/test/java/puzzles/treetent/rules/TouchingTentsContradictionRuleTest.java +++ b/src/test/java/puzzles/treetent/rules/TouchingTentsContradictionRuleTest.java @@ -135,90 +135,6 @@ public void TouchingTentsContradictionRule_2By2Square() throws InvalidFileFormat Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(1, 1))); } - /** - * @throws InvalidFileFormatException Tests a tent of orientation TT T - */ - @Test - public void TouchingTentsContradictionRule_UpLeft() throws InvalidFileFormatException { - TestUtilities.importTestBoard( - "puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedUpLeft", - treetent); - TreeNode rootNode = treetent.getTree().getRootNode(); - TreeTransition transition = rootNode.getChildren().get(0); - transition.setRule(RULE); - - TreeTentBoard board = (TreeTentBoard) transition.getBoard(); - - Assert.assertNull(RULE.checkContradiction(board)); - Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(0, 0))); - Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(0, 1))); - Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(1, 0))); - Assert.assertNotNull(RULE.checkRuleAt(transition, board.getCell(1, 1))); - } - - /** - * @throws InvalidFileFormatException Tests a tent of orientation TT T - */ - @Test - public void TouchingTentsContradictionRule_UpRight() throws InvalidFileFormatException { - TestUtilities.importTestBoard( - "puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedUpRight", - treetent); - TreeNode rootNode = treetent.getTree().getRootNode(); - TreeTransition transition = rootNode.getChildren().get(0); - transition.setRule(RULE); - - TreeTentBoard board = (TreeTentBoard) transition.getBoard(); - - Assert.assertNull(RULE.checkContradiction(board)); - Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(0, 0))); - Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(0, 1))); - Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(1, 1))); - Assert.assertNotNull(RULE.checkRuleAt(transition, board.getCell(1, 0))); - } - - /** - * @throws InvalidFileFormatException Tests a tent of orientation T TT - */ - @Test - public void TouchingTentsContradictionRule_DownLeft() throws InvalidFileFormatException { - TestUtilities.importTestBoard( - "puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedDownLeft", - treetent); - TreeNode rootNode = treetent.getTree().getRootNode(); - TreeTransition transition = rootNode.getChildren().get(0); - transition.setRule(RULE); - - TreeTentBoard board = (TreeTentBoard) transition.getBoard(); - - Assert.assertNull(RULE.checkContradiction(board)); - Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(0, 0))); - Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(1, 0))); - Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(1, 1))); - Assert.assertNotNull(RULE.checkRuleAt(transition, board.getCell(0, 1))); - } - - /** - * @throws InvalidFileFormatException Tests a tent of orientation T TT - */ - @Test - public void TouchingTentsContradictionRule_DownRight() throws InvalidFileFormatException { - TestUtilities.importTestBoard( - "puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedDownRight", - treetent); - TreeNode rootNode = treetent.getTree().getRootNode(); - TreeTransition transition = rootNode.getChildren().get(0); - transition.setRule(RULE); - - TreeTentBoard board = (TreeTentBoard) transition.getBoard(); - - Assert.assertNull(RULE.checkContradiction(board)); - Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(0, 1))); - Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(1, 0))); - Assert.assertNull(RULE.checkRuleAt(transition, board.getCell(1, 1))); - Assert.assertNotNull(RULE.checkRuleAt(transition, board.getCell(0, 0))); - } - /** * @throws InvalidFileFormatException Tests if tree adjacent triggers a null */ @@ -254,6 +170,6 @@ public void TouchingTentsContradictionRule_TreeDiagonal() throws InvalidFileForm Assert.assertNotNull(RULE.checkContradiction(board)); Assert.assertNotNull(RULE.checkRuleAt(transition, board.getCell(0, 0))); - Assert.assertNotNull(RULE.checkRuleAt(transition, board.getCell(1, 0))); + Assert.assertNotNull(RULE.checkRuleAt(transition, board.getCell(1, 1))); } } diff --git a/src/test/java/puzzles/treetent/rules/TreeForTentDirectRuleTest.java b/src/test/java/puzzles/treetent/rules/TreeForTentDirectRuleTest.java index f4ea6703b..ba1b49b8c 100644 --- a/src/test/java/puzzles/treetent/rules/TreeForTentDirectRuleTest.java +++ b/src/test/java/puzzles/treetent/rules/TreeForTentDirectRuleTest.java @@ -1,14 +1,161 @@ package puzzles.treetent.rules; -// This feature is no longer supported +import edu.rpi.legup.model.tree.TreeNode; +import edu.rpi.legup.model.tree.TreeTransition; +import edu.rpi.legup.puzzle.treetent.TreeTent; +import edu.rpi.legup.puzzle.treetent.TreeTentBoard; +import edu.rpi.legup.puzzle.treetent.TreeTentCell; +import edu.rpi.legup.puzzle.treetent.TreeTentLine; +import edu.rpi.legup.puzzle.treetent.rules.TreeForTentDirectRule; +import edu.rpi.legup.save.InvalidFileFormatException; +import legup.MockGameBoardFacade; +import legup.TestUtilities; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.ArrayList; + public class TreeForTentDirectRuleTest { - // private static final TreeForTentBasicRule RULE = new TreeForTentBasicRule(); - // private static TreeTent treetent; + private static final TreeForTentDirectRule RULE = new TreeForTentDirectRule(); + private static TreeTent treetent; + + @BeforeClass + public static void setUp() { + MockGameBoardFacade.getInstance(); + treetent = new TreeTent(); + } + + /** + * 3x3 TreeTent puzzle Tests TreeForTentDirectRule + *

TENT at (1, 0); TREE at (1, 1) + * XTX + * XRX + * XXX + *

Makes a line between (1, 0) and (1, 1) + * Checks that the rule correctly detects the central tree as the only possible connection + */ + @Test + public void TreeForTentTestOneTreeOneTentTest() throws InvalidFileFormatException { + + TestUtilities.importTestBoard( + "puzzles/treetent/rules/TreeForTentDirectRule/OneTentOneTree", + treetent); + + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + + TreeTentCell cell1 = board.getCell(1, 0); + TreeTentCell cell2 = board.getCell(1, 1); + TreeTentLine line = new TreeTentLine(cell1, cell2); + + board.addModifiedData(line); + board.getLines().add(line); + + Assert.assertNull(RULE.checkRule(transition)); + } + + /** + * 3x3 TreeTent puzzle Tests TreeForTentDirectRule + *

TENT at (1, 0) and (1, 2); TREE at (1, 1) + * XTX + * XRX + * XTX + *

Makes a line between (1, 0) and (1, 1) + * Checks that the rule works when connecting a line between the tent at (1, 0) and the tree at (1, 1) + */ + @Test + public void TentForTreeWithArbitraryTreeTest() throws InvalidFileFormatException { + + TestUtilities.importTestBoard( + "puzzles/treetent/rules/TreeForTentDirectRule/ArbitraryTent", + treetent); + + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + + TreeTentCell cell1 = board.getCell(1, 0); + TreeTentCell cell2 = board.getCell(1, 1); + TreeTentLine line = new TreeTentLine(cell1, cell2); + + board.addModifiedData(line); + board.getLines().add(line); + + Assert.assertNull(RULE.checkRule(transition)); + } + + /** + * 3x3 TreeTent puzzle Tests TreeForTentDirectRule + *

TENT at (1, 0) and (1, 2); TREE at (1, 1); LINE between (1, 0) and (1, 1) + * XTX + * XRX + * XTX + *

Makes a line between (1, 1) and (1, 2) + * Checks that the rule fails for the tent at (1, 2) because there are no valid trees to connect to + */ + @Test + public void TentForTreeConnectedTent() throws InvalidFileFormatException { + + TestUtilities.importTestBoard( + "puzzles/treetent/rules/TreeForTentDirectRule/ConnectedTree", + treetent); + + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + + TreeTentCell cell1 = board.getCell(1, 2); + TreeTentCell cell2 = board.getCell(1, 1); + TreeTentLine line = new TreeTentLine(cell1, cell2); + + board.addModifiedData(line); + board.getLines().add(line); + + Assert.assertNull(RULE.checkRule(transition)); + + ArrayList lines = board.getLines(); + for (TreeTentLine l : lines) { + Assert.assertNotNull(RULE.checkRuleAt(transition, l)); + } + } + + /** + * 3x3 TreeTent puzzle Tests TreeForTentDirectRule + *

TENT at (1, 1); TREE at (1, 0) and (1, 2) + * XRX + * XTX + * XRX + *

Makes a line between (1, 1) and (1, 2) + * Checks that the rule fails for the tree at (1, 1) because there are two valid trees to connect to + */ + @Test + public void TentForTreeOneTreeTwoAdjacentTent() throws InvalidFileFormatException { + TestUtilities.importTestBoard( + "puzzles/treetent/rules/TreeForTentDirectRule/OneTentTwoAdjacentTrees", + treetent); + + TreeNode rootNode = treetent.getTree().getRootNode(); + TreeTransition transition = rootNode.getChildren().get(0); + transition.setRule(RULE); + + TreeTentBoard board = (TreeTentBoard) transition.getBoard(); + + TreeTentCell cell1 = board.getCell(1, 2); + TreeTentCell cell2 = board.getCell(1, 1); + TreeTentLine line = new TreeTentLine(cell1, cell2); + + board.addModifiedData(line); + board.getLines().add(line); - // @BeforeClass - // public static void setUp() { - // MockGameBoardFacade.getInstance(); - // treetent = new TreeTent(); - // } + Assert.assertNotNull(RULE.checkRule(transition)); + } } diff --git a/src/test/resources/puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailLeft b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3OneTent similarity index 78% rename from src/test/resources/puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailLeft rename to src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3OneTent index d19e01daf..1e1259a44 100644 --- a/src/test/resources/puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailLeft +++ b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3OneTent @@ -2,16 +2,15 @@ - - + - + diff --git a/src/test/resources/puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailRight b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3ThreeTent similarity index 78% rename from src/test/resources/puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailRight rename to src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3ThreeTent index bf3954964..7c352347d 100644 --- a/src/test/resources/puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailRight +++ b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3ThreeTent @@ -2,16 +2,15 @@ - - + - + diff --git a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedDownLeft b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3TwoTent similarity index 57% rename from src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedDownLeft rename to src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3TwoTent index af4ca0831..1f4a907eb 100644 --- a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedDownLeft +++ b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3TwoTent @@ -1,18 +1,17 @@ - + - - - - + + - + + diff --git a/src/test/resources/puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailBottom b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3ZeroTent similarity index 92% rename from src/test/resources/puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailBottom rename to src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3ZeroTent index 80deadaea..a13c7cc55 100644 --- a/src/test/resources/puzzles/treetent/rules/EmptyFieldDirectRule/EmptyFieldFailBottom +++ b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow3x3ZeroTent @@ -2,7 +2,6 @@ - diff --git a/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow5x5TwoTent b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow5x5TwoTent new file mode 100644 index 000000000..ddfcf44db --- /dev/null +++ b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/EmptyRow5x5TwoTent @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/PartialFillOneTent b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/PartialFillOneTent new file mode 100644 index 000000000..47d06d5b9 --- /dev/null +++ b/src/test/resources/puzzles/treetent/rules/FillinRowCaseRule/PartialFillOneTent @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/DiagTrees b/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/DiagTrees new file mode 100644 index 000000000..4a10b61f2 --- /dev/null +++ b/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/DiagTrees @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/FourTreesOneTent b/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/FourTreesOneTent new file mode 100644 index 000000000..96a06de3b --- /dev/null +++ b/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/FourTreesOneTent @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/NoTrees b/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/NoTrees new file mode 100644 index 000000000..c781cfde9 --- /dev/null +++ b/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/NoTrees @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/OneTreeOneTent b/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/OneTreeOneTent new file mode 100644 index 000000000..103c1ce3e --- /dev/null +++ b/src/test/resources/puzzles/treetent/rules/LinkTentCaseRule/OneTreeOneTent @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/DiagTents b/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/DiagTents new file mode 100644 index 000000000..e50bef8c1 --- /dev/null +++ b/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/DiagTents @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/NoTents b/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/NoTents new file mode 100644 index 000000000..3bab63f75 --- /dev/null +++ b/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/NoTents @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/OneTent b/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/OneTent new file mode 100644 index 000000000..69eb680de --- /dev/null +++ b/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/OneTent @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/TwoTents b/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/TwoTents new file mode 100644 index 000000000..7fb4b6e46 --- /dev/null +++ b/src/test/resources/puzzles/treetent/rules/LinkTreeCaseRule/TwoTents @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/ArbitraryTree b/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/ArbitraryTree new file mode 100644 index 000000000..258ebec21 --- /dev/null +++ b/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/ArbitraryTree @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/ConnectedTent b/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/ConnectedTent new file mode 100644 index 000000000..031bca068 --- /dev/null +++ b/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/ConnectedTent @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/OneTreeOneTent b/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/OneTreeOneTent new file mode 100644 index 000000000..dcc428c8b --- /dev/null +++ b/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/OneTreeOneTent @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/OneTreeTwoAdjacentTent b/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/OneTreeTwoAdjacentTent new file mode 100644 index 000000000..508cda0a8 --- /dev/null +++ b/src/test/resources/puzzles/treetent/rules/TentForTreeDirectRule/OneTreeTwoAdjacentTent @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedDownRight b/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedDownRight deleted file mode 100644 index 05b7a7667..000000000 --- a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedDownRight +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedUpLeft b/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedUpLeft deleted file mode 100644 index b8b81c7b4..000000000 --- a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedUpLeft +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedUpRight b/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedUpRight deleted file mode 100644 index af7fb5df2..000000000 --- a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsMixedUpRight +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsTreeDiagonal b/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsTreeDiagonal index b2f54aef3..b25eb6c4c 100644 --- a/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsTreeDiagonal +++ b/src/test/resources/puzzles/treetent/rules/TouchingTentsContradictionRule/TouchingTentsTreeDiagonal @@ -3,7 +3,7 @@ - + diff --git a/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/ArbitraryTent b/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/ArbitraryTent new file mode 100644 index 000000000..ce083cfc0 --- /dev/null +++ b/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/ArbitraryTent @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/ConnectedTree b/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/ConnectedTree new file mode 100644 index 000000000..6ebecc06f --- /dev/null +++ b/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/ConnectedTree @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/OneTentOneTree b/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/OneTentOneTree new file mode 100644 index 000000000..fabfe06e2 --- /dev/null +++ b/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/OneTentOneTree @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/OneTentTwoAdjacentTrees b/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/OneTentTwoAdjacentTrees new file mode 100644 index 000000000..8218fb2f1 --- /dev/null +++ b/src/test/resources/puzzles/treetent/rules/TreeForTentDirectRule/OneTentTwoAdjacentTrees @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file