以下是我在Python中实现的John的“生命游戏”:
from copy import deepcopy
def countSurrounding(board, row, cell):
SURROUNDING = ((row - 1, cell - 1),
(row - 1, cell ),
(row - 1, cell + 1),
(row , cell - 1),
(row , cell + 1),
(row + 1, cell - 1),
(row + 1, cell ),
(row + 1, cell + 1))
count = 0
for row, cell in SURROUNDING:
if isInRange(board, row, cell) and board[row][cell] == True:
count += 1
return count
def isInRange(board, row, cell):
return 0 <= row < len(board) and 0 <= cell < len(board[0])
def nextGeneration(board):
nextBoard = deepcopy(board)
for row in range(len(board)):
for cell in range(len(board[0])):
if board[row][cell] == True and countSurrounding(board, row, cell) not in (2, 3):
nextBoard[row][cell] = False
elif board[row][cell] == False and countSurrounding(board, row, cell) == 3:
nextBoard[row][cell] = True
return nextBoard
def printBoard(board):
for row in board:
for cell in row:
if cell == True:
print("#", end = "")
else:
print(".", end = "")
print()
print()
def main():
board = [[False, False, False, False, False, False, False, False, False],
[False, False, False, True , False, False, False, False, False],
[False, True , False, True , False, False, False, False, False],
[False, False, True , True , False, False, False, False, False],
[False, False, False, False, False, False, False, False, False],
[False, False, False, False, False, False, False, False, False],
[False, False, False, False, False, False, False, False, False],
[False, False, False, False, False, False, False, False, False],
[False, False, False, False, False, False, False, False, False]]
for i in range(10):
printBoard(board)
board = nextGeneration(board)
main()有人能建议对我的代码进行优化吗?
谢谢
发布于 2013-09-28 20:53:56
的注释
main()的电话上没有警卫。这使得使用交互式解释器调试程序变得更加困难:一旦模块被导入,它就调用main()并开始运行。最好派个警卫:if __name__ == '__main__':main()True或False进行比较。代替: if单元格==真:您可以写: if单元格:和代替: if board划 == False:您可以写:如果不是板划:paste方法,以了解如何解码这种图片。array[cell]而不是array[x][y],相邻的单元可以通过简单的算术操作找到。from itertools import product
class Life(object):
def __init__(self, width, height):
self.width = width
self.height = height
cells = (width + 2) * (height + 2)
self.live = [False] * cells
self.in_bounds = [True] * cells
self.neighbours = [0] * cells
for i in range(width + 2):
self.in_bounds[i] = self.in_bounds[-i] = False
for j in range(height):
k = (j + 1) * (width + 2)
self.in_bounds[k - 1] = self.in_bounds[k] = False
self.neighbourhood = [y * (width + 2) + x
for x, y in product((-1, 0, 1), repeat=2)
if x or y]
self.needs_update = set()
def cell(self, x, y):
"""Return the cell number corresponding to the coordinates (x, y)."""
return (self.width + 2) * (y + 1) + x + 1
def set(self, p, value):
"""Set cell number 'p' to 'value' (True=live, False=dead)."""
if value != self.live[p] and self.in_bounds[p]:
self.live[p] = value
self.needs_update.add(p)
adjust = 1 if value else -1
for n in self.neighbourhood:
n += p
if self.in_bounds[n]:
self.neighbours[n] += adjust
self.needs_update.add(n)
def update(self, steps=1):
"""Update the world by 'steps' generations (default: 1)."""
for _ in range(steps):
u = [(p, self.live[p], self.neighbours[p]) for p in self.needs_update]
self.needs_update = set()
for p, live, neighbours in u:
if live and not 2 <= neighbours <= 3:
self.set(p, False)
elif not live and neighbours == 3:
self.set(p, True)
def paste(self, s, x, y):
"""Decode 's' as a life pattern (o = live, any other character = dead)
and paste it with top left corner at (x, y).
"""
for j, line in enumerate(s.strip().splitlines()):
for i, char in enumerate(line.strip()):
self.set(self.cell(x + i, y + j), char == 'o')注意:
live、in_bounds和neighbours数组组合为一个,也许可以使用位旋转来组合值(邻居计数适合4位,而其他两个数组各为1位)。为了简单起见,我把它放在三个单独的数组中。下面是派克中的一个快速实现:
import pygame
from pygame.constants import KEYUP, MOUSEBUTTONDOWN, MOUSEMOTION, QUIT, \
K_p, K_q, K_s, K_ESCAPE, K_SPACE
class PygameLife(Life):
def __init__(self, width, height,
background=pygame.Color(240, 240, 255),
foreground=pygame.Color('black'),
cell_size=4):
super(PygameLife, self).__init__(width, height)
self.background = background
self.foreground = foreground
self.cell_size = cell_size
def draw(self):
screen = pygame.display.get_surface()
screen.fill(self.background)
c = self.cell_size
for x in range(self.width):
for y in range(self.height):
if self.live[self.cell(x, y)]:
screen.fill(self.foreground, pygame.Rect(x * c, y * c, c, c))
pygame.display.flip()
def screen_cell(self, pos):
"""Return the cell number corresponding to screen position 'pos', or
None if the position is out of bounds.
"""
x, y = pos
x //= self.cell_size
y //= self.cell_size
if 0 <= x < self.width and 0 <= y < self.height:
return self.cell(x, y)
return None
def run(self):
pygame.init()
pygame.display.set_mode((self.width * self.cell_size,
self.height * self.cell_size))
paused = False
drawing = False
running = True
while running:
for event in pygame.event.get():
t = event.type
if t == QUIT or t == KEYUP and event.key in (K_q, K_ESCAPE):
running = False
elif t == KEYUP and event.key in (K_p, K_SPACE):
paused = not paused
elif t == KEYUP and event.key in (K_s,):
self.update()
elif t == MOUSEBUTTONDOWN and event.button == 1:
paused = True
p = self.screen_cell(event.pos)
drawing = not self.live[p]
self.set(p, drawing)
elif t == MOUSEMOTION and event.buttons[0]:
paused = True
self.set(self.screen_cell(event.pos), drawing)
if paused:
pygame.display.set_caption('Paused (press SPACE to run)')
else:
pygame.display.set_caption('Life')
self.update()
self.draw()
pygame.quit()下面是行动中的比尔·高斯珀 滑翔机炮:
>>> glider_gun = '''
........................o...........
......................o.o...........
............oo......oo............oo
...........o...o....oo............oo
oo........o.....o...oo..............
oo........o...o.oo....o.o...........
..........o.....o.......o...........
...........o...o....................
............oo......................'''
>>> p = PygameLife(100, 60)
>>> p.paste(glider_gun, 8, 1)
>>> p.run()
典型的生活模式包含许多重复的对象。例如,滑翔机炮的输出包含许多滑翔机,它们的行为都是相同的。如果能够利用这种重复,只计算一次滑翔机(或任何其他重复模式)的演变,结果就会出现在世界上所有必要的地方,那就太好了。
使这一想法精确,并将其转化为一种算法,将导致比尔·高斯珀的哈希姆。
发布于 2013-09-25 22:22:16
先读http://www.python.org/dev/peps/pep-0008/,然后读毕达顿。您会惊讶于您的代码将如何得到改进,将新代码作为一个新文件编写并进行比较。
在你的董事会名单上,这是一块巨大的假嘘声砖。通过使用列表理解,您可以轻松、干净地填充此列表。
https://codereview.stackexchange.com/questions/31817
复制相似问题