-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhelper.py
More file actions
156 lines (137 loc) · 6.2 KB
/
Copy pathhelper.py
File metadata and controls
156 lines (137 loc) · 6.2 KB
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
import numpy as np
import argparse
# Here we define some variables to determine the board size
DISPLAY_SIZE = 560
GRID_SIZE = 40
WALL_SIZE = 40
# Here we define some variables for the snake size with respect to the board
SNAKE_UNIT_SIZE = 40
BOARD_LIMIT_MIN = 40
BOARD_LIMIT_MAX = 480
IN_WALL_COORD = 520
# Here we define some variables to help draw the board
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
# Here we define more variables to help the snake with walls, food, and actions
NUM_ADJOINING_WALL_X_STATES=3
NUM_ADJOINING_WALL_Y_STATES=3
NUM_FOOD_DIR_X=3
NUM_FOOD_DIR_Y=3
NUM_ADJOINING_BODY_TOP_STATES=2
NUM_ADJOINING_BODY_BOTTOM_STATES=2
NUM_ADJOINING_BODY_LEFT_STATES=2
NUM_ADJOINING_BODY_RIGHT_STATES=2
NUM_ACTIONS = 4
# Here we define a bunch of variables that will determine training, testing and displaying the result
NUM_TRAIN_ITER = 5000
NUM_TEST_ITER = 1000
NUM_DISP_ITER = 5
NUM_TO_STAT = 1000
snake_head_x = 200
snake_head_y = 200
food_x = 120
food_y = 120
# Here we define a varibale to save the trained state.
MODEL_SAVE_FILE = 'model.npy'
MODEL_BEST_SAVE_FILE = 'model_best.npy'
# Here we define a function that checks if the Q array we created is in the proper format
# It doesn't check the values in the array, rather it only checks if the array has the
# correct internal parts based on which it returns true or false
# This function is useful to make sure the Q array isn't curropted when saving and loading
def np_error_checker(arr):
if (type(arr) is np.ndarray and
arr.shape==(NUM_ADJOINING_WALL_X_STATES, NUM_ADJOINING_WALL_Y_STATES, NUM_FOOD_DIR_X, NUM_FOOD_DIR_Y,
NUM_ADJOINING_BODY_TOP_STATES, NUM_ADJOINING_BODY_BOTTOM_STATES, NUM_ADJOINING_BODY_LEFT_STATES,
NUM_ADJOINING_BODY_RIGHT_STATES,NUM_ACTIONS)):
return True
else:
return False
# This function defines all the values to zero
# We use numpy arrays to store all this information
# We use the zeros function from numpy to initialize the values
def initialize_q_as_zeros():
return np.zeros((NUM_ADJOINING_WALL_X_STATES, NUM_ADJOINING_WALL_Y_STATES, NUM_FOOD_DIR_X, NUM_FOOD_DIR_Y,
NUM_ADJOINING_BODY_TOP_STATES, NUM_ADJOINING_BODY_BOTTOM_STATES, NUM_ADJOINING_BODY_LEFT_STATES,
NUM_ADJOINING_BODY_RIGHT_STATES, NUM_ACTIONS))
# Here we define a function to save the Q array that is passed to it. We run a quick check
# to verify the format before saving
def save(arr):
if np_error_checker(arr):
np.save(MODEL_SAVE_FILE,arr)
return True
else:
print("\t********UNABLE TO SAVE MODEL AS FILE********")
return False
def save_best(arr):
if np_error_checker(arr):
np.save(MODEL_BEST_SAVE_FILE,arr)
return True
else:
print("\t********UNABLE TO SAVE MODEL AS FILE********")
return False
# Here we define a function to load Q array. We again run a quick formt check after loading
def load():
try:
arr = np.load(MODEL_SAVE_FILE)
if np_error_checker(arr):
print("\t********MODEL IN " + MODEL_SAVE_FILE + " LOADED")
return arr
return None
except:
print("\t********MODEL FILE NAMED " + MODEL_SAVE_FILE + "NOT FOUND")
return None
# Here we define a function to load Q array. We again run a quick formt check after loading
def load_best():
try:
arr = np.load(MODEL_BEST_SAVE_FILE)
if np_error_checker(arr):
print("\t********MODEL IN " + MODEL_BEST_SAVE_FILE + " LOADED")
return arr
return None
except:
print("\t********MODEL FILE NAMED " + MODEL_BEST_SAVE_FILE + "NOT FOUND")
return None
# This function lets us create a bunch of arguements to pass so we can change initial game state
def make_args():
# Name for program
parser = argparse.ArgumentParser(description='CSE 140 Summer 21 Assignment 5')
# Number of training steps
parser.add_argument('--NTRI', dest="NUM_TRAIN_ITER", type=int, default=NUM_TRAIN_ITER,
help='Number of iterations run when training; set by default as NUM_TRAIN_ITER=5000')
# Number of testing steps
parser.add_argument('--NTEI', dest="NUM_TEST_ITER", type=int, default=NUM_TEST_ITER,
help='Number of iterations run when training; set by default as NUM_TEST_ITER=100')
# Number of games to display
parser.add_argument('--DISP', dest="NUM_DISP_ITER", type=int, default=5,
help='Number of runs displayed; set by default as NUM_DISP_ITER=1')
# Number of games to average statistics over
parser.add_argument('--STAT', dest="NUM_TO_STAT", type=int, default=NUM_TO_STAT,
help='Number of runs to take average statistics over; set by default as NUM_TO_STAT=100')
# Exploration parameter
parser.add_argument('--Ne', dest="Ne", type=int, default=40,
help='Parameter to help with next state exploration; set by default as Ne=40')
# Parameter to calculate learning rate
parser.add_argument('--LPC', dest="LPC", type=int, default=40,
help='Parameter to determine learning parameter during reinforcement learning; by default LPC=40')
# Parameter to calculate learning rate
parser.add_argument('--gamma', dest="gamma", type=float, default=0.7,
help='Parameter used in reinforcement learning; by default gamma=0.7')
# Starting X position of snake
parser.add_argument('--INIT_HEAD_X', dest="snake_head_x", type=int, default=200,
help='Initial X coordinate position of the snake head; by default snake_head_x=200')
# Starting Y position of snake
parser.add_argument('--INIT_HEAD_Y', dest="snake_head_y", type=int, default=200,
help='Initial Y coordinate position of the snake head; by default snake_head_y=200')
# Starting X position of food
parser.add_argument('--INIT_FOOD_X', dest="food_x", type=int, default=120,
help='Initial X coordinate position of the food; by default food_x=120')
# starting Y position of food
parser.add_argument('--INIT_FOOD_Y', dest="food_y", type=int, default=120,
help='Initial Y coordinate position of the food; by default food_y=120')
# Parse everything mentnoned above into args
args = parser.parse_args()
# return args
return args