Python - Game of Life

Post all your tuts or request for tuts here.
Post Reply
User avatar
Miroidan
Posts: 53
Joined: Sat Sep 27, 2014 7:23 pm

Python - Game of Life

Post by Miroidan »

This whole tutorial is written and programmed by Trevor Appleton(http://trevorappleton.blogspot.se/) and I thought it was interesting so I wanted to share the link to his tutorial here http://trevorappleton.blogspot.se/2013/ ... -life.html

There are four rules which are applied simultaneously to all the cells in the game.

1. Any live cell with fewer than two live neighbours dies, as if caused by under-population.
2. Any live cell with two or three live neighbours lives on to the next generation.
3. Any live cell with more than three live neighbours dies, as if by overcrowding.
4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

Complete Source Code. 'FPS = 10' changes game speed.

Code: Select all

import pygame, sys
from pygame.locals import *
import random

# Number of frames per second
FPS = 10

WINDOWWIDTH = 640
WINDOWHEIGHT = 480
CELLSIZE = 10
assert WINDOWWIDTH % CELLSIZE == 0, "Window width must be a multiple of cell size"
assert WINDOWHEIGHT % CELLSIZE == 0, "Window height must be a multiple of cell size"
CELLWIDTH = WINDOWWIDTH / CELLSIZE #Number of cells wide
CELLHEIGHT = WINDOWHEIGHT / CELLSIZE #Number of cells high

# Set up the colours
BLACK =    (0,  0,  0)
WHITE =    (255,255,255)
DARKGRAY = (40, 40, 40)
GREEN =    (0, 255, 0)

# Draws the grid lines
def drawGrid():
    for x in range(0, WINDOWWIDTH, CELLSIZE): # Draw vertical lines
        pygame.draw.line(DISPLAYSURF, DARKGRAY, (x,0), (x, WINDOWHEIGHT))
    for y in range(0, WINDOWHEIGHT, CELLSIZE): # Draw horizontal lines
        pygame.draw.line(DISPLAYSURF, DARKGRAY, (0,y), (WINDOWWIDTH, y))
        
def blankGrid():
    gridDict = {}
    for y in range (CELLHEIGHT):
        for x in range (CELLWIDTH):
            gridDict[x,y] = 0
    return gridDict

def startingGridRandom(lifeDict):
    for item in lifeDict:
        lifeDict[item] = random.randint(0,1)
    return lifeDict

def colourGrid(item, lifeDict):
    x = item[0]
    y = item[1]
    y = y * CELLSIZE # Translates array into grid size
    x = x * CELLSIZE # Translates array into grid size
    if lifeDict[item] == 0:
        pygame.draw.rect(DISPLAYSURF, WHITE, (x, y, CELLSIZE, CELLSIZE))
    if lifeDict[item] == 1:
        pygame.draw.rect(DISPLAYSURF, GREEN, (x, y, CELLSIZE, CELLSIZE))
    return None

def getNeighbours(item, lifeDict):
    neighbours = 0
    for x in range (-1,2):
        for y in range (-1,2):
            checkCell = (item[0]+x,item[1]+y)
            if checkCell[0] < CELLWIDTH  and checkCell[0] >= 0:
                if checkCell [1] < CELLHEIGHT and checkCell[1]>= 0:
                    if lifeDict[checkCell] == 1:
                        if x == 0 and y == 0:
                            neighbours += 0
                        else:
                            neighbours += 1
    return neighbours

def tick(lifeDict):
    newTick = {}
    for item in lifeDict:
        numberNeighbours = getNeighbours(item, lifeDict)
        if lifeDict[item] == 1: # For those cells already alive
            if numberNeighbours < 2: # Kill under-population
                newTick[item] = 0
            elif numberNeighbours > 3: # Kill over-population
                newTick[item] = 0
            else:
                newTick[item] = 1 # Keep status quo (life)
        elif lifeDict[item] == 0:
            if numberNeighbours == 3: # Cell reproduces
                newTick[item] = 1
            else:
                newTick[item] = 0 # Keep status quo (death)
    return newTick

def main():
    pygame.init()
    global DISPLAYSURF
    FPSCLOCK = pygame.time.Clock()
    DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT)) 
    pygame.display.set_caption('Hello World')
    
    DISPLAYSURF.fill(WHITE) # Fills the screen white
    
    lifeDict = blankGrid() # Creates library and populates to match blank grid
    lifeDict = startingGridRandom(lifeDict) # Assign random life
        
    for item in lifeDict:
        colourGrid(item, lifeDict)
    
    drawGrid()

    while True: #main game loop
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
                
        # Runs a tick
        lifeDict = tick(lifeDict)
        
        # Colours the live cells, blanks the dead
        for item in lifeDict:
            colourGrid(item, lifeDict)
                       
        drawGrid()
        pygame.display.update()
        FPSCLOCK.tick(FPS)
        
if __name__=='__main__':
    main()
Imagine them moving, killing each other, reproducing and dying.
Image
Preview

Here's an alternative start after you have done his first tutorial.
http://trevorappleton.blogspot.co.uk/20 ... tarts.html

Alternative Start Complete Source Code. 'FPS = 30' changes game speed.

Code: Select all

import pygame, sys
from pygame.locals import *
import time
import random

FPS = 30
###Sets size of grid
WINDOWWIDTH = 640
WINDOWHEIGHT = 450
CELLSIZE = 5
assert WINDOWWIDTH % CELLSIZE == 0, "Window width must be a multiple of cell size"
assert WINDOWHEIGHT % CELLSIZE == 0, "Window height must be a multiple of cell size"
CELLWIDTH = WINDOWWIDTH / CELLSIZE # number of cells wide
CELLHEIGHT = WINDOWHEIGHT / CELLSIZE # Number of cells high

# set up the colors
BLACK =    (0,  0,  0)
WHITE =    (255,255,255)
DARKGRAY = (40, 40, 40)
GREEN =    (0,255,0)

#Draws the grid lines
def drawGrid():
    for x in range(0, WINDOWWIDTH, CELLSIZE): # draw vertical lines
        pygame.draw.line(DISPLAYSURF, DARKGRAY, (x,0),(x,WINDOWHEIGHT))
    for y in range (0, WINDOWHEIGHT, CELLSIZE): # draw horizontal lines
        pygame.draw.line(DISPLAYSURF, DARKGRAY, (0,y), (WINDOWWIDTH, y))

def colourGrid(item, lifeDict):
    x = item[0]
    y = item [1]
    if lifeDict[item] == 0:
        y = y * CELLSIZE # translates array into grid size
        x = x * CELLSIZE # translates array into grid size
        pygame.draw.rect(DISPLAYSURF, WHITE, (x, y, CELLSIZE, CELLSIZE))
    if lifeDict[item] == 1:
        y = y * CELLSIZE # translates array into grid size
        x = x * CELLSIZE # translates array into grid size
        pygame.draw.rect(DISPLAYSURF, GREEN, (x, y, CELLSIZE, CELLSIZE))
    return None

def blankGrid():
    gridDict = {}
    for y in range (CELLHEIGHT):
        for x in range (CELLWIDTH):
            gridDict[x,y] = 0
    return gridDict

def startingGridRandom(lifeDict):
    for item in lifeDict:
        lifeDict[item] = random.randint(0,1)
    return lifeDict

def startingRpentomino(lifeDict):
    #R-pentomino
    lifeDict[48,32] = 1
    lifeDict[49,32] = 1
    lifeDict[47,33] = 1
    lifeDict[48,33] = 1
    lifeDict[48,34] = 1
    return lifeDict


def startingAcorn(lifeDict):
    #Acorn
    lifeDict[105,55] = 1
    lifeDict[106,55] = 1
    lifeDict[109,55] = 1
    lifeDict[110,55] = 1
    lifeDict[111,55] = 1
    lifeDict[106,53] = 1
    lifeDict[108,54] = 1
    return lifeDict

def startingDiehard(lifeDict):
    #Diehard
    lifeDict[45,45] = 1
    lifeDict[46,45] = 1
    lifeDict[46,46] = 1
    lifeDict[50,46] = 1
    lifeDict[51,46] = 1
    lifeDict[52,46] = 1
    lifeDict[51,44] = 1
    return lifeDict

def startingGosperGliderGun(lifeDict):
    #Gosper Glider Gun
    #left square
    lifeDict[5,15] = 1
    lifeDict[5,16] = 1
    lifeDict[6,15] = 1
    lifeDict[6,16] = 1
    #left part of gun
    lifeDict[15,15] = 1
    lifeDict[15,16] = 1
    lifeDict[15,17] = 1
    lifeDict[16,14] = 1
    lifeDict[16,18] = 1
    lifeDict[17,13] = 1
    lifeDict[18,13] = 1
    lifeDict[17,19] = 1
    lifeDict[18,19] = 1
    lifeDict[19,16] = 1
    lifeDict[20,14] = 1
    lifeDict[20,18] = 1
    lifeDict[21,15] = 1
    lifeDict[21,16] = 1
    lifeDict[21,17] = 1
    lifeDict[22,16] = 1
    #right part of gun
    lifeDict[25,13] = 1
    lifeDict[25,14] = 1
    lifeDict[25,15] = 1
    lifeDict[26,13] = 1
    lifeDict[26,14] = 1
    lifeDict[26,15] = 1
    lifeDict[27,12] = 1
    lifeDict[27,16] = 1
    lifeDict[29,11] = 1
    lifeDict[29,12] = 1
    lifeDict[29,16] = 1
    lifeDict[29,17] = 1
    #right square
    lifeDict[39,13] = 1
    lifeDict[39,14] = 1
    lifeDict[40,13] = 1
    lifeDict[40,14] = 1
    return lifeDict
    
def getNeighbours(item,lifeDict):
    neighbours = 0
    for x in range (-1,2):
        for y in range (-1,2):
            checkCell = (item[0]+x,item[1]+y)
            if checkCell[0] < CELLWIDTH  and checkCell[0] >=0:
                if checkCell [1] < CELLHEIGHT and checkCell[1]>= 0:
                    if lifeDict[checkCell] == 1:
                        if x == 0 and y == 0: # negate the central cell
                            neighbours += 0
                        else:
                            neighbours += 1
    return neighbours

def tick(lifeDict):
    newTick = {}
    for item in lifeDict:
        #get number of neighbours
        numberNeighbours = getNeighbours(item, lifeDict)
        if lifeDict[item] == 1: # For those cells already alive
            if numberNeighbours < 2: # kill underpopulation
                newTick[item] = 0
            elif numberNeighbours > 3: # kill over population
                newTick[item] = 0
            else:
                newTick[item] = 1 # keep status quo
        elif lifeDict[item] == 0:
            if numberNeighbours == 3: # cell reproduces
                newTick[item] = 1
            else:
                newTick[item] = 0 # keep status quo
    return newTick

def main():
    pygame.init()
    global DISPLAYSURF
    FPSCLOCK = pygame.time.Clock()
    DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT))
    pygame.display.set_caption('Game of Life')

    DISPLAYSURF.fill(WHITE)

    lifeDict = blankGrid() # creates library and Populates to match blank grid

    ###Starting options
    #lifeDict = startingGridRandom(lifeDict) # Assign random life
    lifeDict = startingRpentomino(lifeDict) # Setup R-pentomino
    #lifeDict = startingAcorn(lifeDict) # Setup Acorn
    #lifeDict = startingDiehard(lifeDict)
    #lifeDict = startingGosperGliderGun(lifeDict)

    #Colours the live cells, blanks the dead
    for item in lifeDict:
        colourGrid(item, lifeDict)

    drawGrid()
    pygame.display.update()
        
    while True: #main game loop
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

        #runs a tick
        lifeDict = tick(lifeDict)

        #Colours the live cells, blanks the dead
        for item in lifeDict:
            colourGrid(item, lifeDict)

        drawGrid()
        pygame.display.update()    
        FPSCLOCK.tick(FPS)
if __name__=='__main__':
    main()
Image
Second preview

Wikipedia to Conway's Game of Life http://en.wikipedia.org/wiki/Conway's_Game_of_Life

Conway chose his rules carefully, after considerable experimentation, to meet these criteria:
There should be no explosive growth.
There should exist small initial patterns with chaotic, unpredictable outcomes.
There should be potential for von Neumann universal constructors.
The rules should be as simple as possible, whilst adhering to the above constraints.


Image
A screenshot of a puffer-type breeder (red) that leaves glider guns (green) in its wake, which in turn create gliders (blue). (animation)

Conway's Game of Life. Pretty cool!
[YouTube]https://www.youtube.com/watch?v=C2vgICfQawE[/YouTube]
User avatar
Callan S.
Posts: 2043
Joined: Sun Jan 24, 2010 5:43 am

Re: Python - Game of Life

Post by Callan S. »

Has there been any life sims made without abstract rules?

Ie the organism moves around looking for food scraps and after getting enough 'fat', divides?
User avatar
Sharlenwar
Posts: 524
Joined: Mon May 28, 2012 7:14 pm

Re: Python - Game of Life

Post by Sharlenwar »

Callan S. wrote:Has there been any life sims made without abstract rules?

Ie the organism moves around looking for food scraps and after getting enough 'fat', divides?
You are talking about a more "open-world" type idea for growth and development? Maybe even a way for the organism to search for food sources and flourish?
Deep within the Void of Quasion, a creation.

**My Corner of the Web**
***NEW***GrindFest - My own PHP/MySQL game!
Sharlenwar's Adventures
Torn-City - Massively multiplayer online text based RPG
User avatar
Callan S.
Posts: 2043
Joined: Sun Jan 24, 2010 5:43 am

Re: Python - Game of Life

Post by Callan S. »

Yeah, like that :)
User avatar
Miroidan
Posts: 53
Joined: Sat Sep 27, 2014 7:23 pm

Re: Python - Game of Life

Post by Miroidan »

http://indie-resource.com/forums/viewto ... =26&t=7985 lol I just realized there was another topic about Conway's Game of Life :lol:
User avatar
Jackolantern
Posts: 10893
Joined: Wed Jul 01, 2009 11:00 pm

Re: Python - Game of Life

Post by Jackolantern »

Callan S. wrote:Has there been any life sims made without abstract rules?

Ie the organism moves around looking for food scraps and after getting enough 'fat', divides?
Basically, if you just exchange humans for the organisms, you would have The Sims lol :lol:
The indelible lord of tl;dr
Post Reply

Return to “Tutorials”