2012-11-28 9 views
0

이 기사의 목적은 Knights Tour를 합법적 인 게임 중 하나를 선택하기 전에 합법적 이었는지 파악하도록하여 기사단 투어를 무력하게하는 것입니다. 나는 자바에 새로운 오전하지만 내 오류가이 문제를 처리하는 방법을 이해하는 나의 무능력에 같은 느낌 : 코드 지금 :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

유용했을 것이다 있어야한다 makeMoves()

라인의 상단에 "루프는 법적있는 이동 결정" 어떤 라인이 166인지 말할 수있다. –

답변

0

배열 범위를 벗어나는 오류는 일반적으로 배열의 크기를 초과하는 배열에서 저장 위치를 ​​호출하려고한다는 것을 의미합니다. 고정 크기 (예 : 8 데이터 포인트)로 배열을 선언했다면 배열 [0]에서 배열 [7]까지만 배열 값을 설정하고 검색 할 수 있습니다.

기본적으로 배열 계수는 범위 초과 오류의 원인이되는 1보다는 0에서 시작합니다. 위의 예를 참조하여 사람들이 가정하는 마지막 요소에 액세스하려고하기 때문에, 배열 [8].

범위를 벗어나는 오류를 방지하는 가장 쉬운 방법은 필요없는 크기로 확장 할 수 있도록 nil 크기로 배열을 선언하는 것입니다. 그러나이 경우 런 어웨이 코드의 경우 메모리 누수가 발생할 위험이 있습니다.

0

문제는 당신이 당신이 경우 yCurrent < 0을, yCurrent가 될 때 -2 (yMoves[4] 이후 = -2)이 선 (유사한 것들 중 하나)

setY(yCurrent + yMoves[ 4 ]); 

를 호출 할 때 온다 다음 코드 줄 전화 :

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

< 0 yCurrent 이후를, 존재하지 않는 배열 인덱스에 액세스하려는; 그러므로 예외.

이제이 오류가 여러 번 발생할 수 있습니다 (테스트 한 결과). 같은 결과로 yCurrent (또는 xCurrent)이 배열 크기보다 크거나 같은 값이 될 때도 비슷한 결과가 발생할 수 있습니다.

0

코드를 검사 한 결과, saves[yCurrent][xCurrent] = Integer.toString(turnNr); 이 예외를 던지고있는 것 같습니다. yCurrentxCurrent을 변경하는 논리는 부적절합니다. 저장 배열 제한을 늘려 [100] [100]을 저장하더라도 그 동작은 동일합니다.

나는 예외를 직접적으로 다루기보다는 먼저 코드와 흐름을 이해하는 것이 좋습니다. 버그가있는

0

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

대신하는 경우

if (yCurrent + yMoves[i] > 0 && yCurrent + yMoves[i] < rows) 
관련 문제