Time for action – simulating life

The following code is an implementation of Game of Life with some modifications, as follows:

  • Clicking once with the mouse draws a cross until we click again
  • Pressing the r key resets the grid to a random state
  • Pressing b creates blocks based on the mouse position
  • Pressing g creates gliders

The most important data structure in the code is a two-dimensional array holding the color values of the pixels on the game screen. This array is initialized with random values and then recalculated for each iteration of the game loop. More information about the involved functions can be found in the next section.

  1. To evaluate the rules, we will use convolution, as follows.
    def get_pixar(arr, weights):
      states = ndimage.convolve(arr, weights, mode='wrap')
    
      bools = (states == 13) | (states == 12 ) | (states == 3)
    
      return bools.astype(int)
  2. We can draw a cross using basic indexing tricks that we learned in Chapter 2, Beginning with NumPy Fundamentals.
    def draw_cross(pixar):
        (posx, posy) = pygame.mouse.get_pos()
        pixar[posx, :] = 1
        pixar[:, posy] = 1
  3. Initialize the grid with random values:
    def random_init(n):
        return np.random.random_integers(0, 1, (n, n))

    The following is the code in its entirety:

    import os, pygame
    from pygame.locals import *
    import numpy as np
    from scipy import ndimage
    
    def get_pixar(arr, weights):
      states = ndimage.convolve(arr, weights, mode='wrap')
    
      bools = (states == 13) | (states == 12 ) | (states == 3)
    
      return bools.astype(int)
    
    def draw_cross(pixar):
        (posx, posy) = pygame.mouse.get_pos()
        pixar[posx, :] = 1
        pixar[:, posy] = 1
    
    def random_init(n):
        return np.random.random_integers(0, 1, (n, n))
    
    def draw_pattern(pixar, pattern):
         print pattern
    
        if pattern == 'glider':
          coords = [(0,1), (1,2), (2,0), (2,1), (2,2)]
        elif pattern == 'block':
          coords = [(3,3), (3,2), (2,3), (2,2)]
        elif pattern == 'exploder':
          coords = [(0,1), (1,2), (2,0), (2,1), (2,2), (3,3)]
        elif pattern == 'fpentomino':
          coords = [(2,3),(3,2),(4,2),(3,3),(3,4)]
    
        pos = pygame.mouse.get_pos()
    
        xs = np.arange(0, pos[0], 10)
        ys = np.arange(0, pos[1], 10)
    
        for x in xs:
            for y in ys:
               for i, j in coords:
                   pixar[x + i, y + j] = 1
    
    
    def main():
        pygame.init ()
        N = 400
        pygame.display.set_mode((N, N))
        pygame.display.set_caption("Life Demo")
    
        screen = pygame.display.get_surface()
    
        pixar = random_init(N)
        weights = np.array([[1,1,1], [1,10,1], [1,1,1]])
    
        cross_on = False
    
        while True:
           pixar = get_pixar(pixar, weights)
    
           if cross_on:
              draw_cross(pixar)
    
           pygame.surfarray.blit_array(screen, pixar * 255 ** 3)
           pygame.display.flip()
    
            for event in pygame.event.get():
              if event.type == QUIT:
                  return
              if event.type == MOUSEBUTTONDOWN:
                  cross_on = not cross_on
              if event.type == KEYDOWN:
                  if event.key == ord('r'):
                     pixar = random_init(N)
                     print "Random init"
                  if event.key == ord('g'):
                   draw_pattern(pixar, 'glider')
                if event.key == ord('b'):
                   draw_pattern(pixar, 'block')
                if event.key == ord('e'):
                   draw_pattern(pixar, 'exploder')
                if event.key == ord('f'):
                   draw_pattern(pixar, 'fpentomino')
    
    if __name__ == '__main__':
        main()

    You should able to view a screencast on YouTube at https://www.youtube.com/watch?v=NNsU-yWTkXM. The following is a screenshot of the game in action:

    Time for action – simulating life

What just happened?

We used some NumPy and SciPy functions that need an explanation, as follows:

Function

Description

ndimage.convolve(arr, weights, mode='wrap')

This applies the convolve operation on the given array, using weights in wrap mode. The mode has to do it with the array borders.

bools.astype(int)

This converts the array of Booleans to integers.

np.arange(0, pos[0], 10)

This creates an array from 0 to pos[0] in steps of 10. So if pos[0] is equal to 1000, we will get 0, 10, 20, …, 990.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.161.225