From 7dcdfc097b031767aa3058851cdfe2b26187bc02 Mon Sep 17 00:00:00 2001 From: FisherLuba <145061313+FisherLuba@users.noreply.github.com> Date: Tue, 12 Mar 2024 16:41:12 -0400 Subject: [PATCH 1/3] Added BombOrFilledCaseRule --- .../puzzle/minesweeper/MinesweeperBoard.java | 17 ++++++ .../rules/BombOrFilledCaseRule.java | 57 ++++++++++++++++++- src/main/resources/edu/rpi/legup/legup/config | 4 ++ 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/rpi/legup/puzzle/minesweeper/MinesweeperBoard.java b/src/main/java/edu/rpi/legup/puzzle/minesweeper/MinesweeperBoard.java index 696d42113..ea6f560e1 100644 --- a/src/main/java/edu/rpi/legup/puzzle/minesweeper/MinesweeperBoard.java +++ b/src/main/java/edu/rpi/legup/puzzle/minesweeper/MinesweeperBoard.java @@ -16,4 +16,21 @@ public MinesweeperBoard(int size) { public MinesweeperCell getCell(int x, int y) { return (MinesweeperCell) super.getCell(x, y); } + + + /** + * Performs a deep copy of the Board + * + * @return a new copy of the board that is independent of this one + */ + @Override + public MinesweeperBoard copy() { + MinesweeperBoard newMinesweeperBoard = new MinesweeperBoard(this.dimension.width, this.dimension.height); + for (int x = 0; x < this.dimension.width; x++) { + for (int y = 0; y < this.dimension.height; y++) { + newMinesweeperBoard.setCell(x, y, getCell(x, y).copy()); + } + } + return newMinesweeperBoard; + } } diff --git a/src/main/java/edu/rpi/legup/puzzle/minesweeper/rules/BombOrFilledCaseRule.java b/src/main/java/edu/rpi/legup/puzzle/minesweeper/rules/BombOrFilledCaseRule.java index f7c42dc6f..bad89b4a4 100644 --- a/src/main/java/edu/rpi/legup/puzzle/minesweeper/rules/BombOrFilledCaseRule.java +++ b/src/main/java/edu/rpi/legup/puzzle/minesweeper/rules/BombOrFilledCaseRule.java @@ -5,7 +5,12 @@ 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.minesweeper.MinesweeperBoard; +import edu.rpi.legup.puzzle.minesweeper.MinesweeperCell; +import edu.rpi.legup.puzzle.minesweeper.MinesweeperTileData; +import edu.rpi.legup.puzzle.minesweeper.MinesweeperTileType; +import java.util.ArrayList; import java.util.List; public class BombOrFilledCaseRule extends CaseRule { @@ -18,16 +23,64 @@ public BombOrFilledCaseRule() { @Override public CaseBoard getCaseBoard(Board board) { - return null; + MinesweeperBoard minesweeperBoard = (MinesweeperBoard) board.copy(); + CaseBoard caseBoard = new CaseBoard(minesweeperBoard, this); + minesweeperBoard.setModifiable(false); + for (PuzzleElement data : minesweeperBoard.getPuzzleElements()) { + MinesweeperCell cell = (MinesweeperCell) data; + if (cell.getData().isUnset()) { + caseBoard.addPickableElement(data); + } + } + return caseBoard; } @Override public List getCases(Board board, PuzzleElement puzzleElement) { - return null; + ArrayList cases = new ArrayList<>(); + + Board case1 = board.copy(); + MinesweeperCell cell1 = (MinesweeperCell) case1.getPuzzleElement(puzzleElement); + cell1.setData(MinesweeperTileData.bomb()); + case1.addModifiedData(cell1); + cases.add(case1); + + Board case2 = board.copy(); + MinesweeperCell cell2 = (MinesweeperCell) case2.getPuzzleElement(puzzleElement); + cell2.setData(MinesweeperTileData.empty()); + case2.addModifiedData(cell2); + cases.add(case2); + return cases; } @Override public String checkRuleRaw(TreeTransition transition) { + List childTransitions = transition.getParents().get(0).getChildren(); + if (childTransitions.size() != 2) { + return super.getInvalidUseOfRuleMessage() + ": This case rule must have 2 children."; + } + + TreeTransition case1 = childTransitions.get(0); + TreeTransition case2 = childTransitions.get(1); + if (case1.getBoard().getModifiedData().size() != 1 + || case2.getBoard().getModifiedData().size() != 1) { + return super.getInvalidUseOfRuleMessage() + + ": This case rule must have 1 modified cell for each case."; + } + + MinesweeperCell mod1 = (MinesweeperCell) case1.getBoard().getModifiedData().iterator().next(); + MinesweeperCell mod2 = (MinesweeperCell) 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.getData().isBomb() && mod2.getData().isEmpty()) + || (mod2.getData().isBomb() && mod1.getData().isEmpty()))) { + return super.getInvalidUseOfRuleMessage() + + ": This case rule must an empty cell and a bomb cell."; + } + return null; } diff --git a/src/main/resources/edu/rpi/legup/legup/config b/src/main/resources/edu/rpi/legup/legup/config index ccd4f5be3..0bfc68914 100644 --- a/src/main/resources/edu/rpi/legup/legup/config +++ b/src/main/resources/edu/rpi/legup/legup/config @@ -39,5 +39,9 @@ qualifiedClassName="edu.rpi.legup.puzzle.skyscrapers.Skyscrapers" fileType=".xml" fileCreationDisabled="false"/> + From 0e89c1126d2465c1f220854816adf14f486c2dda Mon Sep 17 00:00:00 2001 From: FisherLuba <145061313+FisherLuba@users.noreply.github.com> Date: Tue, 12 Mar 2024 17:14:42 -0400 Subject: [PATCH 2/3] Add bomb image --- .../minesweeper/MinesweeperElementView.java | 15 ++++++++++++ .../puzzle/minesweeper/MinesweeperView.java | 23 ++++++++++++++++++ .../puzzle/minesweeper/elements/Bomb.java | 2 +- .../legup/images/minesweeper/tiles/Bomb.png | Bin 0 -> 5572 bytes 4 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/edu/rpi/legup/images/minesweeper/tiles/Bomb.png diff --git a/src/main/java/edu/rpi/legup/puzzle/minesweeper/MinesweeperElementView.java b/src/main/java/edu/rpi/legup/puzzle/minesweeper/MinesweeperElementView.java index 6384b3d99..e9658a077 100644 --- a/src/main/java/edu/rpi/legup/puzzle/minesweeper/MinesweeperElementView.java +++ b/src/main/java/edu/rpi/legup/puzzle/minesweeper/MinesweeperElementView.java @@ -1,5 +1,6 @@ package edu.rpi.legup.puzzle.minesweeper; +import edu.rpi.legup.puzzle.lightup.LightUpView; import edu.rpi.legup.ui.boardview.GridElementView; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -58,5 +59,19 @@ public void drawElement(@NotNull Graphics2D graphics2D) { graphics2D.setColor(Color.GRAY); graphics2D.fillRect(location.x, location.y, size.width, size.height); } + if (type == MinesweeperTileType.BOMB) { + graphics2D.setColor(Color.LIGHT_GRAY); + graphics2D.fillRect(location.x, location.y, size.width, size.height); + graphics2D.drawImage( + MinesweeperView.BOMB_IMAGE, + location.x, + location.y, + size.width, + size.height, + Color.GRAY, + null); + graphics2D.setColor(Color.BLACK); + graphics2D.drawRect(location.x, location.y, size.width, size.height); + } } } diff --git a/src/main/java/edu/rpi/legup/puzzle/minesweeper/MinesweeperView.java b/src/main/java/edu/rpi/legup/puzzle/minesweeper/MinesweeperView.java index 78747a199..ca9214416 100644 --- a/src/main/java/edu/rpi/legup/puzzle/minesweeper/MinesweeperView.java +++ b/src/main/java/edu/rpi/legup/puzzle/minesweeper/MinesweeperView.java @@ -2,13 +2,36 @@ import edu.rpi.legup.controller.BoardController; import edu.rpi.legup.model.gameboard.PuzzleElement; +import edu.rpi.legup.puzzle.lightup.LightUpView; import edu.rpi.legup.ui.boardview.GridBoardView; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; +import javax.imageio.ImageIO; import java.awt.*; +import java.io.IOException; +import java.util.Objects; public class MinesweeperView extends GridBoardView { + private static final Logger LOGGER = LogManager.getLogger(MinesweeperView.class.getName()); + public static final Image BOMB_IMAGE; + + static { + Image tempBombImage = null; + try { + tempBombImage = + ImageIO.read( + Objects.requireNonNull(ClassLoader.getSystemClassLoader() + .getResource("edu/rpi/legup/images/minesweeper/tiles/Bomb.png"))); + } catch (IOException e) { + LOGGER.error("Failed to open Minesweeper images"); + } + BOMB_IMAGE = tempBombImage; + } + + public MinesweeperView(@NotNull MinesweeperBoard board) { super(new BoardController(), new MinesweeperController(), board.getDimension()); diff --git a/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/Bomb.java b/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/Bomb.java index 6fe86dcee..f5305f46a 100644 --- a/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/Bomb.java +++ b/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/Bomb.java @@ -3,6 +3,6 @@ import edu.rpi.legup.model.elements.NonPlaceableElement; public class Bomb extends NonPlaceableElement{ public Bomb() { - super("MINE-UNPL-0001", "Bomb", "A bomb", "edu/rpi/legup/images/nurikabe/tiles/NumberTile.png"); + super("MINE-UNPL-0001", "Bomb", "A bomb", "edu/rpi/legup/images/minesweeper/tiles/Bomb.png"); } } diff --git a/src/main/resources/edu/rpi/legup/images/minesweeper/tiles/Bomb.png b/src/main/resources/edu/rpi/legup/images/minesweeper/tiles/Bomb.png new file mode 100644 index 0000000000000000000000000000000000000000..dd6bad509542c4ac925986d71315b4d655e952c4 GIT binary patch literal 5572 zcmeHLc~leU77v252(BO~ATgi}$;|!k{eAcT?)~mJ zlN7$Umzl{F6AT7p#+}dh1;1GBVKfSyRdI3M7>t2D&M#2yi)gS4rCcnDM6v2v1&T#u zBw`FErtw6;vhs(Hru{dZ#m4inQ!m^Px;8tf_44?eC%KL74n5InA!VLM?K|ubvHF`= zBo3VZ{d$aYLZMHSyfRpsLY}g6SwMl$;bU*|EIV0k&F$?rp?hZS3c1^+dCQV}8!ix4 zwA3sred~G5ZoaI?&d%o9>QbDqxm2?`+H1>=Rkv(gekr|JVkOJw_hmi{nac0R+@M+Hj z8Ot6m_1PH7XyQF(W%fG}UWr<^Wo_-tt;IiwPTsJ8gG`I7JvmSlzOvp$XmKlcS7T=? za|>zNp>K?K?zGq2w$^9kl=T^LGw+P|4>`T`_LC)wfK8@}2ar6;j9jE|^EE$D^_>*` zDfJd_Iav*(yo2|@eB4b*WDoZvYg3OX_mNRUG2qFo6Yi8zrHN*Q=hS_ zve*A2C zClPzfinm$QZYzGEG|x?ie!0W*a*DdK`|Z@Yr+Xi-_O;%!#+vlb$UdF&@_eIrhrGwI zbZfp#!NR==Jt&cybT+x+A$v1=a_Fe>erZ*W$5JV;CU^_|Pcv_3BX+JtQYbd8(y*LjEI~H;6 zc)j}0%*!FCTx%h< z7`I{4lcrS(_~J8_h3)yrt9z!mPlW{!4tnN?`NfaMRU2?E9S_c!Hm%6Eqw1x%9Q&9+ z7_Hy5kYp%#uuYqoNxdWeZoALPeAc772O+T&HxzK*nmf7Wit-0oeK`Z?N-x!TdA1i% z5?h3LU%|cFy|ZL{cKMU%O)t^%$yv#kOq=`q{bM_dG_M;rT}^U?J2)2)RkXQ?pA|N| z@&E1uZcK9-Ck|TiSNr2?0{3#B!JMVNwenniYyE3e1#MnLhS`~(XDT`tmfyZ*YZ1-ooJZQZ+JPJ!=8~b zV1>cxB}!N9z4Cbs|`1OfZ$ZI?!~=IyUyos&ztn- z9i}HN?JT|rBn8btiI*r*+#g+oXoAL135LQH~rxE2EB2X_k#u=57;DrcUs`- ziAyJ*tw^D*3!_OByWGoa>&n0Vm$$3r%E%PEV+Ug1)f{UnKSkz{a|>opO4;pe`AtZD zUGY3umdz5E{Fljj=bRrymzMr=sj;VpU~18wWqL!BK5g}Mho2G*Mn?JZlhcg$Go2<~ zsj%yLv9W5v{Fu4Y|5R<+swtG(19tDm{-BAlC@EU*>o}(SB>mDk`X5I}S4>IoihoMq zKM~t&8r*LC<9_4%_{^rZ@cZ_m;ntOv&%^7cDvs%IaGhN4^s8@1F@M&G&aiG?Y-sN! ztH7?fh|Y)IdbPd*7igzWPlFc~K8@P0>CyDO?%W#vqlYO^*`ntkcNl{i<1Ya_K_G7- zQz)0>5s_Sg;$x%=uv1_#t{yQ8L>Pgpu>v$qB6Gua{`wmZD-pTj0$g}7Pr*XNCG+Ey z=;AnUKVe*ikRif(xSP1fFadxRRU_CKX{1cWjB&&1aGBs*D<JC*M}YYd?q}K` zW7jDIEgp}_mJ6e_?s3^}IPLsQkz6PdF?E+@Dpf#)MJNPL42U9z1&{zmL=crECKD+n zgd#@8!=Sh_l^T%=Q7sez$4dYXg#kcZ1OkYT3ds#i$l+dTp+o?RNJCsm6jT6-86@BhN+&@A8bX2)7crQH#-Ng6k53(Oqc{NAQ(u7>B~hDaqNH7)-E5c>tNF7 zOH^R~Se-CirR$3r_#)-6)%BIGFJj<}l)qNj|BWt_Pw$GT z3_Rdzz?)#Tr#BzGMUE0I@M2@$Yri{AlxzYLW5xU+6$UeUqV~|kY|8_G3t$Y@Tpq`; zP2bdFgqgHCB@u`oaoKbH0?$6nzG$2Tn>-?|!8*(m3^&u0?Ww%MHVE3nV6|m69`Vnt zs(OUj@8$iuXD`*#-S%qK-PW4-H-&od^>@W^qOI3o1F Date: Tue, 12 Mar 2024 17:25:36 -0400 Subject: [PATCH 3/3] Added reference sheet for Minesweeper tiles for puzzle editor --- .../minesweeper/elements/{Bomb.java => BombTile.java} | 4 ++-- .../legup/puzzle/minesweeper/elements/EmptyTile.java | 10 ++++++++++ .../minesweeper/elements/{Flag.java => FlagTile.java} | 6 +++--- .../legup/puzzle/minesweeper/elements/UnsetTile.java | 11 +++++++++++ .../elements/minesweeper_elements_reference_sheet.txt | 4 ++++ 5 files changed, 30 insertions(+), 5 deletions(-) rename src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/{Bomb.java => BombTile.java} (74%) create mode 100644 src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/EmptyTile.java rename src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/{Flag.java => FlagTile.java} (53%) create mode 100644 src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/UnsetTile.java create mode 100644 src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/minesweeper_elements_reference_sheet.txt diff --git a/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/Bomb.java b/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/BombTile.java similarity index 74% rename from src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/Bomb.java rename to src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/BombTile.java index f5305f46a..90bd8fb90 100644 --- a/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/Bomb.java +++ b/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/BombTile.java @@ -1,8 +1,8 @@ package edu.rpi.legup.puzzle.minesweeper.elements; import edu.rpi.legup.model.elements.NonPlaceableElement; -public class Bomb extends NonPlaceableElement{ - public Bomb() { +public class BombTile extends NonPlaceableElement{ + public BombTile() { super("MINE-UNPL-0001", "Bomb", "A bomb", "edu/rpi/legup/images/minesweeper/tiles/Bomb.png"); } } diff --git a/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/EmptyTile.java b/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/EmptyTile.java new file mode 100644 index 000000000..dad1593ca --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/EmptyTile.java @@ -0,0 +1,10 @@ +package edu.rpi.legup.puzzle.minesweeper.elements; + +import edu.rpi.legup.model.elements.PlaceableElement; + +public class EmptyTile extends PlaceableElement { + + public EmptyTile() { + super("MINE-PLAC-0002", "Empty", "An empty tile", "edu/rpi/legup/images/minesweeper/tiles/Empty.png"); + } +} diff --git a/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/Flag.java b/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/FlagTile.java similarity index 53% rename from src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/Flag.java rename to src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/FlagTile.java index 9e9b53bae..b6d44d11a 100644 --- a/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/Flag.java +++ b/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/FlagTile.java @@ -1,8 +1,8 @@ package edu.rpi.legup.puzzle.minesweeper.elements; import edu.rpi.legup.model.elements.PlaceableElement; -public class Flag extends PlaceableElement{ - public Flag() { - super("NURI-PLAC-0001", "Flag", "The flag", "edu/rpi/legup/images/nurikabe/tiles/BlackTile.png"); +public class FlagTile extends PlaceableElement{ + public FlagTile() { + super("MINE-PLAC-0001", "Flag", "The flag", "edu/rpi/legup/images/nurikabe/tiles/BlackTile.png"); } } diff --git a/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/UnsetTile.java b/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/UnsetTile.java new file mode 100644 index 000000000..1899a4fd5 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/UnsetTile.java @@ -0,0 +1,11 @@ +package edu.rpi.legup.puzzle.minesweeper.elements; + +import edu.rpi.legup.model.elements.NonPlaceableElement; + +public class UnsetTile extends NonPlaceableElement { + + public UnsetTile() { + super("MINE-UNPL-0002", "Unset", "An unset tile", "edu/rpi/legup/images/minesweeper/tiles/Unset.png"); + } + +} diff --git a/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/minesweeper_elements_reference_sheet.txt b/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/minesweeper_elements_reference_sheet.txt new file mode 100644 index 000000000..08ce23f59 --- /dev/null +++ b/src/main/java/edu/rpi/legup/puzzle/minesweeper/elements/minesweeper_elements_reference_sheet.txt @@ -0,0 +1,4 @@ +MINE-UNPL-0001 : BombTile +MINE-PLAC-0001 : FlagTile +MINE-PLAC-0002 : EmptyTile +MINE-UNPL-0002 : UnsetTile \ No newline at end of file