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
|
#!/usr/bin/env python
import sys, pygame, random
class Snake:
"""
Programmable Game of Snake written in PyGame
"""
def __init__(self, startat=(0,0), margin=80,length=4,grid_width=30,grid_height=30, grid_pts=30,fps=180):
# Init attributes
self.grid_width=grid_width
self.grid_height=grid_height
self.grid_pts=grid_pts
self.margin=margin
self.default_length=length
self.attempt=0
self.fps=fps
self.startat=startat
# Setup pygame
pygame.init()
self.font=pygame.font.SysFont(pygame.font.get_default_font(), int(self.margin/2))
self.font_small=pygame.font.SysFont(pygame.font.get_default_font(), int(self.margin/2.5))
self.screen=pygame.display.set_mode((grid_width*grid_pts,grid_height*grid_pts+margin))
def new_game(self):
"""
Reset game state
"""
self.snake=[self.startat]*self.default_length
self.direction=3 # Like clock (12=up, 3=right, 6=bottom, 9=left)
self.new_apple()
self.score=0
self.attempt+=1
def draw_pts(self,x,y,color=(255,255,255),scale=1):
"""
Draw element on the snake area
"""
delta=int(self.grid_pts-int(self.grid_pts*scale))
rect=pygame.Rect(self.grid_pts*x+delta, self.grid_pts*y+self.margin+delta, self.grid_pts-2*delta, self.grid_pts-2*delta)
pygame.draw.rect(self.screen,color,rect, 0)
def draw_infos(self,color=(255,255,255),thickness=10):
"""
Draw the information bar
"""
# Draw separator
rect=pygame.Rect(0, self.margin-thickness, self.grid_width*self.grid_pts, thickness)
pygame.draw.rect(self.screen,(180,180,180),rect, 0)
# Draw score
text = self.font.render('Score: '+str(self.score)+" Length: "+str(len(self.snake))+' Attempt: '+str(self.attempt), True, color)
text_center=text.get_rect(center = (self.grid_width*self.grid_pts // 2, (self.margin-thickness) // 2))
self.screen.blit(text, text_center)
def new_apple(self):
"""
Create a new apple
"""
self.apple=(random.randint(0,self.grid_width-1),random.randint(0,self.grid_height-1))
if self.apple in self.snake:
self.new_apple()
def move(self):
"""
Move the snake
"""
# Update tail
if len(self.snake)>1:
tmp=self.snake[0]
for i in range(1,len(self.snake)):
newtmp=self.snake[i]
self.snake[i]=tmp
tmp=newtmp
# Update head
h=self.snake[0] # Head
if self.direction==3:
self.snake[0]=(h[0]+1,h[1])
elif self.direction==9:
self.snake[0]=(h[0]-1,h[1])
elif self.direction==12:
self.snake[0]=(h[0],h[1]-1)
else:
self.snake[0]=(h[0],h[1]+1)
def draw_snake(self):
"""
Draw the snake with color effects
"""
for i in range(0,len(self.snake)):
color=(0,150,150) if i==0 else (0,max(255-i*10,120),0)
elt=self.snake[i]
self.draw_pts(elt[0],elt[1],color=color)
if i>0:
self.draw_pts(elt[0],elt[1],color=(color[0],int(color[1]/2),color[2]),scale=max(0.7,1-i/4))
else:
self.draw_pts(elt[0],elt[1],color=(color[0],int(color[1]/2),color[2]),scale=0.86)
def draw_apple(self,radius=None):
"""
Draw the apple on the screen
"""
if radius==None:
radius=self.grid_pts/2
pygame.draw.circle(self.screen, (210,0,0), (self.apple[0]*self.grid_pts+int(self.grid_pts/2),self.apple[1]*self.grid_pts+self.margin+int(self.grid_pts/2)), radius)
pygame.draw.circle(self.screen, (170,0,0), (self.apple[0]*self.grid_pts+int(self.grid_pts/2),self.apple[1]*self.grid_pts+self.margin+int(self.grid_pts/2)), radius/1.5)
def has_loose(self):
"""
Return true if the game is loose
"""
if self.snake.count(self.snake[0])>1:
return(True)
h=self.snake[0]
if h[0]<0 or h[1]<0 or h[0] >= self.grid_width or h[1] >= self.grid_height:
return(True)
return(False)
def run(self, event_handler=None):
"""
Play a game (one attempt)
"""
clock = pygame.time.Clock()
ignore_has_loose=True
self.new_game()
last_event=0 # 0 is nothing, 1 is eat an apple and -1 loose
while True:
self.screen.fill((0,0,0))
self.draw_snake()
self.draw_apple()
self.draw_infos()
# Check for loose
if not(ignore_has_loose) and self.has_loose():
event_handler(self,-1)
break
else:
ignore_has_loose=False
# Check inputs
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event_handler==None and event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT and self.direction != 3:
self.direction=9
break
elif event.key == pygame.K_RIGHT and self.direction != 9:
self.direction=3
break
elif event.key == pygame.K_UP and self.direction != 6:
self.direction=12
break
elif event.key == pygame.K_DOWN and self.direction != 12:
self.direction=6
break
# Check if an event handler is available
if event_handler!=None:
code=event_handler(self,last_event)
if code < 0:
break
last_event=0
self.move()
# Check for eating apple
if self.apple==self.snake[0]:
self.snake.append(self.snake[len(self.snake)-1])
self.new_apple()
self.score+=1
last_event=1
pygame.display.flip()
clock.tick(self.fps)
return(self.score)
|