Как найти и решить для нескольких решений в Судоку Солвер? - PullRequest
0 голосов
/ 30 марта 2019

Я создал программу, которая принимает txt-файл для доски судоку. Я сохраняю его в 2D-массив и имею функцию решения, чтобы решить его. Моя единственная проблема, с которой я остаюсь, заключается в том, как мне добавить возможность найти другое решение, если оно уже найдено? Как только решение найдено, я бы спросил пользователя о трех вариантах. Если они захотят найти другое решение, измените значение на доске и выйдите.

Ниже будет двухмерный массив, представляющий собой доску, а 0 будет пустым

int[][] grid = {{3, 0, 6, 5, 0, 8, 4, 0, 0},
                 {5, 2, 0, 0, 0, 0, 0, 0, 0},
                 {0, 8, 7, 0, 0, 0, 0, 3, 1},
                 {0, 0, 3, 0, 1, 0, 0, 8, 0},
                 {9, 0, 0, 8, 6, 3, 0, 0, 5},
                 {0, 5, 0, 0, 9, 0, 6, 0, 0},
                 {1, 3, 0, 0, 0, 0, 2, 5, 0},
                 {0, 0, 0, 0, 0, 0, 0, 7, 4},
                 {0, 0, 5, 2, 0, 6, 3, 0, 0}};

Ниже приведены функции для решения платы. Пока этого достаточно, чтобы решить доску один раз. Это не работает, чтобы решить другое время найти другое решение. Что мне нужно для варианта А из пользовательского ввода.

private static boolean isRowAvailable(int[][] board, int coordinateX, int value){
        for(int i = 0; i < 9; i++){
            if(board[coordinateX][i] == value)
                return false;
        }
        return true;
    }

    private static boolean isColumnAvailable(int[][] board, int coordinateY, int value){
        for(int i = 0; i < 9; i++){
            if(board[i][coordinateY] == value)
                return false;
        }
        return true;
    }

    private static boolean isSquareAvailable(int[][] board, int coordinateX, int coordinateY, int value){
        int firstNewX = 0, secondNewX = 0, firstNewY = 0, secondNewY = 0;

        if(coordinateX >= 0 && coordinateX <= 2){
            firstNewX = 0;
            secondNewX = 2;
        }
        else if(coordinateX >= 3 && coordinateX <= 5){
            firstNewX = 3;
            secondNewX = 5;
        }
        else if(coordinateX >= 6 && coordinateX <= 8){
            firstNewX = 6;
            secondNewX = 8;
        }

        if(coordinateY >= 0 && coordinateY <= 2){
            firstNewY = 0;
            secondNewY = 2;
        }
        else if(coordinateY >= 3 && coordinateY <= 5){
            firstNewY = 3;
            secondNewY = 5;
        }
        else if(coordinateY >= 6 && coordinateY <= 8){
            firstNewY = 6;
            secondNewY = 8;
        }

        for(int i = firstNewX; i <= secondNewX; i++){
            for(int j = firstNewY; j <= secondNewY; j++){
                if(board[i][j] == value)
                    return false;
            }
        }
        return true;

    }

    private static boolean isAvailable(int[][] board, int coordinateX, int coordinateY, int value){
        if(isRowAvailable(board, coordinateX, value) &&
                isColumnAvailable(board, coordinateY, value) &&
                isSquareAvailable(board, coordinateX, coordinateY, value) &&
                board[coordinateX][coordinateY] == 0)
            return true;
        return false;
    }

    private static boolean findEmptySpot(int[][] board, int[] coordinates){
        for(coordinates[0] = 0; coordinates[0] < 9; coordinates[0]++){
            for(coordinates[1] = 0; coordinates[1] < 9; coordinates[1]++){
                if(board[coordinates[0]][coordinates[1]] == 0)
                    return true;
            }
        }
        return false;
    }

    private static boolean solveSudoku(int[][] board){
        int x = 0, y = 0;
        int[] coordinates = {x, y};

        if (!findEmptySpot(board, coordinates))
            return true;

        x = coordinates[0];
        y = coordinates[1];

        for(int num = 1; num <= 9; num++)
        {
            if (isAvailable(board, x, y, num))
            {
                board[x][y] = num;

                if(solveSudoku(board))
                    return true;

                board[x][y] = 0;
            }
        }
        return false;
    }

Ниже приведена функция для обработки пользовательского ввода для меню

switch(upperResponse){
                case 'A':
                    //instructions for finding another solution
                    break;
                case 'B':
                    changeConstraint();
                    break;
                case 'C':
                    break;
                default:
                    System.out.println("Please enter valid option");
            }

Ожидаемый результат, к которому я стремлюсь, будет для этого ниже

Solving the puzzle below:
0 0 1 6 0 0 0 7 0
0 0 0 0 3 0 0 0 6
0 7 0 0 4 0 3 0 0
0 0 9 0 0 0 6 0 3
0 0 0 0 0 0 0 1 0
0 0 0 8 1 0 0 9 2
0 0 6 0 0 0 0 2 5
0 0 0 0 5 0 0 0 0
3 2 0 4 0 0 8 0 9 
A solution is:
5 3 1 6 8 2 9 7 4
8 9 4 1 3 7 2 5 6
6 7 2 5 4 9 3 8 1
1 8 9 7 2 5 6 4 3
2 5 3 9 6 4 7 1 8
4 6 7 8 1 3 5 9 2
7 1 6 3 9 8 4 2 5
9 4 8 2 5 6 1 3 7
3 2 5 4 7 1 8 6 9
What would you like to do? 
(A) find another solution, (B) change a constraint  (C) quit
Input: A
Another solution is:
5 3 1 6 8 2 9 7 4
8 9 4 1 3 7 2 5 6
6 7 2 5 4 9 3 8 1
1 8 9 7 2 5 6 4 3
2 5 3 9 6 4 7 1 8
4 6 7 8 1 3 5 9 2
7 4 6 3 9 8 1 2 5
9 1 8 2 5 6 4 3 7
3 2 5 4 7 1 8 6 9
...