package org.sudoku;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import java.util.*;
public class SudokuBoard {
private final SudokuField[][] board = new SudokuField[9][9];
private final SudokuSolver solver;
private final SudokuColumn[] columnObservers = new SudokuColumn[9];
private final SudokuRow[] rowObservers = new SudokuRow[9];
private final SudokuBox[] boxObservers = new SudokuBox[9];
private boolean state = true;
public SudokuBoard(SudokuSolver solver) {
this.solver = Objects.requireNonNull(solver);
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
board[i][j] = new SudokuField();
}
}
for (int y = 0; y < 9; y++) {
List<SudokuField> fields = Arrays.asList(new SudokuField[9]);
for (int i = 0; i < 9; i++) {
fields.set(i, board[y][i]);
}
rowObservers[y] = new SudokuRow(fields);
}
for (int x = 0; x < 9; x++) {
List<SudokuField> fields = Arrays.asList(new SudokuField[9]);
for (int i = 0; i < 9; i++) {
fields.set(i, board[i][x]);
}
columnObservers[x] = new SudokuColumn(fields);
}
int tableIndex = 0;
for (int x = 0; x < 9; x += 3) {
for (int y = 0; y < 9; y += 3) {
List<SudokuField> fields = Arrays.asList(new SudokuField[9]);
int fieldIndex = 0;
for (int i = x; i < x + 3; i++) {
for (int j = y; j < y + 3; j++) {
fields.set(fieldIndex, board[i][j]);
fieldIndex++;
}
}
boxObservers[tableIndex] = new SudokuBox(fields);
tableIndex++;
}
}
int tableIndex2 = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
board[i][j].setObservers(columnObservers[i], rowObservers[j], boxObservers[tableIndex2]);
if (j % 3 == 2) {
tableIndex2++;
}
}
tableIndex2 = i / 3;
}
}
public void solveGame() {
solver.solve(this);
}
public boolean isSafe() {
return checkBoard();
}
public int get(int y, int x) {
return board[y][x].getFieldValue();
}
public void set(int y, int x, int value) {
try {
board[y][x].setFieldValue(value);
} catch (IllegalArgumentException e) {
state = false;
}
}
public SudokuRow getRow(int y) {
return rowObservers[y];
}
public SudokuColumn getColumn(int x) {
return columnObservers[x];
}
public SudokuBox getBox(int y, int x) {
int row = y / 3 * 3;
int col = x / 3 * 3;
return boxObservers[col + 3 * row];
}
private boolean checkBoard() {
if (state) {
return true;
}
state = true;
for (int i = 0; i < 9; i++) {
state &= columnObservers[i].verify() & rowObservers[i].verify() & boxObservers[i].verify();
}
return state;
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
stringBuilder.append(board[i][j].getFieldValue());
if (j < 8) {
stringBuilder.append(" ");
}
}
stringBuilder.append("\n");
}
return stringBuilder.toString();
}
}
我尝试用这种方式编写 equals 方法(如下),但不幸的是它不起作用。我想重写所有数据模型类中的以下方法:
toString()
、equals()
和hashCode()
方法。
使用外部库来有效地实现它们。
Apache commons-lang3
hashCode() 和 equals() 方法的实现是一致的。当我设置两个板具有相同的值时,equals 方法应该返回 true。
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
SudokuBoard otherBoard = (SudokuBoard) obj;
return new EqualsBuilder()
.append(board, otherBoard.board)
.append(solver, otherBoard.solver)
.append(columnObservers, otherBoard.columnObservers)
.append(rowObservers, otherBoard.rowObservers)
.append(boxObservers, otherBoard.boxObservers)
.append(state, otherBoard.state)
.isEquals();
}
}
我认为你的问题是 one+ 字段与 EqualBuilder 不兼容。具体来说,该类本身没有正确实现
equals()
。由于您不提供这些类的源代码,我们无法知道。
我想也许是二维数组
SudokuField[][] board
。但是看看该实用程序源代码的第 823 行:
看起来好像正确地递归了。
所以,我要做的就是,将每个
append()
放入
return new EqualsBuilder()
.append(board, otherBoard.board)
.append(solver, otherBoard.solver)
.append(columnObservers, otherBoard.columnObservers)
.append(rowObservers, otherBoard.rowObservers)
.append(boxObservers, otherBoard.boxObservers)
.append(state, otherBoard.state)
.isEquals();
并一次删除一个,看看哪一个打破了平等。
您可以做的另一件事是尝试
EqualsBuilder.reflectionEquals(this, obj)
,它应该使用反射遍历整个树深度