无法弄清楚我的OutOfBoundsException

时间:2012-11-28 06:14:24

标签: java

这样做的目的是在选择其中一个合法的之前,让骑士巡回演出确定哪些动作合法。我是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 个答案:

答案 0 :(得分:0)

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

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

避免越界错误的最简单方法是使用nil大小声明数组,这样可以扩展到所需的大小。但是,如果代码失控,这会导致内存泄漏。

答案 1 :(得分:0)

当您拨打此线路(其中一个类似线路)

时,会出现此问题
setY( yCurrent + yMoves[ 4 ] );

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

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

由于yCurrent&lt; 0,您正在尝试访问不存在的数组索引;因此例外。

现在,这个错误可能会出现多次(在我的测试中也是如此);当yCurrent(或xCurrent)变为大于或等于数组大小的值时,也会出现类似的效果。

答案 2 :(得分:0)

我检查了你的代码,似乎是saves[yCurrent][xCurrent] = Integer.toString(turnNr); 抛出一个例外。正在改变yCurrentxCurrent的逻辑是不正确的。 因此,即使您将保存数组限制增加到保存[100] [100],它的行为也会相同。

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

答案 3 :(得分:0)

错误在“循环确定哪些移动是合法的”附近makeMoves()

的顶部

该行

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

应该是

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