骑士游java(递归)

时间:2015-03-13 04:04:05

标签: java recursion java.util.scanner

我正在编写经典骑士之旅的代码,我的代码似乎主要做正确的事情,但它仍然让我“不可能”的可能的板,我无法弄清楚为什么。 (例如:对于一个包含3行,4列的表,从第1行,第3列开始,它失败了)。我在计算行和列时从索引0开始。我不认为这是正确的回溯。任何人都可以帮助指出我的错误?谢谢

import java.util.*;
public class KnightGame 
{
    private int rows;
    private int cols;
    private int [][] array;

    public void initializeArray()
    {
        array = new int [rows][cols];
    }

    public boolean fill (int x, int y, int n)
    {
        if ( x < 0 || x >= rows || y<0 || y >= cols )  //outside of board
            return false;
        else if (array[x][y] != 0)   //location has been visited, array element occupied
            return false;
        else if ( n == (rows * cols))       //have visited all locations
            return true;
        else 
        {   
            array[x][y] = n;
            if ( fill(x+1, y-2, n+1) || fill(x-2, y+1, n+1) || fill(x+1, y+2, n+1)
               || fill(x+2, y+1, n+1) || fill(x-2, y-1, n+1) || fill(x-1, y-2, n+1) || 
               fill(x-1, y+2, n+1) || fill(x+2, y-1, n+1)) 
                return true;
            else
                return false;               
        }
    }

    public static void main (String [] args)
    {   
         KnightGame game = new KnightGame();
        int [] st = new int [2];
        int startx, starty;
        Scanner keyIn = new Scanner (System.in); 

        System.out.println("Enter number of rows: ");
        game.rows=keyIn.nextInt();

        System.out.println("Enter number of columns: ");
         game.cols = keyIn.nextInt();

        game.initializeArray();

        System.out.println("Enter starting location: ");
         for (int i=0; i<2; i++)
         {
             st[i] = keyIn.nextInt();
         }

         startx = st[0];
         starty = st[1];

         //testing for correct starting values
         System.out.println("starting values: " + startx + " " + starty);       

        if (game.fill(startx, starty, 1))
        {
            for (int i=0; i<game.rows; i++)
                {
                  for (int j=0; j<game.cols; j++)
                  {
                     System.out.print(game.array[i][j] + " "); 
                  } 
                }
        }

        else
            System.out.println("Board could not be completed!");

    }

}

2 个答案:

答案 0 :(得分:3)

当您回溯时,您不会清除棋盘上的方块。因此,如果你递减一条潜在的路径,失败然后尝试另一条路径,那么第一次尝试仍然会标记正方形,所以第二次尝试也会失败,即使它可能已经成功。

        array[x][y] = n;
        if ( fill(x+1, y-2, n+1) || fill(x-2, y+1, n+1) || fill(x+1, y+2, n+1)
           || fill(x+2, y+1, n+1) || fill(x-2, y-1, n+1) || fill(x-1, y-2, n+1) || 
           fill(x-1, y+2, n+1) || fill(x+2, y-1, n+1)) 
            return true;
        else
        {
            array[x][y] = 0; // <- add this line
            return false; 
        }

答案 1 :(得分:1)

问题在于,当回溯发生时,你的代码没有将位置重置为0,而下一次在另一次传递中会让人感到困惑,认为它存在,但该位置应该已经重置。以下是带有修复程序的代码段:

else 
{   
    array[x][y] = n;
    if ( fill(x+1, y-2, n+1) || fill(x-2, y+1, n+1) || fill(x+1, y+2, n+1)
       || fill(x+2, y+1, n+1) || fill(x-2, y-1, n+1) || fill(x-1, y-2, n+1) || 
       fill(x-1, y+2, n+1) || fill(x+2, y-1, n+1)) 
        return true;
    else {
        array[x][y] = 0;//NEED THIS LINE
        return false; 
    }              
}