diff --git a/.gitignore b/.gitignore index 722dd18..34124a5 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,3 @@ build .vscode -app/bin \ No newline at end of file diff --git a/Justfile b/Justfile index 6ed91e0..6ef3ad1 100644 --- a/Justfile +++ b/Justfile @@ -2,16 +2,10 @@ run: ./gradlew run test: - ./gradlew test --rerun-tasks - -doc: - ./gradlew javadoc --rerun-tasks + ./gradlew test clean: fd -td -I build -x rm -r watch: - watchexec -r -c -w app/src "just test && just run" - -watchdoc: - watchexec -r -c -w app/src "just doc" + watchexec -c -w app/src "just test && just run" \ No newline at end of file diff --git a/app/sample_sudokus/demo_from_lab.txt b/app/sample_sudokus/demo_from_lab.txt deleted file mode 100644 index f6b5bbc..0000000 --- a/app/sample_sudokus/demo_from_lab.txt +++ /dev/null @@ -1,9 +0,0 @@ -0 0 9 0 7 1 3 0 0 -0 0 1 0 0 0 0 0 0 -6 0 0 0 9 0 0 4 7 -5 0 0 9 0 4 0 0 0 -1 0 4 0 0 0 2 0 9 -0 0 0 1 0 8 0 0 4 -7 3 0 0 1 0 0 0 2 -0 0 0 0 0 0 5 0 0 -0 0 8 2 4 0 6 0 0 \ No newline at end of file diff --git a/app/sample_sudokus/testfall_3.txt b/app/sample_sudokus/testfall_3.txt deleted file mode 100644 index 3d08a4c..0000000 --- a/app/sample_sudokus/testfall_3.txt +++ /dev/null @@ -1,9 +0,0 @@ -1 2 3 0 0 0 0 0 0 -4 5 6 0 0 0 0 0 0 -0 0 0 7 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 \ No newline at end of file diff --git a/app/sample_sudokus/testfall_5.txt b/app/sample_sudokus/testfall_5.txt deleted file mode 100644 index e512bf8..0000000 --- a/app/sample_sudokus/testfall_5.txt +++ /dev/null @@ -1,9 +0,0 @@ -0 0 8 0 0 9 0 6 2 -0 0 0 0 0 0 0 0 5 -1 0 2 5 0 0 0 0 0 -0 0 0 2 1 0 0 9 0 -0 5 0 0 0 0 6 0 0 -6 0 0 0 0 0 0 2 8 -4 1 0 6 0 8 0 0 0 -8 6 0 0 3 0 1 0 0 -0 0 0 0 0 0 4 0 0 \ No newline at end of file diff --git a/app/src/main/java/gui/SudokuController.java b/app/src/main/java/gui/SudokuController.java deleted file mode 100644 index 0d91eed..0000000 --- a/app/src/main/java/gui/SudokuController.java +++ /dev/null @@ -1,142 +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 - boolean solved = model.solve(); - // Update the view - view.updateView(model.getBoard()); - if (!solved) { - view.showErrorMessage("Could not solve the board."); - System.out.println("Could not solve the board."); - System.out.println(model.toString()); - } else { - } - - } - }); - - 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.addFileButtonListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - // Open a file, view handles the parsing internally via SudokuParser - int[][] newBoard = view.openFile(); - - // If the file was parsed successfully - if (newBoard != null) { - // Set the model - model.setBoard(newBoard); - - // Warn and clear if the board is not solvable - if(!model.isSolvable()) { - view.showErrorMessage("The board is not solvable."); - model.clear(); - } - - // Update the view - view.updateView(model.getBoard()); - } - } - }); - - view.addCellActionListener(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(); - - // The value to be inserted into the cell - // Zero inicates an empty cell - // Negative values are invalid - int value = 0; - - String cellValue = view.getCellValue(row, col); - - // We need to check for null and empty string - if (cellValue == null || cellValue.equals("")) { - value = 0; - } else { - try { - value = Integer.parseInt(cellValue); - } catch (NumberFormatException ex) { - value = -1; - } - } - - // If the input is invalid, value < 0 indicates parse error - if (value != 0 && !model.isLegal(row, col, value) || value < 0) { - value = 0; - view.showErrorMessage("Invalid input. Try again."); - } - - // Update the model and view - model.set(row, col, value); - - // Warn if the board is not solvable (e.g. if the user has made a mistake) - // This is very messy, error prone and computationally expensive - if(!model.isSolvable()) { - model.set(row, col, 0); - view.showErrorMessage("Illegal move. The board is not solvable."); - } - - // Sync the view with the model - view.updateView(model.getBoard()); - } - } -} diff --git a/app/src/main/java/gui/SudokuView.java b/app/src/main/java/gui/SudokuView.java deleted file mode 100644 index 7cd86eb..0000000 --- a/app/src/main/java/gui/SudokuView.java +++ /dev/null @@ -1,239 +0,0 @@ -package gui; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; - -import sudoku.SudokuParser; - -/** - * 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; - /** Button for picking a Sudoku-file */ - private JButton fileButton; - - /** 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); - - // Set background color to gray for every third JTextField - if ((row / 3 + col / 3) % 2 == 1) { - grid[row][col].setBackground(Color.LIGHT_GRAY); - } - - 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"); - fileButton = new JButton("Open file"); - - JPanel buttonPanel = new JPanel(); - buttonPanel.add(solveButton); - buttonPanel.add(resetButton); - buttonPanel.add(randomButton); - buttonPanel.add(fileButton); - - 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 file button - * - * @param listener the ActionListener to add - */ - public void addFileButtonListener(ActionListener listener) { - fileButton.addActionListener(listener); - } - - /** - * Method to add ActionListener to individual cells in the grid - *

