Hint a single value for a Sudoku puzzle

I was hoping someone would be able to help me out. I am making a Sudoku game, and I wrote a class which solves the entire puzzle (and it is of course connected to an action button in another java file), and it works well.

What I wanted to know is if someone could point me in the right direction if I wanted to make a "hint" button, which randomly applies the correct value to just one individual square.

Here is the solver code:

public class SudokuSolver {

// set unchangeable number of rows to 9
private static final int ROWS = 9;
// set unchangeable number of columns to 9
private static final int COLUMNS = 9;
// the multidimensional array that will be the solution
private int[][] puzzleSolution;
// the 9x9 solution multidimensional array containing the correct puzzle values
public static int[][] solution = new int[ROWS][COLUMNS];

/**
 * SudokuSolver constructor takes your incomplete puzzle and calls the solver method on it in order to get a
 * completed puzzle. The completed puzzle is stored in a solution multidimensional array.
 * @param puzzle the puzzle you want to solve.
 */
public SudokuSolver(int[][] puzzle) {
    // store puzzle solution into "puzzle" parameter
    puzzleSolution = puzzle;
    // solve the puzzle
    solvePuzzle(puzzleSolution, 0, 0);
} // end SudokuSolver

/**
 * next takes the current position in the puzzle array and moves it forward.
 * next calls upon the solvePuzzle method to continue checking values of the next array location. This is done so
 * if there is a non empty value in the array, we can skip to an empty one.
 * @param puzzle the array that is being moved forward
 * @param row the row position in the array
 * @param column the column position in the array
 */
public void next(int[][] puzzle, int row, int column) {
    // if we are still within the puzzle columns
    if (column < 8) {
        // solve puzzle by filling empty grid squares in columns
        solvePuzzle(puzzle, row, column + 1);
    } else {
        // otherwise, solve the puzzle by filling empty grid squares in rows
        solvePuzzle(puzzle, row + 1, 0);
    }
} // end next

/**
 * solvePuzzle loops through an incomplete sudoku puzzle in order to solve it.
 * It skips already entered 1 to 9 values using the next function, which then calls the updated function with
 * new row and column positioning. If a value doesn't already exist in its respective row, column, or block, solve
 * adds the value to the array and updates the positioning to check for a new value. At the end of the array, the
 * solution is sent to the "solution" array.
 * @param puzzle the incomplete sudoku puzzle being solved.
 * @param row the current row position of the array.
 * @param col the current column position of the array.
 */
public void solvePuzzle(int[][] puzzle, int row, int col) {
    // if the row value is above 8, then every empty value should be solved
    if (row > 8) {
        System.out.println("nThe puzzle has been automatically solved!nSOLUTION APPLIED:");
        // writing the rows
        for (int r = 0; r < ROWS; r++) {
            // writing the columns
            for (int c = 0; c < COLUMNS; c++) {
                // array to hold the solution
                int[][] solutionArray;
                // places the solved array into the solution array
                solutionArray = puzzle;
                // print out the solution puzzle to console
                System.out.print(solutionArray[r][c] + " ");
            } // end writing columns
            // this empty println is needed to print the puzzle line by line in the console
            System.out.println();
        } // end writing rows
    } else {
        // as long as the value in the array is not zero, skip to zero
        if (puzzle[row][col] != 0) {
            // move to next position of row and column
            next(puzzle, row, col);
        } else {
            /* checks for duplicate values of 1 to 9 in rows, columns and 3x3 blocks, and if there are none, places
             the number in an empty location in the array  */
            for (int index = 1; index <= 9; index++) {
                /* checks that there are no duplicated numbers in the row, column or block, so that we can enter
                 the correct number into the right position in the array */
                if (SudokuChecks.findRowDuplicates(puzzle, row, index) &&
                    SudokuChecks.findColumnDuplicates(puzzle, col, index) &&
                    SudokuChecks.findBlockDuplicates(puzzle, row, col, index)) {
                        // set number at current position to index
                        puzzle[row][col] = index;
                        // move to the next position of row and column
                        next(puzzle, row, col);
                }
            }
            //puzzle[row][col] = 0;
        }
    }
} // end solvePuzzle

/**
 * getSolution is a getter method that will get the values of a solved sudoku.
 * @return will return the correct solution to a solved puzzle
 */

public static int[][] getSolution() {
    // return the solution
    return SudokuSolver.solution;
} // end getSolution

} // end class SudokuSolver

The solver puts the correct values in each corresponding square when a user clicks to solve, but I was thinking to implement a hint to just randomly open one square rather than the entire puzzle. The puzzle solution is always printed to the console, and when "solve" is clicked, the solution is written into the GUI grid. If a square has a value in it, it is obviously skipped. If a square is empty, it is filled with the number that is in its exact position in the console, thereby solving the puzzle.

I hope I explained myself properly, and I hope this code is enough for someone to help get me started with a solution. Thanks alot!


I guess the only possible way to implement a "hint" button is through a slight refactoring of your code:

  • First, solve the puzzle from the very beginning and store the solution in an internal variable.
  • Then, if the "hint" button is clicked, chose a random cell from the solution and print it out. Get track of the filled cells not to chose from any of them.
  • And when the "solve" button is clicked, print out the whole solution.
  • Update

    A proposal for the hint algorithm:

    First, two new methods:

    public class SudokuSolver 
    {
        public Coordinates hint(int[][] puzzle, int[][] solved)
        {
            List<Coordinates> availableCells=getAvailableCells(puzzle);
            int chosenIndex=(int)Math.random()*availableCells.size();
            Coordinates chosenCell=availableCells.get(chosenIndex);
            int chosenRow=chosenCell.getRow();
            int choseColumn=chosenCell.getColumn();
            puzzle[chosenRow][chosenColumn]=solved[chosenRow][chosenColumn];
            return chosenCell;
        }
    
        private List<Coordinates> getAvailableCells(int[][] puzzle)
        {
            List<Coordinates> list=new ArrayList<Coordinates>(MAX_ROWS*MAX_COLUMNS);
            // iterate the puzzle and collect every cell ==0
            return list;
        }
    }
    

    And also a new bean class for the coordinates of a cell:

    public class Coordinates
    {
        private int row;
        private int column;
    
        public int getRow() {
            return row;
        }
    
        public void setRow(int row) {
            this.row = row;
        }
    
        public int getColumn() {
            return column;
        }
    
        public void setColumn(int column) {
            this.column = column;
        }
    }
    

    Add a boolean variable or flag that can be passed into the solvePuzzle function. In the solvePuzzle function, if the hint flag is set, break at the first solved box.

    链接地址: http://www.djcxy.com/p/96170.html

    上一篇: 信号集线器在单独的dll中

    下一篇: 提示数独谜题的单个值