-
Notifications
You must be signed in to change notification settings - Fork 0
/
life_game.py
160 lines (122 loc) · 4.69 KB
/
life_game.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
from math import floor
from tkinter import Tk, Canvas
class GameOfLife:
def __init__(self):
# Initialisation des variables dans la class.
self.playing = False
self.size = 10
self.height = self.width = 600
self.colors = {
"cell": "#16d8ed",
"bg": "#191919"
}
self.cells = []
for i in range(0, self.height, self.size):
line = []
for j in range(0, self.width, self.size):
line.append(0)
self.cells.append(line)
self.root = Tk()
self.root.resizable(width=False, height=False)
self.root.title("Game Of Life")
self.canvas = Canvas(self.root,
width=self.width,
height=self.height,
bg=self.colors['bg'])
# On focus le canvas pour avoir accès aux événements du clavier.
self.canvas.focus_set()
# On écoute des évènements du clavier et de la souris.
self.canvas.bind("<Key>", self.key)
self.canvas.bind("<Button-1>", self.click)
self.canvas.bind("<B1-Motion>", self.drag_handler)
self.canvas.pack()
"""
On précise qu'on fait une loop dans le canvas pour éviter que
l'image se close au bout de 2ms
"""
self.root.mainloop()
def copy_array(self, arr) -> list:
new_arr = []
for i in range(len(arr)):
if isinstance(arr[i], list):
new_arr.append(self.copy_array(arr[i]))
else:
new_arr.append(arr[i])
return new_arr
def run(self) -> bool:
"""
Méthode principale du jeu.
Fait tourner le jeu de la vie (à l'infini).
Elle rafraichit l’affichage à chaque tour
"""
if not self.playing:
return False
self.canvas.delete("all")
new_cells = self.copy_array(self.cells)
for y in range(0, len(self.cells)):
for x in range(0, len(self.cells[y])):
status = self.cells[y][x]
neighbors = self.getNeighborsCount(x, y)
if status == 0 and neighbors == 3:
new_cells[y][x] = 1
elif status == 1 and neighbors not in [2, 3]:
new_cells[y][x] = 0
else:
new_cells[y][x] = status
color = self.colors['bg'] if new_cells[y][x] == 0 \
else self.colors['cell']
self.canvas.create_rectangle(
(x * self.size) - (self.size // 2),
(y * self.size) - (self.size // 2),
(x * self.size) + (self.size // 2),
(y * self.size) + (self.size // 2),
fill=color,
outline=self.colors['bg'])
self.cells = new_cells
self.root.update()
return self.run()
def key(self, event) -> None:
if event.char == 'p':
self.playing = not self.playing
if self.playing:
self.run()
def click(self, event, trusted=True) -> bool:
if self.playing:
return False
[case, x, y] = self.nearestCase(event.x, event.y)
if case is None:
return False
if trusted:
self.cells[y][x] = 1 if self.cells[y][x] == 0 else 0
else:
self.cells[y][x] = 1
color = self.colors['bg'] if self.cells[y][x] == 0 \
else self.colors['cell']
self.canvas.create_rectangle((x * self.size) - (self.size // 2),
(y * self.size) - (self.size // 2),
(x * self.size) + (self.size // 2),
(y * self.size) + (self.size // 2),
fill=color,
outline=self.colors['bg'])
return True
def drag_handler(self, event) -> bool or click:
if self.playing:
return False
return self.click(event, trusted=False)
def getNeighborsCount(self, x=0, y=0) -> int:
size = 0
for new_y in range(y - 1, y + 2):
for new_x in range(x - 1, x + 2):
try:
cell = self.cells[new_y][new_x]
except Exception:
continue
if cell == 1 and (new_x != x or new_y != y):
size += 1
return size
def nearestCase(self, x=0, y=0) -> (int, int, int):
x = floor(x / self.size)
y = floor(y / self.size)
return self.cells[y][x], x, y
gameOfLife = GameOfLife()
gameOfLife.run()