-
Notifications
You must be signed in to change notification settings - Fork 2k
/
Copy pathsnake.py
156 lines (128 loc) · 4.94 KB
/
snake.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
import pygame
import random
# setting up some initial parameters
WIDTH, HEIGHT = 600, 600
BLOCK_SIZE = 20
pygame.font.init()
score_font = pygame.font.SysFont("consolas", 20) # or any other font you'd like
score = 0
# color definition
WHITE = (255, 255, 255)
RED = (255, 0, 0)
# initialize pygame
pygame.init()
# setting up display
win = pygame.display.set_mode((WIDTH, HEIGHT))
# setting up clock
clock = pygame.time.Clock()
# snake and food initialization
snake_pos = [[WIDTH//2, HEIGHT//2]]
snake_speed = [0, BLOCK_SIZE]
teleport_walls = True # set this to True to enable wall teleporting
def generate_food():
while True:
x = random.randint(0, (WIDTH - BLOCK_SIZE) // BLOCK_SIZE ) * BLOCK_SIZE
y = random.randint(0, (HEIGHT - BLOCK_SIZE) // BLOCK_SIZE ) * BLOCK_SIZE
food_pos = [x, y]
if food_pos not in snake_pos:
return food_pos
food_pos = generate_food()
def draw_objects():
win.fill((0, 0, 0))
for pos in snake_pos:
pygame.draw.rect(win, WHITE, pygame.Rect(pos[0], pos[1], BLOCK_SIZE, BLOCK_SIZE))
pygame.draw.rect(win, RED, pygame.Rect(food_pos[0], food_pos[1], BLOCK_SIZE, BLOCK_SIZE))
# Render the score
score_text = score_font.render(f"Score: {score}", True, WHITE)
win.blit(score_text, (10, 10)) # draws the score on the top-left corner
def update_snake():
global food_pos, score
new_head = [snake_pos[0][0] + snake_speed[0], snake_pos[0][1] + snake_speed[1]]
if teleport_walls:
# if the new head position is outside of the screen, wrap it to the other side
if new_head[0] >= WIDTH:
new_head[0] = 0
elif new_head[0] < 0:
new_head[0] = WIDTH - BLOCK_SIZE
if new_head[1] >= HEIGHT:
new_head[1] = 0
elif new_head[1] < 0:
new_head[1] = HEIGHT - BLOCK_SIZE
if new_head == food_pos:
food_pos = generate_food() # generate new food
score += 1 # increment score when food is eaten
else:
snake_pos.pop() # remove the last element from the snake
snake_pos.insert(0, new_head) # add the new head to the snake
def game_over():
# game over when snake hits the boundaries or runs into itself
if teleport_walls:
return snake_pos[0] in snake_pos[1:]
else:
return snake_pos[0] in snake_pos[1:] or \
snake_pos[0][0] > WIDTH - BLOCK_SIZE or \
snake_pos[0][0] < 0 or \
snake_pos[0][1] > HEIGHT - BLOCK_SIZE or \
snake_pos[0][1] < 0
def game_over_screen():
global score
win.fill((0, 0, 0))
game_over_font = pygame.font.SysFont("consolas", 50)
game_over_text = game_over_font.render(f"Game Over! Score: {score}", True, WHITE)
win.blit(game_over_text, (WIDTH // 2 - game_over_text.get_width() // 2, HEIGHT // 2 - game_over_text.get_height() // 2))
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
return
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r:
run() # replay the game
return
elif event.key == pygame.K_q:
pygame.quit() # quit the game
return
def run():
global snake_speed, snake_pos, food_pos, score
snake_pos = [[WIDTH//2, HEIGHT//2]]
snake_speed = [0, BLOCK_SIZE]
food_pos = generate_food()
score = 0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
for key in keys:
if keys[pygame.K_UP]:
# when UP is pressed but the snake is moving down, ignore the input
if snake_speed[1] == BLOCK_SIZE:
continue
snake_speed = [0, -BLOCK_SIZE]
if keys[pygame.K_DOWN]:
# when DOWN is pressed but the snake is moving up, ignore the input
if snake_speed[1] == -BLOCK_SIZE:
continue
snake_speed = [0, BLOCK_SIZE]
if keys[pygame.K_LEFT]:
# when LEFT is pressed but the snake is moving right, ignore the input
if snake_speed[0] == BLOCK_SIZE:
continue
snake_speed = [-BLOCK_SIZE, 0]
if keys[pygame.K_RIGHT]:
# when RIGHT is pressed but the snake is moving left, ignore the input
if snake_speed[0] == -BLOCK_SIZE:
continue
snake_speed = [BLOCK_SIZE, 0]
draw_objects()
update_snake()
if game_over():
game_over_screen()
break
pygame.display.update()
clock.tick(10)
pygame.quit()
if __name__ == '__main__':
run()