繁体   English   中英

无限棋盘:康威的人生游戏-Python

[英]Infinite Board: Conway's Game of Life - Python

我被分配了以下说明给该项目:

生命游戏是为无限大小的网格定义的。 在第2章中,我们定义了Life Grid ADT以使用固定大小的网格,其中用户指定了网格的宽度和高度。 这足以说明如何将2D阵列用于实施“生命游戏”。 但是完整的实现应该允许一个无限大小的网格。 使用类似于实现稀疏矩阵的方法来实现稀疏生命网格ADT。

老实说,我不太了解这个概念。 您能给我一个外行可以理解的简短描述(如果不是简短的代码)吗? 我会很感激。

Sparselifegrid.py

""" My initial GameOfLife code
    Feb 27, 2013
    Sparse Matrix code specially designed for Game of Life
"""
class SparseLifeGrid:

    def __init__(self):
        """
        "pass" just allows this to run w/o crashing.
        Replace it with your own code in each method.
        """
        pass 

    def minRange(self):
        """
        Return the minimum row & column as a list.
        """
        pass

    def maxRange(self):
        """
        Returns the maximum row & column as a list.
        """
        pass 

    def configure(self,coordList):
        pass 

    def clearCell(self,row, col):
        pass 

    def setCell(self,row, col):
        pass 

    def isValidRowCol(val1,val2):
        pass 

    def isLiveCell(self,row, col):
        pass 

    def numLiveNeighbors(self, row,col):
        pass 


    def __getitem__(self,ndxTuple):
        pass 

    def __setitem__(self,ndxTuple, life):
        """
        The possible values are only true or false:
        True says alive, False for dead.
        """
        pass 

    def _findPosition(self,row,col):
        pass 

    def __repr__(self):
        pass 

    def __str__(self):
        """
        This method will only print the non-empty values,
        and a row and column outside the non-empty values.
        """
        pass 

    def evolve(self):
        """
        Return the next generation state.
        """
        pass 

    def hasOccurred(self):
        """
        Check whether  this current state has already occured.
        If not, return False.  If true, return which generation number (1-10).
        """
        pass 

    def __eq__(self,other):
        """
        This is good method if we want to compare two sparse matrices.
        You can just use sparseMatrixA == sparseMatrixB because of this method. 
        """
        pass

    def printLifeGrid(lifeGrid):
        """
        Print a column before and after the live cells
        """
        s=""
        maxRange=lifeGrid.maxRange()
        minRange=lifeGrid.minRange()
        for i in range(minRange[0]-1,maxRange[0]+2):
            for j in range(minRange[1]-1,maxRange[1]+2):
                s+=" "+str(lifeGrid[i,j])
            s+="\n"
        print(s)


class _GoLMatrixElement:
    """
    Storage class for one cell
    """
    def __init__(self,row,col):
        pass 

    def __str__self(self):
        pass 

    def __eq__(self,other):
        pass 

这是我的主文件

""" Marcus Brown's  initial GameOfLife code
    Feb 27, 2013
"""
from SparseLifeGrid_Key import SparseLifeGrid
import sys


# You'll probably need to add some other stuff like global variables


""" ####################################################
        Don't change anything below this line: readPoints or main
""" ####################################################

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)
    lifeGrid.printLifeGrid()
    patterns=0
    i=0
    while i <10 and patterns == 0:
        """
        Evolve to the next generation
        """
        lifeGrid.evolve()
        """
        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
        lifeGrid.printLifeGrid()

    if i==10:
        print("No pattern found")
    else: 

        print("Pattern found at: " + str(i)+ " of type: " + str(patterns))

main()

稀疏矩阵是矩阵的表示,其中只有不等于默认值(通常为0)的值的位置存储在内存中。 用Python表示这种矩阵的一种简单方法是使用字典,其中的键是坐标(x, y)的元组,值是矩阵值。

例如,此矩阵:

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

可能具有以下表示形式:

matrix = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0]]
sparse_matrix = {(1, 2): 1}

然后您将访问类似的值:

for x in xrange(4):
  for y in xrange(4):
      assert matrix[y][x] == sparse_matrix.get((x, y), 0)

这应该足以让您入门。 您的练习希望您将此类稀疏矩阵包装在一个类中,该类将为其提供与传统矩阵相同的接口。

有更高级的方法来存储这种稀疏矩阵 ,每种方法都在复杂性,内存使用情况,...之间进行不同的折衷。

这是Python 2.x中一个基于稀疏矩阵的简单生活游戏解决方案。 您可以将大小设置为系统可以处理的大小。 它在x和y方向都环绕:

class Cell():
    def __init__(self, x, y, live=True):
        self.x, self.y = x, y
        self.live = live
        self.around = 0

    def __eq__(self, other):
        return (self.x, self.y) == (other.x, other.y)

    def spawn(self):
        self.live = True
        self.around = 0
        return self

class Grid():
    def __init__(self, width, height):
        self.xMax = width
        self.yMax = height
        self.cells = []
        self.deltas = [(-1, -1), (0, -1), (1, -1), (1, 0),
                      (1, 1), (0, 1), (-1, 1), (-1, 0)]

    def tick(self):
        newCells = self.cells[:]
        ''' create potential new cells '''
        for cell in self.cells:
            for dx, dy in self.deltas:
                newCell = Cell((cell.x+dx)%self.xMax,
                               (cell.y+dy)%self.yMax, live=False)
                if newCell not in newCells:
                    newCells.append(newCell)
                newCells[newCells.index(newCell)].around += 1
        ''' spawn new cells for next grid '''
        self.cells = []
        for cell in newCells:
            if (cell.live and cell.around in [2, 3]
            or not cell.live and cell.around == 3):
                self.cells.append(cell.spawn())

    def show(self):
        for y in range(self.yMax):
            print ''.join('X|' if Cell(x, y) in self.cells
                     else ' |' for x in range(self.xMax))
        print

用法:

>>> glider = [Cell(2,0), Cell(2,1), Cell(2,2), Cell(1,2), Cell(0,1)]
>>> g = Grid(7, 7)
>>> glider = [Cell(2,0), Cell(2,1), Cell(2,2), Cell(1,2), Cell(0,1)]
>>> g.cells = glider
>>> g.show()
 | |X| | | | |
X| |X| | | | |
 |X|X| | | | |
 | | | | | | |
 | | | | | | |
 | | | | | | |
 | | | | | | |

>>> g.tick()
>>> g.tick()
>>> g.show()
 | |X| | | | |
 | | |X| | | |
 |X|X|X| | | |
 | | | | | | |
 | | | | | | |
 | | | | | | |
 | | | | | | |

>>> g.tick()
>>> g.tick()
>>> g.show()
 | | | | | | |
 | | |X| | | |
 |X| |X| | | |
 | |X|X| | | |
 | | | | | | |
 | | | | | | |
 | | | | | | |

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM