-
Notifications
You must be signed in to change notification settings - Fork 942
/
Copy pathmain.py
189 lines (169 loc) · 5.84 KB
/
main.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
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
185
186
187
188
189
# -*- coding: UTF-8 -*-
import time
import os
from random import randint
from getch import KBHit
class Snake:
def __init__(self, x, y):
self.parts = [[1, 1]]
self.length = 1
self.dir = 'd'
self.skins = ['O']
self.fruit = [randint(2, x), randint(2, y)]
self.size = [x, y]
self.print_in_coords()
def get_opposites(self):
return {"w": "s", "s": "w", "d": "a", "a":"d"}
def set_skins(self):
"""
This iterates each snake part, and based where the adjacent ones are,
it gives it a skin between the following: │ ─ └ ┐ ┌ ┘
"""
skins = ['O']
coords_subtraction = lambda a, b: [x1 - x2 for (x1, x2) in zip(a, b)]
for i in range(1, len(self.parts)):
if i == len(self.parts)-1:
a = self.parts[-2]
b = self.parts[-1]
else:
b = self.parts[i+1]
a = self.parts[i-1]
diff = coords_subtraction(a, b)
if diff[0] == 0:
skins.append('│')
elif diff[1] == 0:
skins.append('─')
else:
a = self.parts[i-1]
b = self.parts[i]
diff2 = coords_subtraction(a, b)
if sum(diff) == 0:
if sum(diff2) == 1:
skins.append('└')
else:
skins.append('┐')
else:
if diff2[1] == -1 or diff2[0] == 1:
skins.append('┌')
else:
skins.append('┘')
self.skins = skins
def print_in_coords(self):
"""
Prints the field of game with '·',
prints the snake body parts,
prints the fruit ('X')
"""
coords = self.parts
os.system('cls' if os.name == 'nt' else 'clear')
for i in range(self.size[1], 0, -1):
for j in range(1, self.size[0]+1):
if [j, i] in coords:
print(self.skins[coords.index([j, i])], end=' ')
elif [j, i] == self.fruit:
print('X', end=' ')
else:
print('·', end=' ')
print('')
def update_coors(self):
"""
Makes every part of the snake move to where the following was,
except the head, that moves to the direction the user input
"""
for i in range(len(self.parts)-1, 0, -1):
self.parts[i] = self.parts[i-1][:]
if self.dir == 'w':
self.parts[0][1] += 1
elif self.dir == 'd':
self.parts[0][0] += 1
elif self.dir == 's':
self.parts[0][1] -= 1
elif self.dir == 'a':
self.parts[0][0] -= 1
def check_fruit(self):
"""
Checks if the snake's head is in the same place as the fruit,
if so, the snake grows and another fruit is spawned
"""
if self.parts[0] == self.fruit:
self.grow()
self.generate_fruit()
def alive(self):
"""
Check if the head hit a body part or has crossed the limits
"""
head = self.parts[0]
if (head in self.parts[1:]) or (not(0 < head[0] <= self.size[0])) or (not(0 < head[1] <= self.size[1])):
return False
return True
def get_action(self, character):
if (character in 'wasd') and (self.get_opposites()[character] != self.dir or len(self.parts) == 1):
self.dir = character
self.update_coors()
self.check_fruit()
self.set_skins()
self.print_in_coords()
return self.alive()
def generate_fruit(self):
new_coords = [randint(1,self.size[0]), randint(1,self.size[1])]
if new_coords in self.parts:
self.generate_fruit()
else:
self.fruit = new_coords
def grow(self):
if len(self.parts) > 1:
last = self.parts[-1]
sec_last = self.parts[-2]
diff = [x1 - x2 for (x1, x2) in zip(sec_last, last)]
if diff[0] == 0:
if diff[1] > 0:
self.parts.append([last[0], last[1]-1])
else:
self.parts.append([last[0], last[1]+1])
elif diff[0] > 0:
self.parts.append([last[0]-1, last[1]])
else:
self.parts.append([last[0]+1, last[1]])
else:
head = self.parts[0]
if self.dir == 'w':
self.parts.append([head[0], head[1]-1])
elif self.dir == 'd':
self.parts.append([head[0]-1, head[1]])
elif self.dir == 's':
self.parts.append([head[0], head[1]+1])
elif self.dir == 'a':
self.parts.append([head[0]+1, head[1]])
self.length += 1
def main():
snake = Snake(15, 10) # This means the game field is 15x10
update_time = .125 # This is how much time there is between updates, 1/update_time = fps
keep_playing = True
kb = KBHit()
while keep_playing:
t = 0
key_stroke = ' '
while t < update_time:
start = time.time()
if kb.kbhit():
key_stroke = kb.getch()
end = time.time()
t += end - start
keep_playing = snake.get_action(key_stroke)
if snake.size[0] * snake.size[1] <= snake.length:
print('You win!')
break
kb.set_normal_term()
print('Score:', snake.length)
while True:
again = input('Keep playing? (y/n) ')
if again.lower() == 'y':
main()
break
elif again.lower() == 'n':
print('Bye')
break
else:
print('Input a valid answer')
if __name__ == "__main__":
main()