check_game: some cleanup, better comments

This commit is contained in:
Maximilian Keßler 2023-07-04 18:10:37 +02:00
parent 7845c79889
commit 37f6f78333
Signed by: max
GPG key ID: BCC5A619923C0BA5

View file

@ -1,9 +1,9 @@
import copy import copy
from typing import Tuple, Optional from typing import Tuple
from database.database import conn from database import conn
from compress import decompress_deck, decompress_actions, link from compress import decompress_deck, decompress_actions, link
from hanabi import Action, GameState from hanabi import GameState
from hanab_live import HanabLiveInstance, HanabLiveGameState from hanab_live import HanabLiveInstance, HanabLiveGameState
from sat import solve_sat from sat import solve_sat
from log_setup import logger from log_setup import logger
@ -33,6 +33,7 @@ def check_game(game_id: int) -> Tuple[int, GameState]:
instance = HanabLiveInstance(deck, num_players, variant_id=variant_id) instance = HanabLiveInstance(deck, num_players, variant_id=variant_id)
# check if the instance is already won
if instance.max_score == score: if instance.max_score == score:
game = HanabLiveGameState(instance) game = HanabLiveGameState(instance)
for action in actions: for action in actions:
@ -40,22 +41,21 @@ def check_game(game_id: int) -> Tuple[int, GameState]:
# instance has been won, nothing to compute here # instance has been won, nothing to compute here
return len(actions) + 1, game return len(actions) + 1, game
# store lower and upper bounds of numbers of turns after which we know the game was feasible / infeasible
solvable_turn = 0
unsolvable_turn = len(actions)
# first, check if the instance itself is feasible: # first, check if the instance itself is feasible:
game = HanabLiveGameState(instance) game = HanabLiveGameState(instance)
solvable, solution = solve_sat(game) solvable, solution = solve_sat(game)
if not solvable: if not solvable:
logger.debug("Returning: Instance {} is not feasible.")
return 0, solution return 0, solution
logger.verbose("Instance {} is feasible after 0 turns: {}".format(game_id, link(solution))) logger.verbose("Instance {} is feasible after 0 turns: {}".format(game_id, link(solution)))
# store lower and upper bounds of numbers of turns after which we know the game was feasible / infeasible
solvable_turn = 0
unsolvable_turn = len(actions)
while unsolvable_turn - solvable_turn > 1: while unsolvable_turn - solvable_turn > 1:
try_turn = (unsolvable_turn + solvable_turn) // 2 try_turn = (unsolvable_turn + solvable_turn) // 2
try_game = copy.deepcopy(game) try_game = copy.deepcopy(game)
assert(len(try_game.actions) == solvable_turn) assert len(try_game.actions) == solvable_turn
for a in range(solvable_turn, try_turn): for a in range(solvable_turn, try_turn):
try_game.make_action(actions[a]) try_game.make_action(actions[a])
logger.debug("Checking if instance {} is feasible after {} turns.".format(game_id, try_turn)) logger.debug("Checking if instance {} is feasible after {} turns.".format(game_id, try_turn))
@ -70,5 +70,5 @@ def check_game(game_id: int) -> Tuple[int, GameState]:
unsolvable_turn = try_turn unsolvable_turn = try_turn
logger.verbose("Instance {} is not feasible after {} turns.".format(game_id, unsolvable_turn)) logger.verbose("Instance {} is not feasible after {} turns.".format(game_id, unsolvable_turn))
assert unsolvable_turn - 1 == solvable_turn, "Programming error" assert unsolvable_turn - 1 == solvable_turn
return unsolvable_turn, solution return unsolvable_turn, solution