Python 实施康威的生命游戏
Python implementation of Conway's Game of Life
出于学习目的,我已经开始创建康威生命游戏的实现。我用 numpy 来存储大数组,连接死细胞和活细胞,然后我应用康威规则来创建细胞生命机制。为了管理网格和图形,我使用了 pygame 模块。
看了很多次,改写了很多次代码,也查不出哪里有问题,所以决定问问大家。例如,我曾尝试制作滑翔机(如代码所示),但他在 3 个循环周期后死亡。如果您能提供帮助和提示,我将不胜感激。你能帮我找出为什么细胞不能繁殖吗?提前致谢。
代码:
import pygame
import numpy as np
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
N = 195
WIDTH = 10
HEIGHT = 10
grid = np.zeros(shape=(N, N), dtype=np.int32)
glider = np.array([[0, 0, 1],
[1, 0, 1],
[0, 1, 1]])
grid[3:6, 3:6] = glider
pygame.init()
WINDOW_SIZE = [980, 980]
screen = pygame.display.set_mode(WINDOW_SIZE)
pygame.display.set_caption("GAME OF LIFE")
done = False
clock = pygame.time.Clock()
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
for row in range(N):
for column in range(N):
color = BLACK
if grid[row][column] == 1:
color = GREEN
pygame.draw.rect(screen, color,
[WIDTH * column,
HEIGHT * row,
WIDTH,
HEIGHT])
newGrid = grid.copy()
for i in range(N):
for j in range(N):
total = grid[(i-1) % N:(i+1) % N, (j-1) % N:(j+1) % N].sum() - grid[i, j]
if grid[i, j] == 1:
if(total < 2) or (total > 3):
newGrid[i, j] = 0
else:
if total == 3:
newGrid[i, j] = 1
grid = newGrid
clock.tick(60)
pygame.display.flip()
pygame.quit()
可能是 newGrid 循环中的 else 子句过度缩进了?因为截至目前,网格仅从 1 变为 0 而从未从 0 变为 1。这可能是因为数组切片:[(i-1) % n : (i+1) % n]。有 2 个问题:
- 这只计入 (i+1) % n 之前的索引,所以它不包括 (i+1) % n。
- 它不会像您预期的那样环绕,例如[9:1] 不会从 9 到 10 再到 0 并在 1 之前停止。它只是 returns 空列表。
这里有一个技巧
a.take(range(-1,2),mode='wrap', axis=0).take(range(-1,2),mode='wrap',axis=1)
来自这个 post Wrap slice around edges of a 2D array in numpy。我用这个技巧修改了下面的代码。
import pygame
import numpy as np
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
N = 195
WIDTH = 10
HEIGHT = 10
grid = np.zeros(shape=(N, N), dtype=np.int32)
glider = np.array([[0, 0, 1],
[1, 0, 1],
[0, 1, 1]])
grid[3:6, 3:6] = glider
pygame.init()
WINDOW_SIZE = [980, 980]
screen = pygame.display.set_mode(WINDOW_SIZE)
pygame.display.set_caption("GAME OF LIFE")
done = False
clock = pygame.time.Clock()
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
for row in range(N):
for column in range(N):
color = BLACK
if grid[row][column] == 1:
color = GREEN
pygame.draw.rect(screen, color,
[WIDTH * column,
HEIGHT * row,
WIDTH,
HEIGHT])
newGrid = grid.copy()
for i in range(N):
for j in range(N):
total = grid.take(range(i-1,i+2),mode='wrap', axis=0).take(range(j-1,j+2),mode='wrap',axis=1).sum() - grid[i, j]
if grid[i, j] == 1:
if(total < 2) or (total > 3):
newGrid[i, j] = 0
else:
if total == 3:
newGrid[i, j] = 1
grid = newGrid
clock.tick(60)
pygame.display.flip()
pygame.quit()
我认为您在实现 Conway's rules 的方式中存在一些细微的错误。
详情见我在代码中的注释:
for i in range(N):
for j in range(N):
# I changed the range of the extent of the sum, note +2 rather than +1 !
total = grid[(i-1) % N:(i+2) % N, (j-1) % N:(j+2) % N].sum() - grid[i, j]
if grid[i, j] == 1:
if(total < 2) or (total > 3):
newGrid[i, j] = 0
# allow for survival in case of total = 2 or 3 (this could be dropped though)
else:
newGrid[i, j] = 1
# allow for reproduction if cell is empty
else:
if total == 3:
newGrid[i, j] = 1
通过这些编辑,滑翔机应该可以滑翔了:)
出于学习目的,我已经开始创建康威生命游戏的实现。我用 numpy 来存储大数组,连接死细胞和活细胞,然后我应用康威规则来创建细胞生命机制。为了管理网格和图形,我使用了 pygame 模块。 看了很多次,改写了很多次代码,也查不出哪里有问题,所以决定问问大家。例如,我曾尝试制作滑翔机(如代码所示),但他在 3 个循环周期后死亡。如果您能提供帮助和提示,我将不胜感激。你能帮我找出为什么细胞不能繁殖吗?提前致谢。 代码:
import pygame
import numpy as np
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
N = 195
WIDTH = 10
HEIGHT = 10
grid = np.zeros(shape=(N, N), dtype=np.int32)
glider = np.array([[0, 0, 1],
[1, 0, 1],
[0, 1, 1]])
grid[3:6, 3:6] = glider
pygame.init()
WINDOW_SIZE = [980, 980]
screen = pygame.display.set_mode(WINDOW_SIZE)
pygame.display.set_caption("GAME OF LIFE")
done = False
clock = pygame.time.Clock()
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
for row in range(N):
for column in range(N):
color = BLACK
if grid[row][column] == 1:
color = GREEN
pygame.draw.rect(screen, color,
[WIDTH * column,
HEIGHT * row,
WIDTH,
HEIGHT])
newGrid = grid.copy()
for i in range(N):
for j in range(N):
total = grid[(i-1) % N:(i+1) % N, (j-1) % N:(j+1) % N].sum() - grid[i, j]
if grid[i, j] == 1:
if(total < 2) or (total > 3):
newGrid[i, j] = 0
else:
if total == 3:
newGrid[i, j] = 1
grid = newGrid
clock.tick(60)
pygame.display.flip()
pygame.quit()
可能是 newGrid 循环中的 else 子句过度缩进了?因为截至目前,网格仅从 1 变为 0 而从未从 0 变为 1。这可能是因为数组切片:[(i-1) % n : (i+1) % n]。有 2 个问题:
- 这只计入 (i+1) % n 之前的索引,所以它不包括 (i+1) % n。
- 它不会像您预期的那样环绕,例如[9:1] 不会从 9 到 10 再到 0 并在 1 之前停止。它只是 returns 空列表。
这里有一个技巧
a.take(range(-1,2),mode='wrap', axis=0).take(range(-1,2),mode='wrap',axis=1)
来自这个 post Wrap slice around edges of a 2D array in numpy。我用这个技巧修改了下面的代码。
import pygame
import numpy as np
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
N = 195
WIDTH = 10
HEIGHT = 10
grid = np.zeros(shape=(N, N), dtype=np.int32)
glider = np.array([[0, 0, 1],
[1, 0, 1],
[0, 1, 1]])
grid[3:6, 3:6] = glider
pygame.init()
WINDOW_SIZE = [980, 980]
screen = pygame.display.set_mode(WINDOW_SIZE)
pygame.display.set_caption("GAME OF LIFE")
done = False
clock = pygame.time.Clock()
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
for row in range(N):
for column in range(N):
color = BLACK
if grid[row][column] == 1:
color = GREEN
pygame.draw.rect(screen, color,
[WIDTH * column,
HEIGHT * row,
WIDTH,
HEIGHT])
newGrid = grid.copy()
for i in range(N):
for j in range(N):
total = grid.take(range(i-1,i+2),mode='wrap', axis=0).take(range(j-1,j+2),mode='wrap',axis=1).sum() - grid[i, j]
if grid[i, j] == 1:
if(total < 2) or (total > 3):
newGrid[i, j] = 0
else:
if total == 3:
newGrid[i, j] = 1
grid = newGrid
clock.tick(60)
pygame.display.flip()
pygame.quit()
我认为您在实现 Conway's rules 的方式中存在一些细微的错误。 详情见我在代码中的注释:
for i in range(N):
for j in range(N):
# I changed the range of the extent of the sum, note +2 rather than +1 !
total = grid[(i-1) % N:(i+2) % N, (j-1) % N:(j+2) % N].sum() - grid[i, j]
if grid[i, j] == 1:
if(total < 2) or (total > 3):
newGrid[i, j] = 0
# allow for survival in case of total = 2 or 3 (this could be dropped though)
else:
newGrid[i, j] = 1
# allow for reproduction if cell is empty
else:
if total == 3:
newGrid[i, j] = 1
通过这些编辑,滑翔机应该可以滑翔了:)