Skip to content

Commit

Permalink
Merge pull request #60 from Bram-Hub/nurikabe_issue31_corners_black_out
Browse files Browse the repository at this point in the history
Fix Issue 31: Corners Black Out Bug
  • Loading branch information
charlestian23 authored Dec 21, 2021
2 parents 5da63a9 + be0ea59 commit 940b5b6
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 85 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.gradle/*
.idea/*
out/*
build
build/*
.DS_Store
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public int[][] getIntArray() {

@Override
public NurikabeBoard copy() {
System.out.println("NarukabeBoard copy()");
// System.out.println("NurikabeBoard copy()");
NurikabeBoard copy = new NurikabeBoard(dimension.width, dimension.height);
for (int x = 0; x < this.dimension.width; x++) {
for (int y = 0; y < this.dimension.height; y++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
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.nurikabe.Nurikabe;
import edu.rpi.legup.puzzle.nurikabe.NurikabeBoard;
import edu.rpi.legup.puzzle.nurikabe.NurikabeCell;
import edu.rpi.legup.puzzle.nurikabe.NurikabeType;
import edu.rpi.legup.utility.ConnectedRegions;

Expand All @@ -32,94 +34,64 @@ public CornerBlackBasicRule() {
*/
@Override
public String checkRuleRawAt(TreeTransition transition, PuzzleElement puzzleElement) {
NurikabeBoard destBoardState = (NurikabeBoard) transition.getBoard();
NurikabeBoard origBoardState = (NurikabeBoard) transition.getParents().get(0).getBoard();

int width = destBoardState.getWidth();
int height = destBoardState.getHeight();
NurikabeBoard board = (NurikabeBoard) transition.getBoard();
NurikabeCell cell = (NurikabeCell) board.getPuzzleElement(puzzleElement);
if (cell.getType() != NurikabeType.BLACK)
return "Only black cells are allowed for this rule!";

ContradictionRule tooFewContra = new TooFewSpacesContradictionRule();
Point cellLocation = cell.getLocation();
// 1. Find the coordinates of the white space (should be a corner of cell)
for (int i = -1; i < 2; i += 2)
for (int j = -1; j < 2; j += 2)
{
// If the corner does not exist, skip the corner
if (!(cellLocation.x + i >= 0 && cellLocation.x + i < board.getWidth() && cellLocation.y + j >= 0 && cellLocation.x + i < board.getHeight()))
continue;

for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (!destBoardState.getCell(x, y).equalsData(origBoardState.getCell(x, y))) {
if (destBoardState.getCell(x, y).getData() != NurikabeType.BLACK.ordinal()) {
return "Only black cells are allowed for this rule!";
}

NurikabeBoard modified = origBoardState.copy();
// modified.getBoardCells()[y][x] = nurikabe.CELL_WHITE;

boolean validPoint = false;

// Check each corner of the changed cell
for (int d = -1; d < 2; d += 2) {
if ((x + d >= 0 && x + d < width) && (y + d >= 0 && y + d < height) && modified.getCell(x + d, y + d).getData() >= NurikabeType.WHITE.ordinal()) // >= is used to account for numbered cells
NurikabeCell corner = board.getCell(cellLocation.x + i, cellLocation.y + j);
NurikabeType cornerType = corner.getType();
if (cornerType == NurikabeType.WHITE || cornerType == NurikabeType.NUMBER)
{
Point cornerLocation = corner.getLocation();
// 2. Check if the intersecting adjacent spaces of the white space and the black corner are empty
if (board.getCell(cornerLocation.x, cellLocation.y).getType() == NurikabeType.UNKNOWN && board.getCell(cellLocation.x, cornerLocation.y).getType() == NurikabeType.UNKNOWN)
{
// System.out.println("Went inside if statement");
NurikabeBoard modified = board.copy();
modified.getCell(cornerLocation.x, cellLocation.y).setData(NurikabeType.BLACK.toValue());
modified.getCell(cellLocation.x, cornerLocation.y).setData(NurikabeType.BLACK.toValue());
boolean containsContradiction = tooFewContra.checkContradiction(modified) == null;
if (containsContradiction)
{
// Series of if statements to check conditions of rule
// First check: cells adjacent to changed cell and white region corner are empty
if (modified.getCell(x + d, y).getData() == NurikabeType.UNKNOWN.ordinal() && modified.getCell(x, y + d).getData() == NurikabeType.UNKNOWN.ordinal()) {
modified.getCell(y + d, x).setData(NurikabeType.BLACK.ordinal());
modified.getCell(y, x + d).setData(NurikabeType.BLACK.ordinal());
// Second check: corner is only way to escape from the white region
if (tooFewContra.checkContradiction(modified) == null) {
Set<Point> reg = ConnectedRegions.getRegionAroundPoint(new Point(x + d, y + d), NurikabeType.BLACK.ordinal(), modified.getIntArray(), modified.getWidth(), modified.getHeight());
int regionNum = 0;
for (Point p : reg) {
if (modified.getCell(p.x, p.y).getType() == NurikabeType.NUMBER) {
if (regionNum == 0) {
regionNum = modified.getCell(p.x, p.y).getData();
} else {
return "There is a MultipleNumbers Contradiction on the board.";
}
}
}
//Third check: The white region kittycorner to this currently has one less cell than required
if (regionNum > 0 && reg.size() == regionNum - 11) {
validPoint = true;
break;
}
// 3. Check if the connected region is 1 under what is needed
Set<Point> region = ConnectedRegions.getRegionAroundPoint(cornerLocation, NurikabeType.BLACK.toValue(), modified.getIntArray(), modified.getWidth(), modified.getHeight());
int regionNumber = 0;
// System.out.println("Region set size: " + region.size());
for (Point p : region)
{
NurikabeCell pCell = modified.getCell(p.x, p.y);
if (pCell.getType() == NurikabeType.NUMBER)
{
if (regionNumber == 0)
regionNumber = pCell.getData();
else
return "There is a MultipleNumbers Contradiction on the board.";
}
}
// If the region size is 0, there is a possibility that there was only 1 cell in the white
// region, and that white cell was a NurikabeType.NUMBER cell
if (regionNumber == 0 && corner.getType() == NurikabeType.NUMBER && corner.getData() == 2)
return null;
// If the region size is not 0, make sure the regionNumber and the region size match (need
// to add 1 to account for the cell that was surrounded
if (regionNumber != 0 && region.size() + 1 == regionNumber)
return null;
}

if ((x + d >= 0 && x + d < width) && (y - d >= 0 && y - d < height) && modified.getCell(x + d, y - d).getData() >= NurikabeType.WHITE.ordinal()) {
// Series of if statements to check conditions of rule
// First check: cells adjacent to changed cell and white region corner are empty
if (modified.getCell(x + d, y).getData() == NurikabeType.UNKNOWN.ordinal() && modified.getCell(x, y - d).getData() == NurikabeType.UNKNOWN.ordinal()) {
modified.getCell(y - d, x).setData(NurikabeType.BLACK.ordinal());
modified.getCell(y, x + d).setData(NurikabeType.BLACK.ordinal());
// Second check: corner is only way to escape from the white region
if (tooFewContra.checkContradiction(modified) == null) {
Set<Point> reg = ConnectedRegions.getRegionAroundPoint(new Point(x + d, y - d), NurikabeType.BLACK.ordinal(), modified.getIntArray(), modified.getWidth(), modified.getHeight());
int regionNum = 0;
for (Point p : reg) {
if (modified.getCell(p.x, p.y).getType() == NurikabeType.NUMBER) {
if (regionNum == 0) {
regionNum = modified.getCell(p.x, p.y).getData();
} else {
return "There is a MultipleNumbers Contradiction on the board!";
}
}
}
// Third check: The white region kittycorner to this currently has one less cell than required
if (regionNum > 0 && reg.size() == regionNum - 11) {
validPoint = true;
break;
}
}
}
}


}
if (!validPoint) {
return "This is not a valid use of the corner black rule!";
}
}
}
}
return null;
return "This is not a valid use of the corner black rule!";
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
}
}
for (NurikabeCell c : whiteRegion) {
System.out.println(c.getLocation().x + "\t" + c.getLocation().y);
// System.out.println(c.getLocation().x + "\t" + c.getLocation().y);
NurikabeCell top = nurikabeBoard.getCell(c.getLocation().x, c.getLocation().y+1);
NurikabeCell left = nurikabeBoard.getCell(c.getLocation().x-1, c.getLocation().y);
NurikabeCell right = nurikabeBoard.getCell(c.getLocation().x+1, c.getLocation().y);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public String checkContradictionAt(Board board, PuzzleElement puzzleElement) {
}

if (numberedCell != null && whiteRegion.size() < numberedCell.getData()) {
System.err.println("Cell Value: " + numberedCell.getData() + ", Loc: " + cell.getLocation() + ", region: " + whiteRegion.size());
// System.err.println("Cell Value: " + numberedCell.getData() + ", Loc: " + cell.getLocation() + ", region: " + whiteRegion.size());
return null;
}
return "Does not contain a contradiction at this index";
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/edu/rpi/legup/utility/ConnectedRegions.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ public static boolean regionContains(int toFind, int[][] cells, Set<Point> regio
}

public static Set<Point> getRegionAroundPoint(Point p, int boundaryCell, int[][] cells, int width, int height) {
Set<Integer> boundryCells = new HashSet<>();
boundryCells.add(boundaryCell);
return getRegionAroundPoint(p, boundryCells, cells, width, height);
Set<Integer> boundaryCells = new HashSet<>();
boundaryCells.add(boundaryCell);
return getRegionAroundPoint(p, boundaryCells, cells, width, height);
}

public static Set<Point> getRegionAroundPoint(Point p, Set<Integer> boundaryCells, int[][] cells, int width, int height) {
Expand Down

0 comments on commit 940b5b6

Please sign in to comment.