Exemple #1
0
    def __init__(self, starting_stacks):

        # Must have at least 1 player
        assert len(starting_stacks) > 1

        self.game_started = False
        self.action_index = 0
        self.game = Game(starting_stacks=starting_stacks)
Exemple #2
0
def test_is_all_in():
    game = Game(starting_stacks=[100, 200, 10])

    game.add_action(Action(0, Move.SMALL_BLIND, total_bet=1, amount_added=1))
    game.add_action(Action(1, Move.BIG_BLIND, total_bet=2, amount_added=2))
    game.add_action(Action(2, Move.BET_RAISE, total_bet=10, amount_added=10))

    assert game.view().is_all_in() == [False, False, True]
Exemple #3
0
def test_blinds():
    game = Game(starting_stacks=[10, 20, 100])

    assert game.view().small_blind() == Action(0,
                                               Move.SMALL_BLIND,
                                               total_bet=1,
                                               amount_added=1)
    game.add_action(game.view().small_blind())

    assert game.view().big_blind() == Action(1,
                                             Move.BIG_BLIND,
                                             total_bet=2,
                                             amount_added=2)
Exemple #4
0
def test_street_over_all_fold():
    game = Game(starting_stacks=[100, 200, 300])

    game.add_action(game.view().small_blind())
    game.add_action(game.view().big_blind())
    game.add_action(game.view().bet_raise(to=10))
    game.add_action(game.view().fold())
    game.add_action(game.view().fold())

    assert rules.street_over(game.view()) is True

    game.set_street(Street.FLOP)
    assert rules.street_over(game.view()) is True

    game.set_street(Street.TURN)
    assert rules.street_over(game.view()) is True

    game.set_street(Street.RIVER)
    assert rules.street_over(game.view()) is True
Exemple #5
0
def test_street_over():
    game = Game(starting_stacks=[100, 200, 300])
    assert rules.street_over(game.view()) is False

    game.add_action(game.view().small_blind())
    assert rules.street_over(game.view()) is False

    game.add_action(game.view().big_blind())
    assert rules.street_over(game.view()) is False

    game.add_action(game.view().bet_raise(to=10))
    assert rules.street_over(game.view()) is False

    game.add_action(game.view().call())
    assert rules.street_over(game.view()) is False

    game.add_action(game.view().call())
    assert rules.street_over(game.view()) is True

    # Flop
    game.set_street(Street.FLOP)
    assert rules.street_over(game.view()) is False

    game.add_action(game.view().call())
    assert rules.street_over(game.view()) is False

    game.add_action(game.view().call())
    assert rules.street_over(game.view()) is False

    game.add_action(game.view().call())
    assert rules.street_over(game.view()) is True

    # Turn
    game.set_street(Street.TURN)
    assert rules.street_over(game.view()) is False

    game.add_action(game.view().bet_raise(to=20))
    assert rules.street_over(game.view()) is False

    game.add_action(game.view().fold())
    assert rules.street_over(game.view()) is False

    game.add_action(game.view().call())
    assert rules.street_over(game.view()) is True

    # River
    game.set_street(Street.RIVER)
    assert rules.street_over(game.view()) is False

    game.add_action(game.view().call())
    assert rules.street_over(game.view()) is False

    game.add_action(game.view().bet_raise(to=30))
    assert rules.street_over(game.view()) is False

    game.add_action(game.view().call())
    assert rules.street_over(game.view()) is True
