apply clippy suggestions

This commit is contained in:
Ilion Beyst 2022-03-13 15:20:03 +01:00
parent f7655005ff
commit fd52e266c6
19 changed files with 157 additions and 62 deletions

View file

@ -0,0 +1 @@
SYNTAX IS OVER PARTY

View file

@ -0,0 +1,33 @@
import sys, json
def move(command):
""" print a command record to stdout """
moves = []
if command is not None:
moves.append(command)
print(json.dumps({ 'moves': moves }))
# flush the buffer, so that the gameserver can receive the json-encoded line.
sys.stdout.flush()
for line in sys.stdin:
state = json.loads(line)
# you are always player 1.
my_planets = [p for p in state['planets'] if p['owner'] == 1]
other_planets = [p for p in state['planets'] if p['owner'] != 1]
if not my_planets or not other_planets:
# we don't own any planets, so we can't make any moves.
move(None)
else:
# find my planet that has the most ships
planet = max(my_planets, key=lambda p: p['ship_count'])
# find enemy planet that has the least ships
destination = min(other_planets, key=lambda p: p['ship_count'])
# attack!
move({
'origin': planet['name'],
'destination': destination['name'],
'ship_count': planet['ship_count'] - 1
})

View file

@ -0,0 +1,56 @@
{"type":"stderr","player_id":2,"message":" File \"/workdir/bot.py\", line 1"}
{"type":"stderr","player_id":2,"message":" SYNTAX IS OVER PARTY"}
{"type":"stderr","player_id":2,"message":" ^^"}
{"type":"stderr","player_id":2,"message":"SyntaxError: invalid syntax"}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":6,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":7,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":0,"ship_count":5,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":5}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":6,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":8,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":0,"ship_count":5,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":4},{"id":1,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":5}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":6,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":9,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":0,"ship_count":5,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":3},{"id":1,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":4},{"id":2,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":5}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":6,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":10,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":0,"ship_count":5,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":2},{"id":1,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":3},{"id":2,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":4},{"id":3,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":5}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":6,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":11,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":0,"ship_count":5,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":1},{"id":1,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":2},{"id":2,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":3},{"id":3,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":4},{"id":4,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":5}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":1,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":12,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":5,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":5},{"id":1,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":1},{"id":2,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":2},{"id":3,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":3},{"id":4,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":4}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":0,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":13,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":5,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":4},{"id":6,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":5},{"id":2,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":1},{"id":3,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":2},{"id":4,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":3}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":1,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":14,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":5,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":3},{"id":6,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":4},{"id":7,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":5},{"id":3,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":1},{"id":4,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":2}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":15,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":5,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":2},{"id":6,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":3},{"id":7,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":4},{"id":8,"ship_count":1,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":10},{"id":4,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":1}]}
{"type":"gamestate","planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":16,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":5,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":1},{"id":6,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":2},{"id":7,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":3},{"id":8,"ship_count":1,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":9},{"id":9,"ship_count":2,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":5}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":5,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":17,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":10,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":10},{"id":6,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":1},{"id":7,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":2},{"id":8,"ship_count":1,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":8},{"id":9,"ship_count":2,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":4}]}
{"type":"gamestate","planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":18,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":10,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":9},{"id":11,"ship_count":4,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":5},{"id":7,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":1},{"id":8,"ship_count":1,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":7},{"id":9,"ship_count":2,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":3}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":5,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":19,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":10,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":8},{"id":11,"ship_count":4,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":4},{"id":12,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":10},{"id":8,"ship_count":1,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":6},{"id":9,"ship_count":2,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":2}]}
{"type":"gamestate","planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":2,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":20,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":10,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":7},{"id":11,"ship_count":4,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":3},{"id":12,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":9},{"id":8,"ship_count":1,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":5},{"id":9,"ship_count":2,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":1},{"id":13,"ship_count":4,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":5}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":4,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":21,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":10,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":6},{"id":11,"ship_count":4,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":2},{"id":12,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":8},{"id":8,"ship_count":1,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":4},{"id":14,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":10},{"id":13,"ship_count":4,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":4}]}
{"type":"gamestate","planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":2,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":4,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":22,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":10,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":5},{"id":11,"ship_count":4,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":1},{"id":12,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":7},{"id":8,"ship_count":1,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":3},{"id":14,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":9},{"id":13,"ship_count":4,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":3},{"id":15,"ship_count":2,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":5}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":0,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":23,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":10,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":4},{"id":16,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":10},{"id":12,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":6},{"id":8,"ship_count":1,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":2},{"id":14,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":8},{"id":13,"ship_count":4,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":2},{"id":15,"ship_count":2,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":4}]}
{"type":"gamestate","planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":2,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":0,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":24,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":10,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":3},{"id":16,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":9},{"id":12,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":5},{"id":8,"ship_count":1,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":1},{"id":14,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":7},{"id":13,"ship_count":4,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":1},{"id":15,"ship_count":2,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":3},{"id":17,"ship_count":2,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":5}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":5,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":25,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":10,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":2},{"id":16,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":8},{"id":12,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":4},{"id":18,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":10},{"id":14,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":6},{"id":17,"ship_count":2,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":4},{"id":15,"ship_count":2,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":2}]}
{"type":"gamestate","planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":4,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":2,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":26,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":10,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":1},{"id":16,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":7},{"id":12,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":3},{"id":18,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":9},{"id":14,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":5},{"id":17,"ship_count":2,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":3},{"id":15,"ship_count":2,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":1},{"id":19,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":9}]}
{"type":"gamestate","planets":[{"ship_count":4,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":2,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":7,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":27,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":20,"ship_count":3,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":11},{"id":16,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":6},{"id":12,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":2},{"id":18,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":8},{"id":14,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":4},{"id":17,"ship_count":2,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":2},{"id":19,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":8}]}
{"type":"gamestate","planets":[{"ship_count":5,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":2,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":28,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":20,"ship_count":3,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":10},{"id":16,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":5},{"id":12,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":1},{"id":18,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":7},{"id":14,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":3},{"id":17,"ship_count":2,"origin":"duteros","destination":"tritos","owner":1,"turns_remaining":1},{"id":19,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":7},{"id":21,"ship_count":6,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":9}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":4,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":7,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":29,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":20,"ship_count":3,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":9},{"id":16,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":4},{"id":22,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":10},{"id":18,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":6},{"id":14,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":2},{"id":21,"ship_count":6,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":8},{"id":19,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":6}]}
{"type":"gamestate","planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":5,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":2,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":30,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":20,"ship_count":3,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":8},{"id":16,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":3},{"id":22,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":9},{"id":18,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":5},{"id":14,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":1},{"id":21,"ship_count":6,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":7},{"id":19,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":5},{"id":23,"ship_count":6,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":9}]}
{"type":"gamestate","planets":[{"ship_count":4,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":2,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":5,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":31,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":20,"ship_count":3,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":7},{"id":16,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":2},{"id":22,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":8},{"id":18,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":4},{"id":24,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":11},{"id":21,"ship_count":6,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":6},{"id":19,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":4},{"id":23,"ship_count":6,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":8}]}
{"type":"gamestate","planets":[{"ship_count":5,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":2,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":32,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":20,"ship_count":3,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":6},{"id":16,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":1},{"id":22,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":7},{"id":18,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":3},{"id":24,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":10},{"id":21,"ship_count":6,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":5},{"id":19,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":3},{"id":23,"ship_count":6,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":7},{"id":25,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":9}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":4,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":5,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":33,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":20,"ship_count":3,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":5},{"id":26,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":10},{"id":22,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":6},{"id":18,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":2},{"id":24,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":9},{"id":21,"ship_count":6,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":4},{"id":19,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":2},{"id":23,"ship_count":6,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":6},{"id":25,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":8}]}
{"type":"gamestate","planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":5,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":2,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":34,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":20,"ship_count":3,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":4},{"id":26,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":9},{"id":22,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":5},{"id":18,"ship_count":2,"origin":"protos","destination":"tritos","owner":1,"turns_remaining":1},{"id":24,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":8},{"id":21,"ship_count":6,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":3},{"id":19,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":1},{"id":23,"ship_count":6,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":5},{"id":25,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":7},{"id":27,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":9}]}
{"type":"gamestate","planets":[{"ship_count":4,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":2,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":5,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":35,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":2,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":20,"ship_count":3,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":3},{"id":26,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":8},{"id":22,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":4},{"id":28,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":11},{"id":24,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":7},{"id":21,"ship_count":6,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":2},{"id":27,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":8},{"id":23,"ship_count":6,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":4},{"id":25,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":6}]}
{"type":"gamestate","planets":[{"ship_count":5,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":2,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":36,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":2,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":20,"ship_count":3,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":2},{"id":26,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":7},{"id":22,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":3},{"id":28,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":10},{"id":24,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":6},{"id":21,"ship_count":6,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":1},{"id":27,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":7},{"id":23,"ship_count":6,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":3},{"id":25,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":5},{"id":29,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":9}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":4,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":3,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":37,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":4,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":20,"ship_count":3,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":1},{"id":26,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":6},{"id":22,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":2},{"id":28,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":9},{"id":24,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":5},{"id":30,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":10},{"id":27,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":6},{"id":23,"ship_count":6,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":2},{"id":25,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":4},{"id":29,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":8}]}
{"type":"gamestate","planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":2,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":4,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":38,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":8,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":31,"ship_count":3,"origin":"duteros","destination":"extos","owner":1,"turns_remaining":9},{"id":26,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":5},{"id":22,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":1},{"id":28,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":8},{"id":24,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":4},{"id":30,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":9},{"id":27,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":5},{"id":23,"ship_count":6,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":1},{"id":25,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":3},{"id":29,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":7}]}
{"type":"gamestate","planets":[{"ship_count":4,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":5,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":39,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":12,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":31,"ship_count":3,"origin":"duteros","destination":"extos","owner":1,"turns_remaining":8},{"id":26,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":4},{"id":32,"ship_count":7,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":5},{"id":28,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":7},{"id":24,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":3},{"id":30,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":8},{"id":27,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":4},{"id":29,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":6},{"id":25,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":2}]}
{"type":"gamestate","planets":[{"ship_count":5,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":4,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":40,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":2,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":31,"ship_count":3,"origin":"duteros","destination":"extos","owner":1,"turns_remaining":7},{"id":26,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":3},{"id":32,"ship_count":7,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":4},{"id":28,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":6},{"id":24,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":2},{"id":30,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":7},{"id":27,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":3},{"id":29,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":5},{"id":25,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":1},{"id":33,"ship_count":11,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":5}]}
{"type":"gamestate","planets":[{"ship_count":6,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":5,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":2,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":41,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":7,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":31,"ship_count":3,"origin":"duteros","destination":"extos","owner":1,"turns_remaining":6},{"id":26,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":2},{"id":32,"ship_count":7,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":3},{"id":28,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":5},{"id":24,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":1},{"id":30,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":6},{"id":27,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":2},{"id":29,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":4},{"id":34,"ship_count":5,"origin":"tritos","destination":"extos","owner":1,"turns_remaining":11},{"id":33,"ship_count":11,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":4}]}
{"type":"gamestate","planets":[{"ship_count":7,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":6,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":3,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":42,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":31,"ship_count":3,"origin":"duteros","destination":"extos","owner":1,"turns_remaining":5},{"id":26,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":1},{"id":32,"ship_count":7,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":2},{"id":28,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":4},{"id":35,"ship_count":6,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":5},{"id":30,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":5},{"id":27,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":1},{"id":29,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":3},{"id":34,"ship_count":5,"origin":"tritos","destination":"extos","owner":1,"turns_remaining":10},{"id":33,"ship_count":11,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":3}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":7,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":4,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":43,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":15,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":31,"ship_count":3,"origin":"duteros","destination":"extos","owner":1,"turns_remaining":4},{"id":36,"ship_count":6,"origin":"protos","destination":"extos","owner":1,"turns_remaining":5},{"id":32,"ship_count":7,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":1},{"id":28,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":3},{"id":35,"ship_count":6,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":4},{"id":30,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":4},{"id":33,"ship_count":11,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":2},{"id":29,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":2},{"id":34,"ship_count":5,"origin":"tritos","destination":"extos","owner":1,"turns_remaining":9}]}
{"type":"gamestate","planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":8,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":5,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":44,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":2,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":1,"x":-3.0,"y":-5.0,"owner":1,"name":"extos"}],"expeditions":[{"id":31,"ship_count":3,"origin":"duteros","destination":"extos","owner":1,"turns_remaining":3},{"id":36,"ship_count":6,"origin":"protos","destination":"extos","owner":1,"turns_remaining":4},{"id":37,"ship_count":14,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":5},{"id":28,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":2},{"id":35,"ship_count":6,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":3},{"id":30,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":3},{"id":33,"ship_count":11,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":1},{"id":29,"ship_count":4,"origin":"tritos","destination":"pemptos","owner":1,"turns_remaining":1},{"id":34,"ship_count":5,"origin":"tritos","destination":"extos","owner":1,"turns_remaining":8}]}
{"type":"gamestate","planets":[{"ship_count":4,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":2,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":45,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":7,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":13,"x":-3.0,"y":-5.0,"owner":1,"name":"extos"}],"expeditions":[{"id":31,"ship_count":3,"origin":"duteros","destination":"extos","owner":1,"turns_remaining":2},{"id":36,"ship_count":6,"origin":"protos","destination":"extos","owner":1,"turns_remaining":3},{"id":37,"ship_count":14,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":4},{"id":28,"ship_count":4,"origin":"duteros","destination":"pemptos","owner":1,"turns_remaining":1},{"id":35,"ship_count":6,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":2},{"id":30,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":2},{"id":38,"ship_count":7,"origin":"duteros","destination":"tetartos","owner":1,"turns_remaining":10},{"id":34,"ship_count":5,"origin":"tritos","destination":"extos","owner":1,"turns_remaining":7}]}
{"type":"gamestate","planets":[{"ship_count":5,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":7,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":46,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":12,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":2,"x":-3.0,"y":-5.0,"owner":1,"name":"extos"}],"expeditions":[{"id":31,"ship_count":3,"origin":"duteros","destination":"extos","owner":1,"turns_remaining":1},{"id":36,"ship_count":6,"origin":"protos","destination":"extos","owner":1,"turns_remaining":2},{"id":37,"ship_count":14,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":3},{"id":39,"ship_count":12,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":10},{"id":35,"ship_count":6,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":1},{"id":30,"ship_count":4,"origin":"protos","destination":"pemptos","owner":1,"turns_remaining":1},{"id":38,"ship_count":7,"origin":"duteros","destination":"tetartos","owner":1,"turns_remaining":9},{"id":34,"ship_count":5,"origin":"tritos","destination":"extos","owner":1,"turns_remaining":6}]}
{"type":"gamestate","planets":[{"ship_count":6,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":4,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":8,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":47,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":12,"x":-3.0,"y":-5.0,"owner":1,"name":"extos"}],"expeditions":[{"id":40,"ship_count":11,"origin":"pemptos","destination":"tetartos","owner":1,"turns_remaining":5},{"id":36,"ship_count":6,"origin":"protos","destination":"extos","owner":1,"turns_remaining":1},{"id":37,"ship_count":14,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":2},{"id":39,"ship_count":12,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":9},{"id":34,"ship_count":5,"origin":"tritos","destination":"extos","owner":1,"turns_remaining":5},{"id":38,"ship_count":7,"origin":"duteros","destination":"tetartos","owner":1,"turns_remaining":8}]}
{"type":"gamestate","planets":[{"ship_count":7,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":5,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":9,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":48,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":7,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":8,"x":-3.0,"y":-5.0,"owner":1,"name":"extos"}],"expeditions":[{"id":40,"ship_count":11,"origin":"pemptos","destination":"tetartos","owner":1,"turns_remaining":4},{"id":41,"ship_count":11,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":10},{"id":37,"ship_count":14,"origin":"pemptos","destination":"extos","owner":1,"turns_remaining":1},{"id":39,"ship_count":12,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":8},{"id":34,"ship_count":5,"origin":"tritos","destination":"extos","owner":1,"turns_remaining":4},{"id":38,"ship_count":7,"origin":"duteros","destination":"tetartos","owner":1,"turns_remaining":7}]}
{"type":"gamestate","planets":[{"ship_count":8,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":6,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":2,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":49,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":8,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":23,"x":-3.0,"y":-5.0,"owner":1,"name":"extos"}],"expeditions":[{"id":40,"ship_count":11,"origin":"pemptos","destination":"tetartos","owner":1,"turns_remaining":3},{"id":41,"ship_count":11,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":9},{"id":42,"ship_count":8,"origin":"tritos","destination":"tetartos","owner":1,"turns_remaining":5},{"id":39,"ship_count":12,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":7},{"id":34,"ship_count":5,"origin":"tritos","destination":"extos","owner":1,"turns_remaining":3},{"id":38,"ship_count":7,"origin":"duteros","destination":"tetartos","owner":1,"turns_remaining":6}]}
{"type":"gamestate","planets":[{"ship_count":9,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":7,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":3,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":50,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":9,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":2,"x":-3.0,"y":-5.0,"owner":1,"name":"extos"}],"expeditions":[{"id":40,"ship_count":11,"origin":"pemptos","destination":"tetartos","owner":1,"turns_remaining":2},{"id":41,"ship_count":11,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":8},{"id":42,"ship_count":8,"origin":"tritos","destination":"tetartos","owner":1,"turns_remaining":4},{"id":39,"ship_count":12,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":6},{"id":34,"ship_count":5,"origin":"tritos","destination":"extos","owner":1,"turns_remaining":2},{"id":38,"ship_count":7,"origin":"duteros","destination":"tetartos","owner":1,"turns_remaining":5},{"id":43,"ship_count":22,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":10}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":8,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":4,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":51,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":10,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":3,"x":-3.0,"y":-5.0,"owner":1,"name":"extos"}],"expeditions":[{"id":40,"ship_count":11,"origin":"pemptos","destination":"tetartos","owner":1,"turns_remaining":1},{"id":41,"ship_count":11,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":7},{"id":42,"ship_count":8,"origin":"tritos","destination":"tetartos","owner":1,"turns_remaining":3},{"id":39,"ship_count":12,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":5},{"id":34,"ship_count":5,"origin":"tritos","destination":"extos","owner":1,"turns_remaining":1},{"id":38,"ship_count":7,"origin":"duteros","destination":"tetartos","owner":1,"turns_remaining":4},{"id":43,"ship_count":22,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":9},{"id":44,"ship_count":8,"origin":"protos","destination":"tetartos","owner":1,"turns_remaining":11}]}
{"type":"gamestate","planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":9,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":5,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":41,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":2,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":9,"x":-3.0,"y":-5.0,"owner":1,"name":"extos"}],"expeditions":[{"id":45,"ship_count":9,"origin":"pemptos","destination":"tetartos","owner":1,"turns_remaining":5},{"id":41,"ship_count":11,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":6},{"id":42,"ship_count":8,"origin":"tritos","destination":"tetartos","owner":1,"turns_remaining":2},{"id":39,"ship_count":12,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":4},{"id":44,"ship_count":8,"origin":"protos","destination":"tetartos","owner":1,"turns_remaining":10},{"id":38,"ship_count":7,"origin":"duteros","destination":"tetartos","owner":1,"turns_remaining":3},{"id":43,"ship_count":22,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":8}]}
{"type":"gamestate","planets":[{"ship_count":4,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":2,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":42,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":3,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":10,"x":-3.0,"y":-5.0,"owner":1,"name":"extos"}],"expeditions":[{"id":45,"ship_count":9,"origin":"pemptos","destination":"tetartos","owner":1,"turns_remaining":4},{"id":41,"ship_count":11,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":5},{"id":42,"ship_count":8,"origin":"tritos","destination":"tetartos","owner":1,"turns_remaining":1},{"id":39,"ship_count":12,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":3},{"id":44,"ship_count":8,"origin":"protos","destination":"tetartos","owner":1,"turns_remaining":9},{"id":38,"ship_count":7,"origin":"duteros","destination":"tetartos","owner":1,"turns_remaining":2},{"id":43,"ship_count":22,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":7},{"id":46,"ship_count":8,"origin":"duteros","destination":"tetartos","owner":1,"turns_remaining":10}]}
{"type":"gamestate","planets":[{"ship_count":5,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":7,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":35,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":4,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":2,"x":-3.0,"y":-5.0,"owner":1,"name":"extos"}],"expeditions":[{"id":45,"ship_count":9,"origin":"pemptos","destination":"tetartos","owner":1,"turns_remaining":3},{"id":41,"ship_count":11,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":4},{"id":47,"ship_count":9,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":10},{"id":39,"ship_count":12,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":2},{"id":44,"ship_count":8,"origin":"protos","destination":"tetartos","owner":1,"turns_remaining":8},{"id":38,"ship_count":7,"origin":"duteros","destination":"tetartos","owner":1,"turns_remaining":1},{"id":43,"ship_count":22,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":6},{"id":46,"ship_count":8,"origin":"duteros","destination":"tetartos","owner":1,"turns_remaining":9}]}
{"type":"gamestate","planets":[{"ship_count":6,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":4,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":2,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":29,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":5,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":3,"x":-3.0,"y":-5.0,"owner":1,"name":"extos"}],"expeditions":[{"id":45,"ship_count":9,"origin":"pemptos","destination":"tetartos","owner":1,"turns_remaining":2},{"id":41,"ship_count":11,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":3},{"id":47,"ship_count":9,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":9},{"id":39,"ship_count":12,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":1},{"id":44,"ship_count":8,"origin":"protos","destination":"tetartos","owner":1,"turns_remaining":7},{"id":48,"ship_count":6,"origin":"tritos","destination":"tetartos","owner":1,"turns_remaining":5},{"id":43,"ship_count":22,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":5},{"id":46,"ship_count":8,"origin":"duteros","destination":"tetartos","owner":1,"turns_remaining":8}]}
{"type":"gamestate","planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":5,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":3,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":18,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":4,"x":-3.0,"y":-5.0,"owner":1,"name":"extos"}],"expeditions":[{"id":45,"ship_count":9,"origin":"pemptos","destination":"tetartos","owner":1,"turns_remaining":1},{"id":41,"ship_count":11,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":2},{"id":47,"ship_count":9,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":8},{"id":49,"ship_count":5,"origin":"protos","destination":"tetartos","owner":1,"turns_remaining":11},{"id":44,"ship_count":8,"origin":"protos","destination":"tetartos","owner":1,"turns_remaining":6},{"id":48,"ship_count":6,"origin":"tritos","destination":"tetartos","owner":1,"turns_remaining":4},{"id":43,"ship_count":22,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":4},{"id":46,"ship_count":8,"origin":"duteros","destination":"tetartos","owner":1,"turns_remaining":7}]}
{"type":"gamestate","planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":6,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":4,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":10,"x":6.0,"y":0.0,"owner":2,"name":"tetartos"},{"ship_count":2,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":5,"x":-3.0,"y":-5.0,"owner":1,"name":"extos"}],"expeditions":[{"id":50,"ship_count":5,"origin":"pemptos","destination":"tetartos","owner":1,"turns_remaining":5},{"id":41,"ship_count":11,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":1},{"id":47,"ship_count":9,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":7},{"id":49,"ship_count":5,"origin":"protos","destination":"tetartos","owner":1,"turns_remaining":10},{"id":44,"ship_count":8,"origin":"protos","destination":"tetartos","owner":1,"turns_remaining":5},{"id":48,"ship_count":6,"origin":"tritos","destination":"tetartos","owner":1,"turns_remaining":3},{"id":43,"ship_count":22,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":3},{"id":46,"ship_count":8,"origin":"duteros","destination":"tetartos","owner":1,"turns_remaining":6}]}
{"type":"gamestate","planets":[{"ship_count":4,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":2,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":5,"x":3.0,"y":5.0,"owner":1,"name":"tritos"},{"ship_count":0,"x":6.0,"y":0.0,"owner":null,"name":"tetartos"},{"ship_count":3,"x":3.0,"y":-5.0,"owner":1,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":1,"name":"extos"}],"expeditions":[{"id":50,"ship_count":5,"origin":"pemptos","destination":"tetartos","owner":1,"turns_remaining":4},{"id":51,"ship_count":5,"origin":"duteros","destination":"tetartos","owner":1,"turns_remaining":10},{"id":47,"ship_count":9,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":6},{"id":49,"ship_count":5,"origin":"protos","destination":"tetartos","owner":1,"turns_remaining":9},{"id":44,"ship_count":8,"origin":"protos","destination":"tetartos","owner":1,"turns_remaining":4},{"id":48,"ship_count":6,"origin":"tritos","destination":"tetartos","owner":1,"turns_remaining":2},{"id":43,"ship_count":22,"origin":"extos","destination":"tetartos","owner":1,"turns_remaining":2},{"id":46,"ship_count":8,"origin":"duteros","destination":"tetartos","owner":1,"turns_remaining":5}]}

View file

@ -10,16 +10,9 @@ async fn main() {
_run_match(map_path).await;
}
const IMAGE: &'static str = "python:3.10-slim-buster";
const IMAGE: &str = "python:3.10-slim-buster";
async fn _run_match(map_path: String) {
let code_dir_path = PathBuf::from("../simplebot");
let bot_spec = DockerBotSpec {
image: IMAGE.to_string(),
code_path: code_dir_path,
argv: vec!["python".to_string(), "simplebot.py".to_string()],
};
run_match(MatchConfig {
map_path: PathBuf::from(map_path),
map_name: "hex".to_string(),
@ -27,13 +20,25 @@ async fn _run_match(map_path: String) {
players: vec![
MatchPlayer {
name: "a".to_string(),
bot_spec: Box::new(bot_spec.clone()),
bot_spec: Box::new(DockerBotSpec {
image: IMAGE.to_string(),
// code_path: PathBuf::from("../simplebot"),
code_path: PathBuf::from("./bots/simplebot"),
argv: vec!["python".to_string(), "simplebot.py".to_string()],
}),
},
MatchPlayer {
name: "b".to_string(),
bot_spec: Box::new(bot_spec.clone()),
bot_spec: Box::new(DockerBotSpec {
image: IMAGE.to_string(),
code_path: PathBuf::from("./bots/broken_bot"),
argv: vec!["python".to_string(), "bot.py".to_string()],
}),
},
],
})
.await;
// TODO: use a joinhandle to wait for the logger to finish
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
}

View file

@ -35,7 +35,7 @@ pub fn run_local_bot(player_id: u32, event_bus: Arc<Mutex<EventBus>>, bot: Bot)
};
tokio::spawn(runner.run());
return LocalBotHandle { tx };
LocalBotHandle { tx }
}
pub struct LocalBotRunner {
@ -90,11 +90,11 @@ impl Bot {
let stdout = child.stdout.take().unwrap();
let reader = BufReader::new(stdout).lines();
return BotProcess {
BotProcess {
stdin: child.stdin.take().unwrap(),
stdout: reader,
child,
};
}
}
}

View file

@ -72,7 +72,7 @@ pub async fn run_match(config: MatchConfig) {
start_bot(
player_id,
event_bus.clone(),
&player.bot_spec,
player.bot_spec.as_ref(),
match_logger.clone(),
)
})
@ -111,7 +111,7 @@ pub async fn run_match(config: MatchConfig) {
async fn start_bot(
player_id: u32,
event_bus: Arc<Mutex<EventBus>>,
bot_spec: &Box<dyn BotSpec>,
bot_spec: &dyn BotSpec,
match_logger: MatchLogger,
) -> (u32, Box<dyn PlayerHandle>) {
let player_handle = bot_spec.run_bot(player_id, event_bus, match_logger).await;

View file

@ -57,11 +57,11 @@ impl MatchCtx {
timeout,
});
return Request {
Request {
player_id,
request_id,
event_bus: self.event_bus.clone(),
};
}
}
pub fn players(&self) -> Vec<u32> {
@ -97,6 +97,12 @@ impl EventBus {
}
}
impl Default for EventBus {
fn default() -> Self {
EventBus::new()
}
}
impl EventBus {
pub fn resolve_request(&mut self, id: RequestId, result: RequestResult<Vec<u8>>) {
if self.request_responses.contains_key(&id) {
@ -138,9 +144,9 @@ impl Future for Request {
event_bus
.wakers
.entry(request_id)
.or_insert_with(|| AtomicWaker::new())
.or_insert_with(AtomicWaker::new)
.register(cx.waker());
return Poll::Pending;
Poll::Pending
}
}

View file

@ -29,7 +29,7 @@ pub async fn create_log_sink(log_file_path: &Path) -> MatchLogger {
.await
.expect("Could not create log file");
tokio::spawn(run_log_sink(rx, log_file));
return tx;
tx
}
async fn run_log_sink(mut rx: mpsc::UnboundedReceiver<MatchLogMessage>, mut file: File) {

View file

@ -74,7 +74,7 @@ impl PwMatch {
.iter()
.filter(|p| p.alive)
.map(move |player| {
let state_for_player = pw_serializer::serialize_rotated(&state, player.id - 1);
let state_for_player = pw_serializer::serialize_rotated(state, player.id - 1);
match_ctx
.request(
player.id.try_into().unwrap(),
@ -115,7 +115,7 @@ impl PwMatch {
})
.collect();
return proto::PlayerAction::Commands(commands);
proto::PlayerAction::Commands(commands)
}
}

View file

@ -25,8 +25,8 @@ impl Config {
.collect();
PwState {
players: players,
planets: planets,
players,
planets,
expeditions: Vec::new(),
expedition_num: 0,
turn_num: 0,
@ -37,8 +37,7 @@ impl Config {
fn load_map(&self, num_players: usize) -> Vec<Planet> {
let map = self.read_map().expect("[PLANET_WARS] reading map failed");
return map
.planets
map.planets
.into_iter()
.enumerate()
.map(|(num, planet)| {
@ -55,27 +54,26 @@ impl Config {
});
if planet.ship_count > 0 {
fleets.push(Fleet {
owner: owner,
owner,
ship_count: planet.ship_count,
});
}
return Planet {
Planet {
id: num,
name: planet.name,
x: planet.x,
y: planet.y,
fleets: fleets,
};
fleets,
}
})
.collect();
.collect()
}
fn read_map(&self) -> io::Result<Map> {
let mut file = File::open(&self.map_file)?;
let mut buf = String::new();
file.read_to_string(&mut buf)?;
let map = serde_json::from_str(&buf)?;
return Ok(map);
Ok(serde_json::from_str(&buf)?)
}
}

View file

@ -50,7 +50,7 @@ impl PlanetWars {
serializer::serialize_rotated(&self.state, player_id - 1)
}
pub fn state<'a>(&'a self) -> &'a PwState {
pub fn state(&self) -> &PwState {
&self.state
}
@ -62,7 +62,7 @@ impl PlanetWars {
) -> Result<(), CommandError> {
let dispatch = self.parse_command(player_num, cmd)?;
self.state.dispatch(&dispatch);
return Ok(());
Ok(())
}
/// Check the given command for validity.

View file

@ -128,7 +128,7 @@ impl PwState {
pub fn is_finished(&self) -> bool {
let remaining = self.players.iter().filter(|p| p.alive).count();
return remaining < 2 || self.turn_num >= self.max_turns;
remaining < 2 || self.turn_num >= self.max_turns
}
pub fn living_players(&self) -> Vec<usize> {
@ -187,6 +187,6 @@ impl Planet {
fn distance(&self, other: &Planet) -> u64 {
let dx = self.x - other.x;
let dy = self.y - other.y;
return (dx.powi(2) + dy.powi(2)).sqrt().ceil() as u64;
(dx.powi(2) + dy.powi(2)).sqrt().ceil() as u64
}
}

View file

@ -20,7 +20,7 @@ struct Serializer<'a> {
impl<'a> Serializer<'a> {
fn new(state: &'a PwState, offset: usize) -> Self {
Serializer {
state: state,
state,
player_num_offset: offset,
}
}
@ -49,7 +49,7 @@ impl<'a> Serializer<'a> {
let num_players = self.state.players.len();
let rotated_id = (player_id + num_players - self.player_num_offset) % num_players;
// protocol player ids start at 1
return rotated_id + 1;
rotated_id + 1
}
fn serialize_planet(&self, planet: &Planet) -> proto::Planet {

View file

@ -24,12 +24,11 @@ pub fn create_session(user: &User, conn: &PgConnection) -> Session {
token: gen_session_token(),
user_id: user.id,
};
let session = insert_into(sessions::table)
insert_into(sessions::table)
.values(&new_session)
.get_result::<Session>(conn)
.unwrap();
return session;
.unwrap()
}
pub fn find_user_by_session(token: &str, conn: &PgConnection) -> QueryResult<(Session, User)> {
@ -42,5 +41,5 @@ pub fn find_user_by_session(token: &str, conn: &PgConnection) -> QueryResult<(Se
pub fn gen_session_token() -> String {
let mut rng = rand::thread_rng();
let token: [u8; 32] = rng.gen();
return base64::encode(&token);
base64::encode(&token)
}

View file

@ -48,7 +48,7 @@ pub fn create_user(credentials: &Credentials, conn: &PgConnection) -> QueryResul
let salt: [u8; 32] = rand::thread_rng().gen();
let hash = argon2::hash_raw(credentials.password.as_bytes(), &salt, &argon_config).unwrap();
let new_user = NewUser {
username: &credentials.username,
username: credentials.username,
password_salt: &salt,
password_hash: &hash,
};
@ -73,9 +73,9 @@ pub fn authenticate_user(credentials: &Credentials, db_conn: &PgConnection) -> O
.unwrap();
if password_matches {
return Some(user);
Some(user)
} else {
return None;
None
}
})
}
@ -91,15 +91,15 @@ fn test_argon() {
let salt: [u8; 32] = rand::thread_rng().gen();
let hash = argon2::hash_raw(credentials.password.as_bytes(), &salt, &argon_config).unwrap();
let new_user = NewUser {
username: &credentials.username,
username: credentials.username,
password_hash: &hash,
password_salt: &salt,
};
let password_matches = argon2::verify_raw(
credentials.password.as_bytes(),
&new_user.password_salt,
&new_user.password_hash,
new_user.password_salt,
new_user.password_hash,
&argon2_config(),
)
.unwrap();

View file

@ -10,7 +10,6 @@ pub mod util;
use std::ops::Deref;
use axum;
use bb8::{Pool, PooledConnection};
use bb8_diesel::{self, DieselConnectionManager};
use diesel::{Connection, PgConnection};
@ -60,13 +59,13 @@ pub async fn prepare_db(database_url: &str) -> Pool<DieselConnectionManager<PgCo
let manager = DieselConnectionManager::<PgConnection>::new(database_url);
let pool = bb8::Pool::builder().build(manager).await.unwrap();
seed_simplebot(&pool).await;
return pool;
pool
}
pub async fn api(configuration: Configuration) -> Router {
let db_pool = prepare_db(&configuration.database_url).await;
let api = Router::new()
Router::new()
.route("/register", post(routes::users::register))
.route("/login", post(routes::users::login))
.route("/users/me", get(routes::users::current_user))
@ -91,8 +90,7 @@ pub async fn api(configuration: Configuration) -> Router {
)
.route("/submit_bot", post(routes::demo::submit_bot))
.route("/save_bot", post(routes::bots::save_bot))
.layer(AddExtensionLayer::new(db_pool));
api
.layer(AddExtensionLayer::new(db_pool))
}
pub async fn app() -> Router {

View file

@ -59,8 +59,8 @@ pub async fn save_bot(
owner_id: None,
name: &params.bot_name,
};
let bot = bots::create_bot(&new_bot, &conn).expect("could not create bot");
bot
bots::create_bot(&new_bot, &conn).expect("could not create bot")
}
};
let _code_bundle =

View file

@ -13,8 +13,8 @@ use std::path::PathBuf;
use super::matches::ApiMatch;
const PYTHON_IMAGE: &'static str = "python:3.10-slim-buster";
const OPPONENT_NAME: &'static str = "simplebot";
const PYTHON_IMAGE: &str = "python:3.10-slim-buster";
const OPPONENT_NAME: &str = "simplebot";
#[derive(Serialize, Deserialize, Debug)]
pub struct SubmitBotParams {

View file

@ -57,8 +57,7 @@ pub async fn play_match(
code_path: PathBuf::from(BOTS_DIR).join(code_bundle.path),
image: "python:3.10-slim-buster".to_string(),
argv: shlex::split(&bot_config.run_command)
// TODO: this is an user error, should ideally be handled before we get here
.ok_or_else(|| StatusCode::INTERNAL_SERVER_ERROR)?,
.ok_or(StatusCode::INTERNAL_SERVER_ERROR)?,
}),
});
@ -152,7 +151,7 @@ pub async fn get_match_data(
) -> Result<Json<ApiMatch>, StatusCode> {
let match_data = matches::find_match(match_id, &conn)
.map_err(|_| StatusCode::NOT_FOUND)
.map(|data| match_data_to_api(data))?;
.map(match_data_to_api)?;
Ok(Json(match_data))
}