Skip to content

Instantly share code, notes, and snippets.

@rok
Last active July 9, 2019 23:38
Show Gist options
  • Save rok/8c213c94a8effe8670b6aa4f0913cdb2 to your computer and use it in GitHub Desktop.
Save rok/8c213c94a8effe8670b6aa4f0913cdb2 to your computer and use it in GitHub Desktop.
Conways's Game of Life for pewpew
# https://creativecommons.org/licenses/by/4.0/
# https://en.wikipedia.org/wiki/Conway's_Game_of_Life#Rules
# https://pewpew.readthedocs.io/en/latest/
import pew
import random
n = 8
n_states = 2
# Calculate neighbours mapping
deltas = [(-1, -1), (-1, 0), (0, -1), (0, 1), (1, 0), (-1, 1), (1, -1), (1, 1)]
neighbours = [[None for i in range(n)] for j in range(n)]
for j in range(n):
for i in range(n):
neighbours[j][i] = [(j + delta[0], i + delta[1]) for delta in deltas]
neighbours[j][i] = [(n-1, y) if x < 0 else (x, y) for x, y in neighbours[j][i]]
neighbours[j][i] = [(x, n-1) if y < 0 else (x, y) for x, y in neighbours[j][i]]
neighbours[j][i] = [(0, y) if x >= n else (x, y) for x, y in neighbours[j][i]]
neighbours[j][i] = [(x, 0) if y >= n else (x, y) for x, y in neighbours[j][i]]
def count_elements(values):
counts = [(x, values.count(x)) for x in (set(values) - set([0]))]
ordered_counts = sorted(counts, key=lambda x: x[1], reverse=True)
return ordered_counts
def calculate_step(f, board):
result = [[0 for y in range(n)] for x in range(n)]
for j in range(n):
for i in range(n):
# assert all(x[1] >= 0 for x in neighbours[i][j])
neighbour_values = [board[neighbour[0]][neighbour[1]] for neighbour in neighbours[j][i]]
result[j][i] = f(board[j][i], neighbour_values)
return result
def life(value, neighbours):
# Any live cell with fewer than two live neighbours dies, as if by underpopulation.
# Any live cell with two or three live neighbours lives on to the next generation.
# Any live cell with more than three live neighbours dies, as if by overpopulation.
# Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
count = sum([0 if x == 0 else 1 for x in neighbours])
# Dead cell
if (value == 0) and (count == 3):
return random.randint(1, n_states)
# Live cell
else:
if count < 2:
return 0
elif (count == 2) or (count == 3):
return random.randint(1, n_states)
else:
return 0
def tri_life(value, neighbours):
# http://www.conwaylife.com/wiki/Immigration#Immigration
count = sum([0 if x == 0 else 1 for x in neighbours])
# Dead cell
if (value == 0) and (count == 3):
majority_colour = count_elements(neighbours)[0][0]
return majority_colour
# Live cell
else:
if count < 2:
return 0
elif count == 2 or count == 3:
return value
else:
return 0
pew.init()
screen = pew.Pix()
def random_data():
return [[random.randint(0, n_states) for y in range(n)] for x in range(n)]
def get_game():
while True:
yield life
yield tri_life
data = random_data()
background = pew.Pix.from_iter(data)
games = get_game()
game = next(games)
while True:
keys = pew.keys()
if keys:
game = next(games)
data = random_data()
data = calculate_step(game, data)
background = pew.Pix.from_iter(data)
screen.blit(background)
pew.show(screen)
pew.tick(1/12)
@rok
Copy link
Author

rok commented Jul 9, 2019

You can cycle through two modes: 2 state life and 3 state life by pressing any key on the board.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment