Ejemplo n.º 1
0
 def train(self, *, iterations):
     deck = Deck()
     self.iteration = 1
     self.cumulative_stack_utilities = [
         0 for stack_size in range(TOTAL_STACKS +
                                   1)  # (stack_size) / TOTAL_STACKS
     ]
     for self.iteration in range(1, iterations):
         for p0_stack in range(1, TOTAL_STACKS):
             p1_stack = TOTAL_STACKS - p0_stack
             deck.reset()
             deck.shuffle()
             p0_hand = Hand([deck.pop(), deck.pop()])
             p1_hand = Hand([deck.pop(), deck.pop()])
             big_blind = min(BIG_BLIND, p0_stack, p1_stack)
             self.cumulative_stack_utilities[p0_stack] += self.cfr(
                 deck,
                 (p0_hand, p1_hand),
                 EMPTY_HISTORY,
                 (p0_stack, p1_stack),
                 (SMALL_BLIND, big_blind),
                 (1, 1),
             )
     # print(f"Average game value: {utility/iterations}")
     print(f"Iterations: {iterations}")
     print("Stack size,Utility")
     for stack_size, utility in enumerate(self.cumulative_stack_utilities):
         print(f"{stack_size},{self.get_average_stack_utility(stack_size)}")
     for node in map(lambda node: node[1], sorted(self.node_map.items())):
         print(node)
Ejemplo n.º 2
0
    def test_shuffles_card_in_random_order(self, mock_shuffle):
        deck = Deck()

        cards = [Card(rank="2", suit="Clubs"), Card(rank="Ace", suit="Spades")]

        deck.add_cards(cards)
        deck.shuffle()
        mock_shuffle.assert_called_once_with(cards)
Ejemplo n.º 3
0
    def test_deck_shuffles_the_cards(self, mock_shuffle):

        deck = Deck()

        cards = [
            Card(rank="Ace", suite="clubs"),
            Card(rank="8", suite="clubs")
        ]
        deck.add_cards(cards)
        deck.shuffle()

        mock_shuffle.assert_called_once_with(cards)
Ejemplo n.º 4
0
def setupDeck(heroHand, villainHand, currentBoard=None):
	deck = Deck()

	# Remove dealt cards from Deck
	deck.cards.remove(heroHand.card1)
	deck.cards.remove(heroHand.card2)
	deck.cards.remove(villainHand.card1)
	deck.cards.remove(villainHand.card2)

	if currentBoard:
		for card in currentBoard.cards:
			deck.cards.remove(card)
	deck.shuffle()
	return deck
Ejemplo n.º 5
0
def compute_hand_win_probability(deck: Deck, private_hand_0: Hand,
                                 private_hand_1: Hand):
    """
        Returns a real between 0 and 1 representing the expected win rate
        of Private Hand 0 against Private Hand 1, when randomly sampling
        public cards.
        """
    wins = 0
    for _ in range(EXPECTED_VALUE_SIMULATIONS):
        deck.shuffle()
        public_cards = deck.peek(5)
        full_hand_0 = Hand(private_hand_0.cards + public_cards)
        full_hand_1 = Hand(private_hand_1.cards + public_cards)
        if full_hand_0 > full_hand_1:
            wins += 1
        elif full_hand_0 == full_hand_1:
            wins += 0.5
    return wins / EXPECTED_VALUE_SIMULATIONS
