diff --git a/compress.py b/compress.py index de77932..2663d76 100755 --- a/compress.py +++ b/compress.py @@ -5,10 +5,11 @@ import more_itertools from enum import Enum from termcolor import colored -from typing import List, Optional +from typing import List, Optional, Union from variants import variant_id, variant_name from hanabi import DeckCard, ActionType, Action, GameState, HanabiInstance +from hanab_live import HanabLiveGameState, HanabLiveInstance # use same BASE62 as on hanab.live to encode decks @@ -164,14 +165,18 @@ def decompress_deck(deck_str: str) -> List[DeckCard]: # which can be used in json replay links # The GameState object has to be standard / fitting hanab.live variants, # otherwise compression is not possible -def compress_game_state(state: GameState) -> str: -# if not state.instance.is_standard(): -# raise ValueError("Cannot compress non-standard hanabi instance") +def compress_game_state(state: Union[GameState, HanabLiveGameState]) -> str: + var_id = -1 + if isinstance(state, GameState): + var_id = HanabLiveInstance.select_standard_variant_id(state.instance) + else: + assert isinstance(state, HanabLiveGameState) + var_id = state.instance.variant_id out = "{}{},{},{}".format( state.instance.num_players, compress_deck(state.instance.deck), compress_actions(state.actions), - state.instance.variant_id # Note that a sane default is chosen if construction did not provide one + var_id ) with_dashes = ''.join(more_itertools.intersperse("-", out, 20)) return with_dashes diff --git a/hanab_live.py b/hanab_live.py index f73e2e7..3bd0cab 100644 --- a/hanab_live.py +++ b/hanab_live.py @@ -1,4 +1,4 @@ -from typing import List +from typing import List, Optional import hanabi import constants @@ -26,6 +26,19 @@ class HanabLiveInstance(hanabi.HanabiInstance): self.variant_id = variant_id self.variant = Variant.from_db(self.variant_id) + @staticmethod + def select_standard_variant_id(instance: hanabi.HanabiInstance): + err_msg = "Hanabi instance not supported by hanab.live, cannot convert to HanabLiveInstance: " + assert 3 <= instance.num_suits <= 6, \ + err_msg + "Illegal number of suits ({}) found, must be in range [3,6]".format(instance.num_suits) + assert 0 <= instance.num_dark_suits <= 2, \ + err_msg + "Illegal number of dark suits ({}) found, must be in range [0,2]".format(instance.num_dark_suits) + assert 4 <= instance.num_suits - instance.num_dark_suits, \ + err_msg + "Illegal ratio of dark suits to suits, can have at most {} dark suits with {} total suits".format( + max(instance.num_suits - 4, 0), instance.num_suits + ) + return constants.VARIANT_IDS_STANDARD_DISTRIBUTIONS[instance.num_suits][instance.num_dark_suits] + class HanabLiveGameState(hanabi.GameState): def __init__(self, instance: HanabLiveInstance):