-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsnake_game_3s.py
114 lines (96 loc) · 3.25 KB
/
snake_game_3s.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
import curses
from random import randint
class SnakeGame:
def __init__(self, board_width = 20, board_height = 20, gui = False):
self.score = 0
self.snake_init_length = 3
self.done = False
self.board = {'width': board_width, 'height': board_height}
self.gui = gui
def start(self):
self.snake_init()
self.generate_food()
if self.gui: self.render_init()
return self.generate_observations()
def snake_init(self):
x = randint(5, self.board["width"] - 5)
y = randint(5, self.board["height"] - 5)
self.snake = []
vertical = randint(0,1) == 0
for i in range(self.snake_init_length):
point = [x + i, y] if vertical else [x, y + i]
self.snake.insert(0, point)
def generate_food(self):
food = []
while food == []:
food = [randint(1, self.board["width"]), randint(1, self.board["height"])]
if food in self.snake: food = []
self.food = food
def render_init(self):
curses.initscr()
win = curses.newwin(self.board["width"] + 2, self.board["height"] + 2, 0, 0)
curses.curs_set(0)
win.nodelay(1)
win.timeout(200)
self.win = win
self.render()
def render(self):
self.win.clear()
self.win.border(0)
self.win.addstr(0, 2, 'Score : ' + str(self.score) + ' ')
self.win.addch(self.food[0], self.food[1], 'o')
for i, point in enumerate(self.snake):
if i == 0:
self.win.addch(point[0], point[1], 'X')
else:
self.win.addch(point[0], point[1], 'x')
self.win.getch()
def step(self, key):
# 0 - UP
# 1 - RIGHT
# 2 - DOWN
# 3 - LEFT
if self.done == True: self.end_game()
self.create_new_point(key)
if self.food_eaten():
self.score += 1
self.generate_food()
else:
self.remove_last_point()
self.check_collisions()
if self.gui: self.render()
return self.generate_observations()
def create_new_point(self, key):
new_point = [self.snake[0][0], self.snake[0][1]]
if key == 0:
new_point[0] -= 1
elif key == 1:
new_point[1] += 1
elif key == 2:
new_point[0] += 1
elif key == 3:
new_point[1] -= 1
self.snake.insert(0, new_point)
def remove_last_point(self):
self.snake.pop()
def food_eaten(self):
return self.snake[0] == self.food
def check_collisions(self):
if (self.snake[0][0] == 0 or
self.snake[0][0] == self.board["width"] + 1 or
self.snake[0][1] == 0 or
self.snake[0][1] == self.board["height"] + 1 or
self.snake[0] in self.snake[1:-1]):
self.done = True
def generate_observations(self):
return self.done, self.score, self.snake, self.food
def render_destroy(self):
curses.endwin()
def end_game(self):
if self.gui: self.render_destroy()
raise Exception("Game over")
if __name__ == "__main__":
game = SnakeGame(gui = True)
game.start()
for _ in range(20):
game.step(randint(0,3))