-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSnake_Game.py
More file actions
277 lines (229 loc) · 11.1 KB
/
Snake_Game.py
File metadata and controls
277 lines (229 loc) · 11.1 KB
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
#Snake Game
#Enemy Snake competes for food with Player Snake
#Enemy Snake spawns at score of original snake at intervals of 5, for 10 seconds (If score is 5, enemy snake spawns. If score is 10, enemy snake spawns and so on)
#Enemy Snake will spawn again for 10 seconds if original snake is unable to score more than an interval of 5
import tkinter as tk
import random
class SnakeGame:
def __init__(self, master):
self.master = master
self.master.title("Snake Game")
self.master.geometry("400x460")
self.master.resizable(False, False)
self.canvas = tk.Canvas(self.master, bg="black", width=400, height=400)
self.canvas.pack()
self.scoreboard = tk.Label(self.master, text="Score: 0", font=("Arial", 16), bg="white", fg="black", padx=10, pady=5)
self.scoreboard.pack()
self.countdown_label = tk.Label(self.master, text="", font=("Arial", 16), bg="white", fg="black", padx=10, pady=5)
self.countdown_label.pack()
self.snake = [(100, 100), (90, 100), (80, 100)]
self.direction = "Right"
self.snake_size = 20
self.obstacles = self.create_obstacles()
self.food = self.create_food()
self.master.bind("<KeyPress>", self.start_or_change_direction)
self.snake_moving = False
self.game_started = False
self.score = 0
self.update_scoreboard()
self.enemy_snake = []
self.enemy_direction = None
self.enemy_start_time = None
self.countdown_after_id = None
# Show press any key message on canvas
self.countdown_label.config(text="")
self.draw_snake()
self.canvas.create_text(200, 200, text="Press Any Key To Start", fill="white", font=("Arial", 24), tags="start_text")
def create_food(self):
while True:
x = random.randint(0, 19) * self.snake_size
y = random.randint(0, 19) * self.snake_size
food_coords = (x, y, x + self.snake_size, y + self.snake_size)
if food_coords not in self.obstacles:
break
return self.canvas.create_rectangle(food_coords, fill="red", tags="food")
def create_obstacles(self):
obstacles = []
for _ in range(10):
while True:
x = random.randint(0, 19) * self.snake_size
y = random.randint(0, 19) * self.snake_size
obstacle_coords = (x, y, x + self.snake_size, y + self.snake_size)
if obstacle_coords not in obstacles:
obstacles.append(obstacle_coords)
self.canvas.create_rectangle(obstacle_coords, fill="gray", tags="obstacle")
break
return obstacles
def available_directions(self, head):
directions = ["Right", "Left", "Up", "Down"]
available = []
for direction in directions:
if direction == "Right" and (head[0] + self.snake_size, head[1]) not in self.enemy_snake and (head[0] + self.snake_size, head[1]) not in [obs[:2] for obs in self.obstacles]:
available.append(direction)
elif direction == "Left" and (head[0] - self.snake_size, head[1]) not in self.enemy_snake and (head[0] - self.snake_size, head[1]) not in [obs[:2] for obs in self.obstacles]:
available.append(direction)
elif direction == "Up" and (head[0], head[1] - self.snake_size) not in self.enemy_snake and (head[0], head[1] - self.snake_size) not in [obs[:2] for obs in self.obstacles]:
available.append(direction)
elif direction == "Down" and (head[0], head[1] + self.snake_size) not in self.enemy_snake and (head[0], head[1] + self.snake_size) not in [obs[:2] for obs in self.obstacles]:
available.append(direction)
return available
def move_snake(self, snake):
head = snake[0]
new_head = None
if self.direction == "Right":
new_head = (head[0] + self.snake_size, head[1])
elif self.direction == "Left":
new_head = (head[0] - self.snake_size, head[1])
elif self.direction == "Up":
new_head = (head[0], head[1] - self.snake_size)
elif self.direction == "Down":
new_head = (head[0], head[1] + self.snake_size)
if new_head is not None and (new_head[0] < 0 or new_head[0] >= 400 or
new_head[1] < 0 or new_head[1] >= 400 or
new_head in [obs[:2] for obs in self.obstacles] or
new_head in self.enemy_snake):
self.clear_enemy_snake()
return
snake.insert(0, new_head)
snake.pop()
return True
def create_enemy_snake(self):
self.enemy_snake = [(300, 300), (310, 300), (320, 300)]
self.enemy_direction = "Left"
self.enemy_start_time = self.master.after(10000, self.clear_enemy_snake)
self.start_countdown(10)
def start_countdown(self, seconds):
self.countdown_label.config(text=f"Countdown: {seconds}")
if seconds > 0:
self.countdown_after_id = self.master.after(1000, lambda s=seconds-1: self.start_countdown(s))
else:
self.clear_enemy_snake()
self.countdown_label.config(text="")
def move_enemy_snake(self):
enemy_head = self.enemy_snake[0]
food_coords = self.canvas.coords(self.food)
directions = self.available_directions(enemy_head)
if enemy_head[0] < food_coords[0] and "Right" in directions:
self.enemy_direction = "Right"
elif enemy_head[0] > food_coords[0] and "Left" in directions:
self.enemy_direction = "Left"
elif enemy_head[1] < food_coords[1] and "Down" in directions:
self.enemy_direction = "Down"
elif enemy_head[1] > food_coords[1] and "Up" in directions:
self.enemy_direction = "Up"
else:
self.enemy_direction = random.choice(directions)
new_head = enemy_head
if self.enemy_direction == "Right":
new_head = (enemy_head[0] + self.snake_size, enemy_head[1])
elif self.enemy_direction == "Left":
new_head = (enemy_head[0] - self.snake_size, enemy_head[1])
elif self.enemy_direction == "Up":
new_head = (enemy_head[0], enemy_head[1] - self.snake_size)
elif self.enemy_direction == "Down":
new_head = (enemy_head[0], enemy_head[1] + self.snake_size)
if (new_head[0] < 0 or new_head[0] >= 400 or
new_head[1] < 0 or new_head[1] >= 400 or
new_head in [obs[:2] for obs in self.obstacles] or
new_head in self.enemy_snake):
self.clear_enemy_snake()
return
self.enemy_snake.insert(0, new_head)
if self.canvas.coords(self.food) == [new_head[0], new_head[1], new_head[0] + self.snake_size, new_head[1] + self.snake_size]:
self.canvas.delete("food")
self.food = self.create_food()
else:
self.enemy_snake.pop()
def clear_enemy_snake(self):
self.enemy_snake.clear()
self.enemy_start_time = None
self.canvas.delete("enemy")
self.countdown_label.config(text="")
def update_scoreboard(self):
self.scoreboard.config(text=f"Score: {self.score}")
def draw_snake(self):
self.canvas.delete("snake")
for segment in self.snake:
self.canvas.create_rectangle(segment[0], segment[1], segment[0] + self.snake_size, segment[1] + self.snake_size, fill="green", tags="snake")
def pause_enemy_snake(self):
if self.enemy_start_time:
self.master.after_cancel(self.enemy_start_time)
def end_game(self):
self.snake_moving = False
self.pause_enemy_snake()
self.canvas.create_text(200, 180, text="Game Over!", fill="white", font=("Arial", 24), tags="game_over")
self.canvas.create_text(200, 220, text="Press SPACE to restart", fill="white", font=("Arial", 18), tags="game_over")
if self.countdown_after_id:
self.master.after_cancel(self.countdown_after_id)
self.countdown_label.config(text="")
self.master.bind("<space>", self.restart_game)
def update(self):
if not self.snake_moving:
return
snake_moved = self.move_snake(self.snake)
if not snake_moved:
self.end_game()
return
self.draw_snake()
if self.score % 5 == 0 and self.score != 0 and not self.enemy_snake:
if self.enemy_start_time is None:
self.create_enemy_snake()
if self.enemy_snake:
self.move_enemy_snake()
self.canvas.delete("enemy")
for segment in self.enemy_snake:
self.canvas.create_rectangle(segment[0], segment[1], segment[0] + self.snake_size, segment[1] + self.snake_size, fill="blue",tags="enemy")
food_coords = self.canvas.coords(self.food)
if int(self.snake[0][0]) == food_coords[0] and int(self.snake[0][1]) == food_coords[1]:
self.snake.append(self.snake[-1])
self.canvas.delete("food")
self.food = self.create_food()
self.score += 1
self.update_scoreboard()
if self.snake_moving:
self.master.after(100, self.update)
def restart_game(self, event=None):
# Clear the canvas of game over messages
self.canvas.delete("game_over")
# Reset game state
self.snake = [(100, 100), (90, 100), (80, 100)]
self.direction = "Right"
self.snake_moving = False
self.game_started = False
self.score = 0
self.update_scoreboard()
self.enemy_snake = []
self.enemy_direction = None
self.enemy_start_time = None
# Clear and recreate game elements
self.canvas.delete("all")
self.obstacles = self.create_obstacles()
self.food = self.create_food()
# Show start message
self.canvas.create_text(200, 200, text="Press Any Key To Start", fill="white", font=("Arial", 24), tags="start_text")
self.draw_snake()
# Rebind start key
self.master.bind("<KeyPress>", self.start_or_change_direction)
def start_or_change_direction(self, event):
if event.keysym == "space" and not self.snake_moving and not self.game_started:
self.restart_game()
return
if not self.game_started:
self.game_started = True
self.snake_moving = True
self.countdown_label.config(text="")
self.canvas.delete("start_text")
self.update()
return
if event.keysym == "Right" and self.direction != "Left":
self.direction = "Right"
elif event.keysym == "Left" and self.direction != "Right":
self.direction = "Left"
elif event.keysym == "Up" and self.direction != "Down":
self.direction = "Up"
elif event.keysym == "Down" and self.direction != "Up":
self.direction = "Down"
if __name__ == "__main__":
root = tk.Tk()
game = SnakeGame(root)
root.mainloop()