Source

sketchbook / gol / Life.py

Full commit
import random

class LifeEngine(object):
    """
    dimensions: the number of cells to calculate for
    percent_fill: the percentage of cells to randomise on init
    """
    def __init__(self, dimensions, percent_fill):
        self._width = dimensions[0]
        self._height = dimensions[1]
        self.cells = self.get_2d_array()
        self.heatmap = self.get_2d_array()
        self.living_cells = []
        self.iteration = 1

        starting_cells = int(self._width * self._height * (percent_fill/100.0))
        for i in xrange(starting_cells):
            self.cell_born(self.cells, random.randint(0,self._width-1), random.randint(0,self._height-1))

    def get_2d_array(self):
        return [[0 for x in xrange(self._width)] for y in xrange(self._height)]

    def cell_born(self, data, x, y):
        left = x - 1
        if left < 0:
            left = self._width - 1
		
        right = x + 1
        if right >= self._width:
            right = 0
		
        top = y - 1
        if top < 0:
            top = self._height - 1
		
        bottom = y + 1
        if bottom >= self._height:
            bottom = 0

        data[top][left] += 1
        data[top][x] += 1
        data[top][right] += 1
        
        data[y][left] += 1
        data[y][x] += 32
        data[y][right] += 1

        data[bottom][left] += 1
        data[bottom][x] += 1
        data[bottom][right] += 1
        
        self.living_cells.append((x, y))
        
    def cell_dies(self, x, y):
        if self.cells[x][y] >= 32:
            left = x - 1
            if left < 0:
                left = self._width - 1
			
            right = x + 1
            if right >= self._width:
                right = 0
			
            top = y - 1
            if top < 0:
                top = self.height - 1
			
            bottom = y + 1
            if bottom >= self._height:
                bottom = 0


            self.cells[top][left] -= 1
            self.cells[top][x] -= 1
            self.cells[top][right] -= 1
            
            self.cells[y][left] -= 1
            self.cells[y][x] -= 32
            self.cells[y][right] -= 1
            
            self.cells[bottom][left] -= 1
            self.cells[bottom][x] -= 1
            self.cells[bottom][right] -= 1

            if (x, y) in self.living_cells:
                self.living_cells.remove((x, y))

    def next_iteration(self, cells):
        """
        """

        next_gen = self.get_2d_array()
        self.living_cells = []

        hm = self.heatmap
        for y in xrange(self._height):
            row = self.cells[y]
            for x in xrange(self._width):
                cell = row[x]
                if cell == 3 or cell == 34 or cell == 35:
                    self.cell_born(next_gen, x, y)
                    if hm[y][x] < 19:
                        hm[y][x] += 2
                else:
                    if hm[y][x] > 0:
                        hm[y][x] -= 1

        self.cells = next_gen
            

    def update(self):
        self.next_iteration(self.cells)
        self.iteration += 1

    def tile_range(self):
        """Outputs the entire tile range"""
        for y in xrange(self._height):
            for x in xrange(self._width):
                yield(x,y)