-3

我正在python中創建生命遊戲。我不確定我是否正確地做了。Pygame的生命遊戲

get_cell函數對我來說不太合適。我也想在count_neighbors函數中使用這個函數。

我在做什麼錯,還有什麼可以做得更好?

import pygame 
import time 
import sys 

HEIGHT = 50 
WIDTH = 50 

SCALE = 10 
SCREEN = pygame.display.set_mode((WIDTH*SCALE, HEIGHT*SCALE)) 


def create_blank(): 
    """Creates a HEIGHT x WIDTH list containing all zero's. The inner lists 
    will all be WIDTH long and the outer list will HEIGHT long.""" 
    board = [[0]*WIDTH]*HEIGHT 
    return board 


def get_cell(board, x, y): 
    """Returns the game board at position x,y , this is 1 if the cell at that 
    position is alive and 0 if the cell is dead. If the x or y parameters are 
    out of bounds (not valid coordinates), the function returns 0.""" 
    for x in range(WIDTH): 
     for y in range(HEIGHT): 
      return board[y][x] 
    else: 
     return 0 


def count_neighbours(board, x, y): 
    """Counts the number of alive neighbours around the position x,y , including 
    diagonal neighbours. Does not include the cell itself.""" 
    count = 0 
    for i in range(x-1,x+2): 
     for j in range(y-1,y+2): 
     if not(i == x and j == y): 
       count += int(mat[i][j]) 


def update(board): 
    """Creates a new board copy and applies the game rules to each cell using 
    the old board. Does not modify the old board. Returns the new board.""" 
    if(count < 2 or count > 3): 
     return 0 
    elif count == 3: 
     return 1 
    else: 
     return mat[i][j] 

我沒有得到任何錯誤和板出現,但卻仍不能右看看我...

+0

以何種方式它不看你的權利? –

+0

我不確定它是否有效,因爲我無法真正測試。這個功能對您來說似乎是否可行,並且確實需要做些什麼? –

+0

在'get_cell'中,用範圍中的值替換'x'和'y'。這些將從零開始計數。所以,你總是會返回'board [0] [0]'。真的,你應該返回'board [x] [y]'而不通過範圍循環。你可以先檢查'x'和'y'是否有效,否則返回'0'。 –

回答

1

的問題就在這裏:

board = [[0]*WIDTH]*HEIGHT 

術語實例你的棋盤的每一行都有相同的對象(而不是你所期望的HEIGHT副本)。

也許下面的例子可以讓事情變得清楚:

>>> WIDTH=2 
>>> HEIGHT=3 
>>> board = [[0]*WIDTH]*HEIGHT 
>>> board 
[[0, 0], [0, 0], [0, 0]] 
>>> board[1][1] = 3 
>>> board 
[[0, 3], [0, 3], [0, 3]] 

但是,如果你使用

board = [[0 for x in range(WIDTH)] for y in range(HEIGHT)] 

代替(即每次創建一個行的新實例)的結果看起來是這樣的:

[[0, 0], [0, 3], [0, 0]] 

EDIT此外即興ements

我會推薦使用numpy。

import numpy as np 

... 

board = np.zeros([HEIGHT,WIDTH], dtype=int) 

... 

def count_neighbours(board, x, y): 
    return np.sum(board[x-1:x+2][y-1:y+2]) - board[x][y] 
+0

是的謝謝!你有沒有機會看看其他人? –

1

你正在做迭代的錯誤在一定範圍內,而不是在範圍檢查成員:

>>> x = 3 
>>> for x in range(5): 
...  print x 
1 
2 
3 
4 
5 

相反的for ... in,你需要使用if ... infor是一個循環,if是一個分支:

>>> x = 3 
>>> if x in range(5): 
...  print x 
3 

所以,get_cell將是:

def get_cell(board, x, y): 
    if x in range(WIDTH) and y in range(HEIGHT): 
     return board[y][x] 
    else: 
     return 0 
0

其他已經告訴你了你的代碼的問題是什麼,但請注意,您可以通過簡化它使用set而不是嵌套列表。

下面是一個完整的例子,使用set作爲棋盤和pygame來顯示它。使用鼠標按鈕創建或殺死一個單元格。

import pygame 
from itertools import product, chain 

pygame.init() 
screen = pygame.display.set_mode((300, 300)) 
clock = pygame.time.Clock() 
board = {(0,0),(1,0),(1,1),(0,1),(2,3),(2,2),(3,3),(3,2)} 
pygame.time.set_timer(pygame.USEREVENT, 1500) 

CELLSIZE = 32 
H_CELLSIZE = CELLSIZE/2 

def neighbors(point): 
    x,y = point 
    for dx, dy in product((-1,0,1), repeat=2): 
     if dx != 0 or dy != 0: 
      if x + dx >= 0 and y + dy >= 0: 
       yield x + dx, y + dy 

def step(board): 
    new_board = set() 
    with_neighbors = board | set(chain(*map(neighbors, board))) 
    for point in with_neighbors: 
     count = sum((neigh in board) for neigh in neighbors(point)) 
     if count == 3 or (count == 2 and point in board): 
      new_board.add(point) 
    return new_board 

def scr_to_board(pos): 
    x, y = pos 
    return (x/CELLSIZE , y/CELLSIZE) 

def board_to_scr(pos): 
    x, y = pos 
    return (x * CELLSIZE + H_CELLSIZE, y * CELLSIZE + H_CELLSIZE) 

while True: 
    if pygame.event.get(pygame.QUIT): 
     break 

    for e in pygame.event.get(): 
     if e.type == pygame.MOUSEBUTTONDOWN: 
      board ^= {scr_to_board(pygame.mouse.get_pos())} 
     if e.type == pygame.USEREVENT: 
      board = step(board) 

    screen.fill(pygame.color.Color('white')) 
    for cell in board: 
     pygame.draw.circle(screen, pygame.color.Color('black'), board_to_scr(cell), H_CELLSIZE, 0) 

    pygame.display.flip() 
    clock.tick(60) 

enter image description here