def test_action_probs(): deal = FullDeal( hole_cards=[mkhand("AcAd"), mkhand("AsKh")], board=Board(flop=mkflop("KsJs3d"), turn=mkcard("7s"), river=mkcard("6s")), ) game = GameRunner(starting_stacks=[300, 400]) game.start_game() # Preflop game.bet_raise(to=10) game.call() # Flop game.bet_raise(to=25) game.call() # Turn game.check() game.bet_raise(to=40) game.call() # River game.check() game.check() model = heads_up.HeadsUpModel("HeadsUp") player_index = 1 example = make_forward_example( player_index, game.game_view(), deal.hole_cards[player_index], deal.board, ) logits = model.action_logits( model.feature_config.make_feature_tensors( [example.SerializeToString()])) batch_size = 1 num_steps = 9 num_possible_actions = 22 assert logits.shape == [batch_size, num_steps, num_possible_actions] probs = model.action_probs( model.feature_config.make_feature_tensors( [example.SerializeToString()])) assert_array_almost_equal( tf.reduce_sum(probs, -1).numpy(), np.array([[1, 1, 1, 1, 1, 1, 1, 1, 1]]))
def test_loss(): deal = FullDeal( hole_cards=[mkhand("AcAd"), mkhand("AsKh")], board=Board(flop=mkflop("KsJs3d"), turn=mkcard("7s"), river=mkcard("6s")), ) game = GameRunner(starting_stacks=[300, 400]) game.start_game() # Preflop game.bet_raise(to=10) game.call() # Flop game.bet_raise(to=25) game.call() # Turn game.check() game.bet_raise(to=40) game.call() # River game.check() game.check() results = result.get_result(deal, game.game_view()) model = heads_up.HeadsUpModel("HeadsUp") player_index = 1 example = make_forward_backward_example( player_index, game.game_view(), deal.hole_cards[player_index], deal.board, results, ) ( feature_tensors, target_tensors, ) = model.feature_config.make_features_and_target_tensors( [example.SerializeToString()]) print(tf.cast(target_tensors["reward__cumulative_reward"], tf.float32)) loss = model.loss(feature_tensors, target_tensors) batch_size = 1 num_steps = 9 assert loss.shape == [batch_size, num_steps]
def test_game_result(): deal = FullDeal( hole_cards=[mkhand("AcAh"), mkhand("KdKs"), mkhand("JhJd")], board=Board(flop=mkflop("6dQc2s"), turn=mkcard("6s"), river=mkcard("3c")), ) game = GameRunner(starting_stacks=[100, 200, 300]) game.start_game() # Preflop game.bet_raise(to=10) game.call() game.call() # Flop game.bet_raise(to=20) game.call() game.call() # Turn game.bet_raise(to=30) game.call() game.call() # River game.check() game.check() game.check() result = get_result(deal, game.game_view()) assert result == Result( won_hand=[True, False, False], hand_results=[ EvaluationResult( hand_type=HandType.TWO_PAIR, kicker=33686528, ), EvaluationResult(hand_type=HandType.TWO_PAIR, kicker=16909312), EvaluationResult(hand_type=HandType.TWO_PAIR, kicker=4326400), ], went_to_showdown=[True, True, True], remained_in_hand=[True, True, True], earned_from_pot=[180, 0, 0], profits=[120, -60, -60], )
def test_game_with_tie(): deal = FullDeal( hole_cards=[mkhand("Ac3h"), mkhand("Ad4s"), mkhand("5s5d")], board=Board(flop=mkflop("AsAhKc"), turn=mkcard("Kd"), river=mkcard("7h")), ) game = GameRunner(starting_stacks=[100, 200, 300]) game.start_game() # Preflop game.bet_raise(to=30) game.call() game.call() # Flop game.bet_raise(to=50) game.call() game.call() # Turn game.bet_raise(to=20) game.call() game.call() # River game.bet_raise(to=100) game.call() result = get_result(deal, game.game_view()) assert result == Result( won_hand=[True, True, False], hand_results=[ EvaluationResult(hand_type=HandType.FULL_HOUSE, kicker=33556480), EvaluationResult(hand_type=HandType.FULL_HOUSE, kicker=33556480), EvaluationResult(hand_type=HandType.TWO_PAIR, kicker=50331680), ], remained_in_hand=[True, True, True], went_to_showdown=[True, True, True], earned_from_pot=[150, 350, 0], profits=[50, 150, -200], )
def sanity_tests() -> None: # Order doesn't matter assert evaluate_hand(mkhand("7d8s"), Board(flop=mkflop("5h6cJs"))) == evaluate_hand( mkhand("5hJs"), Board(flop=mkflop("7d8s6c"))) # Suits don't matter for non-flushes assert evaluate_hand(mkhand("7d8s"), Board(flop=mkflop("5h6cJs"))) == evaluate_hand( mkhand("7c8h"), Board(flop=mkflop("5h6cJs"))) # Kickers all the way down matter assert evaluate_hand(mkhand("7d8s"), Board(flop=mkflop("AdAcJs"))) > evaluate_hand( mkhand("8s6h"), Board(flop=mkflop("AdAcJs")))
def test_board_at_street() -> None: board = Board(flop=mkflop("AdKs3h"), turn=mkcard("5h"), river=mkcard("7s")) assert board.at_street(Street.TURN) == Board( flop=( Card(rank=Rank.ACE, suit=Suit.DIAMONDS), Card(rank=Rank.KING, suit=Suit.SPADES), Card(rank=Rank.THREE, suit=Suit.HEARTS), ), turn=Card(rank=Rank.FIVE, suit=Suit.HEARTS), river=None, ) assert board.at_street(Street.FLOP) == Board( flop=( Card(rank=Rank.ACE, suit=Suit.DIAMONDS), Card(rank=Rank.KING, suit=Suit.SPADES), Card(rank=Rank.THREE, suit=Suit.HEARTS), ), turn=None, river=None, )
def test_fold_preflop() -> None: # Player 3 wins with a flopped set of jacks. deal = FullDeal( hole_cards=[mkhand("AcAd"), mkhand("AsKh"), mkhand("JcJh")], board=Board(flop=mkflop("KsJs3d"), turn=mkcard("7s"), river=mkcard("6s")), ) game = GameRunner(starting_stacks=[200, 250, 300]) game.start_game() game.bet_raise(to=10) game.fold() game.fold() results = result.get_result(deal, game.game_view()) s = Stats() s.update_stats(game.game_view(), results, player_id=0) assert s == Stats( num_hands=1, reward=-1, num_wins=0, num_losses=1, num_flops=0, num_turns=0, num_rivers=0, num_showdowns=0, num_decisions=1, num_check=0, num_call=0, total_amount_called=0, num_bet=0, total_amount_bet=0, num_fold=1, ) s = Stats() s.update_stats(game.game_view(), results, player_id=1) assert s == Stats( num_hands=1, reward=-2, num_wins=0, num_losses=1, num_flops=0, num_turns=0, num_rivers=0, num_showdowns=0, num_decisions=1, num_check=0, num_call=0, total_amount_called=0, num_bet=0, total_amount_bet=0, num_fold=1, ) s = Stats() s.update_stats(game.game_view(), results, player_id=2) assert s == Stats( num_hands=1, reward=3, num_wins=1, num_losses=0, num_flops=0, num_turns=0, num_rivers=0, num_showdowns=0, num_decisions=1, num_check=0, num_call=0, total_amount_called=0, num_bet=1, total_amount_bet=10, num_fold=0, )
def test_full_hand() -> None: # Player 3 wins with a flopped set of jacks. deal = FullDeal( hole_cards=[mkhand("AhKs"), mkhand("Kc10d"), mkhand("5h5c"), mkhand("7s3d")], board=Board(flop=mkflop("KdJs3d"), turn=mkcard("7s"), river=mkcard("6s")), ) game = GameRunner(starting_stacks=[300, 300, 300, 300]) game.start_game() # Preflop game.bet_raise(to=10) game.fold() game.bet_raise(to=25) game.call() game.call() # Flop game.bet_raise(to=40) game.call() game.fold() # Turn game.check() game.bet_raise(to=60) game.call() # River game.check() game.bet_raise(to=100) game.call() results = result.get_result(deal, game.game_view()) player_index = 1 example = make_example( public_context=make_public_context(game.game_view()), private_context=make_private_context(deal.hole_cards[1]), target=make_target(deal, results), public_states=make_public_states(game.game_view(), deal.board), player_states=make_player_states( player_index, game.game_view(), deal.hole_cards[player_index], deal.board ), last_actions=make_last_actions(game.game_view()), next_actions=make_next_actions(game.game_view()), rewards=make_rewards(game.game_view(), results), ) example_dict = seq_example_to_dict(example) assert example_dict == { "context": { "num_steps": [14], "private_context__hand_encoded": [140], "private_context__hole_card_0_rank": [13], "private_context__hole_card_0_suit": [2], "private_context__hole_card_1_rank": [10], "private_context__hole_card_1_suit": [3], "public_context__num_players": [4], "public_context__starting_stack_sizes": [300, 300, 300, 300], "target__hole_cards": [168, 140, 3, 36], "target__total_rewards": [250, -225, -25, 0], }, "features": { "last_action__action_encoded": [ [-1], [3], [0], [3], [1], [1], [5], [1], [0], [1], [7], [1], [1], [14], ], "last_action__amount_added": [ [-1], [10], [0], [24], [23], [15], [40], [40], [0], [0], [60], [60], [0], [100], ], "last_action__amount_added_percent_of_remaining": [ [-1.0], [0.03333333507180214], [0.0], [0.08026755601167679], [0.07718120515346527], [0.0517241396009922], [0.145454540848732], [0.145454540848732], [0.0], [0.0], [0.25531914830207825], [0.25531914830207825], [0.0], [0.5714285969734192], ], "last_action__amount_raised": [ [-1], [8], [0], [15], [0], [0], [40], [0], [0], [0], [60], [0], [0], [100], ], "last_action__amount_raised_percent_of_pot": [ [-1.0], [2.6666667461395264], [0.0], [1.1538461446762085], [0.0], [0.0], [0.5333333611488342], [0.0], [0.0], [0.0], [0.3870967626571655], [0.0], [0.0], [0.3636363744735718], ], "last_action__move": [ [-1], [5], [3], [5], [4], [4], [5], [4], [3], [4], [5], [4], [4], [5], ], "next_action__action_encoded": [ [3], [0], [3], [1], [1], [5], [1], [0], [1], [7], [1], [1], [14], [1], ], "next_action__amount_added": [ [10], [0], [24], [23], [15], [40], [40], [0], [0], [60], [60], [0], [100], [100], ], "next_action__amount_raised": [ [8], [0], [15], [0], [0], [40], [0], [0], [0], [60], [0], [0], [100], [0], ], "next_action__move": [ [5], [3], [5], [4], [4], [5], [4], [3], [4], [5], [4], [4], [5], [4], ], "next_action__new_total_bet": [ [10], [10], [25], [25], [25], [40], [40], [40], [0], [60], [60], [0], [100], [100], ], "player_state__current_hand_rank": [ [-1], [-1], [-1], [-1], [-1], [-1], [3652], [-1], [-1], [3648], [-1], [-1], [3648], [-1], ], "player_state__current_hand_strength": [ [-1.0], [-1.0], [-1.0], [-1.0], [-1.0], [-1.0], [0.5105869770050049], [-1.0], [-1.0], [0.51112300157547], [-1.0], [-1.0], [0.51112300157547], [-1.0], ], "player_state__current_hand_type": [ [-1], [-1], [-1], [-1], [-1], [-1], [2], [-1], [-1], [2], [-1], [-1], [2], [-1], ], "player_state__current_player_offset": [ [1], [2], [-1], [0], [1], [-1], [0], [1], [-1], [0], [-1], [-1], [0], [-1], ], "player_state__frac_hands_better": [ [-1.0], [-1.0], [-1.0], [-1.0], [-1.0], [-1.0], [0.046253468841314316], [-1.0], [-1.0], [0.07439613342285156], [-1.0], [-1.0], [0.17171716690063477], [-1.0], ], "player_state__frac_hands_tied": [ [-1.0], [-1.0], [-1.0], [-1.0], [-1.0], [-1.0], [0.005550416186451912], [-1.0], [-1.0], [0.005797101650387049], [-1.0], [-1.0], [0.005050505045801401], [-1.0], ], "player_state__frac_hands_worse": [ [-1.0], [-1.0], [-1.0], [-1.0], [-1.0], [-1.0], [0.9481961131095886], [-1.0], [-1.0], [0.9198067784309387], [-1.0], [-1.0], [0.8232323527336121], [-1.0], ], "player_state__is_current_player": [ [0], [0], [0], [1], [0], [0], [1], [0], [0], [1], [0], [0], [1], [0], ], "player_state__win_prob_vs_any": [ [-1.0], [-1.0], [-1.0], [-1.0], [-1.0], [-1.0], [0.8297058343887329], [-1.0], [-1.0], [0.8359622955322266], [-1.0], [-1.0], [0.8232323527336121], [-1.0], ], "player_state__win_prob_vs_better": [ [-1.0], [-1.0], [-1.0], [-1.0], [-1.0], [-1.0], [0.17900000512599945], [-1.0], [-1.0], [0.09700000286102295], [-1.0], [-1.0], [0.0], [-1.0], ], "player_state__win_prob_vs_tied": [ [-1.0], [-1.0], [-1.0], [-1.0], [-1.0], [-1.0], [0.052000001072883606], [-1.0], [-1.0], [0.0], [-1.0], [-1.0], [0.0], [-1.0], ], "player_state__win_prob_vs_worse": [ [-1.0], [-1.0], [-1.0], [-1.0], [-1.0], [-1.0], [0.8659999966621399], [-1.0], [-1.0], [0.9010000228881836], [-1.0], [-1.0], [1.0], [-1.0], ], "public_state__all_in_player_mask": [ [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], ], "public_state__amount_to_call": [ [1, 0, 2, 2], [9, 8, 0, 10], [9, 8, 0, 10], [0, 23, 15, 25], [0, 0, 15, 25], [0, 0, 0, 0], [0, 40, 40, 40], [0, 0, 40, 40], [0, 0, 0, 0], [0, 0, 0, 0], [60, 0, 60, 60], [0, 0, 0, 0], [0, 0, 0, 0], [100, 0, 100, 100], ], "public_state__current_player_mask": [ [0, 0, 1, 0], [0, 0, 0, 1], [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [1, 0, 0, 0], [0, 1, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0], [1, 0, 0, 0], ], "public_state__flop_0_rank": [ [-1], [-1], [-1], [-1], [-1], [13], [13], [13], [13], [13], [13], [13], [13], [13], ], "public_state__flop_0_suit": [ [-1], [-1], [-1], [-1], [-1], [3], [3], [3], [3], [3], [3], [3], [3], [3], ], "public_state__flop_1_rank": [ [-1], [-1], [-1], [-1], [-1], [11], [11], [11], [11], [11], [11], [11], [11], [11], ], "public_state__flop_1_suit": [ [-1], [-1], [-1], [-1], [-1], [1], [1], [1], [1], [1], [1], [1], [1], [1], ], "public_state__flop_2_rank": [ [-1], [-1], [-1], [-1], [-1], [3], [3], [3], [3], [3], [3], [3], [3], [3], ], "public_state__flop_2_suit": [ [-1], [-1], [-1], [-1], [-1], [3], [3], [3], [3], [3], [3], [3], [3], [3], ], "public_state__folded_player_mask": [ [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 0, 1], [0, 0, 0, 1], [0, 0, 0, 1], [0, 0, 0, 1], [0, 0, 0, 1], [0, 0, 1, 1], [0, 0, 1, 1], [0, 0, 1, 1], [0, 0, 1, 1], [0, 0, 1, 1], [0, 0, 1, 1], ], "public_state__min_raise_amount": [ [2], [8], [8], [15], [15], [2], [40], [40], [2], [2], [60], [2], [2], [100], ], "public_state__pot_size": [ [3], [13], [13], [37], [60], [75], [115], [155], [155], [155], [215], [275], [275], [375], ], "public_state__river_rank": [ [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], [6], [6], [6], ], "public_state__river_suit": [ [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], [1], [1], [1], ], "public_state__stack_sizes": [ [299, 298, 300, 300], [299, 298, 290, 300], [299, 298, 290, 300], [275, 298, 290, 300], [275, 275, 290, 300], [275, 275, 275, 300], [235, 275, 275, 300], [235, 235, 275, 300], [235, 235, 275, 300], [235, 235, 275, 300], [235, 175, 275, 300], [175, 175, 275, 300], [175, 175, 275, 300], [175, 75, 275, 300], ], "public_state__street": [ [1], [1], [1], [1], [1], [2], [2], [2], [3], [3], [3], [4], [4], [4], ], "public_state__turn_rank": [ [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], [7], [7], [7], [7], [7], [7], ], "public_state__turn_suit": [ [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], [1], [1], [1], [1], [1], [1], ], "reward__cumulative_reward": [ [-25], [0], [251], [-223], [-15], [275], [-200], [0], [315], [-160], [315], [375], [-100], [375], ], "reward__instant_reward": [ [-10], [0], [-24], [-23], [-15], [-40], [-40], [0], [0], [-60], [-60], [0], [-100], [375], ], "reward__is_players_last_action": [ [0], [1], [0], [0], [0], [0], [0], [1], [0], [0], [0], [0], [1], [1], ], "reward__won_hand": [ [0], [0], [1], [0], [0], [1], [0], [0], [1], [0], [1], [1], [0], [1], ], }, }
def test_fold_preflop() -> None: # Player 3 wins with a flopped set of jacks. deal = FullDeal( hole_cards=[mkhand("AcAd"), mkhand("AsKh"), mkhand("JcJh")], board=Board(flop=mkflop("KsJs3d"), turn=mkcard("7s"), river=mkcard("6s")), ) game = GameRunner(starting_stacks=[200, 250, 100]) game.start_game() game.bet_raise(to=10) game.fold() game.fold() results = result.get_result(deal, game.game_view()) player_index = 1 example = make_example( public_context=make_public_context(game.game_view()), private_context=make_private_context(deal.hole_cards[1]), target=make_target(deal, results), public_states=make_public_states(game.game_view(), deal.board), player_states=make_player_states( player_index, game.game_view(), deal.hole_cards[player_index], deal.board ), last_actions=make_last_actions(game.game_view()), next_actions=make_next_actions(game.game_view()), rewards=make_rewards(game.game_view(), results), ) example_dict = seq_example_to_dict(example) assert example_dict == { "context": { "num_steps": [3], "private_context__hand_encoded": [168], "private_context__hole_card_0_rank": [14], "private_context__hole_card_0_suit": [1], "private_context__hole_card_1_rank": [13], "private_context__hole_card_1_suit": [4], "public_context__num_players": [3], "public_context__starting_stack_sizes": [200, 250, 100], "target__hole_cards": [12, 168, 9], "target__total_rewards": [-1, -2, 3], }, "features": { "last_action__action_encoded": [[-1], [4], [0]], "last_action__amount_added": [[-1], [10], [0]], "last_action__amount_added_percent_of_remaining": [ [-1.0], [0.10000000149011612], [0.0], ], "last_action__amount_raised": [[-1], [8], [0]], "last_action__amount_raised_percent_of_pot": [ [-1.0], [2.6666667461395264], [0.0], ], "last_action__move": [[-1], [5], [3]], "next_action__action_encoded": [[4], [0], [0]], "next_action__amount_added": [[10], [0], [0]], "next_action__amount_raised": [[8], [0], [0]], "next_action__move": [[5], [3], [3]], "next_action__new_total_bet": [[10], [10], [10]], "player_state__current_hand_rank": [[-1], [-1], [-1]], "player_state__current_hand_strength": [[-1.0], [-1.0], [-1.0]], "player_state__current_hand_type": [[-1], [-1], [-1]], "player_state__current_player_offset": [[1], [-1], [0]], "player_state__frac_hands_better": [[-1.0], [-1.0], [-1.0]], "player_state__frac_hands_tied": [[-1.0], [-1.0], [-1.0]], "player_state__frac_hands_worse": [[-1.0], [-1.0], [-1.0]], "player_state__is_current_player": [[0], [0], [1]], "player_state__win_prob_vs_any": [[-1.0], [-1.0], [-1.0]], "player_state__win_prob_vs_better": [[-1.0], [-1.0], [-1.0]], "player_state__win_prob_vs_tied": [[-1.0], [-1.0], [-1.0]], "player_state__win_prob_vs_worse": [[-1.0], [-1.0], [-1.0]], "public_state__all_in_player_mask": [[0, 0, 0], [0, 0, 0], [0, 0, 0]], "public_state__amount_to_call": [[1, 0, 2], [9, 8, 0], [9, 8, 0]], "public_state__current_player_mask": [[0, 0, 1], [1, 0, 0], [0, 1, 0]], "public_state__flop_0_rank": [[-1], [-1], [-1]], "public_state__flop_0_suit": [[-1], [-1], [-1]], "public_state__flop_1_rank": [[-1], [-1], [-1]], "public_state__flop_1_suit": [[-1], [-1], [-1]], "public_state__flop_2_rank": [[-1], [-1], [-1]], "public_state__flop_2_suit": [[-1], [-1], [-1]], "public_state__folded_player_mask": [[0, 0, 0], [0, 0, 0], [1, 0, 0]], "public_state__min_raise_amount": [[2], [8], [8]], "public_state__pot_size": [[3], [13], [13]], "public_state__river_rank": [[-1], [-1], [-1]], "public_state__river_suit": [[-1], [-1], [-1]], "public_state__stack_sizes": [ [199, 248, 100], [199, 248, 90], [199, 248, 90], ], "public_state__street": [[1], [1], [1]], "public_state__turn_rank": [[-1], [-1], [-1]], "public_state__turn_suit": [[-1], [-1], [-1]], "reward__cumulative_reward": [[3], [0], [0]], "reward__instant_reward": [[3], [0], [0]], "reward__is_players_last_action": [[1], [1], [1]], "reward__won_hand": [[1], [0], [0]], }, }
def test_monster() -> None: deal = FullDeal( hole_cards=[mkhand("JcJd"), mkhand("Kc10d")], board=Board(flop=mkflop("JsTs3h"), turn=mkcard("Jh"), river=mkcard("As")), ) game = GameRunner(starting_stacks=[300, 400]) game.start_game() # Preflop game.bet_raise(to=10) game.call() # Flop game.check() game.check() # Turn game.check() game.check() # River game.check() game.check() player_index = 0 private_states = make_player_states(player_index, game.game_view(), deal.hole_cards[player_index], deal.board) assert private_states == [ PlayerState( is_current_player=True, current_player_offset=0, current_hand_type=None, frac_better_hands=None, frac_tied_hands=None, frac_worse_hands=None, win_odds=None, tie_odds=None, lose_odds=None, win_odds_vs_better=None, tie_odds_vs_better=None, lose_odds_vs_better=None, win_odds_vs_tied=None, tie_odds_vs_tied=None, lose_odds_vs_tied=None, win_odds_vs_worse=None, tie_odds_vs_worse=None, lose_odds_vs_worse=None, ), PlayerState( is_current_player=False, current_player_offset=1, current_hand_type=None, frac_better_hands=None, frac_tied_hands=None, frac_worse_hands=None, win_odds=None, tie_odds=None, lose_odds=None, win_odds_vs_better=None, tie_odds_vs_better=None, lose_odds_vs_better=None, win_odds_vs_tied=None, tie_odds_vs_tied=None, lose_odds_vs_tied=None, win_odds_vs_worse=None, tie_odds_vs_worse=None, lose_odds_vs_worse=None, ), PlayerState( is_current_player=True, current_player_offset=0, current_hand_type=4, frac_better_hands=0.0, frac_tied_hands=0.0, frac_worse_hands=1.0, win_odds=approx(0.9300000071525574, abs=0.1), tie_odds=0.0, lose_odds=approx(0.07000000029802322, abs=0.1), win_odds_vs_better=0.0, tie_odds_vs_better=0.0, lose_odds_vs_better=0.0, win_odds_vs_tied=0.0, tie_odds_vs_tied=0.0, lose_odds_vs_tied=0.0, win_odds_vs_worse=approx(0.9300000071525574, abs=0.1), tie_odds_vs_worse=0.0, lose_odds_vs_worse=approx(0.07000000029802322, abs=0.1), ), PlayerState( is_current_player=False, current_player_offset=1, current_hand_type=None, frac_better_hands=None, frac_tied_hands=None, frac_worse_hands=None, win_odds=None, tie_odds=None, lose_odds=None, win_odds_vs_better=None, tie_odds_vs_better=None, lose_odds_vs_better=None, win_odds_vs_tied=None, tie_odds_vs_tied=None, lose_odds_vs_tied=None, win_odds_vs_worse=None, tie_odds_vs_worse=None, lose_odds_vs_worse=None, ), PlayerState( is_current_player=True, current_player_offset=0, current_hand_type=8, frac_better_hands=0.0, frac_tied_hands=0.0, frac_worse_hands=1.0, win_odds=approx(0.9990000128746033, abs=0.1), tie_odds=0.0, lose_odds=approx(0.0010000000474974513, abs=0.1), win_odds_vs_better=0.0, tie_odds_vs_better=0.0, lose_odds_vs_better=0.0, win_odds_vs_tied=0.0, tie_odds_vs_tied=0.0, lose_odds_vs_tied=0.0, win_odds_vs_worse=approx(0.9990000128746033, abs=0.1), tie_odds_vs_worse=0.0, lose_odds_vs_worse=approx(0.0010000000474974513, abs=0.1), ), PlayerState( is_current_player=False, current_player_offset=1, current_hand_type=None, frac_better_hands=None, frac_tied_hands=None, frac_worse_hands=None, win_odds=None, tie_odds=None, lose_odds=None, win_odds_vs_better=None, tie_odds_vs_better=None, lose_odds_vs_better=None, win_odds_vs_tied=None, tie_odds_vs_tied=None, lose_odds_vs_tied=None, win_odds_vs_worse=None, tie_odds_vs_worse=None, lose_odds_vs_worse=None, ), PlayerState( is_current_player=True, current_player_offset=0, current_hand_type=8, frac_better_hands=approx(0.001010101055726409, abs=0.1), frac_tied_hands=0.0, frac_worse_hands=approx(0.9989898800849915, abs=0.1), win_odds=approx(0.9989898800849915, abs=0.1), tie_odds=0.0, lose_odds=approx(0.001010101055726409, abs=0.1), win_odds_vs_better=0.0, tie_odds_vs_better=0.0, lose_odds_vs_better=1.0, win_odds_vs_tied=0.0, tie_odds_vs_tied=0.0, lose_odds_vs_tied=0.0, win_odds_vs_worse=1.0, tie_odds_vs_worse=0.0, lose_odds_vs_worse=0.0, ), PlayerState( is_current_player=False, current_player_offset=1, current_hand_type=None, frac_better_hands=None, frac_tied_hands=None, frac_worse_hands=None, win_odds=None, tie_odds=None, lose_odds=None, win_odds_vs_better=None, tie_odds_vs_better=None, lose_odds_vs_better=None, win_odds_vs_tied=None, tie_odds_vs_tied=None, lose_odds_vs_tied=None, win_odds_vs_worse=None, tie_odds_vs_worse=None, lose_odds_vs_worse=None, ), ]
def test_state() -> None: deal = FullDeal( hole_cards=[mkhand("AhKs"), mkhand("Kc10d")], board=Board(flop=mkflop("KdJs3d"), turn=mkcard("7s"), river=mkcard("6s")), ) game = GameRunner(starting_stacks=[300, 400]) game.start_game() # Preflop game.bet_raise(to=10) game.call() # Flop game.check() game.check() # Turn game.check() game.check() # River game.check() game.check() player_index = 0 private_states = make_player_states(player_index, game.game_view(), deal.hole_cards[player_index], deal.board) assert private_states == [ PlayerState( is_current_player=True, current_player_offset=0, current_hand_type=None, frac_better_hands=None, frac_tied_hands=None, frac_worse_hands=None, win_odds=None, tie_odds=None, lose_odds=None, win_odds_vs_better=None, tie_odds_vs_better=None, lose_odds_vs_better=None, win_odds_vs_tied=None, tie_odds_vs_tied=None, lose_odds_vs_tied=None, win_odds_vs_worse=None, tie_odds_vs_worse=None, lose_odds_vs_worse=None, ), PlayerState( is_current_player=False, current_player_offset=1, current_hand_type=None, frac_better_hands=None, frac_tied_hands=None, frac_worse_hands=None, win_odds=None, tie_odds=None, lose_odds=None, win_odds_vs_better=None, tie_odds_vs_better=None, lose_odds_vs_better=None, win_odds_vs_tied=None, tie_odds_vs_tied=None, lose_odds_vs_tied=None, win_odds_vs_worse=None, tie_odds_vs_worse=None, lose_odds_vs_worse=None, ), PlayerState( is_current_player=True, current_player_offset=0, current_hand_type=2, frac_better_hands=approx(0.02867715060710907, abs=0.1), frac_tied_hands=approx(0.005550416186451912, abs=0.1), frac_worse_hands=approx(0.9657724499702454, abs=0.1), win_odds=approx(0.8368927240371704, abs=0.1), tie_odds=approx(0.010364476591348648, abs=0.1), lose_odds=approx(0.15274283289909363, abs=0.1), win_odds_vs_better=approx(0.16899999976158142, abs=0.1), tie_odds_vs_better=approx(0.0020000000949949026, abs=0.1), lose_odds_vs_better=approx(0.8289999961853027, abs=0.1), win_odds_vs_tied=0.0, tie_odds_vs_tied=approx(0.9869999885559082, abs=0.1), lose_odds_vs_tied=approx(0.013000000268220901, abs=0.1), win_odds_vs_worse=approx(0.8840000033378601, abs=0.1), tie_odds_vs_worse=approx(0.004000000189989805, abs=0.1), lose_odds_vs_worse=approx(0.1120000034570694, abs=0.1), ), PlayerState( is_current_player=False, current_player_offset=1, current_hand_type=None, frac_better_hands=None, frac_tied_hands=None, frac_worse_hands=None, win_odds=None, tie_odds=None, lose_odds=None, win_odds_vs_better=None, tie_odds_vs_better=None, lose_odds_vs_better=None, win_odds_vs_tied=None, tie_odds_vs_tied=None, lose_odds_vs_tied=None, win_odds_vs_worse=None, tie_odds_vs_worse=None, lose_odds_vs_worse=None, ), PlayerState( is_current_player=True, current_player_offset=0, current_hand_type=2, frac_better_hands=approx(0.05603864789009094, abs=0.1), frac_tied_hands=approx(0.005797101650387049, abs=0.1), frac_worse_hands=approx(0.938164234161377, abs=0.1), win_odds=approx(0.8556057810783386, abs=0.1), tie_odds=approx(0.005797101650387049, abs=0.1), lose_odds=approx(0.13859710097312927, abs=0.1), win_odds_vs_better=0.0, tie_odds_vs_better=0.0, lose_odds_vs_better=1.0, win_odds_vs_tied=0.0, tie_odds_vs_tied=1.0, lose_odds_vs_tied=0.0, win_odds_vs_worse=approx(0.9120000004768372, abs=0.1), tie_odds_vs_worse=0.0, lose_odds_vs_worse=approx(0.08799999952316284, abs=0.1), ), PlayerState( is_current_player=False, current_player_offset=1, current_hand_type=None, frac_better_hands=None, frac_tied_hands=None, frac_worse_hands=None, win_odds=None, tie_odds=None, lose_odds=None, win_odds_vs_better=None, tie_odds_vs_better=None, lose_odds_vs_better=None, win_odds_vs_tied=None, tie_odds_vs_tied=None, lose_odds_vs_tied=None, win_odds_vs_worse=None, tie_odds_vs_worse=None, lose_odds_vs_worse=None, ), PlayerState( is_current_player=True, current_player_offset=0, current_hand_type=2, frac_better_hands=approx(0.14646464586257935, abs=0.1), frac_tied_hands=approx(0.0060606058686971664, abs=0.1), frac_worse_hands=approx(0.8474747538566589, abs=0.1), win_odds=approx(0.8474747538566589, abs=0.1), tie_odds=approx(0.0060606058686971664, abs=0.1), lose_odds=approx(0.14646464586257935, abs=0.1), win_odds_vs_better=0.0, tie_odds_vs_better=0.0, lose_odds_vs_better=1.0, win_odds_vs_tied=0.0, tie_odds_vs_tied=1.0, lose_odds_vs_tied=0.0, win_odds_vs_worse=1.0, tie_odds_vs_worse=0.0, lose_odds_vs_worse=0.0, ), PlayerState( is_current_player=False, current_player_offset=1, current_hand_type=None, frac_better_hands=None, frac_tied_hands=None, frac_worse_hands=None, win_odds=None, tie_odds=None, lose_odds=None, win_odds_vs_better=None, tie_odds_vs_better=None, lose_odds_vs_better=None, win_odds_vs_tied=None, tie_odds_vs_tied=None, lose_odds_vs_tied=None, win_odds_vs_worse=None, tie_odds_vs_worse=None, lose_odds_vs_worse=None, ), ]
def test_royal() -> None: hole_cards = mkhand("AcKc") board = Board(flop=mkflop("TcJcQc")) eval_result = evaluate_hand(hole_cards, board) assert eval_result == EvaluationResult(hand_type=HandType.STRAIGHT_FLUSH, kicker=9)
def test_turn() -> None: hole_cards = mkhand("7d8s") board = Board(flop=mkflop("5h6cJs"), turn=mkcard("5h")) eval_result = evaluate_hand(hole_cards, board) assert eval_result == EvaluationResult(hand_type=HandType.PAIR, kicker=66144)
def test_winner() -> None: hole_cards = mkhand("AdAc") board = Board(flop=mkflop("AdKs3h"), turn=mkcard("5h"), river=mkcard("7s")) eval_result = evaluate_hand(hole_cards, board) assert eval_result == EvaluationResult(hand_type=HandType.TRIPS, kicker=33556512)
def test_wheel() -> None: hole_cards = mkhand("2c7d") board = Board(flop=mkflop("3h4c5s")) eval_result = evaluate_hand(hole_cards, board) assert eval_result == EvaluationResult(hand_type=HandType.HIGH, kicker=47)