微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

棋盘不规则的骑士游问题

如何解决棋盘不规则的骑士游问题

骑士之旅问题是一个基于回溯的问题。在普通版本中,您有一个 N*N 棋盘,您必须与您的骑士一起访问棋盘上的每一个领域。但真正的问题来了:我只能访问每个领域一次!所以如果我没有更多的领域可以访问,我必须回溯。在您的游戏结束时,字段的数量应等于移动的数量。现在到我的不同版本:我不是使用 N*N 棋盘,而是使用不规则棋盘。例如:第一行有 5 个字段,第二行有 3 个,第三行有 8 个。这些信息是通过布尔数组给我的。也有不允许访问的“假”字段。我不允许更改布尔数组。

public static boolean checkboard(boolean[][] board) {
        for (int i0 = 0; i0 < board.length; i0++) {

            boolean[] dim1 = board[i0];

            if (dim1 == null) {
                return false;
            } if (board.length == 1) {
                return false;
            }
        }
        return true;
    }

这是我代码的第一部分。它检查板(布尔数组)是否有效。这意味着如果至少一行为空或没有行,它应该给我 false。

public static boolean checkPoint(boolean[][] board,int i,int j) {
        try {
            boolean test = board[i][j];

        } catch (indexoutofboundsexception a) {
            return false;
        }
        return true;
    }

方法检查点是否在数组中。

public static boolean isValid(int i,int j,int[][] sol,boolean[][] board) {
        if (i >= 0 && j >= 0 && sol[i][j] == -1 && board[i][j] != false && checkPoint(board,i,j)) {
            return true;
        }
        return false;
    }

现在有一些附加信息: 最后,我想要一个名为“sol”的 int 数组,它与我的布尔数组“board”具有相同的棋盘。但是在溶胶中我保存了动作的次数。如果棋盘中有错误,则溶胶中必须有 0。以下是 sol 数组的示例:

Here is an example of the sol array. "#####" means 0

public static boolean springtour(int[][] sol,int step_count,int[] x_move,int[] y_move,boolean[][] board) {
        int counter = 0;
        for (int row = 0; row < sol.length; row++) {
            for (int col = 0; col < sol[row].length; coL++) {
                if (board[row][col] == true) {
                    counter++;
                }
            }
        }
        if (step_count == counter) {
            return true;
        }
        for(int k=0; k<8; k++) {
            int nextI = i+x_move[k];
            int nextJ = j+y_move[k];

            if (isValid(nextI,nextJ,sol,board)) {
                sol[nextI][nextJ] = step_count;
                if (springtour(sol,nextI,step_count+1,x_move,y_move,board)) {
                    return true;
                }
                    sol[nextI][nextJ] = -1;
            }
        }
        return false;
    }

所以现在这里发生了回溯。一个单元格 (i,j) 最多有 8 次可能的移动。因此,我将创建 2 个数组,以便我们可以使用它们来检查可能的移动(称为 x_move 和 y_move)。因此,如果我在单元格 (i,j) 上,我可以遍历这些数组以找到可能的移动,即 (i+2,j+1)、(i+1,j+2) 等。我的下一个任务是移动到下一个可能的骑士移动并检查这是否会引导我找到解决方案。如果没有,那么我将选择不同的移动,如果没有任何移动引导我找到解决方案,那么我将返回 false。

public static int[][] solve(boolean[][] board,int startRow,int startCol) throws IllegalArgumentException {
        if (checkboard(board) == false || checkPoint(board,startRow,startCol) == false) {
            throw new IllegalArgumentException();
        }
        int[][] sol = new int[board.length][];
        for (int i = 0 ; i < board.length; i++) {
            sol[i] = new int[board[i].length];
        }
        for (int row = 0; row < sol.length; row++) {
            for (int col = 0; col < sol[row].length; coL++) {
                if (board[row][col] == false) {
                    sol[row][col] = 0;
                }
                else {
                    sol[row][col] = -1;
                }
            }
        }
        int[] x_move = new int[]{2,1,-1,-2,2};
        int[] y_move = new int[]{1,2,-1};

        sol[startRow][startCol] = 1;

        if(springtour(sol,startCol,board)) {
            return sol;
        }
        return null;
    }

现在到最后一个在这里,我将返回 sol 数组。起初我检查我的棋盘和骑士的起点是否一切正常。然后我创建一个 sol 数组并用 -1 填充它(如果板为假,则为 0)。然后我有这两个数组,其中包含可能的移动 x_move 和 y_move。我将起点设置为 1,并调用我的方法 springtour 进行回溯。如果没有任何效果,则返回 null。 我的代码不起作用。有一个 Arrayindexoutofboundsexception。有人可以帮我弄这个吗?也许我在这里还有其他一些错误。感谢您的帮助!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。