我正在处理一个未完成的Sudoku木板的任务,让用户输入输入,然后按下“解决”按钮后,它将用户的输入与正确的木板进行比较,并用红色突出显示任何不正确的条目。我不知道如何将用户输入存储在2d数组中进行比较,而且我不确定如何完全清除木板。
我尝试将文本设置为空白,我尝试从FlowPane删除子级,尝试重新启动它,但是我认为我做的不正确。我对FXML并不那么熟悉,但是与我交谈的一位老师说这会更容易。我想不是。
Controller.java
// local variables
int mouseColIndex, mouseRowIndex, innerCol, innerRow;
int[][] boardState = new int[9][9];
int[][] board = readAPuzzle();
FlowPane[][] gridPaneNodes;
// handled first
public Controller() {
}
// @FXML tags handled second
@FXML
private GridPane gridParent;
@FXML
private Button solve, clear;
@FXML
private FlowPane topLeft, topMiddle, topRight, middleLeft, middle, middleRight, bottomLeft, bottomMiddle,
bottomRight;
@FXML
private void clearHandler() {
}
// initialize method handled last
@FXML
private void initialize() {
gridHandlers();
for (int y = 0; y < board.length; y++) {
for (int x = 0; x < board[y].length; x++) {
TextField template = new TextField();
template.setMinHeight(60);
template.setMinWidth(45);
template.setMaxWidth(45);
if (board[y][x] > 0) {
template.setText(board[y][x]+"");
}
template.setStyle("-fx-border-color: black");
final int loopY = y, loopX = x;;
gridPaneNodes[x / 3][y / 3].getChildren().add(template);
}
}
}
@FXML
private void solveHandler() {//this was just testing
search(board);
printGrid(board);
}
public void gridHandlers() {
gridPaneNodes = new FlowPane[3][3];
ObservableList<Node> gList = gridParent.getChildren();
for (Node child : gList) {
Integer column = GridPane.getColumnIndex(child);
Integer row = GridPane.getRowIndex(child);
if (column != null && row != null) {
gridPaneNodes[column][row] = (FlowPane) child;
}
}
for (int row = 0; row < gridPaneNodes.length; row++) {
for (int col = 0; col < gridPaneNodes[row].length; col++) {
FlowPane node = gridPaneNodes[col][row];
node.setOnMouseEntered(e -> {
mouseColIndex = GridPane.getColumnIndex(node);
mouseRowIndex = GridPane.getRowIndex(node);
});
}
}
}
/*
* HELPER METHODS
*/
/** Read a Sudoku puzzle from the keyboard */
public static int[][] readAPuzzle() {
// Create a Scanner
String[] fileNames = new String[] { "Sudoku.txt", "Sudoku1.txt", "Sudoku2.txt", "Sudoku3.txt", "Sudoku4.txt", "Sudoku5.txt", "Sudoku6.txt", "Sudoku7.txt" };
Random random = new Random();
String randomFile = "src/sample/" + fileNames[random.nextInt(fileNames.length)];
Scanner scan = null;
try {
scan = new Scanner(new File(randomFile));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
StringTokenizer st = null;
int[][] ret = new int[9][9];
int x = 0, y = 0;
while (scan.hasNextLine()) {
st = new StringTokenizer(scan.nextLine());
while (st.hasMoreTokens()) {
ret[y][x] = Integer.parseInt(st.nextToken());
x++;
}
x = 0;
y++;
}
return ret;
}
public static void printMatrix(int[][] matrix) {
Arrays.stream(matrix).forEach((row) -> {
System.out.print("[");
Arrays.stream(row).forEach((el) -> System.out.print(" " + el + " "));
System.out.println("]");
});
}
/** Obtain a list of free cells from the puzzle */
public static int[][] getFreeCellList(int[][] grid) {
// Determine the number of free cells
int numberOfFreeCells = 0;
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
if (grid[i][j] == 0)
numberOfFreeCells++;
// Store free cell positions into freeCellList
int[][] freeCellList = new int[numberOfFreeCells][2];
int count = 0;
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
if (grid[i][j] == 0) {
freeCellList[count][0] = i;
freeCellList[count++][1] = j;
}
return freeCellList;
}
/** Search for a solution */
public static boolean search(int[][] grid) {
int[][] freeCellList = getFreeCellList(grid); // Free cells
if (freeCellList.length == 0)
return true; // "No free cells");
int k = 0; // Start from the first free cell
while (true) {
int i = freeCellList[k][0];
int j = freeCellList[k][1];
if (grid[i][j] == 0)
grid[i][j] = 1; // Fill the free cell with number 1
if (isValid(i, j, grid)) {
if (k + 1 == freeCellList.length) { // No more free cells
return true; // A solution is found
} else { // Move to the next free cell
k++;
}
} else if (grid[i][j] < 9) {
// Fill the free cell with the next possible value
grid[i][j] = grid[i][j] + 1;
} else { // free cell grid[i][j] is 9, backtrack
while (grid[i][j] == 9) {
if (k == 0) {
return false; // No possible value
}
grid[i][j] = 0; // Reset to free cell
k--; // Backtrack to the preceding free cell
i = freeCellList[k][0];
j = freeCellList[k][1];
}
// Fill the free cell with the next possible value,
// search continues from this free cell at k
grid[i][j] = grid[i][j] + 1;
}
}
}
/** Check whether grid[i][j] is valid in the grid */
public static boolean isValid(int i, int j, int[][] grid) {
// Check whether grid[i][j] is valid at the i's row
for (int column = 0; column < 9; column++)
if (column != j && grid[i][column] == grid[i][j])
return false;
// Check whether grid[i][j] is valid at the j's column
for (int row = 0; row < 9; row++)
if (row != i && grid[row][j] == grid[i][j])
return false;
// Check whether grid[i][j] is valid in the 3 by 3 box
for (int row = (i / 3) * 3; row < (i / 3) * 3 + 3; row++)
for (int col = (j / 3) * 3; col < (j / 3) * 3 + 3; col++)
if (row != i && col != j && grid[row][col] == grid[i][j])
return false;
return true; // The current value at grid[i][j] is valid
}
/** Check whether the fixed cells are valid in the grid */
public static boolean isValid(int[][] grid) {
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
if (grid[i][j] < 0 || grid[i][j] > 9 || (grid[i][j] != 0 && !isValid(i, j, grid)))
return false;
return true; // The fixed cells are valid
}
public static void printGrid(int[][] grid) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++)
System.out.print(grid[i][j] + " ");
System.out.println();
}
}
Main.java
public static void main(String[] args) {
launch();
}
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
Controller controller = new Controller();
Parent root = loader.load();
loader.setRoot(root);
loader.setController(controller);
primaryStage.setTitle("Sudoku");
primaryStage.setResizable(false);
primaryStage.setScene(new Scene(root, 400, 600));
primaryStage.show();
}