Created
January 5, 2022 02:36
-
-
Save eparadis/54adcf08573416b4459a57fb1ca28a20 to your computer and use it in GitHub Desktop.
my Game of Life eurorack module. CircuitPython on an Adafruit QT Py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random | |
import time | |
import board | |
import simpleio | |
from adafruit_ht16k33.matrix import Matrix8x8 | |
import pwmio | |
import analogio | |
i2c = board.I2C() | |
matrix = Matrix8x8(i2c, auto_write=False) | |
pwm3 = pwmio.PWMOut(board.D3, variable_frequency=True) | |
pwm4 = pwmio.PWMOut(board.D6, variable_frequency=True) | |
a_out = analogio.AnalogOut(board.A0) | |
# C5 A4 G4 F4 D4 C4 A3 G3 | |
notes = [ 523, 440, 392, 349, 294, 262, 220, 196 ] | |
clock = simpleio.DigitalIn(board.D1) | |
def apply_life_rule(old, new): | |
width = old.width | |
height = old.height | |
for y in range(height): | |
yyy = y * width | |
ym1 = ((y + height - 1) % height) * width | |
yp1 = ((y + 1) % height) * width | |
xm1 = width - 1 | |
for x in range(width): | |
xp1 = (x + 1) % width | |
neighbors = ( | |
old[xm1 + ym1] + old[xm1 + yyy] + old[xm1 + yp1] + | |
old[x + ym1] + old[x + yp1] + | |
old[xp1 + ym1] + old[xp1 + yyy] + old[xp1 + yp1]) | |
new[x+yyy] = neighbors == 3 or (neighbors == 2 and old[x+yyy]) | |
xm1 = x | |
def display(board): | |
for y in range(board.height): | |
yyy = y * board.width | |
for x in range(board.width): | |
matrix[x,y] = board[x+yyy] | |
matrix.show() | |
def randomize(output, fraction=0.33): | |
for i in range(output.height * output.width): | |
output[i] = random.random() < fraction | |
# our two boards/bitmaps | |
class Board: | |
def __init__(self): | |
self.width = 8 | |
self.height = 8 | |
self.data = bytearray(64) | |
def __getitem__(self, idx): | |
return self.data[idx] | |
def __setitem__(self, idx, val): | |
self.data[idx] = val | |
def blank(self): | |
return all(v == 0 for v in self.data) | |
def population(self): | |
pop = 0 | |
for c in self.data: | |
if c: | |
pop += 1 | |
return pop | |
def step_thru(board): | |
global last_beat_at | |
for beat in range(8): | |
while not clock.value: | |
pass | |
display(board) | |
high_note = -1 | |
low_note = -1 | |
for y in range(8): | |
yyy = y * 8 | |
if board[beat+yyy] and high_note == -1: | |
high_note = y | |
if board[beat+yyy]: | |
low_note = y | |
matrix[beat, y] = not board[beat+yyy] | |
matrix.show() | |
elapsed = now() - last_beat_at | |
#while(elapsed < 2500): | |
# elapsed = now() - last_beat_at | |
while clock.value: | |
pass | |
last_beat_at = now() | |
if low_note != -1: # and low_note > 3: | |
play_low_note(low_note) | |
else: | |
quiet_low_note() | |
if high_note != -1: # and high_note <= 3: | |
play_high_note(high_note) | |
else: | |
quiet_high_note() | |
def now(): | |
return int(time.monotonic()*10000) | |
def play_high_note(note): | |
pwm3.frequency = notes[note] | |
pwm3.duty_cycle = 0x1000 | |
def play_low_note(note): | |
pwm4.frequency = notes[note] | |
pwm4.duty_cycle = 0x8000 | |
def quiet_high_note(): | |
pwm3.duty_cycle = 0x0 | |
def quiet_low_note(): | |
pwm4.duty_cycle = 0x0 | |
matrix.brightness = 0.1 | |
b1 = Board() | |
b2 = Board() | |
randomize(b1) | |
last_beat_at = now() | |
stag_count = 0 | |
max_pop = 0 | |
while True: | |
step_thru(b1) | |
apply_life_rule(b1,b2) | |
step_thru(b2) | |
apply_life_rule(b2, b1) | |
b1p = b1.population() | |
b2p = b2.population() | |
clamped = b1p | |
if clamped > 33: | |
clamped = 33 | |
scaled = (float(clamped) * 65535.0) / 33.0 | |
a_out.value = int(scaled) | |
max_pop = max(b1p, max_pop) | |
print("population: ", b1p, " historical max: ", max_pop, " a_out: ", scaled) | |
if b1p == b2p: #and b1p < 5: | |
stag_count += 1 | |
print("small pop stagnent: ", b1.population(), " for ", stag_count) | |
if stag_count == 4: | |
print("repopulating!") | |
randomize(b1) | |
stag_count = 0 | |
else: | |
stag_count = 0 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment