forked from Hanabi/hanabi-league
add bdr/statistics parser
This commit is contained in:
parent
12434f7c27
commit
4e0b624c3f
1 changed files with 61 additions and 0 deletions
61
src/statistics.py
Normal file
61
src/statistics.py
Normal file
|
@ -0,0 +1,61 @@
|
|||
import enum
|
||||
from typing import List, Tuple
|
||||
|
||||
from hanabi import hanab_game
|
||||
|
||||
|
||||
class GameOutcome(enum.Enum):
|
||||
win = 0
|
||||
discard_crit = 1
|
||||
bomb_crit = 2
|
||||
strikeout = 3
|
||||
bottom_deck = 4
|
||||
vote_to_kill = 5
|
||||
out_of_pace = 6
|
||||
|
||||
|
||||
class GameAnalysisResult:
|
||||
def __init__(self, outcomes: List[GameOutcome], bdrs: List[Tuple[hanab_game.DeckCard, int]]):
|
||||
self.outcome = GameOutcome
|
||||
self.bdrs = bdrs
|
||||
|
||||
|
||||
def analyze_game(instance: hanab_game.HanabiInstance, actions: List[hanab_game.Action]) -> GameAnalysisResult:
|
||||
# List of bdrs
|
||||
bdrs = []
|
||||
# This is the default value if we find no other reason why the game was lost (or won)
|
||||
outcomes = []
|
||||
game = hanab_game.GameState(instance)
|
||||
|
||||
def handle_lost_card(card, game, play: bool):
|
||||
if not game.is_trash(card):
|
||||
if game.is_critical(card):
|
||||
outcomes.append(GameOutcome.bomb_crit if play else GameOutcome.discard_crit)
|
||||
elif card.rank != 1:
|
||||
if card in game.deck[game.progress:]:
|
||||
bdrs.append((card, game.draw_pile_size))
|
||||
else:
|
||||
if game.deck[game.progress:].count(card) == 2:
|
||||
bdrs.append((card, game.draw_pile_size))
|
||||
|
||||
for action in actions:
|
||||
if action.type == hanab_game.ActionType.Discard:
|
||||
discarded_card = instance.deck[action.target]
|
||||
handle_lost_card(discarded_card, game, False)
|
||||
if action.type == hanab_game.ActionType.Play:
|
||||
played_card = instance.deck[action.target]
|
||||
if not game.is_playable(played_card) and not game.is_trash(played_card):
|
||||
bombed_card = instance.deck[action.target]
|
||||
handle_lost_card(bombed_card, game, True)
|
||||
game.make_action(action)
|
||||
if game.pace < 0 and GameOutcome.out_of_pace not in outcomes:
|
||||
outcomes.append(GameOutcome.out_of_pace)
|
||||
|
||||
if game.strikes == 3:
|
||||
outcomes.append(GameOutcome.strikeout)
|
||||
elif actions[-1].type in [hanab_game.ActionType.EndGame, hanab_game.ActionType.VoteTerminate]:
|
||||
outcomes.append(GameOutcome.vote_to_kill)
|
||||
if game.score == 5 * instance.num_suits:
|
||||
outcomes.append(GameOutcome.win)
|
||||
|
||||
return GameAnalysisResult(outcomes, bdrs)
|
Loading…
Reference in a new issue