Python和生命游戏规则

时间:2013-12-06 02:35:12

标签: python conways-game-of-life

好的,所以我终于打印出来了,实际上做了些什么,但规则并没有正确应用?我试过搞乱这些规则,但似乎无法将它们打印出来,这是我的规则的一部分:

nCount = 0
for i in range(x-1,x+2):
  for j in range(y-1,y+2):
    if not(i == x and j == y):
          nCount += int(mat[i][j])
if(nCount < 2 or nCount > 3):
  return 0
elif(nCount == 2 or nCount == 3):
  return 1
else:
  return mat[i][j]

我已经测试了常规的5x5,中间有3个1作为振荡器但不是振荡,而是用方形盒填充5x5边缘,然后停止

以下是我编码的其余部分:

import time
import os

def buildMatrix(fname):
  fp = open(fname, "r")
  row = fp.readlines()
  matrix = []
  for i in range(0, len(row), 1):
    token = row[i].split(" ")
    token[-1] = token[-1].replace('\n', ' ')
    matrix.append(token)
  fp.close()
  return matrix

def getRows(mat):
  return len(mat)

def getCols(mat):
  return len(mat[0])

def printGen(mat): #this is what i use for printing
  os.system('clear')
  for i in range(0, len(mat), 1):
    for j in range(0, len(mat[0]), 1):
      if(mat[i][j] == 1):
        print("#", sep=" ", end=" ")
      else:
        print(" ", sep=" ", end=" ")
    print()

def nextGen(cur, nxt): #use this to update to the next matrix
  for i in range(0, len(cur)-1, 1):
    for j in range(0, len(cur[0])-1, 1):
      nxt[i][j] = neighbors(i, j, cur)
  return nxt

def neighbors(x, y, mat):
  nCount = 0
  for i in range(x-1,x+2):
    for j in range(y-1,y+2):
      if not(i == x and j == y):
            nCount += int(mat[i][j])
  if(nCount < 2 or nCount > 3):
    return 0
  elif(nCount == 2 or nCount ==3):
    return 1
   else:
    return mat[i][j]

这不是我的所有代码,因为我仍然将所有这些导入到另一个仓库并从该仓库运行它,但是我已完成的另一部分

2 个答案:

答案 0 :(得分:3)

elif(nCount == 2,3):

这不能做你想做的事。这将构建一个2元素元组,其第一个元素是nCount == 2的值,第二个元素是3,然后将此元组转换为布尔值以决定走哪条路。如果您想检查nCount是否等于2或3,您可以使用

elif nCount in (2, 3):

但这是多余的,因为nCount必须是控制流量达到elif的其中之一。当然,这对于实施生活规则并不正确;你想要的是

elif nCount == 3:

如果被其他2个活细胞包围,则细胞保持其当前的活/死状态。它周围必须有3个活细胞才能在下一代活着,无论其目前的生活状态如何。

答案 1 :(得分:2)

看起来你的代码没有先制作副本,所以出生或死亡的结果正在影响自己。试试副本:

import numpy

# this function does all the work
def play_life(a):
    xmax, ymax = a.shape
    b = a.copy() # copy current life grid
    for x in range(xmax):
        for y in range(ymax):
            n = numpy.sum(a[max(x - 1, 0):min(x + 2, xmax), max(y - 1, 0):min(y + 2, ymax)]) - a[x, y]
            if a[x, y]:
                if n < 2 or n > 3:
                    b[x, y] = 0 # living cells with <2 or >3 neighbors die
            elif n == 3:
                b[x, y] = 1 # dead cells with 3 neighbors ar born
    return(b)

life = numpy.zeros((5, 5), dtype=numpy.byte)

# place starting conditions here
life[2, 1:4] = 1 # middle three in middle row to 1

# now let's play
print(life)
for i in range(3):
    life = play_life(life)
    print(life)

我还使用numpy来提高速度。请注意,在进行复制时,将处理具有2个或3个邻居的活动单元的情况。以下是此测试用例的结果:

[[0 0 0 0 0]
 [0 0 0 0 0]
 [0 1 1 1 0]
 [0 0 0 0 0]
 [0 0 0 0 0]]

[[0 0 0 0 0]
 [0 0 1 0 0]
 [0 0 1 0 0]
 [0 0 1 0 0]
 [0 0 0 0 0]]

[[0 0 0 0 0]
 [0 0 0 0 0]
 [0 1 1 1 0]
 [0 0 0 0 0]
 [0 0 0 0 0]]

[[0 0 0 0 0]
 [0 0 1 0 0]
 [0 0 1 0 0]
 [0 0 1 0 0]
 [0 0 0 0 0]]

现在,如果你没有numpy,那么你可以像这样使用“2D”数组:

# this function does all the work
def play_life(a):
    xmax = len(a)
    ymax = len(a[0])
    b = [[cell for cell in row] for row in life]
    for x in range(xmax):
        for y in range(ymax):
            n = 0
            for i in range(max(x - 1, 0), min(x + 2, xmax)):
                for j in range(max(y - 1, 0), min(y + 2, ymax)):
                    n += a[i][j]
            n -= a[x][y]
            if a[x][y]:
                if n < 2 or n > 3:
                    b[x][y] = 0 # living cells with <2 or >3 neighbors die
            elif n == 3:
                b[x][y] = 1 # dead cells with 3 neighbors ar born
    return(b)

# this function just prints the board
def show_life(a):
    print('\n'.join([' '.join([str(cell) for cell in row]) for row in life]) + '\n')

# create board
x_size, y_size = (5, 5)
life = [[0 for y in range(y_size)] for x in range(x_size)]

# place starting conditions here
for x in range(1, 4): life[x][2] = 1 # middle three in middle row to 1

# now let's play
show_life(life)
for i in range(3):
    life = play_life(life)
    show_life(life)

为测试用例输出以下内容:

0 0 0 0 0
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 0 0 0

0 0 0 0 0
0 0 0 0 0
0 1 1 1 0
0 0 0 0 0
0 0 0 0 0

0 0 0 0 0
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 0 0 0

0 0 0 0 0
0 0 0 0 0
0 1 1 1 0
0 0 0 0 0
0 0 0 0 0