Stack Overflow first timer here!
First off, I'm creating a Sudoku Solver using JavaFX. I've got everything working, however, the only issue I'm having is creating the bolded 3x3 big blocks with 3x3 cells inside each big block. I've tried creating 2 'for' loops for the big blocks followed by 2 more 'for' loops for each small TextField cell. However, accessing those cells seem impossible since then I'd be technically creating a 4-D array and I somehow have to access that mess.
Hence, I backed off on the aesthetics and worked with 9x9 TextField cells without the appropriate Sudoku lines. It works with the solver, but now I want to add in those lines, since I might as well make it look like a legit Sudoku grid. Thought about using CSS, but nth-child does not work with JavaFX CSS. Thank you, yall!
public class SudokuGUI extends Application {
public static void main(String[] args) {
Application.launch();
}
public static LimitedNumberTextField[][] tf2D =
new LimitedNumberTextField[9][9];
public static int[][] tf2DVal = new int[9][9];
public static int[][] output = SudokuSolver.output;
public static int[][] zeroBoard = SudokuSolver.zeroSudoku;
@Override
public void start(Stage mainStage) throws Exception {
//Solve Button
Button solveButton = new Button("Solve");
solveButton.setMaxWidth(Double.MAX_VALUE);
solveButton.setStyle("-fx-background-color: "
+ "linear-gradient(#f2f2f2, #d6d6d6), "
+ "linear-gradient(#fcfcfc 0%, #d9d9d9 20%, #d6d6d6 100%),"
+ "linear-gradient(#dddddd 0%, #f6f6f6 50%);"
+ "-fx-background-radius: 8,7,6;"
+ "-fx-background-insets: 0,1,2;"
+ "-fx-text-fill: black;"
+ "-fx-effect: dropshadow( three-pass-box , "
+ "rgba(0,0,0,0.6) , 5, 0.0 , 0 , 1 );");
//Reset Button
Button resetButton = new Button("Reset");
resetButton.setMaxWidth(Double.MAX_VALUE);
resetButton.setStyle("-fx-background-color: "
+ "linear-gradient(#f2f2f2, #d6d6d6), "
+ "linear-gradient(#fcfcfc 0%, #d9d9d9 20%, #d6d6d6 100%),"
+ "linear-gradient(#dddddd 0%, #f6f6f6 50%);"
+ "-fx-background-radius: 8,7,6;"
+ "-fx-background-insets: 0,1,2;"
+ "-fx-text-fill: black;"
+ "-fx-effect: dropshadow( three-pass-box , "
+ "rgba(0,0,0,0.6) , 5, 0.0 , 0 , 1 );");
//Grid
GridPane grid = new GridPane();
grid.setPadding(new Insets(40, 40, 40, 40));
//Setting the grid to the scene.
Scene scene = new Scene(grid);
// Will hold the 2 buttons in a vBox.
VBox vb = new VBox();
vb.setPadding(new Insets(10, 0, 0, 30));
vb.setSpacing(10);
vb.getChildren().addAll(solveButton, resetButton);
GridPane.setRowIndex(vb, 0);
GridPane.setColumnIndex(vb, 4);
// Adds in the vBox consisting of the 2 buttons onto the GridPane.
grid.getChildren().add(vb);
grid.setStyle("-fx-background-color: linear-gradient(to bottom, "
+ "#cedbe9 0%,#aac5de 17%,#6199c7 50%,#3a84c3 51%,"
+ "#419ad6 59%,#4bb8f0 71%,#3a8bc2 84%,#26558b 100%);");
// Creation of Sudoku grid consisting of 81 total cells.
GridPane box = new GridPane();
box.setStyle("-fx-background-color: black, "
+ "-fx-control-inner-background; "
+ "-fx-background-insets: 0, 2; "
+ "-fx-padding: 4;"
+ "-fx-grid-lines-visible: true;");
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
LimitedNumberTextField limitNumberTextField =
new LimitedNumberTextField(1);
limitNumberTextField.setStyle(
"-fx-pref-width: 3em; "
+ "-fx-pref-height: 3em;");
GridPane.setConstraints(limitNumberTextField, row, col);
box.getChildren().add(limitNumberTextField);
if (limitNumberTextField.getText().equals("")) {
limitNumberTextField.setText("0");
}
tf2D[row][col]= limitNumberTextField;
tf2DVal[row][col] = Integer
.parseInt(limitNumberTextField.getText());
if (limitNumberTextField.getText().equals("0")) {
limitNumberTextField.setText("");
tf2D[row][col] = limitNumberTextField;
}
}
}
grid.getChildren().add(box);
//Action Listeners for the buttons.
try {
solveButton.setOnAction(e -> {
getBoard();
setBoard(tf2DVal);
if (isZeroBoard(tf2DVal)) {
Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle(" No values!! ");
alert.setHeaderText(null);
alert.setContentText(
" Please input some values and try again.");
alert.showAndWait();
return;
}
try {
SudokuSolver.solveIt(tf2DVal);
} catch (Exception e1) {
Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle(" Invalid Sudoku board! ");
alert.setHeaderText(null);
alert.setContentText(" Your input is invalid!
"
+ " Please check your board and try again.");
alert.showAndWait();
}
setFinalBoard();
});
resetButton.setOnAction(e -> {
getBoard();
resetBoard();
});
//Shows hand when hovered over.
solveButton.setOnMouseEntered(e -> {
solveButton.setCursor(Cursor.HAND);
});
resetButton.setOnMouseEntered(e -> {
resetButton.setCursor(Cursor.HAND);
});
} catch (Exception e) { // In case there is no solution. Not likely.
Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle(" No Solution Found! ");
alert.setHeaderText(null);
alert.setContentText(
"Please check your board and try again. ");
alert.showAndWait();
}
mainStage.setTitle("Sudoku Solver");
mainStage.getIcons().add(new Image("file:logo_icon.png"));
mainStage.setScene(scene);
mainStage.show();
}
//Reading the values of the Sudoku.
public static void getBoard() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
LimitedNumberTextField ltf = tf2D[i][j];
if (ltf.getText().equals("")) {
ltf.setText("0");
}
tf2DVal[i][j] = 0;
tf2DVal[i][j] = Integer.parseInt(ltf.getText());
if (ltf.getText().equals("0")) {
ltf.setText("");
tf2D[i][j] = ltf;
}
}
}
}
//Setting the values to the board.
public static void setBoard(int[][] board) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
tf2DVal[i][j] = board[i][j];
if (tf2D[i][j].getText().equals("")) {
tf2D[i][j].setText("0");
}
tf2D[i][j].setText(Integer.toString(tf2DVal[i][j]));
if (tf2D[i][j].getText().equals("0")) {
tf2D[i][j].setText("");
}
}
}
}
//Method to set the final value after it is solved.
public static void setFinalBoard() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
tf2DVal[i][j] = output[i][j];
if (tf2D[i][j].getText().equals("")) {
tf2D[i][j].setText("0");
}
tf2D[i][j].setText(Integer.toString(tf2DVal[i][j]));
if (tf2D[i][j].getText().equals("0")) {
tf2D[i][j].setText("");
}
}
}
}
//Resets the board.
public static void resetBoard() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
tf2D[i][j].setText("");
}
}
}
//This method compares the board to a board with all zeros.
public static boolean isZeroBoard(int[][] input) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (!(input[i][j] == zeroBoard[i][j])) {
return false;
}
}
}
return true;
}
}
See Question&Answers more detail:
os