PYTHON   13

GameBoard4.py

Guest on 6th June 2021 05:03:48 PM

  1. # GameBoard4.py
  2.  
  3. from LifeDisplay4 import Organism
  4.  
  5. #   TO DO:-- Convert the class Board (below) into a class Cluster, representing
  6. #   a set of organisms that represent the basic Game of Life. Create a new
  7. #   class Board that comprises one or more clusters. The initial configuration
  8. #   of a Board from a file creates a single cluster. However, as the game is
  9. #   played, gliders and other objects may break off and go marching to
  10. #   infinity in one direction or another. Include a function to recognize
  11. #   one of these when it gets sufficiently far from other clusters that it
  12. #   can become its own cluster. (Of course, provision must be made for a
  13. #   cluster to collide with another, thereby merging them..)
  14. #  
  15. #   Also TO DO:-- include a method for comparing two Boards, cluster by cluster,
  16. #   to see if they are the same.
  17.  
  18.  
  19. #   The following private global is a constant list used for driving
  20. #   an interator around a particular element (in clockwise
  21. #   order starting from the upper left. Each member of the
  22. #   list is the relative offset from the particular element.
  23. _neighbors = [(-1, -1), (-1, 0), (-1, 1), (0, 1), (1, 1),
  24.              (1, 0), (1, -1), (0, -1)]
  25.  
  26. class Board:
  27.     """ A board comprises a sparse two-dimendional array of
  28.    organisms. Initially, it is centered (approximately) at
  29.    row zero and column zero, but it can grow and/or shift
  30.  
  31.    The sparse 2D array is represented by a dictionary of
  32.    dictionaries in Python. The main dictionary contains the
  33.    rows, each indexed by its row number.
  34.  
  35.    Each row is, however, a separate dictionary, with the
  36.    elements indexed by column number.
  37.  
  38.    The elements in a row dictionary are the organisms in the
  39.    Game of Life. In the current implementation, they simply
  40.    have the value 1.
  41.  
  42.    """
  43.  
  44.     def __init__(self, initSource):
  45.         self._Rows = {}
  46.         self._minRow, self._maxRow = 0, 0
  47.         self._minCol, self._maxCol = 0, 0
  48.        
  49.         if type(initSource) == type(['oxx', 'xx', 'ox']):
  50.             self._initFromFile(initSource)
  51.         elif type(initSource) == type(self):
  52.             self._initFromBoard(initSource)
  53.         else:
  54.             raise TypeError
  55.         return
  56.  
  57.     def _addOrganism(self, row, col, org=None):
  58.         #   This function adds an organism to the row and column
  59.         #   of the board. If the org argument is not supplied,
  60.         #   a new organism is created. Otherwise, the organism
  61.         #   passed as the org argument is linked to the row and
  62.         #   column.
  63.         #
  64.         #   If there is an organism already at the row and
  65.         #   column, nothing is done.
  66.        
  67.         if row not in self._Rows:
  68.             self._Rows[row] = {}    #add a new row
  69.         if col not in self._Rows[row]:
  70.             if org is None:
  71.                 org = Organism(row, col)
  72.             self._Rows[row][col] = org
  73.         else:
  74.             pass        #   An organism already exists that this
  75.                         #   row and column
  76.  
  77.         #   Update maximum and minimum row and column
  78.         if row < self._minRow:
  79.             self._minRow = row
  80.         if row > self._maxRow:
  81.             self._maxRow = row
  82.         if col < self._minCol:
  83.             self._minCol = col
  84.         if col > self._maxCol:
  85.             self._maxCol = col
  86.         return
  87.  
  88.     def _initFromFile(self, listOfStrings):
  89.         #   Set up local variables because IDLE debugger
  90.         #   does not show instance variables of a object
  91.         maxLen = 0
  92.         #get maximum length of input strings
  93.         numberOfRows = len(listOfStrings)
  94.         for r in range(numberOfRows):
  95.             if len(listOfStrings[r]) > maxLen:
  96.                 maxLen = len(listOfStrings[r])
  97.  
  98.         xOffset, yOffset = maxLen//2, numberOfRows//2
  99.  
  100.         for i in range(numberOfRows):
  101.             row = i - yOffset
  102.             for j in range(len(listOfStrings[i])):
  103.                 if listOfStrings[i][j] == 'x':
  104.                     col = j - xOffset
  105.                     self._addOrganism(row, col)
  106.         return
  107.  
  108.     def _initFromBoard(self, prevBoard):
  109.         self._minRow = prevBoard._maxRow    #   initialize minRow, maxRow,
  110.         self._maxRow = prevBoard._minRow    #   minCol, and maxCol to absurd
  111.         self._minCol = prevBoard._maxCol    #   values so that they will be
  112.         self._maxCol = prevBoard._minCol    #   properly set by _addOrganism
  113.  
  114.         #   First, enumerate the organisms on the board. Link
  115.         #   those that survive to the new board, and remove
  116.         #   those that do not survive.
  117.         for organism in prevBoard.enumerateOrganisms():
  118.             row, column = organism.getCoords()
  119.             neighbors = prevBoard.countNeighbors(row, column)
  120.             if neighbors == 2 or neighbors == 3:
  121.                 #   Survival: Move existing organism to new board
  122.                 self._addOrganism(row, column, organism)
  123.             else:
  124.                 #   Death: delete the organism (so that it removes itself from
  125.                 #   the display)
  126.                 organism.removeFromDisplay()
  127.  
  128.         #   Next, add new organisms to spaces that have exactly
  129.         #   three neighbors, taking care not to add an organism
  130.         #   on top of an already existing one.
  131.         for existingOrganism in prevBoard.enumerateOrganisms():
  132.             #   New organisms can only be adjacent to existing
  133.             #   ones
  134.             existRow, existCol = existingOrganism.getCoords()
  135.             for (adjRow, adjCol) in prevBoard.enumerateNeighbors(existRow, existCol):
  136.                 if prevBoard.countNeighbors(adjRow, adjCol) == 3:
  137.                     #   Birth: create a new organism
  138.                     self._addOrganism(adjRow, adjCol)            
  139.         return
  140.  
  141.     def enumerateOrganisms(self):
  142.         for row in self._Rows:
  143.             for column in self._Rows[row]:
  144.                 yield self._Rows[row][column]
  145.         return
  146.  
  147.     def enumerateNeighbors(self, row, col):
  148.         for (nr, nc) in _neighbors:      # neighbors is a global (defined above)
  149.                                         # that enumerates the relative
  150.                                         # positions of the eight
  151.                                         # immediately adjacent cells
  152.             nRow, nCol = nr + row, nc + col
  153.             yield nRow, nCol
  154.         return
  155.    
  156.     def organismPresent(self, row, col):
  157.         #   This returns true if an organism is at (row, col)
  158.         #   of the board and zero if not
  159.         #
  160.         #   Note that the presence or absence of an organism is determined
  161.         #   by the presence or absence of its row and column in the board. The
  162.         #   organism itself may have already been deleted as part of creating
  163.         #   next generation.
  164.        
  165.         if row in self._Rows:
  166.             if col in self._Rows[row]:
  167.                 return True
  168.         return False
  169.    
  170.     def countNeighbors(self, row, col):
  171.         count = 0
  172.         for (nr, nc) in self.enumerateNeighbors(row, col):
  173.             if self.organismPresent(nr, nc):
  174.                 count += 1
  175.         return count
  176.  
  177.     def minRow(self):
  178.         return self._minRow
  179.  
  180.     def maxRow(self):
  181.         return self._maxRow
  182.  
  183.     def minCol(self):
  184.         return self._minCol
  185.  
  186.     def maxCol(self):
  187.         return self._maxCol
  188.  
  189.     def printBoard(self):
  190.         for x in range (self._minRow, self._maxRow+1):
  191.             for y in range(self._minCol, self._maxCol+1):
  192.                 if  self.organismPresent(x, y):
  193.                     print("x", sep='', end='')
  194.                 else:
  195.                     print("o", sep='', end='')
  196.             print("")   #   Terminate the printed line
  197.         print("MinRow =", self._minRow, ", MaxRow =", self._maxRow,
  198.               ", MinCol =", self._minCol, ", MaxCol =", self._maxCol)
  199.         print("")       #   Print a blank line at the end
  200.         return

Raw Paste


Login or Register to edit or fork this paste. It's free.