-
Notifications
You must be signed in to change notification settings - Fork 97
/
GameOfLife.py
89 lines (80 loc) · 3.39 KB
/
GameOfLife.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
from tkinter import *
#preset board size
x, y = 15, 15
#called once the cells are selected
def start():
for r in range(x):
for c in range(y):
if cells[r][c].get() == 1:
selected_cells.add(Cell(r, c))
show_evolution(selected_cells)
#called recursively to display the evolution; closes the window when 'quit' is clicked
def show_evolution(curr_cells):
board = Grid(x, y, curr_cells)
for widgets in window.winfo_children():
widgets.destroy()
for r in range(x):
for c in range(y):
if Cell(r, c) in board.alive_cells:
b = Checkbutton(window, bg="yellow", onvalue=1, offvalue=0, indicatoron=False, width=3,
variable=cells[r][c])
else:
b = Checkbutton(window, bg="black", onvalue=1, offvalue=0, indicatoron=False, width=3,
variable=cells[r][c])
b.grid(row=r + 1, column=c + 1)
b.deselect()
Button(window, text = "Next", fg = "gold", bg = "black", command = lambda: show_evolution(board.evolve())).grid(row = x+1,column = y+1)
Button(window, text="Quit", fg="white", bg="red", command=lambda: window.destroy()).grid(
row=x + 2, column=y + 1)
#initial set-up window
window = Tk()
window.title("Game of Life")
window.geometry('500x400')
#window.resizable(False, False)
cells = [[IntVar() for r in range(x)] for c in range(y)]
buttons = [[None]*y]*x
selected_cells = set()
for r in range(x):
for c in range(y):
b = Checkbutton(window, bg = "dark gray", onvalue=1, offvalue=0, indicatoron = False, width = 3, variable = cells[r][c])
b.grid(row = r + 1, column = c + 1)
buttons[r][c] = b
Label(window, text = "Select a cell to indicate it's alive.\n Click 'start' when done").grid(row = x+1, column = y + 1)
start = Button(window, text = "Start", fg = "gold", bg = "black", command = start)
start.grid(row = x+2, column = y + 1)
#implementing base classes for Conway's Game of Life
from collections import namedtuple
Cell = namedtuple("Cell", ["row", "col"])
"""A class implementing a Game_of_Life grid"""
class Grid:
offsets = [(-1,0), (1,0), (0,1), (0,-1), (-1, -1), (1, 1), (-1, 1), (1, -1)]
def __init__(self, r, c, alive_cells = {}):
self.alive_cells = alive_cells
self.rows = r
self.columns = c
def evolve(self):
next_alive = set(self.alive_cells)
for row in range(self.rows):
for col in range(self.columns):
current_cell = Cell(row, col)
alive = get_neighbours(self, current_cell)
if current_cell in self.alive_cells:
if alive < 2 or alive > 3:
next_alive.remove(current_cell)
else:
if alive == 3:
next_alive.add(current_cell)
return next_alive
def __str__(self):
rep = ""
for row in range(self.rows):
rep += "".join("1 " if Cell(row, col) in self.alive_cells else "0 " for col in range(self.columns))
rep += "\n"
return rep
"""A function to get the number of alive neighbours of a cell"""
def get_neighbours(grid, cell):
alive = 0
for offset in grid.offsets:
if Cell(cell.row + offset[0], cell.col + offset[1]) in grid.alive_cells:
alive += 1
return alive