Last active
March 3, 2018 21:37
-
-
Save chrisfosterelli/64b399bb67bcd0091964a394896c70d1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" Web application for serving agent """ | |
import time | |
import json | |
import bottle | |
import numpy as np | |
import battlesnake.agent | |
def map_state(player, state, width, height): | |
as_xy = lambda locs: [ { 'x': l[0], 'y': l[1] } for l in locs ] | |
enemy_snakes = [ s for s in state['snakes'] if s['id'] != player ] | |
player_snake = [ s for s in state['snakes'] if s['id'] == player ][0] | |
return { | |
'width': width, | |
'height': height, | |
'food': { | |
'data': as_xy(state['food']) | |
}, | |
'snakes': { | |
'data': [ { | |
'name': s['id'], | |
'body': { | |
'data': as_xy(s['locations']) | |
} | |
} for s in enemy_snakes ] | |
}, | |
'you': { | |
'health': player_snake['health'], | |
'body': { | |
'data': as_xy(player_snake['locations']) | |
} | |
} | |
} | |
agent = battlesnake.agent.Agent() | |
agent.load() | |
@bottle.route('/static/<path:path>') | |
def static(path): | |
return bottle.static_file(path, root='static/') | |
@bottle.post('/start') | |
def start(): | |
data = bottle.request.json | |
game_id = data['game_id'] | |
board_width = data['width'] | |
board_height = data['height'] | |
head_url = '%s://%s/static/head.png' % ( | |
bottle.request.urlparts.scheme, | |
bottle.request.urlparts.netloc | |
) | |
return { | |
'color': '#D5FD67', | |
'taunt': 'Whoooooops!', | |
'head_url': head_url, | |
'name': 'Silly Snake' | |
} | |
@bottle.post('/move') | |
def move(): | |
start = time.time() | |
data = bottle.request.json | |
totals = np.array([ 0 ] * 4) | |
deaths = np.array([ 0 ] * 4) | |
while (time.time() - start) < .150: | |
game = battlesnake.game.Game( | |
height=data['height'], width=data['width'], | |
food=0, snakes=0 | |
) | |
for food in data['food']['data']: | |
game.food.append([ food['x'], food['y'] ]) | |
for snake in data['snakes']['data']: | |
locations = [ [ p['x'], p['y'] ] for p in snake['body']['data'] ] | |
game.snakes.append({ | |
'locations': locations, | |
'id': snake['id'], | |
'health': snake['health'], | |
'alive': True | |
}) | |
for i in range(5): | |
moves = [] | |
for snake in game.snakes: | |
agent_state = map_state(snake['id'], game.get_state(), game.width, game.height) | |
move = agent.move(agent_state) | |
if i == 0 and snake['id'] == data['you']['id']: | |
if move == 'up': picked_move = 0 | |
if move == 'right': picked_move = 1 | |
if move == 'down': picked_move = 2 | |
if move == 'left': picked_move = 3 | |
moves.append((snake['id'], move)) | |
game.move(moves) | |
post_state = game.get_state() | |
alive_snakes = [ s['id'] for s in post_state['snakes'] ] | |
if data['you']['id'] not in alive_snakes: | |
deaths[picked_move] += 1 | |
break | |
totals[picked_move] += 1 | |
ratios = (totals - deaths) / totals | |
i = np.nanargmax(ratios) | |
print(ratios) | |
print(np.nanmax(ratios)) | |
print(ratios == np.nanmax(ratios)) | |
print((ratios == np.nanmax(ratios)).sum()) | |
if (ratios == ratios.max()).sum() > 1: | |
move = agent.move(data) | |
print('More than 1 equal move') | |
else: | |
if i == 0: move = 'up' | |
if i == 1: move = 'right' | |
if i == 2: move = 'down' | |
if i == 3: move = 'left' | |
end = time.time() | |
print('Response time', int((end - start)*1000),'ms') | |
print(sum(totals)) | |
return { | |
'move': move | |
} | |
run = bottle.app().run |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment