This Game of Life series is an adapted chapter from my book titled “Simulations in Swift”. Because I already cover the basics in my book, this post assumes you already have some working knowledge of Swift Playgrounds.
If you’re interested in learning more about writing simulations using the Swift programming language, or struggling with with Playgrounds, you can purchase my book from most popular online retailers in paperback or eBook format.
I’m also available for hire!
Developed by John Conway in 1970, the Game of Life is a cellular-automaton, zero-player game. A game in the lightest sense as there is no user interaction beyond the initial starting conditions and neither is there an end.
The game takes place on a grid of cells. Each cell can either be alive or dead. Four simple rules determine the vitality of each cell.
- Any live cell with fewer than two live neighbors will die.
- Any live cell with two or three live neighbors will live on to the next generation.
- Any live cell with more than three live neighbors will die.
- Any dead cell with exactly three live neighbors will become a live cell.
If you’re unfamiliar with the game and its rules, I highly recommend finding an online version of the game to play around with before continuing.
Create a new playground and name it “GameOfLife”. From the above description of the game, you might already have an idea of the kind of elements we’ll need to create. A cell and world object is a great place to start.
So let’s create two new files in the source folder of our playground and call them
We’re also going to be making use of Swift Playgrounds live views. While it might be ok to print out results to the console, being able to see them is even better. So create another file and call it
Cells represent each of the little lives in the simulation. They can be in one of two states — dead or alive — they also know their position in the world. These are the properties we’ll add to our cell.
Cell.swift and under
import Foundation create a new public enum and name it
Below the enum is where we will create our cell struct.
Usually, we’d take advantage of the fact that structures give us an initializer without doing any further work. We’re using playgrounds though, and that means we need to have a public initializer to create our cells inside the main playground file. Unfortunately, we don’t get a public initializer for free, so let’s add that real quick.
We’ll also give a cell the ability to tell us if it is the neighbor to a given cell. This will help when enforcing our game rules where we determine if the cell should be dead or alive based on those surrounding it.
Inside the cell struct, below the properties, we’ll add a new function and make it public.
So the calculations performed here will take the coordinates of both cells and check if they are situated right next to each other. It’s quite simple:
If one cell is at
x position of
10 and the other cell is at
x position of
11–10 = 1 or
10–11 = -1. Wrapping the result in
abs() gives us an “absolute value”. So
1. Whether the subtraction is
11–10, we get the same result either way. This indicates that the cells are neighbors on the
x axis. For cells to be neighbors, they cannot be any further than
1 point away from each other on either axis.
We can test that this works by going back to our main playground file and creating a few cells.
This code will print
true to the console as
secondCell is one step away on both axes from
firstCell. Let’s try some more combinations.
Okay so the last one probably won’t happen in our simulation, but it’s worth testing out anyway.
In part 2 we’ll look at filling our world with the cells we’ve just created.