2012-11-28 26 views
0

这样做的目的是在选择其中一个合法的选项之前弄清楚哪些动作是合法的,以暴力推动骑士之旅。我是新来的Java,但我觉得我的错误是我无法理解如何处理这个问题:找不到我的OutOfBoundsException

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) 

编辑:现在代码行号是好的。

+2

会,如果你是有益的可以说哪一行是166 –

回答

0

数组超出界限错误通常意味着您正在尝试调用数组中超出数组大小的存储位置。如果你声明了一个固定大小的数组(例如8个数据点),你只能够设置和检索数组值[array] [array array [7])。

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

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

0

问题来了,当你调用这条线(类似者之一)

setY(yCurrent + yMoves[ 4 ]); 

yCurrent < 0。当这种情况发生,yCurrent为-2(因为yMoves[4] = -2),并且你然后调用下面这行代码:

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

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

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

0

我检查了您的代码,并且从中看来,saves[yCurrent][xCurrent] = Integer.toString(turnNr); 正在引发异常。正在改变yCurrentxCurrent的逻辑是不正确的。 因此,即使您将保存数组限制增加到保存[100] [100],其行为也是如此。

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

0

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

线顶部

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

应改为

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