Exemple #6
0
def test_amount_bet():
    game = Game(starting_stacks=[100, 200, 300])

    preflop_action = [
        Action(0, Move.SMALL_BLIND, total_bet=1, amount_added=1),
        Action(1, Move.BIG_BLIND, total_bet=2, amount_added=2),
        Action(2, Move.BET_RAISE, total_bet=6, amount_added=6),
    ]

    for a in preflop_action:
        game.add_action(a)

    assert game.view().amount_added_in_street() == [1, 2, 6]

    game.set_street(Street.FLOP)

    flop_action = [
        Action(0, Move.CHECK_CALL, total_bet=0, amount_added=0),
        Action(1, Move.BET_RAISE, total_bet=10, amount_added=10),
        Action(2, Move.FOLD, amount_added=0, total_bet=10),
        Action(0, Move.FOLD, amount_added=0, total_bet=10),
    ]

    for a in flop_action:
        game.add_action(a)

    assert game.view().amount_added_in_street() == [0, 10, 0]
    assert game.view().amount_added_total() == [1, 12, 6]
Exemple #7
0
def test_num_players():
    game = Game(starting_stacks=[100, 200, 300])

    assert game.num_players() == 3
    assert game.view().num_players() == 3
Exemple #8
0
def test_call_all_in():
    game = Game(starting_stacks=[10, 20, 100])

    game.add_action(Action(0, Move.SMALL_BLIND, total_bet=1, amount_added=1))
    game.add_action(Action(1, Move.BIG_BLIND, total_bet=2, amount_added=2))
    game.add_action(Action(2, Move.BET_RAISE, total_bet=100, amount_added=100))

    call = game.view().call()
    assert game.view().call() == Action(player_index=0,
                                        move=Move.CHECK_CALL,
                                        amount_added=9,
                                        total_bet=100)
    game.add_action(call)

    call = game.view().call()
    assert call == Action(player_index=1,
                          move=Move.CHECK_CALL,
                          amount_added=18,
                          total_bet=100)
Exemple #9
0
def test_is_folded():
    game = Game(starting_stacks=[100, 200, 300])

    game.add_action(Action(0, Move.SMALL_BLIND, total_bet=1, amount_added=1))
    game.add_action(Action(1, Move.BIG_BLIND, total_bet=2, amount_added=2))
    game.add_action(Action(2, Move.FOLD, total_bet=2, amount_added=0))

    assert game.view().is_folded() == [False, False, True]

    game.add_action(Action(1, Move.CHECK_CALL, total_bet=2, amount_added=1))
    game.add_action(Action(2, Move.CHECK_CALL, total_bet=2, amount_added=0))

    assert game.view().is_folded() == [False, False, True]

    game.set_street(Street.TURN)

    assert game.view().is_folded() == [False, False, True]

    game.add_action(Action(0, Move.BET_RAISE, total_bet=10, amount_added=10))
    game.add_action(Action(1, Move.FOLD, total_bet=10, amount_added=0))
    assert game.view().is_folded() == [False, True, True]
Exemple #10
0
def test_latest_bet_raise_amount():
    game = Game(starting_stacks=[100, 200, 300])

    assert game.view().last_raise_amount() == 0

    game.add_action(Action(0, Move.SMALL_BLIND, total_bet=1, amount_added=1))
    assert game.view().last_raise_amount() == 1
    assert game.view().current_bet_amount() == 1

    game.add_action(Action(1, Move.BIG_BLIND, total_bet=2, amount_added=2))
    assert game.view().last_raise_amount() == 1
    assert game.view().current_bet_amount() == 2

    game.add_action(Action(2, Move.BET_RAISE, total_bet=10, amount_added=10))
    assert game.view().last_raise_amount() == 8
    assert game.view().current_bet_amount() == 10

    # Raise to 20 total.  This is a raise of 8 on top of the original 10.
    # It is a min-raise.
    game.add_action(
        Action(0, Move.BET_RAISE, total_bet=18, amount_added=18 - 1))
    assert game.view().last_raise_amount() == 8
    assert game.view().current_bet_amount() == 18

    # Riase it to 30 total (up from the previous 18).  This is a raise of 12.
    game.add_action(
        Action(1, Move.BET_RAISE, total_bet=30, amount_added=30 - 2))
    assert game.view().last_raise_amount() == 12
    assert game.view().current_bet_amount() == 30
