def run(self): self.game.broadcast_event( Event('button', player_id=self.game.id[self.button])) # do the blinds small_blind, big_blind = self.calculate_blinds(self.button) self.game.broadcast_event( Event('small_blind', player_id=self.game.id[small_blind])) self.bet(small_blind, self.game.small_blind_amount) self.game.broadcast_event( Event('big_blind', player_id=self.game.id[big_blind])) self.bet(big_blind, self.game.big_blind_amount) hole_cards = {} # deal each player 2 cards for player in self.players: hole_cards[player] = self.deck.take(2) self.game.send_event( player, Event('deal', cards=copy.copy(hole_cards[player]))) try: # first round of betting, no 'check' allowed unless you're the big # blind and nobody raised self.betting_round(1, self.button, self.pot) # flop community_cards = self.deck.take(3) self.game.broadcast_event( Event('flop', cards=copy.copy(community_cards))) self.betting_round(2, self.button, self.pot) # turn turn = self.deck.take_one() self.game.broadcast_event(Event('turn', card=turn)) community_cards.append(turn) self.betting_round(3, self.button, self.pot) # river river = self.deck.take_one() self.game.broadcast_event(Event('river', card=river)) community_cards.append(river) # final betting round self.betting_round(4, self.button, self.pot) except WinByDefault, e: player = e.winner credits = self.pot.total # TODO: win should indicate amount won, (gained over previous round) self.game.broadcast_event( Event('win', player_id=self.game.id[player], rank=0, amount=credits)) self.game.adjust_credits(player, credits) return tuple( (player, creds) for player, creds in self.game.credits.items())
def run_turn(self, player): try: return player.turn() except Exception, e: self.game.send_event( player, Event('bad_bot', message='bot threw an exception: ' + str(e), action=None)) return Action('fold')
def run(self): assert (len(self.active_players) > 0) rounds = [] round_num = 1 # button is random and goes to the next player (higher index) each round, # looping around at the end button = random.choice(self.active_players) # send out join messages for player in self.active_players: for other_player in self.active_players: if player is not other_player: event = Event('join', player_id=self.id[player], credits=self.credits[player]) self.send_event(other_player, event) self.output("Start of Game State:") self.print_state() while len(self.active_players) > 1: self.broadcast_event(Event('new_round')) self.output("Round: %d" % round_num) round = Round(self, button, self.evaluator) rounds.append(round.run()) self.output("End of Round State:") self.print_state() self.broadcast_event(Event('end_of_round')) round_num += 1 button = self.active_players[(self.active_players.index(button) + 1) % len(self.active_players)] # determine next blinds, remove any players that are at 0 credits # or can't pay the blind button = self.remove_losers(button) self.output("Game Over") winner = self.active_players[0] self.output("Game Winner: %s with credits %d" % (winner, self.credits[winner])) return (winner, self.credits[winner], rounds)
def turn(self): """ Send all events to the bot and then get the bot's action """ self.log("bot's turn") continue_process(self.p) # write the events to the child, then tell the child that it is # his turn self.log("sending events to bot") for event in self.event_queue: self.send_event(event) self.event_queue = [] self.send_event(Event(type='your_turn')) self.log("waiting for response from bot") # get the action produced by the bot action = self.receive_action() self.log("got response from bot") stop_process(self.p) self.log("end of bot's turn") return action
def warn(message): self.game.send_event( current_player, Event('bad_bot', message=message, action=action))
def betting_round(self, n, button, pot): player_bets = {} self.has_bet = {} # TODO: don't let player keep betting if it's just him and all_in guys for player in self.players: player_bets[player] = 0 small_blind, big_blind = self.calculate_blinds(button) if n == 1: current_player = self.get_player(self.players.index(big_blind) + 1) player_bets[small_blind] = self.game.small_blind_amount player_bets[big_blind] = self.game.big_blind_amount current_bet = self.game.big_blind_amount else: current_player = self.get_player(self.players.index(button) + 1) current_bet = 0 self.game.output("Start of betting round %d" % n) while True: if len(self.active_players) == 1: winner = self.active_players[0] self.game.output("Player %s won when everyone else folded" % winner) raise WinByDefault(winner) # figure out if this betting round is over for player in self.active_players: if player not in self.has_bet and player not in self.all_in: break # found a player that can still make an action else: break # all players have bet, folded, or are all in, break out of the while loop # if player is all in, he does not get another turn if current_player in self.all_in: self.game.output("Player is all in, skipping %s" % current_player) current_player = self.next_player(current_player) continue if current_player not in self.active_players: self.game.output("Player has folded, skipping %s" % current_player) current_player = self.next_player(current_player) continue #GAMESTATE STUFF current_player.active_player_count = len(self.active_players) current_player.bet_to_player = current_bet - player_bets[ current_player] current_player.pot = self.pot.total action = self.run_turn(current_player) def warn(message): self.game.send_event( current_player, Event('bad_bot', message=message, action=action)) if action is None or \ getattr(action, 'type', None) not in ['fold', 'call', 'raise', 'check'] or \ action.type == 'raise' and not hasattr(action, 'amount'): warn('invalid action, folding') action = Action('fold') if action.type == 'raise': if action.amount <= 0 or self.game.credits[ current_player] < action.amount: warn('invalid raise, calling') action = Action('call') else: amount_to_bet = action.amount + ( current_bet - player_bets[current_player]) if self.game.credits[current_player] < amount_to_bet: warn( 'tried to raise more than player possesses, betting maximum' ) amount_to_bet = self.game.credits[current_player] if player_bets[ current_player] + amount_to_bet > current_bet: current_bet = player_bets[ current_player] + amount_to_bet self.bet(current_player, amount_to_bet) player_bets[current_player] += amount_to_bet self.has_bet = {current_player: True} if action.type == 'call': if current_bet == 0: warn('tried to call on zero bet, checking') action = Action('check') elif current_bet == player_bets[current_player]: warn( 'tried to call but had already bet that amount, should have checked, checking' ) action = Action('check') else: amount_to_bet = current_bet - player_bets[current_player] self.bet(current_player, amount_to_bet) player_bets[current_player] += amount_to_bet self.has_bet[current_player] = True if action.type == 'check': if current_bet != player_bets[current_player]: warn('tried to check when not up to current bet, calling') # TODO: action = Action('call') amount_to_bet = current_bet - player_bets[current_player] self.bet(current_player, amount_to_bet) player_bets[current_player] += amount_to_bet self.has_bet[current_player] = True else: self.has_bet[current_player] = True if action.type == 'fold': self.active_players.remove(current_player) self.game.broadcast_event( Event('action', action=action, player_id=self.game.id[current_player])) current_player = self.next_player(current_player) self.game.output("End of betting round %d" % n)
def adjust_credits(self, player, amount): self.credits[player] += amount self.broadcast_event( Event('adjust_credits', player_id=self.id[player], amount=amount))
def remove_loser(self, player): self.active_players.remove(player) self.broadcast_event(Event('quit', player_id=self.id[player]))
self.game.broadcast_event( Event('win', player_id=self.game.id[player], rank=0, amount=credits)) self.game.adjust_credits(player, credits) return tuple( (player, creds) for player, creds in self.game.credits.items()) else: ranking = self.determine_ranking(community_cards, hole_cards) print ranking for rank, (player, credits) in enumerate( (sorted(self.pot.split(ranking)))): self.game.broadcast_event( Event('win', player_id=self.game.id[player], rank=rank, amount=credits)) self.game.adjust_credits(player, credits) return tuple( (player, creds) for player, creds in self.game.credits.items()) def run_turn(self, player): return player.turn() # try: # return player.turn() # except Exception, e: # self.game.send_event(player, Event('bad_bot', message='bot threw an exception: ' + str(e), action=None)) # return Action('fold') def get_player(self, index):