Ejemplo n.º 6
0
class Game:
    def __init__(self, small_b, big_b):
        self.small_blind = small_b
        self.big_blind = big_b
        self.players = [None, None, None, None, None, None, None, None]
        self.fil_players = []
        self.flop = []
        self.turn = None
        self.river = None
        self.deck = None
        self.small_b_pos = None
        self.big_b_pos = None
        self.utg_pos = None
        self.small_b_pos_f = None
        self.big_b_pos_f = None
        self.side_pot = 0
        self.pot = 0
        self.current_bet = 0  # highest bet on the table
        self.round_num = 0
        self.side_pot_active = False
        self.folded_val = 0
        self.round_over = False

    def add_player(self, seat_pos, username, chips, id):
        if seat_pos < 8:
            if not self.players[seat_pos]:
                self.players[seat_pos] = Player()
                self.players[seat_pos].user = username
                self.players[seat_pos].seat_num = seat_pos
                self.players[seat_pos].coins = chips
                self.players[seat_pos].id = id

    def start_round(self):
        self.flop = []
        self.turn = None
        self.river = None
        self.deck = Deck()
        self.deck.shuffle()

    def deal_cards(self):
        for i in range(8):
            if self.players[i] is not None:
                fst_card = self.deck.deck_card.pop(0)
                self.players[i].addToHand(fst_card)
                s_card = self.deck.deck_card.pop(0)
                self.players[i].addToHand(s_card)
                print(self.players[i].user, ":", fst_card, "and", s_card)

    def deal_flop(self):
        self.flop.append(self.deck.deck_card.pop(0))
        self.flop.append(self.deck.deck_card.pop(0))
        self.flop.append(self.deck.deck_card.pop(0))
        print("The flop is:")
        for i in self.flop:
            print(i.number, i.suit)
        for i in self.flop:
            for j in self.fil_players:
                j.addToHand(i)

    def deal_turn(self):
        self.turn = self.deck.deck_card.pop(0)
        for j in self.fil_players:
            j.addToHand(self.turn)
        print("The turn is: ", self.turn)

    def deal_river(self):
        self.river = self.deck.deck_card.pop(0)
        for j in self.fil_players:
            j.addToHand(self.river)
        print("The river is: ", self.river)

    def set_blinds(self):
        cnt = 0
        if self.round_num == 0:
            self.round_num += 1
            for i in range(8):
                if self.players[i] is not None:
                    self.players[i].small_blind = False
                    self.players[i].big_blind = False
            for i in range(8):
                if self.players[i] is not None and cnt == 0:
                    self.players[i].small_blind = True
                    self.small_b_pos = i
                    cnt += 1
                elif self.players[i] is not None and cnt == 1:
                    self.players[i].big_blind = True
                    self.big_b_pos = i
                    cnt += 1
        else:
            big_b_set = False
            for i in range(8):
                if self.players[i] is not None and self.players[
                        i].small_blind and cnt == 0:
                    self.players[i].small_blind = False
                elif self.players[i] is not None and self.players[
                        i].big_blind and cnt == 0:
                    self.players[i].small_blind = True
                    self.players[i].big_blind = False
                    self.small_b_pos = i
                    cnt += 1
                elif self.players[i] is not None and cnt == 1:
                    self.players[i].big_blind = True
                    self.big_b_pos = i
                    big_b_set = True
                    cnt += 1
                elif i == 7 and big_b_set == False:
                    for j in range(8):
                        if self.players[j] is not None and cnt == 1:
                            self.players[j].big_blind = True
                            self.big_b_pos = i
                            big_b_set = True
                            self.round_num = 0
                            cnt = 0

    def one_pl_left(self):
        cnt = 0
        for i in self.fil_players:
            if i.is_playing:
                cnt += 1
        if cnt == 1:
            return True

    def last_player_pos(self):
        for i in range(len(self.fil_players)):
            if self.fil_players[i].is_playing:
                return i

    def fst_pos_after_bb(self):
        lst = []
        for i in range(1, len(self.fil_players)):
            if self.fil_players[(self.big_b_pos_f + i) %
                                len(self.fil_players)].is_playing:
                lst.append((self.big_b_pos_f + i) % len(self.fil_players))
        return lst[0]

    def process_turn(self, pl_id, bet_size):
        for i in self.fil_players:
            if i.id == pl_id:
                if bet_size == -1:
                    print("You have folded.")
                    i.fold()
                    self.folded_val += i.cumu_bet
                    if self.one_pl_left():
                        print(self.fil_players[self.last_player_pos()].user,
                              " has won the pot")
                        self.fil_players[
                            self.last_player_pos()].coins += self.pot
                        self.round_over = True
                        self.pot = 0
                        break
                elif bet_size + i.bet == self.current_bet:
                    i.call_check_raise(bet_size)
                    i.coins -= bet_size
                    self.pot += bet_size
                    self.current_bet = i.bet
                    i.cumu_bet += i.bet
                    i.rebet = False
                elif bet_size + i.bet > self.current_bet:
                    i.call_check_raise(bet_size)
                    i.coins -= bet_size
                    self.pot += bet_size
                    self.current_bet = i.bet
                    i.cumu_bet += i.bet
                    i.rebet = False
                    for j in self.fil_players:
                        if j.is_playing and not j.id == i.id:
                            j.rebet = True
                elif bet_size == -2:  # means player is still in but has no coins to bet
                    i.rebet = False
                else:
                    print("Invalid bet. You have folded.")
                    i.fold()
                    if self.one_pl_left():
                        print(self.fil_players[self.last_player_pos()].user,
                              " has won the pot")
                        self.fil_players[
                            self.last_player_pos()].coins += self.pot
                        self.pot = 0
                        break

    def bet_round_pf_new(self):
        re_bet = True
        while re_bet:
            re_bet = False
            for j in range(1, len(self.fil_players) + 1):
                if self.fil_players[(self.big_b_pos_f + j) % len(
                        self.fil_players)].is_playing and self.fil_players[
                            (self.big_b_pos_f + j) %
                            len(self.fil_players)].coins != 0:
                    x = int(input("Enter a bet(-1 if folding): "))
                    y = self.fil_players[(self.big_b_pos_f + j) %
                                         len(self.fil_players)].id
                    self.process_turn(y, x)
                    some_true = False
                    for i in self.fil_players:
                        if i.is_playing:
                            if i.rebet:
                                some_true = True
                    if not some_true:
                        break
            for i in self.fil_players:
                if i.is_playing:
                    if i.rebet:
                        re_bet = True
            if not re_bet:
                self.current_bet = 0
                for i in self.players:
                    if i is not None:
                        i.bet = 0
                        i.rebet = True
                for i in self.fil_players:
                    i.bet = 0
                    i.rebet = True

    def bet_round_af_new(self):
        re_bet = True
        while re_bet:
            re_bet = False
            for j in range(len(self.fil_players)):
                if self.fil_players[(self.small_b_pos_f + j) % len(
                        self.fil_players)].is_playing and self.fil_players[
                            (self.big_b_pos_f + j) %
                            len(self.fil_players)].coins != 0:
                    x = int(input("Enter a bet(-1 if folding): "))
                    y = self.fil_players[(self.small_b_pos_f + j) %
                                         len(self.fil_players)].id
                    self.process_turn(y, x)
                    some_true = False
                    for i in self.fil_players:
                        if i.is_playing:
                            if i.rebet:
                                some_true = True
                    if not some_true:
                        break
            for i in self.fil_players:
                if i.is_playing:
                    if i.rebet:
                        re_bet = True
            if not re_bet:
                self.current_bet = 0
                for i in self.players:
                    if i is not None:
                        i.bet = 0
                        i.rebet = True
                for i in self.fil_players:
                    i.bet = 0
                    i.rebet = True

    def check_dup(self, list_elems):
        if len(list_elems) == len(set(list_elems)):
            return False
        else:
            return True

    def get_cumu(self, c):
        return c.cumu_bet

    def get_winner(self):
        winner = []
        win_cumu_bets = []
        loser_bets = []
        players_in = 0
        for i in self.fil_players:
            if i.is_playing:
                players_in += 1
        top_val = 0
        for i in self.fil_players:
            if i.bestHand() > top_val:
                top_val = i.bestHand()
                winner = [i]
                win_cumu_bets = [i.cumu_bet]
            elif i.bestHand() == top_val:
                winner.append(i)
                win_cumu_bets.append(i.cumu_bet)
        for i in self.fil_players:
            if i not in winner:
                loser_bets.append(i)
        winner.sort(key=self.get_cumu)
        for i in winner:
            i.coins += i.cumu_bet
            print(i.user, "wins", "with a", i.top_hand[0])
        prev_win = 0
        prev_bet = 0
        while winner:
            for i in loser_bets:
                if i.cumu_bet <= winner[0].cumu_bet:
                    r_value = round(i.cumu_bet / len(winner))
                    winner[0].coins += r_value
                    i.cumu_bet -= r_value
                else:
                    prev_win = round((winner[0].cumu_bet - prev_bet) /
                                     len(winner)) + prev_win
                    winner[0].coins += prev_win
                    i.cumu_bet -= prev_win
                    prev_bet = winner[0].cumu_bet
            winner.pop(0)
        for i in loser_bets:
            i.coins += i.cumu_bet
        self.pot = 0

    def sb_bb_setup(self):
        for i in range(8):
            if self.players[i] is not None and self.players[i].small_blind:
                self.players[i].call_check_raise(self.small_blind)
                self.players[
                    i].coins = self.players[i].coins - self.small_blind
                self.players[i].bet = self.small_blind
                self.pot += self.small_blind
                print(self.players[i].user, " puts in a small blind of ",
                      self.small_blind)
            if self.players[i] is not None and self.players[i].big_blind:
                self.players[i].call_check_raise(self.big_blind)
                self.players[i].coins = self.players[i].coins - self.big_blind
                self.pot += self.big_blind
                self.current_bet = self.big_blind
                self.players[i].bet = self.big_blind
                print(self.players[i].user, " puts in a small blind of ",
                      self.big_blind)

    def filter_players(self):
        for i in self.players:
            if i is not None:
                self.fil_players.append(i)

    def play(self):
        self.start_round()
        self.deal_cards()
        self.set_blinds()
        self.sb_bb_setup()
        self.filter_players()
        for i in range(len(self.fil_players)):
            if self.fil_players[i].big_blind:
                self.small_b_pos_f = (i - 1) % len(self.fil_players)
                self.big_b_pos_f = i
        self.bet_round_pf_new()
        if not self.round_over:
            self.deal_flop()
        print("---------------------")
Ejemplo n.º 7
0
 def test_shuffle(self):
     deck1 = Deck()
     deck2 = Deck()
     deck2.shuffle()
     assert deck1.cards != deck2.cards
     assert len(deck2.cards) == 52