2012-07-29 3 views
3

Ken Ken 퍼즐을 만드는 프로젝트를 시작했습니다. Ken Ken이 무엇인지 잘 모르는 경우 Sudoku와 비슷하게 행이나 열에 중복 된 정수 값을 사용할 수 없습니다.무작위로 된 숫자로 2D 배열 채우기

모든 새로운 행에 대해 생성 된 배열 목록의 숫자로 2D 배열을 채우려고합니다. 배열 목록에서 가져온 번호가 자체 행과 열의 숫자와 일치하지 않는지 확인합니다.

내 코드를 실행할 때 목록에서 정수 값을 제거하려고하면 "Index Out Of Bounds"예외가 발생합니다. 나는 왜 내가 올바른 요소를 얻고 있다고 생각하기 때문에 이런 일이 일어나고 있는지 확신 할 수 없다. 이것에 대해 몇 가지 질문이

int GRID_SIZE = 4; int[][] grid = new int[GRID_SIZE][GRID_SIZE]; List<Integer> nums = new ArrayList<Integer>();

private void populateGrid() { 

    for (int row = 0; row < GRID_SIZE; row ++) { 

     // Creates an array of values from 1 to grid size. 
     for (int i = 1; i <= GRID_SIZE; i++) nums.add(i); 

     for (int col = 0; col < GRID_SIZE; col++) { 

      while (nums.size() > 0) { 

       // Gets a random number from the Array List 
       int ranNum = nums.get(numGen.nextInt(GRID_SIZE)); 

       // Checks to see if the number is placeable. 
       if (canPlace(ranNum, row, col)) { 

        // Places the number in the 2D Array 
        grid[row][col] = ranNum; 
        break; 

       } else { 

        // Removes duplicate element from the Array List. 
        nums.remove(ranNum); <------{Index Out Of Bounds Exception] 
       } 
      } 
     } 
    } 
} 

private boolean canPlace(int ranNum, int row, int col) { 

    for (int i = 0; i < GRID_SIZE; i++) { 

     // Checks if the specified number is already in the row/column. 
     if (grid[col][i] == ranNum) return false; 
     if (grid[i][row] == ranNum) return false; 
    } 

    return true; 
} 

: 여기

내 코드 모두의

첫째, 가 왜 오류를 얻고을 그 나는입니까?

둘째 더 나은 아무것도 그리드에 대한 2 차원 배열과 내 번호를 배치하는 방식보다이 사용할 수 있나요?

마지막으로 나는 정확하게 휴식 시간을 사용하고 있습니다.?

미리 답변 해 주셔서 감사합니다.

+0

이 루프의 두 번째 잘못된 것 같다 '내가 <= GRID_SIZE' 당신은 임의의 숫자 목록을 저장하기 위해 사용하는 정확한 어떤 데이터 유형 – Keppil

+0

? 목록 일 경우 항목을 제거하면 축소 될 가능성이 큽니다. 따라서 목록에 9 개가 있고 그 중 하나를 찾아 제거하면 이제 8 개가 생깁니다. 다시 9 번째 위치를 보려고하면 범위를 벗어납니다. 예외 –

+0

나는 어디에서 시작해야할지 정말로 모른다. 사소한 문제가 해결 되더라도 전체 접근법이 잘못되어 가장 어려운 문제를 해결할 수 없습니다. 역 추적이 필요합니다. –

답변

1

문제에 대한 다른 접근 방법은 어떻습니까? 유효한 정사각형으로 시작하여 변형하십시오.'2 행 교환'과 '2 열 교환'작업은 사각형의 속성을 유지합니다. 이렇게하면 두 개의 Fisher-Yates 셔플을 할 수 있습니다. 하나는 행에, 다른 하나는 유효한 사각형으로 시작하는 유효한 임의의 사각형을 제공합니다. 초기 유효 광장을 건설하는 것은 간단하다 :

123456 
234561 
345612 
456123 
561234 
612345 
+0

정말 고마워요.이 생각을 해봤 고 (다른 많은 퍼즐 게임과 함께)이 게임을 만들었습니다. 감사! –

2

IndexOutOFBoundsExceptionList API의 오류 (IMO)로 인해 발생합니다. 그것에는 remove(Object element) 메쏘드가 있습니다.이 메쏘드는 여러분이 호출하기를 원하는 것이고, 여러분이 실제로 호출하는 메쏘드는 remove(int index)입니다. 후자는 주어진 인덱스에서 요소를 제거하려고 시도합니다. 인수는 아마 목록 크기보다 커야합니다. ranNum 변수를 Integer 또는 Object 중 하나로 변환하여 올바른 방법을 호출 할 수 있습니다.

+0

이 답변을 주셔서 대단히 감사합니다. 저는 항상 int와 Integer가 같다고 생각했습니다. 이것은 나를 위해 배운 위대한 교훈입니다. 지금 코드를 수정했는데 제대로 작동하고 있습니다. 다시 한번 감사드립니다! –

1
for (int i = 0; i <= GRID_SIZE; i++) nums.add(i); 

이것은 나에게 의미가 없습니다. 0-4의 숫자를 추가하고 있습니다. 배열에는 최대 3 개의 인덱스 만 있습니다. 0-1-2-3 ...

코드를 실제로 보지 않거나 인덱스가 경계를 벗어나는 위치를 정확히 알지 못하면 어둡습니다.

+0

답장을 보내 주셔서 감사합니다. 이제 문제를 해결하고 원하는 번호를 얻습니다. –

+0

@Jordan King 대답이 맞다면 올바른 대답으로 받아 들여야합니다. 사람들이 펑하는 소리가 들려서 틀린 것을 알고 있습니다. 기쁜 데 도움이되었습니다. –

0

내 코드를 다시 살펴본 후 내 주된 오류는 canPlace(int ranNum, int row, int col) 방법과 관련이 있다는 것을 깨달았습니다.

나는 colrow 값을으로 바꿔서 모두 이었습니다.

도움 주셔서 감사합니다.