intelli-snake / utility.py
geetu040's picture
uploading api
b697ed4
import json, random
import numpy as np
from keras.models import model_from_json
# GETTING THE MODELS
with open("models/random_model.json", "r") as f:
random_model = model_from_json(f.read())
random_model.load_weights("models/random_model.h5")
with open("models/fixed_model.json", "r") as f:
fixed_model = model_from_json(f.read())
fixed_model.load_weights("models/fixed_model.h5")
models = {
"fixed": fixed_model,
"random": random_model,
}
# GETTING THE MAP
with open("binary_map.json", "r") as f:
fixed_map = json.loads(f.read())
rows = 31
cols = 28
# FUNCTTIONS FOR AUTOMATION
def automate_faster(info):
infos = []
for i in range(info['automated_infos_count']):
dirs = automate(info, stringify_dirs=False)
for dir in dirs:
if move(info, dir): break
info['second_pref_count'] += 1
print("SECOND PREFERENCE USED")
new_info = {}
for key, value in info.items():
if key == 'map':
new_info[key] = value.copy()
else:
new_info[key] = value
infos.append(new_info)
return infos
def move(info, dir):
h = info['map'].index(3)
if dir == 0: n = h-cols
if dir == 1: n = h-1
if dir == 2: n = h+cols
if dir == 3: n = h+1
# IF FOOD IS EATEN
if (info['map'][n] == 2):
# updating board
info['score'] += 1
info['parts'] += 1
info['steps'] = 0
info['map'][n] = info['parts']+3
# placing food randomly
if info['map_type'] == 'random':
info = load_map(info)
return info
else:
info = randomize(info, head=False, food=True)
# r = random.randint(0, 31*28-1)
# while (info['map'][r] != 0): r = random.randint(0, 31*28-1)
# info['map'][r] = 2
# IF SNAKE HITS THE BODY
if (info['map'][n] > 4 and info['map'][n] != info['parts']+3 and not info['evade_bite']):
parts_to_remove = (info['parts']+3) - info['map'][n]
for i in range(parts_to_remove):
info['map'][info['map'].index(info['parts']-i+3)] = 0
info['parts'] -= parts_to_remove
info['fouls'] += 1
# MOVING THE BODY
if ( info['map'][n] != 1 and info['map'][n] != 3 and info['map'][n] != 4 ):
for i in range(info['parts']+1):
try:
cache_n = info['map'].index(3+i)
info['map'][cache_n] = 0
info['map'][n] = 3+i
n = cache_n
except:
info['map'][n] = 3+i
info['steps'] += 1
if info['steps'] > info['steps_limit']:
info['steps'] = 0
info['fouls'] += 1
# placing food randomly
info = randomize(info, head=False, food=True)
return True
return False
def automate(info, stringify_dirs=True):
x = preprocessing(info['map'], info['map_type'])
y = models[info['map_type']].predict(x)
dirs = postprocess(y)
if stringify_dirs: return str(dirs)
else: return dirs
def preprocessing(x, type):
x = np.array(x).reshape(31, 28, 1)
food_x, food_y = np.where(x == 2)[1], np.where(x == 2)[0]
head_x, head_y = np.where(x == 3)[1], np.where(x == 3)[0]
possible_dirs = np.array([[0, 0, 0, 0]])
try: possible_dirs[0, 0] = int(x[head_y-1, head_x] == 0 or x[head_y-1, head_x] == 2)
except: pass
try: possible_dirs[0, 1] = int(x[head_y, head_x-1] == 0 or x[head_y, head_x-1] == 2)
except: pass
try: possible_dirs[0, 2] = int(x[head_y+1, head_x] == 0 or x[head_y+1, head_x] == 2)
except: pass
try: possible_dirs[0, 3] = int(x[head_y, head_x+1] == 0 or x[head_y, head_x+1] == 2)
except: pass
possitions = np.array([[head_x[0]/27, head_y[0]/30, food_x[0]/27, food_y[0]/30]])
if type == 'random':
maps = np.where(x == 1, 1, 0).reshape(1, 31, 28, 1)
x = [maps, possitions, possible_dirs]
elif type == 'fixed':
x = [possitions, possible_dirs]
return x
def postprocess(y):
dirs = [0, 0, 0, 0]
y = y[0]
for i in range(4):
dirs[i] = np.argmax(y)
y[np.argmax(y)] = -1
return dirs
# FUNCTIONS FOR MAPS
def load_map(info):
if info['map_type'] == 'fixed':
info['map'] = fixed_map[:]
elif info['map_type'] == 'random':
info['map'] = [1]*rows*cols
info['map'] = add_rects(info['map'], times=8, cross=False, d=8)
info = randomize(info, head=True, food=True)
return info
def randomize(info, head, food):
if food:
# finding possition
r = random.randint(0, rows*cols -1)
while info['map'][r] != 0:
r = random.randint(0, rows*cols-1)
# removing previous
try: info['map'][info['map'].index(2)] = 0
except: pass
# adding new
info['map'][r] = 2
if head:
# removing previous
for i in range(info['parts']+1):
try:info['map'][info['map'].index(3+i)] = 0
except: pass
# finding possition
r = random.randint(0, rows*cols -1)
while info['map'][r] != 0:
r = random.randint(0, rows*cols-1)
# adding head
info['map'][r] = 3
# adding body
prev = r
for part in range(info['parts']):
dirs = [prev-1, prev+1, prev-cols, prev+cols]
r = random.choice(dirs)
while info['map'][r] != 0:
dirs.remove(r)
if len(dirs) == 0:
return randomize(info, head, food)
r = random.choice(dirs)
info['map'][r] = 4+part
prev = r
if info['map'][info['map'].index(3)+1] != 0 and info['map'][info['map'].index(3)-1] != 0 and info['map'][info['map'].index(3)+cols] != 0 and info['map'][info['map'].index(3)-cols] != 0:
return randomize(info, head, food)
return info
def add_rects(map, times=1, d=5, cross=False):
map = np.array(map).reshape(rows, cols)
x1, y1 = random.randint(1, cols-2-d), random.randint(1, rows-2-d)
x2, y2 = random.randint(x1+d, cols-2), random.randint(y1+d, rows-2)
for x in range(x2-x1+1):
map[y1, x1+x] = 0
map[y2, x1+x] = 0
if cross:
map[(y1+y2)//2, x1+x] = 0
for y in range(y2-y1+1):
map[y1+y, x2] = 0
map[y1+y, x1] = 0
if cross:
map[y1+y, (x1+x2)//2] = 0
if times == 1: return map.ravel().tolist()
else: return add_rects(map=map, times=times-1, d=d, cross=cross)