I am writing the game of life in python using a Sparse Matrix. My program takes coordinates from user input and sets the cells at the chosen coordinates to be alive. I have it to where it will print the first generation, but I can't seem to figure out why it wont print any subsequent generations. Any help would be appreciated.
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.
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()
The loop only executes once because of this:
patterns
will never equal -1 under any circumstance, sincehasOccurred
can only returnFalse
or a member ofself.generations
orNone
. As a result, the loop will alwaysbreak
in the first iteration, and no subsequent generations will be printed.Incidentally, your
hasOccurred
logic is strange. iflen(self.generations)
equals zero, then the loop will not get executed at all, and none of yourreturn
statements will be evaluated, so the result will beNone
. If the length is greater than zero, then the condition within the loop is always True, soself.generations[i]
is always returned in the first iteration. Perhaps you meant to do:Then, within
main
: