summaryrefslogtreecommitdiff
path: root/snake/snake.py
blob: 98975cb93b507210ab3ade23a715b071ebe83fdc (plain)
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
#!/usr/bin/env python
import sys, pygame, random


class Snake:

    def __init__(self, margin=80,length=10,grid_width=40,grid_height=40, grid_pts=20,fps=10):
        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
        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):
        self.snake=[(0,0)]*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)):
        rect=pygame.Rect(self.grid_pts*x, self.grid_pts*y+self.margin, self.grid_pts, self.grid_pts)
        pygame.draw.rect(self.screen,color,rect, 0)

    def draw_infos(self,color=(255,255,255),thickness=5):
        rect=pygame.Rect(0, self.margin-thickness, self.grid_width*self.grid_pts, thickness)
        pygame.draw.rect(self.screen,color,rect, 0)
        text = self.font.render('Score '+str(self.score)+"     Length "+str(len(self.snake)), 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)
        text = self.font_small.render('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, (self.grid_pts/2,text_center[1]))

    def new_apple(self):
        self.apple=(random.randint(0,self.grid_width-1),random.randint(0,self.grid_height-1))
        while self.apple in self.snake:
            self.apple=(random.randint(0,self.grid_width),random.randint(0,self.grid_height))

    def move(self):
        # 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):
        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)

    def has_loose(self):
        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):
        clock = pygame.time.Clock()
        ignore_has_loose=True
        self.new_game()
        while True:
            self.screen.fill((0,0,0))
            self.draw_snake()
            self.draw_pts(self.apple[0],self.apple[1],color=(255,0,0))
            self.draw_infos()
            # Check for loose
            if not(ignore_has_loose) and self.has_loose():
                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
            if event_handler!=None:
                event_handler(self)
            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
            pygame.display.flip()
            clock.tick(self.fps)


game=Snake()

def event_handler(game):
    if game.snake[0][0]==10:
        game.direction=6

for i in range(0,10):
    game.run()