Micropython game of life
A very basic implementation of Conway's game of life for Micropython, accelerated by the numpy implementation provided by ulab.
Using toroidal boundary conditions on the grid, one update cycle can be easily implemented:
def step(grid):
"""
computes one step of Conway's game of life on a toroidal 2D grid
"""
count = np.zeros(grid.shape, dtype=np.uint8)
count[:, :] = grid
# sum all 8 neighbors
count += np.roll(grid, 1, axis=0) + np.roll(grid, -1, axis=0)
count += np.roll(grid, 1, axis=1) + np.roll(grid, -1, axis=1)
count += np.roll(np.roll(grid, 1, axis=0), 1, axis=1) + np.roll(np.roll(grid, -1, axis=0), 1, axis=1)
count += np.roll(np.roll(grid, 1, axis=0), -1, axis=1) + np.roll(np.roll(grid, -1, axis=0), -1, axis=1)
# logical operator encoding the rules
return (count == 3) | (grid & (count == 4))
On a rp2040 running at 250MHz
, one full update cycle on a 128 x 64
grid takes ~76ms
, including blitting the array to a 1306 OLED display through I2C. This is a refresh rate of ~13Hz
, enough for realtime applications.
You can find the full code here.
Installation
Step 1: install Micropython
This implementation heavily relies on the ulab library. You can find a special version of Micropython with built-in ulab support here. For a generic rp2040 board, download this file and place it on the device's flash storage after enabling the bootloader through a hard reset.
Step 2: install code
After installing Micropython on your device, interface with it using your favorite editor. If in doubt, you can use Thonny. Save the main.py file on the device, as well as the ssd1306.py library, with these exact filenames.
The default I2C pins are configured for a xiao rp2040:
- SDA: 6
- SCL: 7
You can change these if needed, in function main()
in main.py
.
Step 3: start code
By either pressing the run button in your editor or performing a reset of your device, the main.py
should start and run the game of life.