diff --git a/hanab_live.py b/hanab_live.py new file mode 100644 index 0000000..21669d5 --- /dev/null +++ b/hanab_live.py @@ -0,0 +1,59 @@ +from typing import List + +import hanabi +import constants +from variants import Variant + + +class HanabLiveInstance(hanabi.HanabiInstance): + def __init__( + self, + deck: List[hanabi.DeckCard], + num_players: int, + variant_id: int + ): + assert(2 <= num_players <= 6) + super().__init__(deck, num_players) + self.variant_id = variant_id + self.variant = Variant.from_db(self.variant_id) + + +class HanabLiveGameState(hanabi.GameState): + def __init__(self, instance: HanabLiveInstance): + super().__init__(instance) + self.instance: HanabLiveInstance = instance + + def make_action(self, action): + match action.type: + case hanabi.ActionType.ColorClue | hanabi.ActionType.RankClue: + assert(self.clues > 0) + self.actions.append(action) + self.clues -= self.instance.clue_increment + self._make_turn() + # TODO: could check that the clue specified is in fact legal + case hanabi.ActionType.Play: + self.play(action.target) + case hanabi.ActionType.Discard: + self.discard(action.target) + case hanabi.ActionType.EndGame | hanabi.ActionType.VoteTerminate: + self.over = True + + def _waste_clue(self) -> hanabi.Action: + for player in range(self.turn + 1, self.turn + self.num_players): + for card in self.hands[player % self.num_players]: + for rank in self.instance.variant.ranks: + if self.instance.variant.rank_touches(card, rank): + return hanabi.Action( + hanabi.ActionType.RankClue, + player % self.num_players, + rank + ) + for color in range(self.instance.variant.num_colors): + if self.instance.variant.color_touches(card, color): + return hanabi.Action( + hanabi.ActionType.ColorClue, + player % self.num_players, + color + ) + raise RuntimeError("Current game state did not permit any legal clue." + "This case is incredibly rare and currently not handled.")