- * 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 addCellActionListener(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); - } - - /** - * Method to open a file picker dialog - * - * @return 2D array of integers representing the Sudoku board - */ - public int[][] openFile() { - // Create a file chooser and set all related options - JFileChooser fileChooser = new JFileChooser(); - fileChooser.setCurrentDirectory(new java.io.File(".")); - fileChooser.setDialogTitle("Select a Sudoku file"); - fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); - fileChooser.setAcceptAllFileFilterUsed(false); - - // Show the file chooser and return if the user cancels - int returnValue = fileChooser.showOpenDialog(this); - if (returnValue != JFileChooser.APPROVE_OPTION) { - return null; - } - - // Get the path - String filepath = fileChooser.getSelectedFile().getAbsolutePath(); - - // Try to parse it - try { - return SudokuParser.parseSudoku(filepath); - } catch (Exception e) { - showErrorMessage(e.getMessage()); - return null; - } - } -} diff --git a/app/src/main/java/sudoku/Solver.java b/app/src/main/java/sudoku/Solver.java index 95a77b3..4eb977c 100644 --- a/app/src/main/java/sudoku/Solver.java +++ b/app/src/main/java/sudoku/Solver.java @@ -1,44 +1,36 @@ package sudoku; -/** Solver is a class that implements the SudokuSolver interface */ public class Solver implements SudokuSolver { private int[][] board = null; - private int tries = 0; - /** Constructor */ public Solver() { board = new int[9][9]; } - /** {@inheritDoc} */ - @Override - public void setBoard(int[][] board) throws IllegalArgumentException, NullPointerException { - if (board == null) - throw new NullPointerException("Board cannot be null"); - if (board.length != 9 || board[0].length != 9) - throw new IllegalArgumentException("Board must be 9x9"); + /** + * {@inheritDoc} + */ + public void setBoard(int[][] board) { this.board = board; } - /** {@inheritDoc} */ - @Override + /** + * {@inheritDoc} + */ public int[][] getBoard() { return board; } - /** Resets the board to all zeros */ - @Override + /** + * Resets the board to all zeros + */ public void clear() { - for (int[] row : board) { - for (int i = 0; i < row.length; ++i) { - row[i] = 0; - } - } - // board = new int[9][9]; + board = new int[9][9]; } - /* {@inheritDoc} */ - @Override + /** + * {@inheritDoc} + */ public boolean solve() { return solve(0, 0); } @@ -51,10 +43,6 @@ public class Solver implements SudokuSolver { * @return true if solved */ private boolean solve(int row, int col) { - if (++tries >= 10000) { - return false; - } - if (row < 0 || row > 9 || col < 0 || col > 9) { return false; } @@ -69,7 +57,6 @@ public class Solver implements SudokuSolver { // If we have a "number" in the current cell // recursively call solve() on the next cell - // until we find a zero (empty cell) if (board[row][col] != 0) { return solve(row + 1, col); } @@ -85,26 +72,16 @@ public class Solver implements SudokuSolver { } } - // Reset the current cell to zero and backtrack board[row][col] = 0; return false; } /** - * {@inheritDoc} - *

- * Default difficulty is 3 + * Randomizes the board. This guarantees a solvable board. */ public void randomizeBoard() { - randomizeBoard(3); - } - - /** {@inheritDoc} */ - @Override - public void randomizeBoard(int difficulty) { - int amount_prefilled = (difficulty * 9) + 1; this.clear(); - for (int i = 0; i < amount_prefilled; ++i) { + for (int i = 0; i < 9; ++i) { int row = (int) (Math.random() * 9); int col = (int) (Math.random() * 9); int val = (int) (Math.random() * 9) + 1; @@ -112,28 +89,20 @@ public class Solver implements SudokuSolver { board[row][col] = val; } } - - // Recursively call randomizeBoard() until we get a solvable board - // This is expensive, and there should be a better way to do this - if (!isSolvable()) { - randomizeBoard(difficulty); - } } - /** - * {@inheritDoc} - *

- * This is not checked for validity + /** + * {@inheritDoc} */ - @Override public void set(int row, int col, int val) { if (row < 9 && col < 9) { board[row][col] = val; } } - /** {@inheritDoc} */ - @Override + /** + * {@inheritDoc} + */ public int get(int row, int col) { if (row < 9 && col < 9) { return board[row][col]; @@ -141,32 +110,35 @@ public class Solver implements SudokuSolver { return 0; } - /** {@inheritDoc} */ - @Override - public boolean isLegal(int row, int col, int num) { - // Sanity check - if (row < 0 || row >= 9 || col < 0 || col >= 9 || num < 1 || num > 9) { + /** + * {@inheritDoc} + */ + public boolean isLegal(int row, int col, int val) { + if (row < 0 || row >= 9 || col < 0 || col >= 9 || val < 1 || val > 9) { return false; } - // Ihe the number is already present in the cell - if (board[row][col] == num) { - return true; + // Check if val is already in col + for (int i = 0; i < 9; ++i) { + if (val == board[i][col]) { + return false; + } } - // Check both the row and column - for (int i = 0; i < 9; i++) { - if (board[row][i] == num || board[i][col] == num) { - return false; // 'num' is already in the row or column + // Check if val is already in row + for (int j = 0; j < 9; ++j) { + if (val == board[row][j]) { + return false; } } // Check the 3x3 box int boxRowOffset = (row / 3) * 3; int boxColOffset = (col / 3) * 3; + for (int k = 0; k < 3; ++k) { for (int m = 0; m < 3; ++m) { - if (num == board[boxRowOffset + k][boxColOffset + m]) { + if (val == board[boxRowOffset + k][boxColOffset + m]) { return false; } } @@ -176,26 +148,11 @@ public class Solver implements SudokuSolver { return true; } - /** {@inheritDoc} */ - public boolean isSolvable() { - // We want to work on a copy - int[][] copy = new int[9][9]; - for (int row = 0; row < 9; row++) { - System.arraycopy(board[row], 0, copy[row], 0, 9); - } - - Solver copyModel = new Solver(); - copyModel.setBoard(copy); - - return copyModel.solve(); - } - /** * Checks if the board is solved * * @return true if solved */ - @Override public boolean isSolved() { return isSolved(0, 0); } @@ -247,7 +204,7 @@ public class Solver implements SudokuSolver { } } - return isSolved(row + 1, col); + return true; } /** diff --git a/app/src/main/java/sudoku/SolverMain.java b/app/src/main/java/sudoku/SolverMain.java index ea5ed7c..7077608 100644 --- a/app/src/main/java/sudoku/SolverMain.java +++ b/app/src/main/java/sudoku/SolverMain.java @@ -1,34 +1,12 @@ package sudoku; -import gui.SudokuController; -import gui.SudokuView; - -/** SolverMain is the main class for the Sudoku Solver */ 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) { - SolverMain main = new SolverMain(); - main.start(); + Solver s = new Solver(); + System.out.println(s.toString()); + s.randomizeBoard(); + System.out.println(s.toString()); + s.solve(); + System.out.println(s.toString()); } } diff --git a/app/src/main/java/sudoku/SudokuParser.java b/app/src/main/java/sudoku/SudokuParser.java deleted file mode 100644 index bbe7ac9..0000000 --- a/app/src/main/java/sudoku/SudokuParser.java +++ /dev/null @@ -1,73 +0,0 @@ -package sudoku; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.io.FileNotFoundException; - -/** Helpers class for parsing Sudoku files */ -public class SudokuParser { - private static final int BOARD_SIZE = 9; - - // * Empty private constructor */ - private SudokuParser() { - // Empty - }; - - /** - * Parses a Sudoku file and returns a 2D array of integers - * - * @param filePath Path to the Sudoku file - * @return 2D array of integers representing the Sudoku board - * @throws IOException If an IO error occurs - * @throws FileNotFoundException When the file cannot be found - * @throws NumberFormatException When the file contains invalid characters - * @throws IllegalArgumentException When the file contains an invalid number of - * rows or columns - */ - public static int[][] parseSudoku(String filePath) - throws IOException, FileNotFoundException, NumberFormatException, IllegalArgumentException { - int[][] sudokuBoard = new int[BOARD_SIZE][BOARD_SIZE]; - - // In practice we could just split the entire file into a single string and then - // parse it into an array of integers, which is then partitioned into a 2D - // array. - // However, this is how the assignment is specified, so we will do it this way. - - // Try to read the file with a BufferedReader - try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { - String line; - int row = 0; - - // While there are lines to read and we haven't reached the end of the board - while ((line = reader.readLine()) != null && row < BOARD_SIZE) { - // Split it into an array of strings - String[] values = line.trim().split("\\s+"); - - // Check that the number of columns is correct - if (values.length != BOARD_SIZE) { - throw new IllegalArgumentException("Invalid number of columns in the Sudoku file."); - } - - // Parse the strings into integers and add them to the board - for (int col = 0; col < BOARD_SIZE; col++) { - sudokuBoard[row][col] = Integer.parseInt(values[col]); // Throws NumberFormatException - } - - row++; - } - - if (row != BOARD_SIZE) { - throw new IllegalArgumentException("Invalid number of rows in the Sudoku file."); - } - } catch (FileNotFoundException e) { - throw new FileNotFoundException("The Sudoku file could not be found."); - } catch (IOException e) { - throw new IOException("An error occurred while reading the Sudoku file."); - } catch (NumberFormatException e) { - throw new NumberFormatException("The Sudoku file contains invalid characters."); - } - - return sudokuBoard; - } -} diff --git a/app/src/main/java/sudoku/SudokuSolver.java b/app/src/main/java/sudoku/SudokuSolver.java index 758e5b5..e77ecdd 100644 --- a/app/src/main/java/sudoku/SudokuSolver.java +++ b/app/src/main/java/sudoku/SudokuSolver.java @@ -1,6 +1,5 @@ package sudoku; -/** SudokuSolver is an interface for implementing Sudoku solvers */ public interface SudokuSolver { /** * Set sudoku board, numbers 1-9 are fixed values, 0 is unsolved. @@ -8,12 +7,10 @@ public interface SudokuSolver { * @param board a board to copy values from * @throws IllegalArgumentException if board is invalid, e.g. not 9x9 */ - void setBoard(int[][] board) throws IllegalArgumentException, NullPointerException; + void setBoard(int[][] board); /** * Get a copy of the sudoku board - * - * @return a copy of the sudoku board */ int[][] getBoard(); @@ -27,9 +24,9 @@ public interface SudokuSolver { /** * Check if digit is legal on the current board * - * @param row row - * @param col column - * @param nbr number to check + * @param row + * @param col + * @param nbr * @return true if legal */ boolean isLegal(int row, int col, int nbr); @@ -37,8 +34,8 @@ public interface SudokuSolver { /** * Get number on board * - * @param row row - * @param col column + * @param row + * @param col * @return number on board */ int get(int row, int col); @@ -46,38 +43,12 @@ public interface SudokuSolver { /** * Set number on board, numbers 1-9 are fixed values, 0 is unsolved. * - * @param row row - * @param col column - * @param nbr number to set + * @param row + * @param col + * @param nbr */ void set(int row, int col, int nbr); - /** - * Randomize the board. Guaranteed to be solvable. - */ - public void randomizeBoard(); - - /** - * Randomize the board. Guaranteed to be solvable. - * - * @param difficulty 0-9, 0 being easiest - */ - void randomizeBoard(int difficulty); - - /** - * Check if the board is solved - * - * @return true if solved - */ - boolean isSolved(); - - /** - * Checks if the board is solvable - * - * @return true if solvable - */ - boolean isSolvable(); - /** * Clear the board */ diff --git a/app/src/test/java/sudoku/SolverTest.java b/app/src/test/java/sudoku/SolverTest.java index 7000140..2877430 100644 --- a/app/src/test/java/sudoku/SolverTest.java +++ b/app/src/test/java/sudoku/SolverTest.java @@ -1,6 +1,6 @@ package sudoku; -import org.junit.jupiter.api.RepeatedTest; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; import java.util.stream.IntStream; @@ -34,8 +34,7 @@ class SolverTest { assertTrue(solver.isLegal(0, 0, 1)); solver.set(0, 0, 1); - // Start from one, since setting the same value is legal - IntStream.range(1, 9).forEach(i -> { + IntStream.range(0, 9).forEach(i -> { assertFalse(solver.isLegal(0, i, 1)); assertFalse(solver.isLegal(i, 0, 1)); }); @@ -46,7 +45,6 @@ class SolverTest { } @Test - @RepeatedTest(100) void solverTest() { Solver solver = new Solver(); assertFalse(solver.isSolved()); @@ -54,16 +52,12 @@ class SolverTest { assertTrue(solver.isSolved()); solver.clear(); + solver.randomizeBoard(); assertFalse(solver.isSolved()); assertTrue(solver.solve()); - } - - @Test - @RepeatedTest(100) - void randomizeBoardGuaranteeSolvableTest() { - Solver solver = new Solver(); + solver.clear(); solver.randomizeBoard(); - assertTrue(solver.solve()); + assertFalse(solver.isSolved()); } @Test @@ -85,64 +79,11 @@ class SolverTest { } @Test + @Disabled void unsolvableTest() { Solver solver = new Solver(); - - // Simple example - solver.clear(); solver.set(0, 0, 1); solver.set(0, 1, 1); assertFalse(solver.solve()); - - // More complex example - solver.clear(); - solver.set(0, 5, 7); - solver.set(0, 6, 8); - solver.set(0, 7, 2); - solver.set(1, 5, 3); - solver.set(2, 7, 1); - solver.set(3, 1, 4); - solver.set(5, 2, 8); - solver.set(5, 8, 6); - solver.set(7, 1, 8); - assertFalse(solver.solve()); - } - - @Test - void unsolvableTestCase3() { - Solver solver = new Solver(); - - // More complex example - solver.clear(); - solver.set(0, 0, 1); - solver.set(0, 1, 2); - solver.set(0, 2, 3); - solver.set(1, 0, 4); - solver.set(1, 1, 5); - solver.set(1, 2, 6); - solver.set(2, 3, 7); - assertFalse(solver.isSolvable()); - } - - @Test - void solvableTestCase3() { - Solver solver = new Solver(); - - // More complex example - solver.clear(); - solver.set(0, 0, 1); - solver.set(0, 1, 2); - solver.set(0, 2, 3); - solver.set(1, 0, 4); - solver.set(1, 1, 5); - solver.set(1, 2, 6); - assertTrue(solver.isSolvable()); - } - - @Test - void setBoardInvalidInputThrowsTest() { - Solver solver = new Solver(); - assertThrows(NullPointerException.class, () -> solver.setBoard(null)); - assertThrows(IllegalArgumentException.class, () -> solver.setBoard(new int[8][8])); } } diff --git a/app/src/test/java/sudoku/SudokuParserTest.java b/app/src/test/java/sudoku/SudokuParserTest.java deleted file mode 100644 index b63be11..0000000 --- a/app/src/test/java/sudoku/SudokuParserTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package sudoku; - -import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - -public class SudokuParserTest { - @Test - void constructorTest() { - int[][] board; - try { - board = SudokuParser.parseSudoku("sample_sudokus/demo_from_lab.txt"); - } catch (Exception e) { - board = null; - } - assertNotNull(board); - } -}