Skip to content

Commit

Permalink
Merge pull request #771 from vockek/minesweeper
Browse files Browse the repository at this point in the history
  • Loading branch information
vockek authored Mar 31, 2024
2 parents 27d831e + a45ed95 commit 6230b7b
Show file tree
Hide file tree
Showing 12 changed files with 383 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ public MinesweeperCell(@NotNull MinesweeperTileData value, @NotNull Point locati
return super.data.type();
}

public @NotNull int getTileNumber() {
return super.data.data();
}

@Override
@Contract(pure = false)
/**
Expand Down Expand Up @@ -56,6 +60,10 @@ public void setType(@NotNull Element element, @NotNull MouseEvent event) {
}
}

public void setCellType(MinesweeperTileData type){
this.data = type;
}

@Override
@Contract(pure = true)
public @NotNull MinesweeperCell copy() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,18 @@ public void drawElement(@NotNull Graphics2D graphics2D) {
return;
}
if (type == MinesweeperTileType.EMPTY) {
graphics2D.setStroke(new BasicStroke(1));
graphics2D.setColor(Color.LIGHT_GRAY);
graphics2D.fillRect(location.x, location.y, size.width, size.height);
graphics2D.drawImage(
MinesweeperView.EMPTY_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);
graphics2D.setColor(Color.GRAY);
graphics2D.fillRect(location.x, location.y, size.width, size.height);
}
if (type == MinesweeperTileType.BOMB) {
graphics2D.setColor(Color.LIGHT_GRAY);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.Objects;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.*;

public final class MinesweeperUtilities {

Expand Down Expand Up @@ -75,4 +76,66 @@ public int countNeededBombsFromFlag(MinesweeperBoard board, MinesweeperCell cell
return cell.getData().data() - countSurroundingBombs(board, cell);
}

public static boolean hasEmptyAdjacent(MinesweeperBoard board, MinesweeperCell cell) {
ArrayList<MinesweeperCell> adjCells = getAdjacentCells(board, cell);
for (MinesweeperCell adjCell : adjCells) {
if (adjCell.getTileType() == MinesweeperTileType.UNSET) {
return true;
}
}
return false;
}

public static ArrayList<MinesweeperCell> getAdjacentCells(MinesweeperBoard board, MinesweeperCell cell) {
ArrayList<MinesweeperCell> adjCells = new ArrayList<MinesweeperCell>();
Point cellLoc = cell.getLocation();
for (int i=-1; i <= 1; i++) {
for (int j=-1; j <= 1; j++) {
if (cellLoc.getX() + i < 0 || cellLoc.y + j < 0 || cellLoc.x + i >= board.getWidth() || cellLoc.y + j >= board.getHeight()) {
continue;
}
MinesweeperCell adjCell = (MinesweeperCell) board.getCell(cellLoc.x + i, cellLoc.y + j);
if (adjCell == null) {
continue;
}
adjCells.add(adjCell);
}
}
return adjCells;
}

public static ArrayList<boolean[]> getCombinations(int chosenNumItems, int totalNumItems) {
ArrayList<boolean[]> combinations = new ArrayList<boolean[]>();

// calculate all combinations
boolean[] array = new boolean[totalNumItems];
recurseCombinations(combinations, 0, chosenNumItems, 0, totalNumItems, array);

return combinations;
}

private static void recurseCombinations(ArrayList<boolean[]> result, int curIndex, int maxBlack, int numBlack, int len, boolean[] workingArray) {
if (curIndex == len) {
// complete, but not valid solution
if (numBlack != maxBlack) {
return;
}
// complete and valid solution
result.add(workingArray.clone());
return;
}
// there is no chance of completing the required number of solutions, so quit
if (len - curIndex < maxBlack - numBlack) {
return;
}

if (numBlack < maxBlack) {
workingArray[curIndex] = true;
recurseCombinations(result, curIndex+1, maxBlack, numBlack+1, len, workingArray);
}
workingArray[curIndex] = false;
recurseCombinations(result, curIndex+1, maxBlack, numBlack, len, workingArray);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public class MinesweeperView extends GridBoardView {
private static final Logger LOGGER = LogManager.getLogger(MinesweeperView.class.getName());
public static final Image BOMB_IMAGE;

public static final Image EMPTY_IMAGE;

static {
Image tempBombImage = null;
try {
Expand All @@ -31,6 +33,19 @@ public class MinesweeperView extends GridBoardView {
BOMB_IMAGE = tempBombImage;
}

static {
Image tempEmptyImage = null;
try {
tempEmptyImage =
ImageIO.read(
Objects.requireNonNull(ClassLoader.getSystemClassLoader()
.getResource("edu/rpi/legup/images/minesweeper/tiles/Empty.png")));
} catch (IOException e) {
LOGGER.error("Failed to open Minesweeper images");
}
EMPTY_IMAGE = tempEmptyImage;
}


public MinesweeperView(@NotNull MinesweeperBoard board) {
super(new BoardController(), new MinesweeperController(), board.getDimension());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
public class BombOrFilledCaseRule extends CaseRule {

public BombOrFilledCaseRule() {
super("MINE-CASE-0000", "Bomb Or Filled",
super("MINE-CASE-0001", "Bomb Or Filled",
"A cell can either be a bomb or filled.\n",
"");
"edu/rpi/legup/images/minesweeper/cases/BombOrFilled.jpg");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package edu.rpi.legup.puzzle.minesweeper.rules;

import edu.rpi.legup.model.gameboard.Board;
import edu.rpi.legup.model.gameboard.PuzzleElement;
import edu.rpi.legup.model.rules.ContradictionRule;
import edu.rpi.legup.puzzle.minesweeper.MinesweeperBoard;
import edu.rpi.legup.puzzle.minesweeper.MinesweeperCell;
import edu.rpi.legup.puzzle.minesweeper.MinesweeperTileType;
import edu.rpi.legup.puzzle.minesweeper.MinesweeperTileData;
import edu.rpi.legup.puzzle.minesweeper.MinesweeperUtilities;
import java.util.ArrayList;

public class MoreBombsThanFlagContradictionRule extends ContradictionRule {

public MoreBombsThanFlagContradictionRule() {
super(
"MINE-CONT-0001",
"More Bombs Than Flag",
"There can not be more Bombs around a flag than the specified number\n",
"edu/rpi/legup/images/minesweeper/contradictions/Bomb_Surplus.jpg");
}

/**
* 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) {
MinesweeperBoard minesweeperBoard = (MinesweeperBoard) board;
MinesweeperCell cell = (MinesweeperCell) minesweeperBoard.getPuzzleElement(puzzleElement);

int cellNum = cell.getTileNumber();
if (cellNum < 0 || cellNum >= 10) {
return super.getNoContradictionMessage();
}
int numBlack = 0;
ArrayList<MinesweeperCell> adjCells = MinesweeperUtilities.getAdjacentCells(minesweeperBoard, cell);
for (MinesweeperCell adjCell : adjCells) {
if (adjCell.getTileType() == MinesweeperTileType.BOMB) {
numBlack++;
}
}
if (numBlack > cellNum) {
return null;
}

return super.getNoContradictionMessage();
}
}
Loading

0 comments on commit 6230b7b

Please sign in to comment.