Version: 1.1.0

Get started with Mojo

This tutorial builds Conway's Game of Life: a grid of cells that live or die from the number of living neighbors.

Rules

  • A living cell with two or three neighbors stays alive.
  • A dead cell with exactly three neighbors becomes alive.
  • Every other cell is dead on the next tick.

The grid

Store cells in a struct so the rest of the program does not index a bare list.

@fieldwise_init
struct Grid:
    var width: Int
    var height: Int
    var cells: List[Int]

    def index(self, x: Int, y: Int) -> Int:
        return y * self.width + x

    def get(self, x: Int, y: Int) -> Int:
        if x < 0 or y < 0 or x >= self.width or y >= self.height:
            return 0
        return self.cells[self.index(x, y)]

One step

Count the eight neighbors, then write into a new list. Do not update the grid in place or a cell will see a mix of old and new values.

def step(grid: Grid) -> Grid:
    var next = List[Int]()
    for y in range(grid.height):
        for x in range(grid.width):
            var n = 0
            for dy in range(-1, 2):
                for dx in range(-1, 2):
                    if dx != 0 or dy != 0:
                        n += grid.get(x + dx, y + dy)
            var alive = grid.get(x, y)
            var born = n == 3 or (alive == 1 and n == 2)
            next.append(1 if born else 0)
    return Grid(grid.width, grid.height, next)

Run it

def main():
    var cells = List[Int](0, 1, 0, 0, 1, 0, 0, 1, 0)
    var grid = Grid(3, 3, cells)
    grid = step(grid)
    print(grid.get(1, 1))

Print the grid for a few generations. When the pattern looks right, you understand variables, structs, loops, and returning values.

Keep going

Read functions and structs for the rules this tutorial only used.