Exemple #11
0
def test_bet_and_call_amount():
    game = Game(starting_stacks=[100, 200, 300])

    assert game.view().current_bet_amount() == 0
    assert game.view().amount_to_call() == [0, 0, 0]

    game.add_action(Action(0, Move.SMALL_BLIND, total_bet=1, amount_added=1))
    assert game.view().current_bet_amount() == 1
    assert game.view().amount_to_call() == [0, 1, 1]

    game.add_action(Action(1, Move.BIG_BLIND, total_bet=2, amount_added=2))
    game.add_action(Action(2, Move.BET_RAISE, total_bet=10, amount_added=10))
    assert game.view().current_bet_amount() == 10
    assert game.view().amount_to_call() == [9, 8, 0]

    game.add_action(Action(0, Move.CHECK_CALL, total_bet=10, amount_added=9))
    game.add_action(Action(1, Move.CHECK_CALL, total_bet=10, amount_added=8))
    assert game.view().current_bet_amount() == 10
    assert game.view().amount_to_call() == [0, 0, 0]
Exemple #12
0
def test_action_views():
    game = Game(starting_stacks=[100, 200, 300])

    preflop_action = [
        Action(0, Move.SMALL_BLIND, total_bet=1, amount_added=1),
        Action(1, Move.BIG_BLIND, total_bet=2, amount_added=2),
        Action(2, Move.BET_RAISE, total_bet=6, amount_added=6),
        Action(0, Move.CHECK_CALL, total_bet=6, amount_added=5),
        Action(1, Move.CHECK_CALL, total_bet=6, amount_added=4),
    ]

    for a in preflop_action:
        game.add_action(a)

    assert game.current_street() == Street.PREFLOP
    assert game.events == preflop_action

    preflop_view = game.view()
    assert preflop_view.street_action() == preflop_action
    assert preflop_view.all_actions() == preflop_action

    game.set_street(Street.FLOP)

    flop_action = [
        Action(0, Move.CHECK_CALL, total_bet=0, amount_added=0),
        Action(1, Move.BET_RAISE, total_bet=10, amount_added=10),
        Action(2, Move.FOLD, total_bet=10, amount_added=0),
        Action(0, Move.FOLD, total_bet=10, amount_added=0),
    ]

    for a in flop_action:
        game.add_action(a)

    assert game.current_street() == Street.FLOP
    assert game.events == preflop_action + [Street.FLOP] + flop_action

    # assert preflop_view.timestamp ==
    assert preflop_view.street_action() == preflop_action
    assert preflop_view.all_actions() == preflop_action

    # Recreate the preflop view
    preflop_view = game.view(timestamp=5)
    assert preflop_view.street_action() == preflop_action
    assert preflop_view.all_actions() == preflop_action

    flop_view = game.view()

    assert flop_view.street_action() == flop_action
    assert flop_view.all_actions() == preflop_action + flop_action

    # Test a view in the middle of the preflop

    mid_preflop_view = game.view(3)
    assert mid_preflop_view.street_action() == [
        Action(0, Move.SMALL_BLIND, total_bet=1, amount_added=1),
        Action(1, Move.BIG_BLIND, total_bet=2, amount_added=2),
        Action(2, Move.BET_RAISE, total_bet=6, amount_added=6),
    ]
Exemple #13
0
def test_stack_sizes():
    game = Game(starting_stacks=[100, 200, 300])

    assert game.view().current_stack_sizes() == [100, 200, 300]

    game.add_action(Action(0, Move.SMALL_BLIND, total_bet=1, amount_added=1))
    game.add_action(Action(1, Move.BIG_BLIND, total_bet=2, amount_added=2))
    game.add_action(Action(2, Move.BET_RAISE, total_bet=6, amount_added=6))
    assert game.view().current_stack_sizes() == [99, 198, 294]

    game.add_action(Action(0, Move.CHECK_CALL, total_bet=6, amount_added=5))
    game.add_action(Action(1, Move.CHECK_CALL, total_bet=6, amount_added=4))
    assert game.view().current_stack_sizes() == [94, 194, 294]

    game.set_street(Street.TURN)

    game.add_action(Action(0, Move.CHECK_CALL, total_bet=0, amount_added=0))
    game.add_action(Action(1, Move.BET_RAISE, total_bet=10, amount_added=10))
    assert game.view().current_stack_sizes() == [94, 184, 294]
