2016-11-29 63 views
2

我學習生活的康威的遊戲來實現它在我自己的,和整個以下實現的規則來:Java:如何實施康威的人生遊戲?

由N個單元給定板有m個,每個單元都有活的初始狀態(1)或死(0)。

  • 少於兩隻活鄰居的活細胞死亡,彷彿引起下:每個單元有八個鄰國(水平,垂直,對角線)採用以下四個規則(從上面的維基百科文章所)相互作用-人口。
  • 任何有兩個或三個活着的鄰居的活細胞都活在下一代。
  • 三個以上的活鄰居的活細胞死亡,彷彿被過度人口..
  • 正好與三隻活鄰居的死細胞變活細胞,彷彿再現。

而實現(https://discuss.leetcode.com/topic/29054/easiest-java-solution-with-explanation):

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; 
} 

和驅動器:

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); 
} 

我的問題是,怎樣做liveNeighbors()xy代表什麼?不明白爲什麼需要Math.min()Math.max()。還有,lives是否代表董事會初始化的生命數量?

回答

3

給定的代碼使用minmax函數將搜索限制爲數組中的有效條目。如果沒有這樣做,代碼將在嘗試使用-1,mn作爲數組索引時返回ArrayOutOfBoundsException。 (循環不知道在地圖的右邊緣給出了一個正方形,它不應該搜索右邊的活着的鄰居;這些函數編碼該事實)。xy只是循環控制變量用於迭代目標方塊周圍的有效方塊。

至於lives變量,這是佔位符來保持計數下面的循環找到了多少活的鄰居。您可能已經猜到了這一點,因爲它是liveNeighbors函數的返回值。

我們來舉個例子。我們將撥打liveNeighbors(board,9,9,0,2),其中board是司機給出的主板。您的主板尺寸爲9x9,因此我們通過mn,對於我們的示例,我們正在調查0,2(這是第三行中的第一個條目(右邊有一個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

循環簡化爲:

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

內循環運行六次,具有以下(x,y)雙:(0,1),(0,2),(0,3),(1,1),(1,2),(1,3)。相信這些是我們正在調查的廣場的鄰居,以及廣場本身。

這六個平方五將在(1,2)返回1返回0,用一個,所以在這個循環結束,lives將等於1的最後一件事做的是lives -= board[i][j] & 1;,從而降低lives 1如果正方形我們正在調查中有一個1。在我們的情況下,它不會(board[i][j] = 0),所以我們減去0,留下1,我們返回。 liveNeighbors(board,9,9,0,2) = 1

我可能已經將xy倒退一次或兩次,但希望這足以讓您瞭解正在發生的事情。

+0

我誤解實施的可能性,爲了澄清,在我接受/贊成答案之前,您能評論每次迭代發生了什麼嗎?真的有助於清理事情。 –

+0

非常感謝。這清理了很多東西!還有幾個問題。我仍然沒有得到'生命' - 板子[i] [j]&1'部分。我們的廣場沒有1個?在'(1,2)'?減1的原因是什麼?編輯:啊,這是我們正在尋找周圍的方格本身,如果這本身是1,我們減去1,對嗎? –

+0

另外,board [i] [j] >> = 1'中的board [x] [y]&1'和>> = 1中的&1是做什麼的? –