-
Notifications
You must be signed in to change notification settings - Fork 0
/
snake.py
76 lines (58 loc) · 2.18 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
# NOTE:
#
# turtle.xcor(), turtle.ycor(), turtle.position(), turtle.distance().
# These functions sometimes return relative values (decimals) instead of absolute values (integers)
# which causes errors if we compare two objects for the exact position.
from turtle import Turtle
BODY_SIZE = 20
UP, DOWN, LEFT, RIGHT = 90, 270, 180, 0
BORDER = 290
MAX_SPEED = 20
class Snake:
def __init__(self):
self.body = []
self.__init_body()
self.head = self.body[0]
self.move_speed = 110 # Milliseconds
self.__prev_heading = self.head.heading() # Block simultaneous movement causing conflict
def __init_body(self):
t = Turtle(shape='square')
t.color('white')
t.penup()
t.setx(BODY_SIZE)
self.body.append(t)
for x in (0, -BODY_SIZE):
clone = t.clone()
clone.setx(x)
self.body.append(clone)
def up(self, is_paused=False):
if self.__prev_heading != DOWN and not is_paused:
self.head.setheading(UP)
def down(self, is_paused=False):
if self.__prev_heading != UP and not is_paused:
self.head.setheading(DOWN)
def left(self, is_paused=False):
if self.__prev_heading != RIGHT and not is_paused:
self.head.setheading(LEFT)
def right(self, is_paused=False):
if self.__prev_heading != LEFT and not is_paused:
self.head.setheading(RIGHT)
def move(self):
for i in range(len(self.body) - 1, 0, -1):
self.body[i].goto(self.body[i - 1].position())
# self.body[i].setheading(self.body[i - 1].heading())
self.head.forward(BODY_SIZE)
self.__prev_heading = self.head.heading()
def grow(self):
self.body.append(self.body[-1].clone())
# self.add_segment(self.body[-1].position())
def speed_up(self):
if self.move_speed > MAX_SPEED:
self.move_speed -= 10
def is_out_of_bound(self):
return abs(self.head.xcor()) > BORDER or abs(self.head.ycor()) > BORDER
def is_hit(self):
for fragment in self.body[1:]:
if self.head.distance(fragment) < 10:
return True
return False