使用Python实现康威生命游戏?


大约在1970年,一位英国数学家创造了他的“生命游戏”——它实际上是一套规则,描述了生物有机体群落混乱而有规律的生长。“生命游戏”是一个二维网格,由“活”细胞和“死”细胞组成。

生命游戏的规则

  • **过度繁殖:** 如果一个细胞周围有超过三个活细胞,则该细胞死亡。

  • **稳定:** 如果一个细胞周围有两个或三个活细胞,则该细胞存活。

  • **人口不足:** 如果一个细胞周围少于两个活细胞,则该细胞死亡。

  • **繁殖:** 如果一个死细胞周围恰好有三个活细胞,则该细胞活过来。

 细胞将在下一个时间步长死亡

 细胞将在下一个时间步长存活

 细胞存活

 细胞死亡

通过按顺序步骤应用上述规则,我们将得到美丽而意想不到的图案。

实现步骤

i. Initialise an empty universe
ii. Fill the universe with the seed
iii. Calculate if the current cell survives to the next timestamps, based on its neighbours
iv. Repeat this survival function(like step-iii) over all the cells in the universe neighbours.
v. Repeat steps iii-iv for the desired number of generations.

安装

要创建康威生命游戏,我们将使用matplotlib和numpy数组库。要安装numpy和matplolib,请使用pip -

$pip install numpy, matplolib

实现康威生命游戏的程序

现在是时候根据我们上述规则编写程序了。以下是实现生命游戏的程序:

#Import required library

import numpy as np
import matplotlib.pyplot as plt

import argparse
import time

#-------------------------------------------------------------------------
class Board(object):
   def __init__(self, size, seed = 'Random'):
      if seed == 'Random':
         self.state = np.random.randint(2, size = size)
      self.engine = Engine(self)
      self.iteration = 0
   def animate(self):
      i = self.iteration
      im = None
      plt.title("Conway's Game of Life")
      while True:
         if i == 0:
            plt.ion()
            im = plt.imshow(self.state, vmin = 0, vmax = 2, cmap = plt.cm.gray)
         else:
            im.set_data(self.state)
         i += 1
         self.engine.applyRules()
         print('Life Cycle: {} Birth: {} Survive: {}'.format(i, self.engine.nBirth, self.engine.nSurvive))
         plt.pause(0.01)
         yield self

#-------------------------------------------------------------------------

class Engine(object):
   def __init__(self, board):
      self.state = board.state
   def countNeighbors(self):
      state = self.state
      n = (state[0:-2,0:-2] + state[0:-2,1:-1] + state[0:-2,2:] +
          state[1:-1,0:-2] + state[1:-1,2:] + state[2:,0:-2] +
          state[2:,1:-1] + state[2:,2:])
      return n
   def applyRules(self):
      n = self.countNeighbors()
      state = self.state
      birth = (n == 3) & (state[1:-1,1:-1] == 0)
      survive = ((n == 2) | (n == 3)) & (state[1:-1,1:-1] == 1)
      state[...] = 0
      state[1:-1,1:-1][birth | survive] = 1
      nBirth = np.sum(birth)
      self.nBirth = nBirth
      nSurvive = np.sum(survive)
      self.nSurvive = nSurvive
   return state

#-------------------------------------------------------------------------

def main():
   ap = argparse.ArgumentParser(add_help = False) # Intilialize Argument Parser
   ap.add_argument('-h', '--height', help = 'Board Height', default = 256)
   ap.add_argument('-w', '--width', help = 'Board Width', default = 256)
   args = vars(ap.parse_args()) # Gather Arguments
   bHeight = int(args['height'])
   bWidth = int(args['width'])
   board = Board((bHeight,bWidth))
   for _ in board.animate():
      pass
#-------------------------------------------------------------------------

if __name__ == '__main__':
   main()

输出

Console:
Life Cycle: 1 Birth: 7166 Survive: 10621
Life Cycle: 2 Birth: 7930 Survive: 8409
Life Cycle: 3 Birth: 7574 Survive: 8756
Life Cycle: 4 Birth: 7114 Survive: 8406
Life Cycle: 5 Birth: 7005 Survive: 8126
Life Cycle: 6 Birth: 6644 Survive: 7926
Life Cycle: 7 Birth: 6266 Survive: 7711
Life Cycle: 8 Birth: 6132 Survive: 7427
Life Cycle: 9 Birth: 5957 Survive: 7322
Life Cycle: 10 Birth: 5769 Survive: 7290
Life Cycle: 11 Birth: 5585 Survive: 6937
Life Cycle: 12 Birth: 5381 Survive: 6791
Life Cycle: 13 Birth: 5208 Survive: 6686
Life Cycle: 14 Birth: 5063 Survive: 6563
….
…

上述结果将持续出现,直到我们在终端中按下Ctrl-C以停止程序。

图形显示

细胞将不断变化,并将模拟非常美丽的图案。

您可以通过更改设置和更改滑块值来更改上述子图。

更新于:2019年7月30日

504 次浏览

启动你的职业生涯

完成课程获得认证

开始
广告