Prepare for refresh

This commit is contained in:
2019-03-28 10:56:22 +01:00
parent d4d13edc1a
commit 36d26f5004
7 changed files with 203 additions and 89 deletions
+34 -4
View File
@@ -1,4 +1,34 @@
from os.path import dirname, basename, isfile
import glob
modules = glob.glob(dirname(__file__)+"/*/ai.py")
__all__ = ['.'.join(f.split('.')[:-1]) for f in modules if isfile(f)]
from os.path import dirname, basename, isfile, getmtime
from importlib import import_module
from glob import glob
modules = glob(dirname(__file__)+"/*/ai.py")
__all__ = []
class UploadedAi:
def __init__(self, name, module, constructor, date):
self.name = name
self.module = module
self.constructor = constructor
self.date = date
for path in [f for f in modules if isfile(f)]:
# Remove the .py
toto = '.'.join(path.split('.')[:-1])
# Compute the name
name = toto.split('/')[-2]
# Find the module
module = import_module('.'.join(toto.split('/')[-3:]))
# Find the constructor
constructor = getattr(module, 'Ai')
# Moment when the file was last modified
date = getmtime(path)
# Append to the list of uploaded ais
__all__.append(UploadedAi(name, module, constructor, date))
__all__ = sorted(__all__, key = lambda ai: ai.name)
+77
View File
@@ -0,0 +1,77 @@
#!/usr/bin/env python3
import os
import pathlib
import sys
import json
sys.path.append('../pytron')
from tron.map import Map
from tron.game import Game, PositionPlayer
from tron.player import Direction, ConstantPlayer
import ai_manager
from utils import run_battle
ASSETS_PATH = "assets/data.json"
LAST_REFRESH_PATH = "assets/refresh.dat"
width = 10
height = 10
def main():
print('Welcome to pytron refresh!')
sys.stdout.flush()
# Read the last moment when this script was run
last_refresh = os.path.getmtime(LAST_REFRESH_PATH)
# Set last update time
pathlib.Path(LAST_REFRESH_PATH).touch()
# Find the ais that need to be refreshed
ais_to_refresh = [ai for ai in ai_manager.__all__ if ai.date > last_refresh]
print('New ais: ', list(map(lambda x: x.name, ais_to_refresh)))
print('Ais: ', list(map(lambda x: x.name, ai_manager.__all__)))
# Read current state
with open(ASSETS_PATH, 'r') as file:
dictionnary = json.loads(file.read())
# Dictionnary to record battles that already occured
battles_done = {}
for ai1 in ais_to_refresh:
for ai2 in ai_manager.__all__:
if ai1.name == ai2.name:
continue
# Sort ais by name just to be sure
if ai1.name > ai2.name:
(sai2, sai1) = (ai1, ai2)
else:
(sai1, sai2) = (ai1, ai2)
slash_name = sai1.name + "/" + sai2.name
# Record battle to be done, skip if already done
if battles_done.get(slash_name, None) is None:
battles_done[slash_name] = True
else:
continue
print("Battling {} vs {}".format(sai1.name, sai2.name))
sys.stdout.flush()
(score1, score2, nulls) = run_battle(sai1, sai2, width, height)
dictionnary[slash_name] = [score1, score2, nulls]
with open(ASSETS_PATH, "w") as f:
f.write(json.dumps(dictionnary))
print('Pytron run has finished')
if __name__ == '__main__':
main()
+19 -58
View File
@@ -2,82 +2,43 @@
import sys
import json
import pathlib
sys.path.append('../pytron')
from tron.map import Map
from tron.game import Game, PositionPlayer
from tron.player import Direction, ConstantPlayer
from importlib import import_module
import positions
import ai_manager
from utils import run_battle
# Find all the AIs
class AiClass:
def __init__(self, name, builder):
self.name = name
self.builder = builder
ais = []
for real_ai in ai_manager.__all__:
ai_name = real_ai.split('/')[-2]
ai_module = import_module('.'.join(real_ai.split('/')[-3:]))
ai_class = getattr(ai_module, "Ai")
ais.append(AiClass(ai_name, ai_class))
# This script shows how to create a game with AI, that will run automatically.
# It is made to be fast and not to be used by humans. It especially doesn't
# display and window and doesn't listen to any keystrokes.
ASSETS_PATH = "assets/data.json"
LAST_REFRESH_PATH = "assets/refresh.dat"
width = 10
height = 10
def run_battle(ai1, ai2):
games = 50
ai1_victories = 0
ai2_victories = 0
for (initial_position_one, initial_position_two) in positions.positions():
game = Game(width, height, [
PositionPlayer(1, ai1.builder(), initial_position_one),
PositionPlayer(2, ai2.builder(), initial_position_two),
])
game.main_loop()
if game.winner == 1:
ai1_victories += 1
elif game.winner == 2:
ai2_victories += 1
# Inverse positions and replay to be symmetrical
game = Game(width, height, [
PositionPlayer(1, ai2.builder(), initial_position_one),
PositionPlayer(2, ai1.builder(), initial_position_two),
])
game.main_loop()
if game.winner == 1:
ai2_victories += 1
elif game.winner == 2:
ai1_victories += 1
return (ai1_victories, ai2_victories, 2 * games - ai1_victories - ai2_victories)
def main():
print('Welcome to pytron run!')
dictionnary = {"ais": list(map(lambda x: x.name, ais)), "battles": {}}
dictionnary = {}
for (id1, ai1) in enumerate(ais):
for (id2, ai2) in enumerate(ais):
# Set last update time
pathlib.Path(LAST_REFRESH_PATH).touch()
for (id1, ai1) in enumerate(ai_manager.__all__):
for (id2, ai2) in enumerate(ai_manager.__all__):
if id1 >= id2:
continue
print("Battling {} vs {}".format(ai1.name, ai2.name))
(score1, score2, nulls) = run_battle(ai1, ai2)
dictionnary["battles"][ai1.name + "/" + ai2.name] = [score1, score2, nulls]
# Sort ais by name just to be sure
if ai1.name > ai2.name:
(sai2, sai1) = (ai1, ai2)
else:
(sai1, sai2) = (ai1, ai2)
print("Battling {} vs {}".format(sai1.name, sai2.name))
(score1, score2, nulls) = run_battle(sai1, sai2, width, height)
dictionnary[sai1.name + "/" + sai2.name] = [score1, score2, nulls]
with open("assets/data.json", "w") as f:
f.write(json.dumps(dictionnary))
+34
View File
@@ -0,0 +1,34 @@
from positions import positions
from tron.game import Game, PositionPlayer
def run_battle(ai1, ai2, width, height):
games = 50
ai1_victories = 0
ai2_victories = 0
for (initial_position_one, initial_position_two) in positions():
game = Game(width, height, [
PositionPlayer(1, ai1.constructor(), initial_position_one),
PositionPlayer(2, ai2.constructor(), initial_position_two),
])
game.main_loop()
if game.winner == 1:
ai1_victories += 1
elif game.winner == 2:
ai2_victories += 1
# Inverse positions and replay to be symmetrical
game = Game(width, height, [
PositionPlayer(1, ai2.constructor(), initial_position_one),
PositionPlayer(2, ai1.constructor(), initial_position_two),
])
game.main_loop()
if game.winner == 1:
ai2_victories += 1
elif game.winner == 2:
ai1_victories += 1
return (ai1_victories, ai2_victories, 2 * games - ai1_victories - ai2_victories)