diff --git a/endgames.py b/endgames.py new file mode 100644 index 0000000..614611f --- /dev/null +++ b/endgames.py @@ -0,0 +1,63 @@ +import json +import re +import subprocess +from typing import Dict + +from pathlib import Path +DATA_FILE = Path('endgame-data.json') + +if not DATA_FILE.exists(): + DATA_FILE.write_text('{}') + + +with open(DATA_FILE, 'r') as f: + DATA: Dict = json.loads(f.read()) + + +def analyze_game(game_id: int): + probabilities = {} + for deck_size in range(1, 16): + try: + result = subprocess.run(['./endgame-analyzer', '-g', str(game_id), '-d', str(deck_size), '-i', '0'], stdout=subprocess.PIPE, timeout=30) + except subprocess.TimeoutExpired: + return probabilities + output = result.stdout.decode('utf-8') + m = re.search('Probability with optimal play: .*/.* ~ ([0-9.]+)', output) + if not m: + raise ValueError("Invalid program output: {}".format(output)) + probabilities[str(deck_size)] = m.group(1) + return probabilities + +def full_analyze_game(game_id: int): + probabilities = {} + try: + result = subprocess.run(['./endgame-analyzer', '-g', str(game_id), '-d', str(deck_size), '-i', '0', '--all-clues', '-r'], stdout=subprocess.PIPE, timeout=180) + except subproces.TimeoutExpired: + return probabilities + output = result.stdout.decode('utf-8') + for m in re.finditer('Probability with (\d+) cards left in deck and (\d) clues (+|-\d): .*/.* ~ ([0-9.]+)', output): + probabilities[m.group(1)][m.group(3)] = m.group(4) + return probabilities + +def full_analyze_game_cached(game_id: int): + cached = DATA.get('all', {}).get(str(game_id), None) + if cached is not None: + return cached + result = full_analyze_game(game_id) + DATA['all'][game_id] = result + save_cache() + return result + +def analyze_game_cached(game_id: int): + cached = DATA['normal'].get(str(game_id), None) + if cached is not None: + return cached + result = analyze_game(game_id) + DATA['normal'][game_id] = result + save_cache() + return result + + +def save_cache(): + with open(DATA_FILE, 'w') as f: + f.writelines(json.dumps(DATA, indent=2))