def naive_rank(pocket, community_cards): print("Evaluating") pocket = [Card(v, s) for v, s in pocket] community_cards = [Card(v, s) for v, s in community_cards] unopened_slots = min(3, 7 - len(pocket) - len(community_cards)) deck = Deck() deck.removeall(pocket + community_cards) count = 0 _rank = 0 for possibility in itertools.combinations(deck.cards, r=unopened_slots): _rank += max(generate_possible_hands(pocket, community_cards + list(possibility))).rank count += 1 LOGGER.debug("Evaluated %d hands" % count) return _rank / count
def __init__(self, players, button_player, small_blind, event_queue, game): self.game = game self.event_queue = event_queue self.players = players[:] self.folded_players = [] self.small_blind = small_blind self.betting_player = None self.pot = None self.deck = Deck() self.community_cards = [] self.button_player = button_player self.pot = Pot(self.small_blind) self.action_log = [] LOGGER.info("Dealing cards") for player in self.players: player.set_pocket(self.deck.draw_single(), self.deck.draw_single())
def __init__(self, players, button_player, small_blind): self.players = players[:] self.folded_players = [] self.small_blind = small_blind self.betting_player = None self.pot = None self.deck = Deck() self.community_cards = [] self.button_player = button_player self.pot = Pot(self.small_blind) LOGGER.info("Dealing cards") for player in self.players: player.set_pocket(self.deck.draw(), self.deck.draw())
class Round(object): def __init__(self, players, button_player, small_blind, event_queue, game): self.game = game self.event_queue = event_queue self.players = players[:] self.folded_players = [] self.small_blind = small_blind self.betting_player = None self.pot = None self.deck = Deck() self.community_cards = [] self.button_player = button_player self.pot = Pot(self.small_blind) self.action_log = [] LOGGER.info("Dealing cards") for player in self.players: player.set_pocket(self.deck.draw_single(), self.deck.draw_single()) def bet(self, player, amount): self.event_queue.put(Events.PLAYER_BET) self.pot.bet(player, amount) def is_folded(self, player): return player in self.folded_players @property def active_players(self): return [player for player in self.players if player not in self.folded_players] def after(self, player): index = self.players.index(player) return self.players[(index + 1) % len(self.players)] def take_blinds(self): self.small_blind_player().force_bet(self.small_blind, self) self.big_blind_player().force_bet(2 * self.small_blind, self) return self.betting_player def small_blind_player(self): return self.after(self.button_player) def big_blind_player(self): return self.after(self.after(self.button_player)) def winner(self): # check if only a single player is left return self.players[0] if len(self.players) - len(self.folded_players) == 1 else None def pre_flop_betting(self): if self.winner() is not None: return self.betting_player = self.after(self.big_blind_player()) self.place_bets() def pre_turn_betting(self): if self.winner() is not None: return self.betting_player = self.after(self.button_player) self.place_bets() def pre_river_betting(self): if self.winner() is not None: return self.betting_player = self.after(self.button_player) self.place_bets() def final_betting(self): if self.winner() is not None: return self.betting_player = self.after(self.button_player) self.place_bets() def next_betting_player(self): start = self.betting_player candidate = self.after(start) while candidate is not start: if candidate.is_betting(self): LOGGER.info("Found betting player %s" % candidate) return candidate LOGGER.info("Skipping player %s" % candidate) candidate = self.after(candidate) return None def place_bets(self): # when no betting players are left # self.betting_player will be set to None # set player first_bet to True to indicate this player is yet to bet for player in self.active_players: player.first_bet = True if not self.betting_player.is_betting(self): LOGGER.info("Skipping player: %s" % str(self.betting_player)) self.betting_player = self.next_betting_player() while self.betting_player is not None: LOGGER.info("player %s is choosing an action", self.betting_player.name) self.betting_player.first_bet = False self.event_queue.put(Events.PLAYER_BETTING) action = self.betting_player.interact(self.game) LOGGER.info("%s chose Action: %s" % (self.betting_player.name, action.__class__.__name__)) self.action_log.append(action) action.apply() self.betting_player = self.next_betting_player() LOGGER.info("Done betting for pre_flop_round") def play(self): LOGGER.info("Playing another round of poker") self.take_blinds() LOGGER.info("Playing first round (pre-flop)") self.pre_flop_betting() self.open_flop_cards() LOGGER.info("Playing first round (pre-turn)") self.pre_turn_betting() self.open_turn_cards() LOGGER.info("Playing first round (pre-river)") self.pre_river_betting() self.open_river_cards() self.final_betting() LOGGER.info("Round winners:") for winner_ in self.get_round_winners(): LOGGER.info("%s" % winner_) return dict(self.finish_round()) def open_card(self): self.event_queue.put(Events.CARD_OPENED) self.community_cards.append(self.deck.draw_single()) def open_flop_cards(self): self.open_card() self.open_card() self.open_card() def open_turn_cards(self): self.open_card() def open_river_cards(self): self.open_card() def finish_round(self): self.event_queue.put(Events.ROUND_FINISHED) for winner_ in self.get_round_winners(): winnings = self.pot.take_pot_for_player(winner_) LOGGER.info("Giving winnings (%d) to player: %s [%s]" % ( winnings, winner_.name, winner_.best_hand(self.community_cards))) winner_.money += winnings yield winner_, winnings def get_round_winners(self): return sorted( set(self.players) - set(self.folded_players), key=lambda x: x.best_hand(self.community_cards), reverse=True )
class Round(object): def __init__(self, players, button_player, small_blind, event_queue, game): self.game = game self.event_queue = event_queue self.players = players[:] self.folded_players = [] self.small_blind = small_blind self.betting_player = None self.pot = None self.deck = Deck() self.community_cards = [] self.button_player = button_player self.pot = Pot(self.small_blind) self.action_log = [] LOGGER.info("Dealing cards") for player in self.players: player.set_pocket(self.deck.draw_single(), self.deck.draw_single()) def bet(self, player, amount): self.event_queue.put(Events.PLAYER_BET) self.pot.bet(player, amount) def is_folded(self, player): return player in self.folded_players @property def active_players(self): return [ player for player in self.players if player not in self.folded_players ] def after(self, player): index = self.players.index(player) return self.players[(index + 1) % len(self.players)] def take_blinds(self): self.small_blind_player().force_bet(self.small_blind, self) self.big_blind_player().force_bet(2 * self.small_blind, self) return self.betting_player def small_blind_player(self): return self.after(self.button_player) def big_blind_player(self): return self.after(self.after(self.button_player)) def winner(self): # check if only a single player is left return self.players[0] if len(self.players) - len( self.folded_players) == 1 else None def pre_flop_betting(self): if self.winner() is not None: return self.betting_player = self.after(self.big_blind_player()) self.place_bets() def pre_turn_betting(self): if self.winner() is not None: return self.betting_player = self.after(self.button_player) self.place_bets() def pre_river_betting(self): if self.winner() is not None: return self.betting_player = self.after(self.button_player) self.place_bets() def final_betting(self): if self.winner() is not None: return self.betting_player = self.after(self.button_player) self.place_bets() def next_betting_player(self): start = self.betting_player candidate = self.after(start) while candidate is not start: if candidate.is_betting(self): LOGGER.info("Found betting player %s" % candidate) return candidate LOGGER.info("Skipping player %s" % candidate) candidate = self.after(candidate) return None def place_bets(self): # when no betting players are left # self.betting_player will be set to None # set player first_bet to True to indicate this player is yet to bet for player in self.active_players: player.first_bet = True if not self.betting_player.is_betting(self): LOGGER.info("Skipping player: %s" % str(self.betting_player)) self.betting_player = self.next_betting_player() while self.betting_player is not None: LOGGER.info("player %s is choosing an action", self.betting_player.name) self.betting_player.first_bet = False self.event_queue.put(Events.PLAYER_BETTING) action = self.betting_player.interact(self.game) LOGGER.info("%s chose Action: %s" % (self.betting_player.name, action.__class__.__name__)) self.action_log.append(action) action.apply() self.betting_player = self.next_betting_player() LOGGER.info("Done betting for pre_flop_round") def play(self): LOGGER.info("Playing another round of poker") self.take_blinds() LOGGER.info("Playing first round (pre-flop)") self.pre_flop_betting() self.open_flop_cards() LOGGER.info("Playing first round (pre-turn)") self.pre_turn_betting() self.open_turn_cards() LOGGER.info("Playing first round (pre-river)") self.pre_river_betting() self.open_river_cards() self.final_betting() LOGGER.info("Round winners:") for winner_ in self.get_round_winners(): LOGGER.info("%s" % winner_) return dict(self.finish_round()) def open_card(self): self.event_queue.put(Events.CARD_OPENED) self.community_cards.append(self.deck.draw_single()) def open_flop_cards(self): self.open_card() self.open_card() self.open_card() def open_turn_cards(self): self.open_card() def open_river_cards(self): self.open_card() def finish_round(self): self.event_queue.put(Events.ROUND_FINISHED) for winner_ in self.get_round_winners(): winnings = self.pot.take_pot_for_player(winner_) LOGGER.info("Giving winnings (%d) to player: %s [%s]" % (winnings, winner_.name, winner_.best_hand(self.community_cards))) winner_.money += winnings yield winner_, winnings def get_round_winners(self): return sorted(set(self.players) - set(self.folded_players), key=lambda x: x.best_hand(self.community_cards), reverse=True)