2016-11-29 1 views
2

내가 내 자신에 그것을 구현하는 생명의 콘웨이의 게임을 공부하고, 규칙에 다음과 같은 구현을 통해 온거야 :자바 : Conway의 Game of Life를 구현하는 방법은 무엇입니까?

N 세포에 의해 m와 보드 감안할 때, 각 셀은 라이브 초기 상태를 가지고 (1) 또는 죽은 (0). 아래로 인한 것처럼

  • 두 개 미만 라이브 이웃과 모든 살아있는 세포가 죽는다 : 각 셀은 (위키 백과 문서 위에서 가져온) 다음과 같은 네 가지 규칙을 사용하여 팔 이웃 (수평, 수직, 대각선)와 상호 작용 -인구.
  • 2 ~ 3 개의 라이브 이웃이있는 모든 라이브 셀은 다음 세대에 존재합니다.
  • 인구가 과도하게 많은 것처럼 살아있는 이웃이 세 개 이상인 라이브 셀이 죽습니다.
  • 정확히 3 개의 라이브 이웃이있는 모든 죽은 셀은 마치 복제에 의한 것처럼 라이브 셀이됩니다.

및 구현 (https://discuss.leetcode.com/topic/29054/easiest-java-solution-with-explanation) : liveNeighbors()에서 xy 대표 무엇

public static void main(String args[]) { 
    GameOfLife gl = new GameOfLife(); 

    int[][] board = { 
       {0, 0, 0, 0, 0, 0, 0, 0, 0}, 
       {0, 0, 0, 1, 0, 0, 0, 0, 0}, 
       {0, 1, 0, 1, 0, 0, 0, 0, 0}, 
       {0, 0, 1, 1, 0, 0, 0, 0, 0}, 
       {0, 0, 0, 0, 0, 0, 0, 0, 0}, 
       {0, 0, 0, 0, 0, 0, 0, 0, 0}, 
       {0, 0, 0, 0, 0, 0, 0, 0, 0}, 
       {0, 0, 0, 0, 0, 0, 0, 0, 0}, 
       {0, 0, 0, 0, 0, 0, 0, 0, 0} 
      }; 

    gl.gameOfLife(board); 
} 

그리고 내 질문은 :

public void gameOfLife(int[][] board) { 
    if (board == null || board.length == 0) return; 
    int m = board.length, n = board[0].length; 

    for (int i = 0; i < m; i++) { 
     for (int j = 0; j < n; j++) { 
      int lives = liveNeighbors(board, m, n, i, j); 

      // In the beginning, every 2nd bit is 0; 
      // So we only need to care about when will the 2nd bit become 1. 
      if (board[i][j] == 1 && lives >= 2 && lives <= 3) { 
       board[i][j] = 3; // Make the 2nd bit 1: 01 ---> 11 
      } 
      if (board[i][j] == 0 && lives == 3) { 
       board[i][j] = 2; // Make the 2nd bit 1: 00 ---> 10 
      } 
     } 
    } 

    for (int i = 0; i < m; i++) { 
     for (int j = 0; j < n; j++) { 
      board[i][j] >>= 1; // Get the 2nd state. 
     } 
    } 
} 

public int liveNeighbors(int[][] board, int m, int n, int i, int j) { 
    int lives = 0; 
    for (int x = Math.max(i - 1, 0); x <= Math.min(i + 1, m - 1); x++) { 
     for (int y = Math.max(j - 1, 0); y <= Math.min(j + 1, n - 1); y++) { 
      lives += board[x][y] & 1; 
     } 
    } 
    lives -= board[i][j] & 1; 
    return lives; 
} 

그리고 드라이버? Math.min()Math.max()의 필요성을 이해하지 못합니다. 또한 lives은 보드의 초기화 수명을 나타 냅니까?

답변

3

주어진 코드는 minmax 함수를 사용하여 검색을 배열의 유효한 항목으로 제한합니다. 이 작업을 수행하지 않으면 -1, m 또는 n을 배열 인덱스로 사용하려고하면 코드에서 ArrayOutOfBoundsException을 반환합니다. (루프는지도의 오른쪽 가장자리에 정사각형이있는 것을 "알지 못합니다. 더 오른쪽 오른쪽의 살아있는 이웃을 검색하면 안됩니다. 이러한 기능을 인코딩합니다.) xy은 단순히 루프 제어 변수입니다 대상 사각형을 둘러싼 유효한 사각형을 반복하는 데 사용됩니다.

lives 변수는 아래 루프에서 얼마나 많은 라이브 이웃을 찾았는지 계산하는 자리 표시 자입니다. liveNeighbors 함수의 반환 값이라는 사실에 의해 짐작할 수 있습니다.

예를 들어 보겠습니다. liveNeighbors(board,9,9,0,2)으로 전화 할 것입니다. 여기서 board은 드라이버에 지정된 보드입니다. 보드의 크기는 9x9이므로이 숫자는 mn이며 예를 들어 02의 제곱을 조사하고 있습니다 (오른쪽에 1이 있음). 좋아, 시작하자.

i=0, 그래서 x = Math.max(i - 1, 0) = Math.max(-1, 0) = 0 (이것은 max 함수 이유를 보여준다. 방금 int x=i-1 상기 않으면 배열의 범위를 벗어나 x = -1 끝낼 것이다 다음 우리는 평가 X < = Math.min (i + 1, m - 1) = Math.min (1, 8) = 1. 마지막 열에서 셀을 조사 할 경우이 조건은 배열의 오른쪽 가장자리를 강제했을 것입니다.

비슷한 로직을 yj과 관련 있습니다. 내부 루프는 다음 (x,y)쌍으로, 여섯 번 실행됩니다

for (int x = 0; x <= 1; x++) { 
    for (int y = 1; y <= 3; y++) { 
     lives += board[x][y] & 1; 
    } 
} 

:에

루프는 간단 (0,1),(0,2),(0,3),(1,1),(1,2),(1,3). 이것들은 우리가 조사하는 광장의 이웃들뿐만 아니라 광장 자체라고 확신하십시오. , lives이해야 할 1 마지막 것은 동일합니다이 루프의 끝에 그래서이 여섯 제곱의

다섯, (1,2) 1을 반환에 하나, 0를 반환합니다 제곱 경우 1 lives을 줄일 수있는 lives -= board[i][j] & 1;입니다 우리는 수사 중입니다. 우리의 경우에는 (board[i][j] = 0)이 아니므로 0을 빼고 1을 남겨 둡니다. liveNeighbors(board,9,9,0,2) = 1

나는 xy을 한두 번 거꾸로 들었을 지 모르지만, 충분히 잘하면 이해할 수있을 것입니다.

+0

설명을 이해하기에 앞서 구현을 오해 할 가능성이 있으며 대답을 수락하거나/upvote하기 전에 각 반복에서 무슨 일이 일어 났는지에 대해 의견을 나눌 수 있습니까? 정말 분명히 도움이 될 것입니다. –

+0

정말 고마워요. 그것은 많은 것을 정리했습니다! 몇 가지 질문 만 있습니다. 나는 아직도 '삶 - 보드 [i] [j] & 1'부분을 얻지 못한다. 우리 광장에 1이 없었나요? '(1,2)? 그리고 1을 뺀 이유는 무엇입니까? 편집 : 아, 그것은 주위에 광장을 찾는 지점 자체이며, 그 자체가 1이라면 1을 뺍니다. 맞습니까? –

+0

또한,'board [i] [j] >> = 1'에서'board [x] [y] & 1'와 >> = 1의 & 1은 무엇을합니까? –