1
+ import pygame
2
+ import random
3
+ from enum import Enum
4
+ from collections import namedtuple
5
+
6
+ pygame .init ()
7
+ font = pygame .font .Font ('arial.ttf' , 25 )
8
+ #font = pygame.font.SysFont('arial', 25)
9
+
10
+ class Direction (Enum ):
11
+ RIGHT = 1
12
+ LEFT = 2
13
+ UP = 3
14
+ DOWN = 4
15
+
16
+ Point = namedtuple ('Point' , 'x, y' )
17
+
18
+ # rgb colors
19
+ WHITE = (255 , 255 , 255 )
20
+ RED = (200 ,0 ,0 )
21
+ BLUE1 = (0 , 0 , 255 )
22
+ BLUE2 = (0 , 100 , 255 )
23
+ BLACK = (0 ,0 ,0 )
24
+
25
+ BLOCK_SIZE = 20
26
+ SPEED = 20
27
+
28
+ class SnakeGame :
29
+
30
+ def __init__ (self , w = 640 , h = 480 ):
31
+ self .w = w
32
+ self .h = h
33
+ # init display
34
+ self .display = pygame .display .set_mode ((self .w , self .h ))
35
+ pygame .display .set_caption ('Snake' )
36
+ self .clock = pygame .time .Clock ()
37
+
38
+ # init game state
39
+ self .direction = Direction .RIGHT
40
+
41
+ self .head = Point (self .w / 2 , self .h / 2 )
42
+ self .snake = [self .head ,
43
+ Point (self .head .x - BLOCK_SIZE , self .head .y ),
44
+ Point (self .head .x - (2 * BLOCK_SIZE ), self .head .y )]
45
+
46
+ self .score = 0
47
+ self .food = None
48
+ self ._place_food ()
49
+
50
+ def _place_food (self ):
51
+ x = random .randint (0 , (self .w - BLOCK_SIZE )// BLOCK_SIZE )* BLOCK_SIZE
52
+ y = random .randint (0 , (self .h - BLOCK_SIZE )// BLOCK_SIZE )* BLOCK_SIZE
53
+ self .food = Point (x , y )
54
+ if self .food in self .snake :
55
+ self ._place_food ()
56
+
57
+ def play_step (self ):
58
+ # 1. collect user input
59
+ for event in pygame .event .get ():
60
+ if event .type == pygame .QUIT :
61
+ pygame .quit ()
62
+ quit ()
63
+ if event .type == pygame .KEYDOWN :
64
+ if event .key == pygame .K_LEFT :
65
+ self .direction = Direction .LEFT
66
+ elif event .key == pygame .K_RIGHT :
67
+ self .direction = Direction .RIGHT
68
+ elif event .key == pygame .K_UP :
69
+ self .direction = Direction .UP
70
+ elif event .key == pygame .K_DOWN :
71
+ self .direction = Direction .DOWN
72
+
73
+ # 2. move
74
+ self ._move (self .direction ) # update the head
75
+ self .snake .insert (0 , self .head )
76
+
77
+ # 3. check if game over
78
+ game_over = False
79
+ if self ._is_collision ():
80
+ game_over = True
81
+ return game_over , self .score
82
+
83
+ # 4. place new food or just move
84
+ if self .head == self .food :
85
+ self .score += 1
86
+ self ._place_food ()
87
+ else :
88
+ self .snake .pop ()
89
+
90
+ # 5. update ui and clock
91
+ self ._update_ui ()
92
+ self .clock .tick (SPEED )
93
+ # 6. return game over and score
94
+ return game_over , self .score
95
+
96
+ def _is_collision (self ):
97
+ # hits boundary
98
+ if self .head .x > self .w - BLOCK_SIZE or self .head .x < 0 or self .head .y > self .h - BLOCK_SIZE or self .head .y < 0 :
99
+ return True
100
+ # hits itself
101
+ if self .head in self .snake [1 :]:
102
+ return True
103
+
104
+ return False
105
+
106
+ def _update_ui (self ):
107
+ self .display .fill (BLACK )
108
+
109
+ for pt in self .snake :
110
+ pygame .draw .rect (self .display , BLUE1 , pygame .Rect (pt .x , pt .y , BLOCK_SIZE , BLOCK_SIZE ))
111
+ pygame .draw .rect (self .display , BLUE2 , pygame .Rect (pt .x + 4 , pt .y + 4 , 12 , 12 ))
112
+
113
+ pygame .draw .rect (self .display , RED , pygame .Rect (self .food .x , self .food .y , BLOCK_SIZE , BLOCK_SIZE ))
114
+
115
+ text = font .render ("Score: " + str (self .score ), True , WHITE )
116
+ self .display .blit (text , [0 , 0 ])
117
+ pygame .display .flip ()
118
+
119
+ def _move (self , direction ):
120
+ x = self .head .x
121
+ y = self .head .y
122
+ if direction == Direction .RIGHT :
123
+ x += BLOCK_SIZE
124
+ elif direction == Direction .LEFT :
125
+ x -= BLOCK_SIZE
126
+ elif direction == Direction .DOWN :
127
+ y += BLOCK_SIZE
128
+ elif direction == Direction .UP :
129
+ y -= BLOCK_SIZE
130
+
131
+ self .head = Point (x , y )
132
+
133
+
134
+ if __name__ == '__main__' :
135
+ game = SnakeGame ()
136
+
137
+ # game loop
138
+ while True :
139
+ game_over , score = game .play_step ()
140
+
141
+ if game_over == True :
142
+ break
143
+
144
+ print ('Final Score' , score )
145
+
146
+
147
+ pygame .quit ()
0 commit comments