def end_game(self) -> None: Debug.table( f'Table {self.id} hand {self.board.hand}: cards - {self.board}') if self.players.count_in_game_players() == 1: if self.online: self.network.hand_results(self.board, []) sleep(Delay.HandResults) winner = max(p for p in self.players.in_game_players()) winner.wins += winner.in_pot for player in self.players.all_players(): if player != winner: if winner.in_pot >= player.in_pot: winner.wins += player.in_pot player.in_pot = 0 else: Debug.error('THERE IS SOME ERROR') self.give_money(winner) else: self.collect_pot() hand_results = [] for player in self.players.in_game_players(): player.hand = HandStrength.max_strength(player.cards.get() + self.board.get()) hand_results += [(player.hand, player, str(player.hand))] Debug.table( f'Table {self.id} hand {self.board.hand}: ' f'{player.get_cards()}, {player.name} has {player.hand}') hand_results.sort(reverse=True, key=lambda x: x[0]) if self.online: self.network.hand_results(self.board, hand_results) sleep(Delay.HandResults) while self.players.count_in_game_players() > 0: wins_hand = max(player.hand for player in self.players.in_game_players()) players_wins = [ p for p in self.players.in_game_players() if p.hand == wins_hand ] count_winners = len(players_wins) Debug.table( f"Table {self.id} hand {self.board.hand}: " f"{', '.join(p.name for p in players_wins)} wins with {wins_hand}" ) all_inners = [p for p in self.players.all_in_players()] undivided_money = 0 if all_inners: all_inners_wins = sorted( [p for p in all_inners if p in players_wins], key=lambda x: x.in_pot) for player in all_inners_wins: side_pot = player.in_pot Debug.table( f'Table {self.id} hand {self.board.hand}: ' f'{player.name} opened pot with {player.in_pot}') for opponent in self.players.all_players(): if opponent != player: give_away = min(player.in_pot, opponent.in_pot) Debug.table( f'Table {self.id} hand {self.board.hand}: ' f'{opponent.name} moved to pot {give_away}' ) side_pot += give_away opponent.in_pot -= give_away win_for_everyone = side_pot / count_winners if win_for_everyone % 1 != 0: undivided_money = round( (win_for_everyone % 1) * count_winners) win_for_everyone = int(win_for_everyone) if undivided_money > 0: for lucky_man in self.players.sort_by_nearest_to_button( players_wins): lucky_man.wins += 1 undivided_money -= 1 if undivided_money == 0: break for winner in players_wins: winner.wins += win_for_everyone Debug.table( f'Table {self.id} hand {self.board.hand}: ' f'{winner.name} took {winner.wins} money from pot' ) self.give_money(player) del players_wins[players_wins.index(player)] count_winners -= 1 if count_winners > 0: main_pot = sum(p.in_pot for p in players_wins) Debug.table( f'Table {self.id} hand {self.board.hand}: ' f'{" ".join(p.name for p in players_wins)} opened main pot with ' f'{main_pot // len(players_wins)} each and sum {main_pot}' ) for player in self.players.all_players(): if player not in players_wins: Debug.table( f'Table {self.id} hand {self.board.hand}: ' f'{player.name} move {player.in_pot} in main pot' ) main_pot += player.in_pot player.in_pot = 0 player.in_game = False win_for_everyone = main_pot / count_winners if win_for_everyone % 1 != 0: undivided_money = round( (win_for_everyone % 1) * count_winners) win_for_everyone = int(win_for_everyone) if undivided_money > 0: for lucky_man in self.players.sort_by_nearest_to_button( players_wins): lucky_man.wins += 1 undivided_money -= 1 if undivided_money == 0: break for winner in players_wins: Debug.table( f'Table {self.id} hand {self.board.hand}: ' f'{winner.name} took {win_for_everyone} money from main pot' ) winner.wins += win_for_everyone self.give_money(winner) for player in self.players.in_game_players(): if player.in_pot == 0: player.in_game = False self.print_result() if self.pot.money != 0: Debug.error('ERROR IN POT') raise ValueError(f"POT != 0 pot = {self.pot.money}") self.players.remove_losers(self.game) self.take_cards() for player in self.players.all_players(): if player.in_pot != 0: raise ValueError( f"POT != 0 on {player.name} POT = {player.in_pot}") if player.in_game: raise ValueError(f"{player.name} IN GAME AFTER ALL") if player.gived != 0: raise ValueError( f"GIVED != 0 on {player.name} gived = {player.gived}") if player.wins != 0: raise ValueError( f"WINS != 0 on {player.name} wins = {player.wins}") self.in_game = False
def start_game(self) -> None: if self.wait: self.in_game = False return if self.players.count < 2: Debug.table(f'Table {self.id} has {self.players.count} player') self.in_game = False return for player in self.players.controlled: self.network.init_hand(player, self, self.game) player.network.place(self.game.find_place(player)) if self.online: self.network.init_hand(None, self, self.game) sleep(Delay.InitHand) if not self.first_hand: self.players.move_button() else: self.first_hand = False self.players.lock.acquire() ante = self.blinds.ante sb = self.blinds.small_blind bb = self.blinds.big_blind self.collect_ante(ante) for step in Step: if step == Step.Preflop: self.collect_blinds(sb, bb) self.give_cards() Debug.table(self) to_call = bb self.raise_counter = 1 else: self.players.to_button() to_call = 0 self.raise_counter = 0 player = self.players.next_player() last_seat = player.id min_raise = bb can_raise_from = to_call + min_raise players_not_decided = self.players.count_in_game_players() while True: if player.money > 0 and player.in_game and self.players.count_in_game_players( ) > 1 and not (self.players.count_in_game_players( ) - self.players.count_all_in_players() == 1 and max( p.gived for p in self.players.in_game_not_in_all_in_players()) >= max(p.gived for p in self.players.all_in_players())): if self.online: self.network.switch_decision(player) sleep(Delay.SwitchDecision) result = player.make_decision( online=self.online, step=step, to_call=to_call, min_raise=can_raise_from, board=self.board.get(), pot=self.pot.money + sum(p.gived for p in self.players.all_players()), bb=self.blinds.big_blind, ) if result == Result.Raise or result == Result.Allin: players_not_decided = self.players.count_in_game_players( ) - 1 # without raiser else: players_not_decided -= 1 self.log(player, result) if self.online: self.network.made_decision(player, result) sleep(Delay.MadeDecision) if result == Result.Raise or result == Result.Allin: raised = player.gived difference = raised - to_call if difference > 0: last_seat = player.id to_call = raised else: Debug.error('ERROR IN DECISIONS') raise ValueError( 'Error in decisions: player actually did not raised' ) if difference >= min_raise: min_raise = difference self.raise_counter += 1 can_raise_from = raised + min_raise player = self.players.next_player() if last_seat == player.id: break if self.online: sleep(Delay.EndOfRound) if self.players.count_in_game_players() == 1: player_max_pot = max(p for p in self.players.in_game_players()) second_max_pot = max(p.gived for p in self.players.all_players() if p != player_max_pot) difference = player_max_pot.gived - second_max_pot player_max_pot.gived -= difference player_max_pot.money += difference if self.online: self.network.back_excess_money(player_max_pot, difference) sleep(Delay.ExcessMoney) self.log(player_max_pot, Result.ReturnMoney, difference) self.collect_pot() self.end_game() return if self.players.count_in_game_players( ) - self.players.count_all_in_players() <= 1: if self.players.count_in_game_players( ) == self.players.count_all_in_players(): max_all_in = sorted( p.gived + p.in_pot for p in self.players.all_players())[-2] max_in_pot = max(p.gived + p.in_pot for p in self.players.in_game_players()) else: max_all_in = max([ p.gived + p.in_pot for p in self.players.all_in_players() ] + [ p.gived + p.in_pot for p in self.players.not_in_game_players() ]) max_in_pot = max(p.gived + p.in_pot for p in self.players.in_game_players()) if max_in_pot > max_all_in: player_max_pot = max( p for p in self.players.in_game_players() if p.gived + p.in_pot == max_in_pot) difference = max_in_pot - max_all_in player_max_pot.gived -= difference player_max_pot.money += difference if self.online: self.network.back_excess_money(player_max_pot, difference) sleep(Delay.ExcessMoney) self.log(player, Result.ReturnMoney, difference) self.collect_pot() if self.online: self.network.open_cards(self) sleep(Delay.OpenCards) self.board.open_all_with_network(self) self.end_game() return if step == Step.Preflop: Debug.table( f'Table {self.id} hand {self.board.hand}: open flop') elif step == Step.Flop: Debug.table( f'Table {self.id} hand {self.board.hand}: open turn') elif step == Step.Turn: Debug.table( f'Table {self.id} hand {self.board.hand}: open river') elif step == Step.River: Debug.table( f'Table {self.id} hand {self.board.hand}: open cards') self.collect_pot() if self.online: self.network.open_cards(self) sleep(Delay.OpenCards) self.end_game() return self.collect_pot() self.board.open_with_network(self) Debug.table( f'Table {self.id} hand {self.board.hand}: board {self.board}')