2017-06-02 27 views
1

這是使用Python製作的Conway的Game of Life模擬代碼片段。這對於檢查它是否可行是非常簡單的 - 事實並非如此。不知道爲什麼,但據我所知,這是更新的東西。(已關閉)Conway的生命遊戲未正確更新(Python)

希望任何輸入,爲什麼它更新它的方式:

GIF圖片pygame的(相同的代碼): http://imgur.com/6US3Nje 不更新正確: http://imgur.com/9gubzAF

import pprint,random 
#here we make the initial board, 6x6 
board = [] 
for y in range (6): 
    row = [] 
    for x in range (6): 
     row.append(random.randint(0,1)) 
    board.append(row) 
#and display it 
pprint.pprint(board) 

#this function counts the neighbours for each cell 
def neighbours(x,y): 
    counter = 0 
    neighbours = \ 
    [(x-1,y+1),(x,y+1),(x+1,y+1),\ 
    (x-1,y),   (x+1,y),\ 
    (x-1,y-1),(x,y-1),(x+1,y-1)] 
    for n in neighbours: 
     a, b = n 
     try: 
      counter += board[a][b] 
     except: 
      pass 
#printed out the counter to check if it counted correctly (it does, as far as I could tell) 
    if x == 4 and y == 4: 
     print(counter) 
    return counter 

#function to make a new board based off the old one - basically, the updater. 
#here's where the problem might lie - but for the life of me I cannot tell where and why. 
def new(board): 
    new_board = [] 
    for y in range(6): 
     new_row = [] 
     for x in range(6): 
      n = neighbours(x,y) 
      oldcell = board[x][y] 
      #everything is set up to be according to the rules 
      #(if dead(0) can only come alive with 3 alive cells 
      #(if alive(1) can continue to live with exactly 2 or 3 live neighbours 
      if oldcell == 0: 
       newcell = 0 
       if n == 3: 
        newcell = 1 
      elif oldcell == 1: 
       newcell = 1 
       if n > 3 or n < 2: 
        newcell = 0 
      new_row.append(newcell) 
     new_board.append(new_row) 
    return new_board 

#displaying the board for 6 instances 
for i in range (6): 
    nboard = new(board) 
    board = nboard 
    pprint.pprint(board) 

提前感謝!

+1

不確定是什麼問題,但是如果oldcell else int(n == 3)' –

+0

@tobias_k,你可以將內部邏輯簡化爲'newcell = int(n在(2,3)中)這種簡化是真的只在競爭中表現良好,你可以根據代碼中使用的語句數來判斷。在幾乎所有其他情況下,爲了可讀性和調試目的,將邏輯如OP所做的那樣擴展得更好。 – Xirema

+1

@Xirema我想這是一個意見。當我看到這條線時,我讀到「如果舊的細胞還活着,如果有兩個或三個鄰居,新的細胞是活着的,否則,如果確切地說有三個鄰居」,那麼恕我直言比這8行嵌套的if /其他。但正如我所說,這是個人喜好的問題。 –

回答

2

您正在混合循環中的行和列,將每個新電路板的整個矩陣有效地轉置。該循環應該是這樣的:

for x in range(6): 
    new_row = [] 
    for y in range(6): 
     ... 

此外,您if/else邏輯循環中的大部分可以簡化爲一條直線。這是否容易閱讀和理解是由你來決定的。

def new(board): 
    new_board = [] 
    for x in range(6): 
     new_row = [] 
     for y in range(6): 
      n = neighbours(x,y) 
      oldcell = board[x][y] 
      newcell = int(n in (2, 3)) if oldcell else int(n == 3) 
      new_row.append(newcell) 
     new_board.append(new_row) 
    return new_board 

如前所述in comments,有一個第二(儘管不太明顯)的問題:當你try/except跳過所有場外指數是一個不錯的主意,它並不如趕上x-1對於x = 0,因爲[-1]是Python中的一個合法索引(索引序列中的最後一個元素),使您的電路板「環繞」四個邊中的兩個。相反,你應該明確檢查板子的邊界。如果你願意,你可以把這個另一種「樂趣」的一行:

def neighbours(x,y): 
    return sum(board[a][b] for a in (x-1,x,x+1) for b in (y-1,y,y+1) 
       if (a,b) != (x,y) and 0 <= a < len(board) and 0 <= b < len(board[a])) 

當然,你也可以讓你的循環,只需更換try/exceptif檢查。

+0

非常感謝!現在一切都按原樣進行。這麼小的事情讓我非常悲傷) – Alfr

+1

至於簡化,我會牢記這一點 - 令人驚訝的是,比我通常撰寫的更容易閱讀。理解將與一些練習) – Alfr

+0

爲了環繞,我做了這樣的事情(因爲,像單線望遠鏡一樣有趣,我在繞過這些事情時遇到了一些麻煩): if a == - 1或b == -1: 繼續嘗試/除外之前的 。 (無法弄清楚如何在這裏格式化代碼:C) – Alfr