-
Notifications
You must be signed in to change notification settings - Fork 4
/
snake_headless.py
178 lines (140 loc) · 5.65 KB
/
snake_headless.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
import pygame, sys, time, random
import numpy as np
from time import sleep
#Headless version for training that disables fps limit and graphics
screenSize = {'x': 500,'y':500}
FPS = 100
direction = 'RIGHT'
change_to = direction
colors = {
'black': pygame.Color(0, 0, 0),
'white': pygame.Color(255, 255, 255),
'red': pygame.Color(255, 0, 0),
'green':pygame.Color(0, 255, 0),
'darkGreen':pygame.Color(50, 200, 50),
'blue': pygame.Color(0, 0, 255)
}
init_pos_x = random.randrange(1, (screenSize['x']//10)) * 10
init_pos_y = random.randrange(1, (screenSize['y']//10)) * 10
snake_pos = [init_pos_x, init_pos_y]
snake_body = [[init_pos_x, init_pos_y], [init_pos_x-10, init_pos_y], [init_pos_x-(2*10), init_pos_y]]
food_pos = [random.randrange(1, (screenSize['x']//10)) * 10, random.randrange(1, (screenSize['y']//10)) * 10]
#food_pos = [20,30]
score = 0
food_spawn = True
def newGame():
global snake_pos, food_pos, score, food_spawn, snake_body
init_pos_x = random.randrange(1, (screenSize['x']//10)) * 10
init_pos_y = random.randrange(1, (screenSize['y']//10)) * 10
snake_pos = [init_pos_x, init_pos_y]
snake_body = [[init_pos_x, init_pos_y], [init_pos_x-10, init_pos_y], [init_pos_x-(2*10), init_pos_y]]
food_pos = [random.randrange(1, (screenSize['x']//10)) * 10, random.randrange(1, (screenSize['y']//10)) * 10]
food_spawn = True
score = 0
def main(emulate, onGameOver, onScore):
# Checks for errors encountered
check_errors = pygame.init()
# pygame.init() example output -> (6, 0)
# second number in tuple gives number of errors
if check_errors[1] > 0:
#print(f'[!] Had {check_errors[1]} errors when initialising game, exiting...')
sys.exit(-1)
else:
#print('[+] Game successfully initialised')
pass
mainGame(emulate, onGameOver, onScore)
moveCounter = 0
moves = []
moveSinceScore = 0
def mainGame(emulate, onGameOver, onScore):
global moveCounter, moves, moveSinceScore
global food_pos, food_spawn, snake_body, snake_pos, score, colors, screenSize, direction, change_to
moveCounter = 0
while True:
#calc diff between food and snake head
diff = [snake_pos[0]-food_pos[0], snake_pos[1] - food_pos[1]]
diff = abs(diff[0] + diff[1])
#params that get converted to state (not all of them)
params = {
'food_pos': food_pos,
'snake_pos': snake_pos,
'snake_body': snake_body,
'score': score,
'diff':diff,
'screenSizeX': screenSize['x'],
'screenSizeY': screenSize['y'],
'moveSinceScore': moveSinceScore
}
######## emulate keyPresses ##########
#call emulate function in qlearning.py, returns direction
choosenDirection = emulate(params)
if choosenDirection == 'U':
change_to = 'UP'
moveCounter += 1
moves.append(moveCounter)
moveSinceScore += 1
if choosenDirection == 'D':
change_to = 'DOWN'
moveCounter += 1
moves.append(moveCounter)
moveSinceScore += 1
if choosenDirection == 'L':
change_to = 'LEFT'
moveCounter += 1
moves.append(moveCounter)
moveSinceScore += 1
if choosenDirection == 'R':
change_to = 'RIGHT'
moveCounter += 1
moves.append(moveCounter)
moveSinceScore += 1
# Making sure the snake cannot move in the opposite direction instantaneously
if change_to == 'UP' and direction != 'DOWN':
direction = 'UP'
if change_to == 'DOWN' and direction != 'UP':
direction = 'DOWN'
if change_to == 'LEFT' and direction != 'RIGHT':
direction = 'LEFT'
if change_to == 'RIGHT' and direction != 'LEFT':
direction = 'RIGHT'
# Moving the snake
if direction == 'UP':
snake_pos[1] -= 10
if direction == 'DOWN':
snake_pos[1] += 10
if direction == 'LEFT':
snake_pos[0] -= 10
if direction == 'RIGHT':
snake_pos[0] += 10
# Snake body growing mechanism
snake_body.insert(0, list(snake_pos))
if snake_pos[0] == food_pos[0] and snake_pos[1] == food_pos[1]:
score += 1
moveSinceScore = 0
onScore(params)
food_spawn = False
else:
snake_body.pop()
# Spawning food on the screen
if not food_spawn:
food_pos = [random.randrange(1, (screenSize['x']//10)) * 10, random.randrange(1, (screenSize['y']//10)) * 10]
for x in snake_body: #when food spawns in snake body --> new position
while (food_pos == x):
food_pos = [random.randrange(1, (screenSize['x']//10)) * 10, random.randrange(1, (screenSize['y']//10)) * 10]
food_spawn = True
# Game Over conditions
# Getting out of bounds
if snake_pos[0] < 0 or snake_pos[0] > screenSize['x']-10:
game_over(emulate, colors, score, screenSize, onGameOver)
if snake_pos[1] < 0 or snake_pos[1] > screenSize['y']-10:
game_over(emulate, colors, score, screenSize, onGameOver)
# Touching the snake body
for block in snake_body[1:]:
if snake_pos[0] == block[0] and snake_pos[1] == block[1]:
game_over(emulate, colors, score, screenSize, onGameOver)
# Game Over
def game_over(emulate, colors, score, screenSize, onGameOver):
global moves, moveCounter
moveCounter = 0
onGameOver(score, moves)
newGame()