使用递归通过Java中的国际象棋骑士移动模式在2D数组中放置数字

时间:2018-09-28 02:35:36

标签: java arrays multidimensional-array chess

public class ChessComplete 
{
    private int size;
    private int[][] board;
    private long callNum;

    public ChessComplete(int size)//constructor with 2D array size as a parameter
    {
        this.size = size;
        board = new int [size][size];
        board[0][0] = 1;
    }
    public boolean isValid(int r, int c)//To check the if the number that is added is in the 2D array is in bound
    {
        if(r < 0 || c < 0 || r >= size || c >= size)
        {
            return false;
        }
        return true;
    }

    /*
     * Move through the 2D array by placing the consecutive number for each (row,col) until its full
     * Moves Are only allowed in a chess knight pattern
     */
    public boolean move(int r, int c, int count) {
    callNum++;

    if (!isValid(r, c)) {
        return false;
    }

    if (count == (size * size))// Base case if count reaches the end of 2D
                                // array

    {

        return true;
    }
    board[r][c] = count;// fills the positon with the current count

    if (board[r][c] == 0) {
        return false;
    }

    // Check if each possible move is valid or not
    if (board[r][c] != 0) {

        for (int i = 0; i < 8; i++) {

            int X[] = { 2, 1, -1, -2, -2, -1, 1, 2 };
            int Y[] = { 1, 2, 2, 1, -1, -2, -2, -1 };

            // Position of knight after move
            int x = r + X[i];
            int y = c + Y[i];

            if (move(x, y, count + 1)) {

                return move(x, y, count + 1);
            }

        }
    }
    board[r][c] = 0;
    return false;
}
    public long getSteps()//Number of reccursive trials
    {
        return callNum;
    }
    public void displayBoard()
    {
        String s = " ";
        for(int r = 0; r < size; r++)
        {
            for(int c = 0; c < size; c++)
            {
                System.out.print(board[r][c] + " ");
            }
            System.out.println();
        }

    }
}

输出为:

1,  0,  0,  0,  0, 

0,  0,  0,  23, 0, 

0,  2,  0,  0,  0, 

0,  0,  0,  0, 24, 

0,  0,  3,  0,  0 

Recursive method call count: 78,293,671

说明

(0, 0)位置(行,列)的通知1,在(2, 1)位置有2的通知。如您所见,棋盘中的骑士以类似的方式移动。这样,我们需要用连续的数字填充整个2D数组,以使其严格遵循骑士模式。

问题

我不明白为什么整个2D数组没有被所有其他连续数字填充。例如,在2D数组中用3填充位置后,数字会一直跳到23。

1 个答案:

答案 0 :(得分:0)

在执行移动之前,您无需检查正方形是否已被占用,因此您的解决方案包括重复写入的重复移动。

更改isValid,以检查目标正方形是否为空:

public boolean isValid(int r, int c) {
    if (r < 0 || c < 0 || r >= size || c >= size || board[r][c] != 0) {
        return false;
    }
    return true;
}

...,然后删除构造函数中的初始化步骤board[0][0] = 1;(应该在对move的第一次调用中进行设置)。

另外(但不是致命的)

if (move(x, y, count + 1)) {
    return move(x, y, count + 1);
}

应该是

if (move(x, y, count + 1)) {
    return true;
}

检查if (board[r][c] == 0)if (board[r][c] != 0)不会执行任何操作,因为它们是在您设置board[r][c] = count;之后立即进行的。