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)