Skip to content
Permalink
main
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
import math
import time
from random import random
import machine
import badger2040
# ------------------------------
# Program setup
# ------------------------------
# Global constants
CELL_SIZE = 6 # Size of cell in pixels
INITIAL_DENSITY = 0.3 # Density of cells at start
# Create a new Badger and set it to update TURBO
screen = badger2040.Badger2040()
screen.update_speed(badger2040.UPDATE_TURBO)
restart = False # should sim be restarted
# ------------------------------
# Button functions
# ------------------------------
# Button handling function
def button(pin):
global restart
# if 'a' button is pressed, restart the sim
if pin == button_a:
restart = True
# Set up button
button_a = machine.Pin(badger2040.BUTTON_A, machine.Pin.IN, machine.Pin.PULL_DOWN)
button_a.irq(trigger=machine.Pin.IRQ_RISING, handler=button)
# ------------------------------
# Screen functions
# ------------------------------
# Remove everything from the screen
def init_screen():
screen.update_speed(badger2040.UPDATE_NORMAL)
screen.pen(15)
screen.clear()
screen.update()
screen.update_speed(badger2040.UPDATE_TURBO)
# ------------------------------
# Classes
# ------------------------------
# Define a 'cell'
class Cell:
def __init__(self):
self._alive = False
def make_alive(self):
self._alive = True
def make_dead(self):
self._alive = False
def is_alive(self):
return self._alive
# Define the whole board
class Board:
def __init__(self):
self._rows = math.floor(badger2040.WIDTH / CELL_SIZE)
self._columns = math.floor(badger2040.HEIGHT / CELL_SIZE)
self._grid = [[Cell() for _ in range(self._columns)] for _ in range(self._rows)]
self._initialise_board()
# Draw the board to the screen
def draw_board(self):
row_idx = 0
column_idx = 0
for row in self._grid:
column_idx = 0
for cell in row:
if cell.is_alive():
screen.pen(0)
else:
screen.pen(15)
screen.rectangle(
row_idx * CELL_SIZE, column_idx * CELL_SIZE, CELL_SIZE, CELL_SIZE
)
column_idx += 1
row_idx += 1
screen.update()
# Generate the first iteration of the board
def _initialise_board(self):
for row in self._grid:
for cell in row:
if random() <= INITIAL_DENSITY:
cell.make_alive()
# Get the neighbour cells for a given cell
def get_neighbours(self, current_row, current_column):
# Cells either side of current cell
neighbour_min = -1
neighbour_max = 2
neighbours = []
for row in range(neighbour_min, neighbour_max):
for column in range(neighbour_min, neighbour_max):
neighbour_row = current_row + row
neighbour_column = current_column + column
# Don't count the current cell
if not (
neighbour_row == current_row and neighbour_column == current_column
):
# It's a toroidal world so go all the way round if necessary
if (neighbour_row) < 0:
neighbour_row = self._rows - 1
elif (neighbour_row) >= self._rows:
neighbour_row = 0
if (neighbour_column) < 0:
neighbour_column = self._columns - 1
elif (neighbour_column) >= self._columns:
neighbour_column = 0
neighbours.append(self._grid[neighbour_row][neighbour_column])
return neighbours
# Calculate the next generation
def create_next_generation(self):
to_alive = []
to_dead = []
changed = False
for row in range(len(self._grid)):
for column in range(len(self._grid[row])):
# Get all the neighours that are alive
alive_neighbours = []
for neighbour_cell in self.get_neighbours(row, column):
if neighbour_cell.is_alive():
alive_neighbours.append(neighbour_cell)
current_cell = self._grid[row][column]
# Apply the Conway GoL rules (B3/S23)
if current_cell.is_alive():
if len(alive_neighbours) < 2 or len(alive_neighbours) > 3:
to_dead.append(current_cell)
if len(alive_neighbours) == 3 or len(alive_neighbours) == 2:
to_alive.append(current_cell)
else:
if len(alive_neighbours) == 3:
to_alive.append(current_cell)
for cell in to_alive:
if not cell.is_alive():
# The board has changed since the previous generation
changed = True
cell.make_alive()
for cell in to_dead:
if cell.is_alive():
# The board has changed since the previous generation
changed = True
cell.make_dead()
return changed
# ------------------------------
# Main program loop
# ------------------------------
def main():
global restart
init_screen()
board = Board()
board.draw_board()
time.sleep(1)
while True:
# The 'a' button has been pressed so restart sim
if restart:
init_screen()
restart = False
board = Board()
board.draw_board()
time.sleep(5)
# The board didn't update since the previous generation
if not board.create_next_generation():
screen.update_speed(badger2040.UPDATE_NORMAL)
board.draw_board()
screen.update_speed(badger2040.UPDATE_TURBO)
time.sleep(5)
restart = True
# Draw the next generation
else:
board.draw_board()
main()