import simplegui
class GameOfLife :
def __init__(self, col_num, row_num, cell_size, line_size = 1) :
self._col_num = col_num
self._row_num = row_num
self._cell_size = cell_size
self._line_size = line_size
self._cells = [[0] * col_num for _ in range(row_num)]
def get_width(self) :
return self._col_num * (self._cell_size + self._line_size) + self._line_size
def get_height(self) :
return self._row_num * (self._cell_size + self._line_size) + self._line_size
def get_color_of_cell(self, x, y) :
return "Black" if self._cells[y][x] == 0 else "Lime"
def get_position_of_cell(self, x, y) :
px = x * (self._line_size + self._cell_size) + self._line_size + 1
py = y * (self._line_size + self._cell_size) + self._line_size + 1
ww = self._cell_size - 2
return [(px, py), (px + ww, py), (px + ww, py + ww), (px, py + ww)]
def reset(self) :
for y in range(self._row_num) :
for x in range(self._col_num) :
self._cells[y][x] = 0
def toggle_cell(self, x, y) :
self._cells[y][x] = (1 + self._cells[y][x]) % 2
def toggle_position(self, position) :
s = self._line_size + self._cell_size
x = position[0] / s
y = position[1] / s
if x < self._col_num and y < self._row_num and x >= 0 and y >= 0 :
self.toggle_cell(x, y)
def update(self) :
temp = [[0] * self._col_num for _ in range(self._row_num)]
for y in range(self._row_num) :
for x in range(self._col_num) :
z = self._cells[y - 1][x - 1]
z += self._cells[y - 1][x]
z += self._cells[y][x - 1]
z += self._cells[y][x]
xx = 0 if x + 1 == self._col_num else x + 1
yy = 0 if y + 1 == self._row_num else y + 1
z += self._cells[y - 1][xx]
z += self._cells[y][xx]
z += self._cells[yy][x - 1]
z += self._cells[yy][x]
z += self._cells[yy][xx]
temp[y][x] = z
for y in range(self._row_num) :
for x in range(self._col_num) :
z = temp[y][x]
if self._cells[y][x] == 1 :
z -= 1
if z < 2 :
self._cells[y][x] = 0
elif z < 4 :
pass
else :
self._cells[y][x] = 0
elif z == 3 :
self._cells[y][x] = 1
def draw(self, canvas) :
width = self.get_width()
y = self._line_size / 2
for _ in range(1 + self._row_num) :
canvas.draw_line((0, y), (width, y), self._line_size, "Teal")
y += self._cell_size + self._line_size
height = self.get_height()
x = self._line_size / 2
for _ in range(1 + self._col_num) :
canvas.draw_line((x, 0), (x, height), self._line_size, "Teal")
x += self._cell_size + self._line_size
for y in range(self._row_num) :
for x in range(self._col_num) :
color = self.get_color_of_cell(x, y)
canvas.draw_polygon(self.get_position_of_cell(x, y), 2, color, color)
button_start = None
button_clear = None
running = False
gol = GameOfLife(20, 20, 38, 2)
def demo(name) :
global running
running = True
gol.reset()
button_start.set_text("Pause")
patterns = {
"toad" : [(3, 2), (4, 2), (5, 2), (2, 3), (3, 3), (4, 3)],
"blinker" : [(4, 3), (4, 4), (4, 5)],
"beacon" : [(1, 1), (2, 1), (1, 2), (4, 4), (4, 3), (3, 4)],
"pulsar" : [(4, 2), (5, 2), (6, 2), (10, 2), (11, 2), (12, 2), \
(2, 4), (2, 5), (2, 6), (7, 4), (7, 5), (7, 6), \
(9, 4), (9, 5), (9, 6), (14, 4), (14, 5), (14, 6), \
(4, 7), (5, 7), (6, 7), (10, 7), (11, 7), (12, 7), \
(4, 9), (5, 9), (6, 9), (10, 9), (11, 9), (12, 9), \
(2, 10), (2, 11), (2, 12), (7, 10), (7, 11), (7, 12), \
(9, 10), (9, 11), (9, 12), (14, 10), (14, 11), (14, 12), \
(4, 14), (5, 14), (6, 14), (10, 14), (11, 14), (12, 14)],
"glider" : [(5, 5), (6, 6), (6, 7), (5, 7), (4, 7)],
"lwss" : [(2, 2), (2, 4), (5, 2), (6, 3), (6, 4), (6, 5), (3, 5), (4, 5), (5, 5)]
}
map(lambda x : gol.toggle_cell(x[0], x[1]), patterns[name])
def on_mouse_clicked(position) :
if not running :
gol.toggle_position(position)
def on_demo_toad() :
demo("toad")
def on_demo_blinker() :
demo("blinker")
def on_demo_beacon() :
demo("beacon")
def on_demo_pulsar() :
demo("pulsar")
def on_demo_glider() :
demo("glider")
def on_demo_lwss() :
demo("lwss")
def on_start() :
global running
running = not running
if running :
button_start.set_text("Pause")
else :
button_start.set_text("Start")
def on_clear() :
global running
running = False
button_start.set_text("Start")
gol.reset()
def update_game_of_life() :
if running :
gol.update()
def on_draw(canvas) :
gol.draw(canvas)
# Create a frame and assign callbacks to event handlers
frame = simplegui.create_frame("Game of Life", gol.get_width(), gol.get_height())
frame.add_button('Demo Toad', on_demo_toad)
frame.add_button('Demo Blinker', on_demo_blinker)
frame.add_button('Demo Beacon', on_demo_beacon)
frame.add_button('Demo Pulsar', on_demo_pulsar)
frame.add_button('Demo Glider', on_demo_glider)
frame.add_button('Demo LWSS', on_demo_lwss)
button_start = frame.add_button('Start', on_start)
button_clear = frame.add_button('Clear', on_clear)
frame.set_mouseclick_handler(on_mouse_clicked)
frame.set_draw_handler(on_draw)
frame.start()
# timer to update
timer = simplegui.create_timer(500, update_game_of_life)
timer.start()
on_demo_toad()