CodeNewbie Community 🌱

Ulysse Valdenaire
Ulysse Valdenaire

Posted on

Let's create game of life in Python !

Game of life (which is not a game) is a good programming excercise and it is quite funny.

This cellular automation was invented by a mathematician named John Conway.

This is very easy to understand: it consists of a grid of cells which can live, die or multiply based on two rules.

1 - Each cell with one or two neigbhors die by soliture
2 - Each cell with four or more neigbhors dies by overpopulation
3 - Each cell with two or three neigbors survives

You can have more informations here.

Let's create it !

We will use Python, so basics of Python are required.
To create a GUI (graphical user interface), we will use the Python library Tkinter.
More infos about Tkinter here.

Create the GUI

Create a python file, you can name it main.py or any other name.

from tkinter import Tk, Canvas

window = Tk()
window.geometry(str(600) + "x" + str(600))
canvas = Canvas(window, width=600, height=600, borderwidth=0, highlightthickness=0, bg='lightgray')
canvas.pack()
window.mainloop()
Enter fullscreen mode Exit fullscreen mode

Here we create a window with Tkinter of 600 by 600 and a canvas to draw the cells.

We will represent the cells with a list of lists. Since the GUI window is 600 x 600, our cells list wil be 60 x 60. An alive cell is represents with the value 1 and a dead one with the value 0. So, to begin, we fill our list with dead cells.

cells = []
for i in range(60):
    cells.append([0] * 60)
Enter fullscreen mode Exit fullscreen mode

Then, we generate random alive cells, here 500. So we give them the value one.

for i in range(500):
    x = random.randint(1, 59)
    y = random.randint(1, 59)
    cells[x][y] = 1
Enter fullscreen mode Exit fullscreen mode

Don't forget to import the random module :
import random

Now we want to display on the window our cells. For that, we will create a function displayCells.

def displayCells():
    canvas.delete("all")
    for x in range(60):
        for y in range(60):
            if cells[x][y] == 1:
                xx = x * 10
                yy = y * 10
                c="black"
                canvas.create_rectangle(xx, yy, xx+10, yy+10, fill=c)
Enter fullscreen mode Exit fullscreen mode

We will call displayCells in a loop to display the new cells on the window. Here, we delete the precedent cells with canvas.delete("all") and we loop through the cells list to display a 10x10 black rectangle if the cell is alive.

As we will want to call others functions in the main program loop, we can create a function programLoop.

def programLoop():
    displayCells()
Enter fullscreen mode Exit fullscreen mode

And add this to call the programLoop function on the window

window = Tk()
window.geometry(str(600) + "x" + str(600))
canvas = Canvas(window, width=600, height=600, borderwidth=0, highlightthickness=0, bg='lightgray')
canvas.pack()
#the programLoop function will be called 100 milliseconds after the program runs
window.after(100, programLoop) 
window.mainloop()
Enter fullscreen mode Exit fullscreen mode

The result must looks like something like this:

Image of game of life

Make the cells evolve

To make the cells evolve, we first need to count how many each cell have alive cells in its neighborhood. According to this number we could know if each cell is alive or dead (1 or 0). We could create a new list with these new values and then display on the window the new cells. Since is it looping every 100 milliseconds, it will be like the cells are moving.

To count how many a cells have alive neighbor cells, we will create a countAliveCellsAround(x,y). It takes two arguments, x and y which are the coordinates of the cell in the list cells.

We initialize count to the value 0.

def countAliveCellsAround(x, y):
    count = 0
Enter fullscreen mode Exit fullscreen mode

Each cell have 8 neighbors to check.
Theses cells can be represent with this list of tuples:

V = [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)]

We can access each neighbors cells of a cell of coordinates (x, y) like this :

for dx, dy in V:
    cells[(x+dx)][(y+dy)]
Enter fullscreen mode Exit fullscreen mode

Like cells[(x+dx)][(y+dy)] is either 1 or 0, we can add its value to count.

so we have :

for dx, dy in V:
    count += cells[(x+dx)][(y+dy)]
Enter fullscreen mode Exit fullscreen mode

But we have a problem for the cells which are on the border, we will have an error of index out of range. We can resolve it by saying that the next cell of the cell [60][1] is cell[1][1]
and that the next cell[1][60] is cell[1][1]

for dx, dy in V:
    count += cells[(x+dx)%60][(y+dy)%60]
Enter fullscreen mode Exit fullscreen mode

So the function looks like this :

def countAliveCellsAround(x,y):
    count = 0
    V = [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)]

    for dx, dy in V:
        count += cells[(x+dx)%60][(y+dy)%60]
    return count
Enter fullscreen mode Exit fullscreen mode

Last thing to do:
Create a evolution() function
Start by creating a new_cells_list with the same size as cells and initialisze with zeros:

new_cells_list = []
for i in range(60):
    new_cells_list.append([0]*60)
Enter fullscreen mode Exit fullscreen mode

Now we simpply loop through the current list of cells and for each cells we check how many alive neigbord cells it has.

for x in range(60):
    for y in range(60):
        nbAliveCells = countAliveCellsAround(x, y)
Enter fullscreen mode Exit fullscreen mode

If the cell is alive (with the value 1) and it has 2 or 3 alive cells around it, then it stays alive. If it is 0 and it has 3 alive cells around it, it become alive, else it stays or becomes dead. Let's translate that in Python :

for x in range(60):
    for y in range(60):
        nbAliveCells = countAliveCellsAround(x, y)
        if cells[x][y] == 0 and nbAliveCells == 3:
                new_cells_list[x][y] = 1
        if cells[x][y] == 1 and nbAliveCells in [2, 3]:
            new_cells_list[x][y] = 1
    cells = new_cells_list
Enter fullscreen mode Exit fullscreen mode

So the evolution function looks like this :

def evolution():
    global cells
    new_cells_list = []
    for i in range(60):
        new_cells_list.append([0]*60)

    for x in range(60):
        for y in range(60):
            nbAliveCells = countAliveCellsAround(x, y)
            if cells[x][y] == 0 and nbAliveCells == 3:
                new_cells_list[x][y] = 1
            if cells[x][y] == 1 and nbAliveCells in [2, 3]:
                new_cells_list[x][y] = 1
    cells = new_cells_list

Enter fullscreen mode Exit fullscreen mode

Now we can call this function in the programLoop() function:
And repeat all again each 100 milliseconds

def programLoop():
    displayCells()
    evolution()
    window.after(100, programLoop)
Enter fullscreen mode Exit fullscreen mode

Final result is here :

Get the whole code on github.

Oldest comments (1)

Collapse
 
fillis34 profile image
Fillis34

A lot of modern mobile games are made using Python. However, I would like to draw your attention to the fact that there are more profitable projects to develop now. Look at how popular bookmaker portals are. I like 1xbet-et.com. This is done in the form of an information portal with high-quality support. It's perfect for any sports fan.