康威';s使用稀疏矩阵的生命游戏(Python)
我正在使用稀疏矩阵用python编写生命游戏。我的程序从用户输入中获取坐标,并将选定坐标处的单元格设置为活动。我已经把它打印到第一代的地方了,但我似乎不明白为什么它不会打印下一代。任何帮助都将不胜感激康威';s使用稀疏矩阵的生命游戏(Python),python,sparse-matrix,conways-game-of-life,Python,Sparse Matrix,Conways Game Of Life,我正在使用稀疏矩阵用python编写生命游戏。我的程序从用户输入中获取坐标,并将选定坐标处的单元格设置为活动。我已经把它打印到第一代的地方了,但我似乎不明白为什么它不会打印下一代。任何帮助都将不胜感激 class SparseLifeGrid: generations = list() def __init__(self): """ "pass" just allows this to run w/o crashing. Replace it with your ow
class SparseLifeGrid:
generations = list()
def __init__(self):
"""
"pass" just allows this to run w/o crashing.
Replace it with your own code in each method.
"""
self._mat = list()
self.col = []
self.row = []
def minRange(self):
"""
Return the minimum row & column as a tuple.
"""
for i in range(len(self.row)):
if self.row[i] < self.minRow:
self.minRow = self.row[i]
if self.col[i] < self.minCol:
self.minCol = self.col[i]
min_Range = [self.minRow,self.minCol]
return min_Range
def maxRange(self):
"""
Returns the maximum row & column as a tuple.
"""
for i in range(len(self.row)):
if self.row[i] > self.maxRow:
self.maxRow = self.row[i]
if self.col[i] > self.maxCol:
self.maxCol = self.col[i]
max_Range = [self.maxRow,self.maxCol]
return max_Range
def configure(self,coordList):
"""
Set up the initial board position.
"coordlist" is a list of coordinates to make alive.
"""
# for i in coordList:
# self.setCell(i[0],i[1])
self._mat = list()
self.coordList = coordList
for i in range(len(self.coordList)):
spot = self.coordList[i]
self.row += [spot[0]]
self.col += [spot[1]]
self._mat += [[self.row[i],self.col[i]]]
self.maxRow = self.minRow = self.row[0]
self.maxCol = self.minCol = self.col[0]
def clearCell(self,row, col):
"""
Set the cell to "dead" (False)
"""
self[row,col] = 0
def setCell(self,row, col):
"""
Set the cell to "live" (True") and if necessary, expand the
minimum or maximum range.
"""
self[row,col] = 1
def isLiveCell(self,row,col):
n = len(self.coordList)
for i in range(n):
if (self._mat[i] == [row,col]):
return True
return False
def numLiveNeighbors(self, row,col):
"""
Returns the number of live neighbors a cell has.
"""
neighbors = 0
if self.isLiveCell(row+1,col): #checks below the current cell
neighbors += 1
if self.isLiveCell(row-1,col): #checks above the current cell
neighbors += 1
if self.isLiveCell(row,col+1): #checks to the right of the current cell
neighbors += 1
if self.isLiveCell(row,col-1): #checks to the left of the current cell
neighbors += 1
if self.isLiveCell(row+1,col+1): #checks downwards diagonally to the right of the current cell
neighbors += 1
if self.isLiveCell(row+1,col-1): #checks downwards diagonally to the left of the current cell
neighbors += 1
if self.isLiveCell(row-1,col+1): #checks upwards diagonally to the right of the current cell
neighbors += 1
if self.isLiveCell(row-1,col-1): #checks upawards diagonally to the left of the current cell
neighbors += 1
return neighbors
def __getitem__(self,ndxTuple):
row = ndxTuple[0]
col = ndxTuple[1]
if(self.isLiveCell(row,col)==1):
return 1
else:
return 0
def __setitem__(self,ndxTuple, life):
"""
The possible values are only true or false:
True says alive, False for dead.
Also, check to see if this cell is outside of the maximum row and/or
column. If it is, modify the maximum row and/or maximum column.
"""
ndx = self._findPosition(ndxTuple[0],ndxTuple[1])
if ndx != None:
if life != True:
self._mat[ndx].value = life
else:
self._mat.pop[ndx]
else:
if life != True:
element = _GoLMatrixElement(ndxTuple[0],ndxTuple[1],life)
self._mat.append(element)
def _findPosition(self,row,col):
''' Does a search through the matrix when given the row&col and
returns the index of the element if found
'''
n = len(self._mat)
for i in range(n):
if (row == self._mat[i]) and (col == self._mat[i]):
return i
return None
def __str__(self):
"""
Print a column before and after the live cells
"""
s=""
maxRange=self.maxRange()
minRange=self.minRange()
for i in range(minRange[0]-1,maxRange[0]+2):
for j in range(minRange[1]-1,maxRange[1]+2):
s+=" "+str(self[i,j])
s+="\n"
return s
def getCopy(self):
"""
Return a copy of the current board object, including the max and min
values, etc.
"""
return SparseLifeGrid()
def evolve(self):
"""
Save the current state to the "generations" list.
Based on the current generation, return the next generation state.
"""
self.generations.append(self._mat)
for row in range(len(self.row)):
for col in range(len(self.col)):
if ((self[row,col] == True) and (self.numLiveNeighbors(row,col) == 2)):
self.setCell(row,col)
if ((self[row,col] == True) and (self.numLiveNeighbors(row,col) == 3)):
self.setCell(row,col)
if ((self[row,col] == True) and (self.numLiveNeighbors(row,col) < 2)):
self.clearCell(row,col)
if ((self[row,col] == True) and (self.numLiveNeighbors(row,col) > 3)):
self.clearCell(row,col)
if ((self[row,col] == False) and (self.numLiveNeighbors(row,col) == 3)):
self.setCell(row,col)
self.generations.append(self._mat)
return self._mat
def hasOccurred(self):
"""
Check whether this current state has already occured.
If not, return False. If true, return which generation number (1-10).
"""
for i in range(len(self.generations)):
if len(self.generations) > 0:
print("This is generation",len(self.generations))
return self.generations[i]
else:
print("No Generations")
return False
def __eq__(self,other):
"""
This is good method if we want to compare two sparse matrices.
You can just use "sparseMatrixA == sparseMatrixB" once this method
is working.
"""
pass
class _GoLMatrixElement:
"""
Storage class for one cell
"""
def __init__(self,row,col):
self.row = row
self.col = col
self.next = None #
# Since this node exists, this cell is now alive!
# To kill it, we just delete this node from the lists.
class SparseLifeGrid:
代=列表()
定义初始化(自):
"""
“通过”只允许在没有崩溃的情况下运行。
在每个方法中用您自己的代码替换它。
"""
self.\u mat=list()
self.col=[]
self.row=[]
def最小范围(自身):
"""
以元组形式返回最小行和列。
"""
对于范围内的i(len(self.row)):
如果self.row[i]self.maxRow:
self.maxRow=self.row[i]
如果self.col[i]>self.maxCol:
self.maxCol=self.col[i]
max_Range=[self.maxRow,self.maxCol]
返回最大范围
def配置(自我、合作列表):
"""
设置初始板位置。
“coordlist”是要激活的坐标列表。
"""
#对于合作列表中的i:
#self.setCell(i[0],i[1])
self.\u mat=list()
self.coordList=coordList
对于范围内的i(len(self.coordList)):
spot=self.coordList[i]
self.row+=[spot[0]]
self.col+=[spot[1]]
self.\u mat+=[[self.row[i],self.col[i]]
self.maxRow=self.minRow=self.row[0]
self.maxCol=self.minCol=self.col[0]
def clearCell(自身、行、列):
"""
将单元格设置为“死”(假)
"""
self[行,列]=0
def设置单元(自身、行、列):
"""
将单元格设置为“活动”(True),如有必要,展开
最小或最大范围。
"""
self[行,列]=1
def isLiveCell(自身、行、列):
n=len(self.coordList)
对于范围(n)中的i:
如果(自身材料[i]==[行,列]:
返回真值
返回错误
def numLiveNeighbors(自身、行、列):
"""
返回单元格的活动邻居数。
"""
邻居=0
如果self.isLiveCell(行+1,列):#检查当前单元格下方
邻居+=1
如果self.isLiveCell(第1行,列):#在当前单元格上方检查
邻居+=1
如果self.isLiveCell(行、列+1):#检查当前单元格的右侧
邻居+=1
if self.isLiveCell(行,列-1):#检查当前单元格的左侧
邻居+=1
如果self.isLiveCell(行+1,列+1):#向下检查当前单元格右侧的对角线
邻居+=1
如果self.isLiveCell(行+1,列-1):#向下检查当前单元格左侧的对角线
邻居+=1
如果self.isLiveCell(第1行,第+1列):#沿当前单元格右侧的对角线向上检查
邻居+=1
if self.isLiveCell(第1行,第1列):#在当前单元格左侧对角检查奖励
邻居+=1
回乡
def uu getitem(self,ndxTuple):
行=ndxTuple[0]
col=ndxTuple[1]
如果(self.isLiveCell(行、列)==1):
返回1
其他:
返回0
定义设置项(自我、个人、生活):
"""
可能的值仅为真或假:
真代表活着,假代表死亡。
此外,检查此单元格是否超出最大行和/或
柱如果是,请修改最大行和/或最大列。
"""
ndx=self.\u查找位置(ndxTuple[0],ndxTuple[1])
如果ndx!=无:
如果生活是真的:
自我。_mat[ndx]。价值=寿命
其他:
自洁材料流行性[ndx]
其他:
如果生活是真的:
元素=_GoLMatrixElement(ndxTuple[0],ndxTuple[1],life)
自身材料附加(元素)
def_查找位置(自身、行、列):
''在给定行和列时搜索矩阵
返回元素的索引(如果找到)
'''
n=透镜(自聚焦)
对于范围(n)中的i:
如果(行==self.\u mat[i])和(列==self.\u mat[i]):
返回i
一无所获
定义(自我):
"""
打印活动单元格前后的列
"""
s=“”
maxRange=self.maxRange()
minRange=self.minRange()
对于范围内的i(最小范围[0]-1,最大范围[0]+2):
对于范围内的j(最小范围[1]-1,最大范围[1]+2):
s+=“”+str(self[i,j])
s+=“\n”
返回s
def getCopy(self):
"""
返回当前线路板对象的副本,包括最大值和最小值
价值观等。
"""
返回SparseLifeGrid()
def演进(自我):
"""
将当前状态保存到“代”列表中。
基于当前代,返回下一代状态。
"""
self.generations.append(self.\u mat)
对于范围内的行(len(self.row)):
对于范围内的列(len(self.col)):
如果((self[row,col]==True)和(self.numlineighbors(row,col)==2)):
self.setCell(行、列)
如果((self[row,col]==True)和(self.numlineighbors(row,col)==3)):
self.setCell(行、列)
如果((self[row,col]==True)和(self.numlineighbors(row,col)<2)):
self.clearCell(行、列)
如果((self[row,col]==True)和(self.numlineighbors(row,col)>3)):
self.clearCell(行、列)
如果((self[row,col]==False)和(self.numlineighbors(row,col)==3)):
self.setCell(行、列)
self.generations.append(self.\u mat)
返回自我
def已发生(自身):
"""
检查当前状态是否已发生。
如果不是,则返回False。如果为true,则返回哪一代编号(1-10)。
"""
对于范围内的i(len(self.generations)):
如果len(自生成)>0:
from SparseLifeGrid import SparseLifeGrid
import sys
def readPoints(lifeGrid):
"""
Reads the locations of life and set to the SparseMatrix
"""
print("1. Enter positions of life with row,col format (e.g., 2,3).")
print("2. Enter empty line to stop.")
life=input()
coordList=[]
while life:
points=life.split(",")
try:
coord=[int(points[0]),int(points[1])]
coordList.append(coord)
except ValueError:
print("Ignored input:" + life+ ", row, col not valid numbers")
except:
print("Unexpected error:", sys.exc_info()[0])
print("added, keep entering or enter empty line to stop.")
life=input()
print("Thanks, finished entering live cells")
lifeGrid.configure(coordList)
def main():
"""
Runs for ten generations if a stable (repeating) state is not found.
"""
lifeGrid= SparseLifeGrid()
readPoints(lifeGrid)
patterns=0
i=0
while i <10 :
"""
Evolve to the next generation
"""
lifeGrid.evolve()
print(lifeGrid)
"""
Check whether this generation is a repetition of any of the
previous states.
If yes return the previous matching generation (1-10).
"""
patterns=lifeGrid.hasOccurred()
if patterns != -1:
break
i+=1
if i==10:
print("No pattern found")
else:
print("Pattern found at: " + str(i)+ " of type: " + str(patterns))
main()
patterns=lifeGrid.hasOccurred()
if patterns != -1:
break
#changed the name from `hasOcurrence`, since that implies the method can only return True or False.
def get_last_occurrence(self):
for i in range(len(self.generations)):
#todo: somehow compare self.generations[i] to the current generation
if the generations match:
return i
#the loop ended without finding a match!
return False
patterns=lifeGrid.hasOccurred()
if patterns != False:
break