123 lines
3.7 KiB
Java
123 lines
3.7 KiB
Java
package domain;
|
|
|
|
import java.util.*;
|
|
|
|
public class GameSolver extends HitoriGameMoves {
|
|
|
|
public GameSolver(int[][] initialBoard) {
|
|
super(initialBoard);
|
|
}
|
|
|
|
public boolean isSolved() {
|
|
// First check if all cells are marked (either black or white)
|
|
for (int i = 0; i < board.length; i++) {
|
|
for (int j = 0; j < board[0].length; j++) {
|
|
if (!blackCells[i][j] && !whiteCells[i][j]) {
|
|
return false; // Found an unmarked cell
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check for adjacent black cells
|
|
for (int i = 0; i < board.length; i++) {
|
|
for (int j = 0; j < board[0].length; j++) {
|
|
if (blackCells[i][j] && !isValidBlackMark(i, j)) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check for duplicates in rows and columns
|
|
for (int i = 0; i < board.length; i++) {
|
|
Set<Integer> seenInRow = new HashSet<>();
|
|
Set<Integer> seenInCol = new HashSet<>();
|
|
|
|
for (int j = 0; j < board[0].length; j++) {
|
|
// Check row
|
|
if (!blackCells[i][j]) {
|
|
if (seenInRow.contains(board[i][j])) {
|
|
return false;
|
|
}
|
|
seenInRow.add(board[i][j]);
|
|
}
|
|
|
|
// Check column
|
|
if (!blackCells[j][i]) {
|
|
if (seenInCol.contains(board[j][i])) {
|
|
return false;
|
|
}
|
|
seenInCol.add(board[j][i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check connectivity of white cells
|
|
return isOrthogonallyConnected();
|
|
}
|
|
|
|
private boolean isValidBlackMark(int row, int col) {
|
|
if (row > 0 && blackCells[row-1][col] ||
|
|
row < board.length-1 && blackCells[row+1][col] ||
|
|
col > 0 && blackCells[row][col-1] ||
|
|
col < board[0].length-1 && blackCells[row][col+1]) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private boolean isOrthogonallyConnected() {
|
|
if (board.length == 0) return true;
|
|
|
|
boolean[][] visited = new boolean[board.length][board[0].length];
|
|
int[] start = findFirstWhiteCell();
|
|
if (start == null) return true;
|
|
|
|
dfs(start[0], start[1], visited);
|
|
|
|
for (int i = 0; i < board.length; i++) {
|
|
for (int j = 0; j < board[0].length; j++) {
|
|
if (!blackCells[i][j] && !visited[i][j]) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private int[] findFirstWhiteCell() {
|
|
for (int i = 0; i < board.length; i++) {
|
|
for (int j = 0; j < board[0].length; j++) {
|
|
if (!blackCells[i][j]) {
|
|
return new int[]{i, j};
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private void dfs(int row, int col, boolean[][] visited) {
|
|
if (row < 0 || row >= board.length || col < 0 || col >= board[0].length ||
|
|
visited[row][col] || blackCells[row][col]) {
|
|
return;
|
|
}
|
|
|
|
visited[row][col] = true;
|
|
|
|
dfs(row - 1, col, visited);
|
|
dfs(row + 1, col, visited);
|
|
dfs(row, col - 1, visited);
|
|
dfs(row, col + 1, visited);
|
|
}
|
|
|
|
public List<int[]> findIncorrectBlackMarks() {
|
|
List<int[]> incorrectMarks = new ArrayList<>();
|
|
for (int i = 0; i < board.length; i++) {
|
|
for (int j = 0; j < board[0].length; j++) {
|
|
if (blackCells[i][j] && !isValidBlackMark(i, j)) {
|
|
incorrectMarks.add(new int[]{i, j});
|
|
}
|
|
}
|
|
}
|
|
return incorrectMarks;
|
|
}
|
|
} |