-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsnake.py
More file actions
executable file
·184 lines (152 loc) · 5.55 KB
/
Copy pathsnake.py
File metadata and controls
executable file
·184 lines (152 loc) · 5.55 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
import pygame
import random
import sys
CELL_SIZE = 20
GRID_WIDTH = 30
GRID_HEIGHT = 20
WIDTH = CELL_SIZE * GRID_WIDTH
HEIGHT = CELL_SIZE * GRID_HEIGHT
FPS_START = 8
SPEED_INCREMENT = 0.5
WRAP_AROUND = False
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
DARK_GREEN = (10, 120, 10)
GREEN = (34, 177, 76)
RED = (200, 30, 30)
GRAY = (50, 50, 50)
UP = (0, -1)
DOWN = (0, 1)
LEFT = (-1, 0)
RIGHT = (1, 0)
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Snake (pygame)")
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 28)
big_font = pygame.font.SysFont(None, 56)
def draw_cell(pos, color):
x, y = pos
rect = pygame.Rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
pygame.draw.rect(screen, color, rect)
def random_empty_cell(snake):
available = [(x, y) for x in range(GRID_WIDTH) for y in range(GRID_HEIGHT) if (x, y) not in snake]
return random.choice(available) if available else None
def step_head(head, direction):
x, y = head
dx, dy = direction
return (x + dx, y + dy)
def in_bounds(pos):
x, y = pos
return 0 <= x < GRID_WIDTH and 0 <= y < GRID_HEIGHT
def draw_grid():
for x in range(0, WIDTH, CELL_SIZE):
pygame.draw.line(screen, GRAY, (x, 0), (x, HEIGHT))
for y in range(0, HEIGHT, CELL_SIZE):
pygame.draw.line(screen, GRAY, (0, y), (WIDTH, y))
def show_text(text, size=28, color=WHITE, center=None):
f = pygame.font.SysFont(None, size)
surf = f.render(text, True, color)
rect = surf.get_rect()
if center:
rect.center = center
else:
rect.topleft = (10, 10)
screen.blit(surf, rect)
def game_loop():
mid_x = GRID_WIDTH // 2
mid_y = GRID_HEIGHT // 2
snake = [(mid_x - 1, mid_y), (mid_x, mid_y)]
direction = RIGHT
pending_direction = RIGHT
score = 0
fps = FPS_START
apple = random_empty_cell(snake)
running = True
game_over = False
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key in (pygame.K_UP, pygame.K_w):
pending_direction = UP
elif event.key in (pygame.K_DOWN, pygame.K_s):
pending_direction = DOWN
elif event.key in (pygame.K_LEFT, pygame.K_a):
pending_direction = LEFT
elif event.key in (pygame.K_RIGHT, pygame.K_d):
pending_direction = RIGHT
elif event.key == pygame.K_r and game_over:
return True
elif event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()
if not game_over:
opp = (-direction[0], -direction[1])
if pending_direction != opp:
direction = pending_direction
new_head = step_head(snake[-1], direction)
if WRAP_AROUND:
new_x = new_head[0] % GRID_WIDTH
new_y = new_head[1] % GRID_HEIGHT
new_head = (new_x, new_y)
else:
if not in_bounds(new_head):
game_over = True
if not game_over and new_head in snake:
game_over = True
if not game_over:
snake.append(new_head)
if apple and new_head == apple:
score += 1
fps += SPEED_INCREMENT
apple = random_empty_cell(snake)
else:
snake.pop(0)
screen.fill(BLACK)
for segment in snake[:-1]:
draw_cell(segment, DARK_GREEN)
if snake:
draw_cell(snake[-1], GREEN)
if apple:
draw_cell(apple, RED)
draw_grid()
show_text(f"Score: {score}")
if game_over:
show_text("GAME OVER", size=56, color=WHITE, center=(WIDTH//2, HEIGHT//2 - 20))
show_text("Press R to restart or ESC to quit", size=28, color=WHITE, center=(WIDTH//2, HEIGHT//2 + 30))
pygame.display.flip()
if not game_over:
clock.tick(fps)
else:
clock.tick(10)
def main_menu():
while True:
screen.fill(BLACK)
show_text("Snake (pygame)", size=48, color=WHITE, center=(WIDTH//2, HEIGHT//2 - 80))
show_text("Arrow keys or WASD to move", size=28, color=WHITE, center=(WIDTH//2, HEIGHT//2 - 20))
wrap_text = "Wrap-around: ON" if WRAP_AROUND else "Wrap-around: OFF"
show_text(wrap_text + " (toggle in code)", size=20, color=WHITE, center=(WIDTH//2, HEIGHT//2 + 10))
show_text("Press SPACE to start, ESC to quit", size=28, color=WHITE, center=(WIDTH//2, HEIGHT//2 + 60))
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
return
if event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()
clock.tick(10)
def main():
while True:
main_menu()
restart = game_loop()
if not restart:
break
if __name__ == "__main__":
main()