#! /usr/bin/env python3
import time
import random
import copy
print_chars = [' ', 'o', '+', 'o']
def main():
nx = 78
ny = 23
n_states = 2
n_iterations = 1000
pause_seconds = 2.0/24.0
board = new_board(nx, ny)
set_initial_board_random(board, n_states)
# set_initial_specific_cells(board, n_states,
# [(8, 13), (9, 13), (10, 13)])
# set_initial_board_glider(board, 40, 12)
draw_board_text(board)
for i in range(n_iterations):
(board, chanaged_cells) = apply_rule_to_board(board, rule_conway, 3, 3)
draw_board_text(board)
time.sleep(pause_seconds)
def new_board(nx, ny):
board = []
for row_no in range(nx):
row = []
for cell_no in range(ny):
row.append(0)
board.append(row)
return board
def draw_board_text(board):
nx, ny = len(board), len(board[0])
print('')
print('-'*nx)
for j in range(ny):
for i in range(nx):
print('o' if board[i][j] else ' ', end="")
print()
def apply_rule_to_board(old_board, rule_func, neigh_x, neigh_y):
changed_cells = []
board = copy.deepcopy(old_board)
nx, ny = len(board), len(board[0])
for i in range(nx):
for j in range(ny):
old_cell = old_board[i][j]
neighborhood = extract_neighborhood(old_board, i, j, neigh_x, neigh_y)
board[i][j] = rule_func(neighborhood, neigh_x, neigh_y)
new_cell = board[i][j]
if new_cell != old_cell:
changed_cells.append((i, j))
return (board, changed_cells)
def rule_conway(neighborhood, neigh_x, neigh_y):
assert(neigh_x == 3 and neigh_y == 3)
assert(len(neighborhood) == neigh_x and len(neighborhood[0]) == neigh_y)
old_cell = neighborhood[1][1]
n_neighbors = 0
for i in range(neigh_x):
for j in range(neigh_y):
if i == 1 and j == 1: # don't count yourself
continue
n_neighbors += neighborhood[i][j]
if old_cell == 1 and n_neighbors in (2, 3):
new_cell = 1
elif old_cell == 0 and n_neighbors == 3:
new_cell = 1
else:
new_cell = 0
return new_cell
def rule_snowflake(neighborhood, neigh_x, neigh_y):
"""Apply a rule that should yield a snowflake, like that at page 371
of Wolfram's "A New Kind of Science
"""
assert(neigh_x == 3 and neigh_y == 3)
assert(len(neighborhood) == neigh_x and len(neighborhood[0]) == neigh_y)
old_cell = neighborhood[1][1]
n_neighbors = 0
n_neighbors += old_cell
for (i, j) in ((0, 1), (1, 0), (2, 1), (1, 2)):
n_neighbors += neighborhood[i][j]
if old_cell == 1 or n_neighbors >= 1:
new_cell = 1
else:
new_cell = 0
return new_cell
def extract_neighborhood(board, x, y, nx, ny):
board_nx = len(board)
board_ny = len(board[0])
neighborhood = []
for i in range(nx):
neighborhood.append([])
for j in range(ny):
neighborhood[i].append(board[(x - int(nx/2) + i + board_nx) % board_nx]
[(y - int(ny/2) + j + board_ny) % board_ny])
return neighborhood
def set_initial_board_random(board, n_states):
nx, ny = len(board), len(board[0])
for row_no in range(nx):
for col_no in range(ny):
board[row_no][col_no] = random.randint(0, n_states-1)
def set_initial_specific_cells(board, n_states, list_of_points):
nx, ny = len(board), len(board[0])
for pt in list_of_points:
board[pt[0]][pt[1]] = 1
def set_initial_board_glider(board, centerx, centery):
positions = [(centerx-1, centery+1), (centerx, centery+1),
(centerx+1, centery+1), (centerx-1, centery),
(centerx, centery-1)]
set_initial_specific_cells(board, 2, positions)
def set_initial_board_lwss(board, centerx, centery):
"""puts a light weight spaceship on the board"""
positions = [(centerx-2, centery-2),
(centerx-2, centery),
(centerx-1, centery+1),
(centerx, centery+1),
(centerx+1, centery-2),
(centerx+1, centery+1),
(centerx+2, centery-1),
(centerx+2, centery),
(centerx+2, centery+1)]
set_initial_specific_cells(board, 2, positions)
def set_initial_board_one_cell_thick(board, startx, starty, direction_x, length):
positions = []
## FIXME: must make things wrap around
for i in range(length):
x, y = startx, starty
if direction_x:
x += i
else:
y += i
positions.append((x,y))
set_initial_specific_cells(board, 2, positions)
if __name__ == '__main__':
main()