0

这样做的目的是通过在选择合法的动作之一之前确定哪些动作是合法的,从而蛮力骑士巡回赛。我是 Java 新手,但我觉得我的错误在于我无法理解如何处理这个问题:

import java.util.*;



public class KnightTour
{
    public static void main( String[] args )
    {
    KnightTour kt = new KnightTour(8, 8);
    int tries = 3;
    int tryCount = 0;

    while(tryCount < tries )
    {
        kt.makeMoves();
    }
}

int rows = 0;  //change to args later
int columns = 0;  //change to args later
int tries = 0; //change to args later
String[][] saves;   

int tryCount = 0;
int turnNr = 2;
int wait = 0;

Random rand = new Random();

int xCurrent = 1;
int yCurrent = 1;

int[] xMoves = { 1, 2, -1, -2, 1, 2, -1, -2 };
int[] yMoves = { 2, 1, 2, 1, -2, -1, -2, -1 };

public KnightTour( int x, int y)
{
    rows = x;
    columns = y;
    saves = new String[y][x];

    for (int i = 0; i < y; i++) 
    {
        for (int j = 0; j < x; j++) 
        {
            saves[i][j] = Integer.toString(0);
        }
    }
    saves[0][0] = Integer.toString(1);
}

private void makeMoves()
{
    int k = 0;

    while( k < (rows * columns ) )
    {
        int[] d = { 0, 0, 0, 0, 0, 0, 0, 0 }; // holds move legality
        int i = 0;

        while( i < d.length ) // loop determines which moves are legal
        {
            if( xCurrent + xMoves[ i ] > 0 && xCurrent + xMoves[ i ] < rows )
            {
                if( xCurrent + yMoves[ i ] > 0 && yCurrent + yMoves[ i ] < rows )
                    d[ i ] = 1;
            }
            i++;
        }

        int t = 0;
        int w = 0;

        while( t < d.length ) // checks if no moves are legal
        {   
            if( d[ t ] == 0 )
            {
                w++;
            }
            t++;
        }

        if( w == 8 )
        {
            writeFailures(); // fills the rest of the grid with "x"'s
            k = (rows * columns);  // breaks the loop
        }
        else
        {
            w = 0;
            chooseMove( d );
        }
        k++;
    }
    printSolution();
}

private void chooseMove(int[] d) // chooses a move that was previously determined to be legal randomly and checks if it is available
{
    System.out.println( "trace" );
    Random rand = new Random();
    int r = rand.nextInt(8);
    switch( r )
    {
    case 0:
        if( d[ 0 ] == 1 )
        {
            setX( xCurrent + xMoves[ 0 ] );
            setY( yCurrent + yMoves[ 0 ] );
            saves[yCurrent][xCurrent] = Integer.toString(turnNr);
            turnNr++;
        }
        else
        {
            chooseMove(d);
        }
        break;

    case 1:
        if( d[ 1 ] == 1 )
        {
            setX( xCurrent + xMoves[ 1 ] );
            setY( yCurrent + yMoves[ 1 ] );
            saves[yCurrent][xCurrent] = Integer.toString(turnNr);
            turnNr++;
        }
        else
        {
            chooseMove(d);
        }
        break;

    case 2:
        if( d[ 2 ] == 1 )
        {
            setX( xCurrent +  xMoves[ 2 ] );
            setY( yCurrent + yMoves[ 2 ] );
            saves[yCurrent][xCurrent] = Integer.toString(turnNr);
            turnNr++;
        }
        else
        {
            chooseMove(d);
        }
        break;

    case 3:
        if( d[ 3 ] == 1 )
        {
            setX( xCurrent + xMoves[ 3 ] );
            setY( yCurrent + yMoves[ 3 ] );
            saves[yCurrent][xCurrent] = Integer.toString(turnNr);
            turnNr++;
        }
        else
        {
            chooseMove(d);
        }
        break;

    case 4:
        if( d[ 4 ] == 1 )
        {
            setX( xCurrent + xMoves[ 4 ] );
            setY( yCurrent + yMoves[ 4 ] );
            saves[yCurrent][xCurrent] = Integer.toString(turnNr); // LINE 166
            turnNr++;
        }
        else
        {
            chooseMove(d);
        }
        break;

    case 5:
        if( d[ 5 ] == 1 )
        {
            setX( xCurrent + xMoves[ 5 ] );
            setY( yCurrent + yMoves[ 5 ] );
            saves[yCurrent][xCurrent] = Integer.toString(turnNr);
            turnNr++;
        }
        else
        {
            chooseMove(d);
        }
        break;

    case 6:
        if( d[ 6 ] == 1 )
        {
            setX( xCurrent + xMoves[ 6 ] );
            setY( yCurrent + yMoves[ 6 ] );
            saves[yCurrent][xCurrent] = Integer.toString(turnNr);
            turnNr++;
        }
        else
        {
            chooseMove(d);
        }
        break;

    case 7:
        if( d[ 7 ] == 1 )
        {
            setX( xCurrent + xMoves[ 7] );
            setY( yCurrent + yMoves[ 7 ] );
            saves[yCurrent][xCurrent] = Integer.toString(turnNr);
            turnNr++;
        }
        else
        {
            chooseMove(d);
        }
        break;
    default:
        System.out.println( "error" );
    }
}

public int getX() 
{
    return xCurrent;
}

public void setX(int x) 
{
    xCurrent = x;
}

public int getY() 
{
    return yCurrent;
}

public void setY(int y) 
{
     yCurrent = y;
}

private void writeFailures() // writes an "x" to empty spots in the save array when no legal moves are found
{
    for (int i = 0; i < saves.length; i++) 
    {
        for (int j = 0; j < saves[i].length; j++) 
        {
            if( saves[i][j] == "0");
                saves[i][j] = "x";
        }            
    }
}

private void printSolution()
{
    for (int i = 0; i < saves.length; i++) 
    {
        for (int j = 0; j < saves[i].length; j++) 
        {
            System.out.print(saves[i][j] + " ");
        }
        System.out.println("");
    }
    System.out.println("");
}
}

我得到的错误是:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -2
at KnightTour.chooseMove(KnightTour.java:166)
at KnightTour.makeMoves(KnightTour.java:91)
at KnightTour.main(KnightTour.java:14)

编辑:现在代码行号没问题。

4

4 回答 4

0

数组越界错误通常意味着您试图调用数组中超出数组大小的存储位置。如果您声明了具有固定大小(例如 8 个数据点)的数组,您将只能设置和检索从数组 [0] 到数组 [7] 的数组值。

默认情况下,数组计数从 0 而不是 1 开始,这是大多数越界错误的原因,因为人们会尝试访问他们假设的最后一个元素,参考我上面的示例,array[8] .

避免越界错误的最简单方法是将数组声明为 nil 大小,这将允许它扩展到所需的大小。但是,这会在代码失控的情况下存在内存泄漏的风险。

于 2012-11-28T06:21:16.410 回答
0

当您调用此行时会出现问题(类似的行之一)

setY( yCurrent + yMoves[ 4 ] );

yCurrent<0。发生这种情况时,yCurrent变为 -2(因为yMoves[4]=-2),然后调用这行代码:

saves[yCurrent][xCurrent] = Integer.toString(turnNr);

由于yCurrent<0,您试图访问一个不存在的数组索引;因此例外。

现在,这个错误可能会出现很多次(并且在我的测试中出现过);yCurrent出于同样的原因,当(or xCurrent) 变为大于或等于数组大小的值时,也会发生类似的效果。

于 2012-11-28T06:22:10.997 回答
0

我已经检查了您的代码,并且似乎saves[yCurrent][xCurrent] = Integer.toString(turnNr); 正在引发异常。正在发生变化且不正确的yCurrent逻辑xCurrent。因此,即使您将保存数组限制增加到 saves[100][100],它的行为也是一样的。

我建议您先了解代码和流程,而不是直接处理异常。

于 2012-11-28T06:24:00.067 回答
0

该错误位于顶部附近的“循环确定哪些移动是合法的”中makeMoves()

线

if (xCurrent + yMoves[i] > 0 && yCurrent + yMoves[i] < rows)

应该改为

if (yCurrent + yMoves[i] > 0 && yCurrent + yMoves[i] < rows)
于 2012-11-28T06:34:22.280 回答