Compare commits
No commits in common. "71c43b35c3e5c8474a100bedc566d4b305d9b391" and "196f066281f287f6b2247b2ee28f36a562fde316" have entirely different histories.
71c43b35c3
...
196f066281
5 changed files with 35 additions and 319 deletions
8
Justfile
8
Justfile
|
@ -2,16 +2,10 @@ run:
|
||||||
./gradlew run
|
./gradlew run
|
||||||
|
|
||||||
test:
|
test:
|
||||||
./gradlew test --rerun-tasks
|
./gradlew test
|
||||||
|
|
||||||
doc:
|
|
||||||
./gradlew javadoc --rerun-tasks
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
fd -td -I build -x rm -r
|
fd -td -I build -x rm -r
|
||||||
|
|
||||||
watch:
|
watch:
|
||||||
watchexec -c -w app/src "just test && just run"
|
watchexec -c -w app/src "just test && just run"
|
||||||
|
|
||||||
watchdoc:
|
|
||||||
watchexec -c -w app/src "just doc"
|
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
package gui;
|
|
||||||
|
|
||||||
import sudoku.SudokuSolver;
|
|
||||||
import java.awt.event.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SolverController is a controller for the SudokuSolver interface
|
|
||||||
*/
|
|
||||||
public class SudokuController {
|
|
||||||
SudokuSolver model;
|
|
||||||
SudokuView view;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* @param model SudokuSolver model
|
|
||||||
* @param view SudokuView view
|
|
||||||
*/
|
|
||||||
public SudokuController(SudokuSolver model, SudokuView view) {
|
|
||||||
this.model = model;
|
|
||||||
this.view = view;
|
|
||||||
|
|
||||||
// Add action listeners to the buttons
|
|
||||||
view.addSolveButtonListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
// Solve the board
|
|
||||||
model.solve();
|
|
||||||
|
|
||||||
// Update the view
|
|
||||||
view.updateView(model.getBoard());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
view.addResetButtonListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
// Clear the board
|
|
||||||
model.clear();
|
|
||||||
|
|
||||||
// Update the view
|
|
||||||
view.updateView(model.getBoard());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
view.addRandomButtonListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
// Randomize the board
|
|
||||||
model.randomizeBoard();
|
|
||||||
|
|
||||||
// Update the view
|
|
||||||
view.updateView(model.getBoard());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
view.addCellClickListener(new CellActionListener());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Start the GUI */
|
|
||||||
public void start() {
|
|
||||||
view.setVisible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CellActionListener is an ActionListener for the Sudoku grid cells
|
|
||||||
*/
|
|
||||||
private class CellActionListener implements ActionListener {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
// Get the row and column from the clicked cell
|
|
||||||
int row = view.getSelectedRow();
|
|
||||||
int col = view.getSelectedColumn();
|
|
||||||
|
|
||||||
String inputText = view.getCellValue(row, col);
|
|
||||||
int value = Integer.parseInt(inputText);
|
|
||||||
// Check if the input is legal and update the model and view
|
|
||||||
if (model.isLegal(row, col, value)) {
|
|
||||||
model.set(row, col, value);
|
|
||||||
view.updateView(model.getBoard());
|
|
||||||
} else {
|
|
||||||
view.showErrorMessage("Invalid input. Try again.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,186 +0,0 @@
|
||||||
package gui;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.event.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SolverView is a GUI for the SudokuSolver interface
|
|
||||||
*/
|
|
||||||
public class SudokuView extends JFrame {
|
|
||||||
/** The grid of text fields */
|
|
||||||
private JTextField[][] grid;
|
|
||||||
|
|
||||||
/** Button for solve */
|
|
||||||
private JButton solveButton;
|
|
||||||
/** Button for reset */
|
|
||||||
private JButton resetButton;
|
|
||||||
/** Button for random */
|
|
||||||
private JButton randomButton;
|
|
||||||
|
|
||||||
/** Constructor */
|
|
||||||
public SudokuView() {
|
|
||||||
setTitle("Sudoku Solver");
|
|
||||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
||||||
setLayout(new BorderLayout());
|
|
||||||
|
|
||||||
initializeGrid();
|
|
||||||
initializeButtons();
|
|
||||||
|
|
||||||
pack();
|
|
||||||
setLocationRelativeTo(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Initialize the grid, called by the constructor */
|
|
||||||
private void initializeGrid() {
|
|
||||||
grid = new JTextField[9][9];
|
|
||||||
JPanel gridPanel = new JPanel(new GridLayout(9, 9));
|
|
||||||
|
|
||||||
for (int row = 0; row < 9; row++) {
|
|
||||||
for (int col = 0; col < 9; col++) {
|
|
||||||
grid[row][col] = new JTextField(2);
|
|
||||||
grid[row][col].setHorizontalAlignment(JTextField.CENTER);
|
|
||||||
gridPanel.add(grid[row][col]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
add(gridPanel, BorderLayout.CENTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Initialize the buttons, called by the constructor */
|
|
||||||
private void initializeButtons() {
|
|
||||||
solveButton = new JButton("Solve");
|
|
||||||
resetButton = new JButton("Reset");
|
|
||||||
randomButton = new JButton("Randomize");
|
|
||||||
|
|
||||||
JPanel buttonPanel = new JPanel();
|
|
||||||
buttonPanel.add(solveButton);
|
|
||||||
buttonPanel.add(resetButton);
|
|
||||||
buttonPanel.add(randomButton);
|
|
||||||
|
|
||||||
add(buttonPanel, BorderLayout.SOUTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the view with a new grid
|
|
||||||
*
|
|
||||||
* @param newGrid the new grid to display
|
|
||||||
*/
|
|
||||||
public void updateView(int[][] newGrid) {
|
|
||||||
for (int row = 0; row < 9; row++) {
|
|
||||||
for (int col = 0; col < 9; col++) {
|
|
||||||
if (newGrid[row][col] != 0) {
|
|
||||||
grid[row][col].setText(String.valueOf(newGrid[row][col]));
|
|
||||||
} else {
|
|
||||||
grid[row][col].setText("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to add ActionListener to solve button
|
|
||||||
*
|
|
||||||
* @param listener the ActionListener to add
|
|
||||||
*/
|
|
||||||
public void addSolveButtonListener(ActionListener listener) {
|
|
||||||
solveButton.addActionListener(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to add ActionListener to reset button
|
|
||||||
*
|
|
||||||
* @param listener the ActionListener to add
|
|
||||||
*/
|
|
||||||
public void addResetButtonListener(ActionListener listener) {
|
|
||||||
resetButton.addActionListener(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to add ActionListener to randomize button
|
|
||||||
*
|
|
||||||
* @param listener the ActionListener to add
|
|
||||||
*/
|
|
||||||
public void addRandomButtonListener(ActionListener listener) {
|
|
||||||
randomButton.addActionListener(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to add ActionListener to individual cells in the grid
|
|
||||||
* <p>
|
|
||||||
* Assumes that the ActionListener will be the same for all cells
|
|
||||||
* and that the listener will be capable of determining which cell
|
|
||||||
* was clicked
|
|
||||||
*
|
|
||||||
* @param listener the ActionListener to add
|
|
||||||
*/
|
|
||||||
public void addCellClickListener(ActionListener listener) {
|
|
||||||
for (int row = 0; row < 9; row++) {
|
|
||||||
for (int col = 0; col < 9; col++) {
|
|
||||||
grid[row][col].addActionListener(listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Getter method to retrieve the values from the text fields
|
|
||||||
*
|
|
||||||
* @param row the row of the cell
|
|
||||||
* @param col the column of the cell
|
|
||||||
* @return the value of the cell
|
|
||||||
*/
|
|
||||||
public String getCellValue(int row, int col) {
|
|
||||||
return grid[row][col].getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to get the selected row (example implementation)
|
|
||||||
*
|
|
||||||
* @return the selected row, or -1 if no cell is selected
|
|
||||||
*/
|
|
||||||
public int getSelectedRow() {
|
|
||||||
for (int row = 0; row < 9; row++) {
|
|
||||||
for (int col = 0; col < 9; col++) {
|
|
||||||
if (grid[row][col].isFocusOwner()) {
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1; // Return -1 if no cell is selected
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to get the selected column (example implementation)
|
|
||||||
*
|
|
||||||
* @return the selected row, or -1 if no cell is selected
|
|
||||||
*/
|
|
||||||
public int getSelectedColumn() {
|
|
||||||
for (int row = 0; row < 9; row++) {
|
|
||||||
for (int col = 0; col < 9; col++) {
|
|
||||||
if (grid[row][col].isFocusOwner()) {
|
|
||||||
return col;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1; // Return -1 if no cell is selected
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Methods to show dialogs
|
|
||||||
*
|
|
||||||
* @param message the message to display
|
|
||||||
* @return the user input
|
|
||||||
*/
|
|
||||||
public String showInputDialog(String message) {
|
|
||||||
return JOptionPane.showInputDialog(this, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to show error messages
|
|
||||||
*
|
|
||||||
* @param message the message to display
|
|
||||||
*/
|
|
||||||
public void showErrorMessage(String message) {
|
|
||||||
JOptionPane.showMessageDialog(this, message);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +1,40 @@
|
||||||
package sudoku;
|
package sudoku;
|
||||||
|
|
||||||
/** Solver is a class that implements the SudokuSolver interface */
|
|
||||||
public class Solver implements SudokuSolver {
|
public class Solver implements SudokuSolver {
|
||||||
private int[][] board = null;
|
private int[][] board = null;
|
||||||
private int tries = 0;
|
private int tries = 0;
|
||||||
|
|
||||||
/** Constructor */
|
|
||||||
public Solver() {
|
public Solver() {
|
||||||
board = new int[9][9];
|
board = new int[9][9];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setBoard(int[][] board) {
|
public void setBoard(int[][] board) {
|
||||||
this.board = board;
|
this.board = board;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int[][] getBoard() {
|
public int[][] getBoard() {
|
||||||
return board;
|
return board;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resets the board to all zeros */
|
/**
|
||||||
|
* Resets the board to all zeros
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void clear() {
|
public void clear() {
|
||||||
board = new int[9][9];
|
board = new int[9][9];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*{@inheritDoc} */
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean solve() {
|
public boolean solve() {
|
||||||
return solve(0, 0);
|
return solve(0, 0);
|
||||||
|
@ -92,7 +98,9 @@ public class Solver implements SudokuSolver {
|
||||||
randomizeBoard(3);
|
randomizeBoard(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void randomizeBoard(int difficulty) {
|
public void randomizeBoard(int difficulty) {
|
||||||
int amount_prefilled = (difficulty * 9) + 1;
|
int amount_prefilled = (difficulty * 9) + 1;
|
||||||
|
@ -113,7 +121,9 @@ public class Solver implements SudokuSolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void set(int row, int col, int val) {
|
public void set(int row, int col, int val) {
|
||||||
if (row < 9 && col < 9) {
|
if (row < 9 && col < 9) {
|
||||||
|
@ -121,7 +131,9 @@ public class Solver implements SudokuSolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int get(int row, int col) {
|
public int get(int row, int col) {
|
||||||
if (row < 9 && col < 9) {
|
if (row < 9 && col < 9) {
|
||||||
|
@ -130,7 +142,9 @@ public class Solver implements SudokuSolver {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isLegal(int row, int col, int num) {
|
public boolean isLegal(int row, int col, int num) {
|
||||||
// Sanity check
|
// Sanity check
|
||||||
|
@ -160,7 +174,9 @@ public class Solver implements SudokuSolver {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public boolean isSolvable() {
|
public boolean isSolvable() {
|
||||||
// We want to work on a copy
|
// We want to work on a copy
|
||||||
int[][] copy = new int[9][9];
|
int[][] copy = new int[9][9];
|
||||||
|
|
|
@ -1,34 +1,12 @@
|
||||||
package sudoku;
|
package sudoku;
|
||||||
|
|
||||||
import gui.SudokuController;
|
|
||||||
import gui.SudokuView;
|
|
||||||
|
|
||||||
/** SolverMain is the main class for the Sudoku Solver */
|
|
||||||
public class SolverMain {
|
public class SolverMain {
|
||||||
|
|
||||||
private Solver model;
|
|
||||||
private SudokuView view;
|
|
||||||
private SudokuController controller;
|
|
||||||
|
|
||||||
/** Constructor */
|
|
||||||
SolverMain() {
|
|
||||||
model = new Solver();
|
|
||||||
view = new SudokuView();
|
|
||||||
controller = new SudokuController(model, view);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Start the GUI */
|
|
||||||
void start() {
|
|
||||||
controller.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main method
|
|
||||||
*
|
|
||||||
* @param args command line arguments
|
|
||||||
*/
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SolverMain main = new SolverMain();
|
Solver s = new Solver();
|
||||||
main.start();
|
System.out.println(s.toString());
|
||||||
|
s.randomizeBoard();
|
||||||
|
System.out.println(s.toString());
|
||||||
|
s.solve();
|
||||||
|
System.out.println(s.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue