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…
	
	Add table
		Add a link
		
	
		Reference in a new issue