Exemple #14
0
class GameRunner:
    def __init__(self, starting_stacks):

        # Must have at least 1 player
        assert len(starting_stacks) > 1

        self.game_started = False
        self.action_index = 0
        self.game = Game(starting_stacks=starting_stacks)

    def game_view(self):
        return self.game.view()

    def current_player(self):
        return self.game_view().current_player()

    def street(self):
        return self.game_view().street()

    def start_game(self):
        # Small/Big Blind
        self.game_started = True
        self.game.set_street(Street.PREFLOP)
        self.add_small_blind()
        self.add_big_blind()

    def advance(self, action: Action) -> ActionResult:
        if not self.game_started:
            raise Exception("Game not started")

        player_index = self.game_view().current_player()

        action_result = rules.action_valid(
            action_index=self.action_index,
            player_index=player_index,
            action=action,
            game=self.game_view(),
        )

        # Validate the action
        if player_index != action.player_index:
            raise Exception("Wrong Player")

        if not action_result.is_valid():
            logger.error("Action is invalid %s %s", action, action_result)
            raise ActionError(self.game_view(), action, action_result)

        self.game.add_action(action)
        self.action_index += 1
        player_index = self.game_view().current_player()

        if self.all_but_one_player_folded():
            return self._end_hand()

        while rules.street_over(self.game_view()):
            self._advance_street()
            if self.street() == Street.HAND_OVER:
                break

        # Return the current state of the game
        if self.game_view().street() == Street.HAND_OVER:
            return ActionResult(street=self.game_view().street())
        else:
            return ActionResult(
                street=self.game_view().street(),
                current_player=self.game_view().current_player(),
                total_bet=self.game_view().current_bet_amount(),
                amount_to_call=self.game_view().amount_to_call()[player_index],
            )

    def add_small_blind(self) -> ActionResult:
        return self.advance(self.game_view().small_blind())

    def add_big_blind(self) -> ActionResult:
        return self.advance(self.game_view().big_blind())

    def call(self) -> ActionResult:
        return self.advance(self.game_view().call())

    def check(self) -> ActionResult:
        return self.advance(self.game_view().check())

    def bet_raise(self,
                  to: Optional[int] = None,
                  raise_amount: Optional[int] = None) -> ActionResult:
        return self.advance(self.game_view().bet_raise(
            to=to, raise_amount=raise_amount))

    def fold(self) -> ActionResult:
        return self.advance(self.game_view().fold())

    def _advance_street(self):

        if self.game_view().street() == Street.PREFLOP:
            self.game.set_street(Street.FLOP)
        elif self.game_view().street() == Street.FLOP:
            self.game.set_street(Street.TURN)
        elif self.game_view().street() == Street.TURN:
            self.game.set_street(Street.RIVER)

        elif self.game_view().street() == Street.RIVER:
            self.game.set_street(Street.HAND_OVER)
        else:
            raise Exception()

    def _end_hand(self):
        self.game.set_street(Street.HAND_OVER)
        return ActionResult(street=self.game_view().street())

    def all_but_one_player_folded(self):
        num_not_folded = 0
        for is_folded in self.game_view().is_folded():
            if not is_folded:
                num_not_folded += 1
        return num_not_folded == 1

    def all_players_all_in(self):
        num_not_all_in = 0
        for is_all_in in self.game_view().is_all_in():
            if not is_all_in:
                num_not_all_in += 1
        return num_not_all_in == 0