python数据结构学习笔记-2016-10-15-02-生命游戏
2016-10-15 11:57
751 查看
2.5 生命游戏
生命游戏由英国数学及John H.Conway设计,是一个零人游戏。
2.5.1 游戏规则
这个游戏使用一张无限大的直角坐标网格,每一个网格可以由一个细胞占据,当一个网格被细胞占据,称为活的(alive),而空网格被称为死的(dead),也可以以活细胞和死细胞称呼。
游戏的每一轮称为一代(generation),根据每个网格细胞的当前形态(configuration),决定下一代中网格细胞的形态。
当一个网格细胞是活的,并且周围有2~3个邻居(活细胞)时,其在下一代中是活的,注意周围是指水平、竖直和对角线相邻的网格;
当一个网格细胞是活的,并且周围有0~1个邻居时,其在下一代中变成死的;
当一个网格细胞是活的,并且周围有4~5个邻居时,其在下一代中变成死的;
当一个网格细胞是死的,并且周围有3个邻居时,其在下一代中变成活的,其余所有死细胞在下一代中,仍是死的。
这一游戏的最终结果依据于初始状态和世代数,大部分结果是所有细胞都会死去,但也有一些有趣的情况。
稳态:
两相振荡:
2.5.2 设计一个解决方法
本游戏需要创建一个生命网格ADT,来记录每一代的网格细胞的状态。这一ADT,应包含如下方法:
LifeGrid(nrows, ncols):创建生命网格实例,行数是nrows,列数是ncols,所有网格被初始化为死的状态;
numRows():返回行数;
numCols():返回列数;
configure(coordList):设定本世代中网格细胞的状态,将一系列给定坐标的网格设定为活细胞状态,而coordList是由多个含两个数值的元组组成,其余网格为死细胞状态;
clearCell(row, col):将给定坐标的网格细胞设定为死细胞;
setCell(row, col):将给定坐标的网格细胞设定为活细胞;
isLiveCell(row, col):判断给定坐标的网格细胞的状态,False为死细胞,True为活细胞;
numLiveNeighbors(row, col):计算给定坐标周围活细胞数,特殊情况是考虑在网格边缘处周围活细胞数统计。
2.5.3 实现
生命游戏由英国数学及John H.Conway设计,是一个零人游戏。
2.5.1 游戏规则
这个游戏使用一张无限大的直角坐标网格,每一个网格可以由一个细胞占据,当一个网格被细胞占据,称为活的(alive),而空网格被称为死的(dead),也可以以活细胞和死细胞称呼。
游戏的每一轮称为一代(generation),根据每个网格细胞的当前形态(configuration),决定下一代中网格细胞的形态。
当一个网格细胞是活的,并且周围有2~3个邻居(活细胞)时,其在下一代中是活的,注意周围是指水平、竖直和对角线相邻的网格;
当一个网格细胞是活的,并且周围有0~1个邻居时,其在下一代中变成死的;
当一个网格细胞是活的,并且周围有4~5个邻居时,其在下一代中变成死的;
当一个网格细胞是死的,并且周围有3个邻居时,其在下一代中变成活的,其余所有死细胞在下一代中,仍是死的。
这一游戏的最终结果依据于初始状态和世代数,大部分结果是所有细胞都会死去,但也有一些有趣的情况。
稳态:
两相振荡:
2.5.2 设计一个解决方法
本游戏需要创建一个生命网格ADT,来记录每一代的网格细胞的状态。这一ADT,应包含如下方法:
LifeGrid(nrows, ncols):创建生命网格实例,行数是nrows,列数是ncols,所有网格被初始化为死的状态;
numRows():返回行数;
numCols():返回列数;
configure(coordList):设定本世代中网格细胞的状态,将一系列给定坐标的网格设定为活细胞状态,而coordList是由多个含两个数值的元组组成,其余网格为死细胞状态;
clearCell(row, col):将给定坐标的网格细胞设定为死细胞;
setCell(row, col):将给定坐标的网格细胞设定为活细胞;
isLiveCell(row, col):判断给定坐标的网格细胞的状态,False为死细胞,True为活细胞;
numLiveNeighbors(row, col):计算给定坐标周围活细胞数,特殊情况是考虑在网格边缘处周围活细胞数统计。
#-*-coding: utf-8-*- # 生命游戏程序 from life import LifeGrid # 网格大小 GRID_WIDTH = int(raw_input("Please enter a positive integer as width: ")) GRID_HEIGHT = int(raw_input("Please enter a positive integer as height: ")) # 初始状态 INIT_CONFIG = [(0, 0), (0, 1), (1, 0), (1, 2), (3, 2), (3, 4), (5, 4), (5, 6), (7, 6), (7, 8), (9, 8), (9, 10), (11, 10), (11, 12), (12, 11), (12, 12)] # 世代数 NUM_GENS = int(raw_input("Please enter a positive integer as generation: ")) # 产生下一代的生命 def evolve(grid): # 储存下一代活细胞的列表 liveCells = list() # 遍历整个网格 for i in range(grid.numRows()): for j in range(grid.numCols()): # 读取周围活细胞数 neighbors = grid.numLiveNeighbors(i, j) # 如果该坐标有活细胞,并且周围活细胞数是2或3,将该坐标加入到下一代活细胞的列表 if (neighbors == 2 and grid.isLiveCell(i, j)) or (neighbors == 3): liveCells.append((i, j)) # 使用下一代活细胞的列表去初始化网格 grid.configure(liveCells) # 打印一个基于文本表示的生命游戏 def draw(grid): for i in range(grid.numRows()): string = '' for j in range(grid.numCols()): if grid.isLiveCell(i, j): string += '@ ' else: string += '. ' print string print '\n' def main(): # 构建游戏网格,并初始化 grid = LifeGrid(GRID_WIDTH, GRID_HEIGHT) grid.configure(INIT_CONFIG) # 游戏开始 draw(grid) # for i in INIT_CONFIG: # print grid.numLiveNeighbors(*i) for i in range(NUM_GENS): evolve(grid) draw(grid) if __name__ == "__main__": main()draw()函数是打印当前网格状态,而evolve()是产生下一代的网格状态。
2.5.3 实现
#-*-coding: utf-8-*- # 实现LifeGrid ADT from myarray2d import Array2D class LifeGrid(object): # 定义代表细胞状态的常量 DEAD_CELL = 0 LIVE_CELL = 1 # 创建游戏网格实例,并将所有细胞设定为死细胞状态 def __init__(self, numRows, numCols): # 创建网格实例 self._grid = Array2D(numRows, numCols) # 将所有细胞设定为死细胞状态 self.configure(list()) def numRows(self): return self._grid.numRows() def numCols(self): return self._grid.numCols() # 将给定网格坐标的细胞设为活细胞,网格坐标由列表传入 def configure(self, coordList): # 先将所有网格中的细胞设为死细胞 for i in range(self.numRows()): for j in range(self.numCols()): self.clearCell(i, j) # 再将给定网格坐标的细胞设为活细胞 for coord in coordList: self.setCell(coord[0], coord[1]) # 判断给定网格坐标中的细胞状态 def isLiveCell(self, row, col): return self._grid[row, col] == LifeGrid.LIVE_CELL def clearCell(self, row, col): self._grid[row, col] = LifeGrid.DEAD_CELL def setCell(self, row, col): self._grid[row, col] = LifeGrid.LIVE_CELL # 计算给定网格周围活细胞数 def numLiveNeighbors(self, row, col): count = -1 if self.isLiveCell(row, col) else 0 for r in range(row-1, row+2): for c in range(col-1, col+2): try: if self.isLiveCell(r, c): count += 1 except AssertionError, e: continue return count
相关文章推荐
- python数据结构学习笔记-2016-11-26-02-树结构
- python数据结构学习笔记-2016-10-15-01-矩阵ADT
- python数据结构学习笔记-2016-11-02-02-迷宫问题
- python数据结构学习笔记-2016-11-24-02-基数排序
- python数据结构学习笔记-2016-10-14-02-python列表
- python数据结构学习笔记-2016-10-24-02-使用排序列表实现集合ADT
- python数据结构学习笔记-2016-10-17-02-映射
- python数据结构学习笔记-2016-10-28-02-使用链表实现稀疏矩阵
- python数据结构学习笔记-2016-11-05-02-优先级队列
- python数据结构学习笔记-2016-11-12-02-递归的应用
- python数据结构学习笔记-2016-10-27-02-使用单链表实现包ADT
- python数据结构学习笔记-2016-12-04-02-二叉搜索树
- python数据结构学习笔记-2016-10-05-02-抽象数据类型(二)
- python数据结构学习笔记-2016-10-23-02-排序
- Python学习笔记02
- Python学习笔记02 变量和程序的编写
- python数据结构学习笔记-1
- 【python学习笔记02】python的数据类型2
- python学习笔记(django入门02)
- python学习笔记-02