def n_card_strength(self, n: int): deck = Deck() for _ in range(100): deck.shuffle() cards = [] for _ in range(n): cards += [deck.next()] correct_result = max( HandStrength.strength(*c) for c in combinations(cards, 5)).strength self.assertEqual(HoldemPoker.fast_max_strength(cards), correct_result)
def test_fast_hand_strength(self): cards = [Card('AS'), Card('8C'), Card('9D'), Card('2S'), Card('KD')] self.assertEqual(HoldemPoker.fast_hand_strength(cards), Strength.Nothing) cards = [Card('AS'), Card('AC'), Card('9D'), Card('2S'), Card('KD')] self.assertEqual(HoldemPoker.fast_hand_strength(cards), Strength.Pair) cards = [Card('AS'), Card('AC'), Card('9D'), Card('9S'), Card('KD')] self.assertEqual(HoldemPoker.fast_hand_strength(cards), Strength.Pairs) cards = [Card('AS'), Card('KC'), Card('9D'), Card('9S'), Card('9H')] self.assertEqual(HoldemPoker.fast_hand_strength(cards), Strength.Set) cards = [Card('JS'), Card('QC'), Card('KD'), Card('9S'), Card('TH')] self.assertEqual(HoldemPoker.fast_hand_strength(cards), Strength.Straight) cards = [Card('AS'), Card('8S'), Card('9S'), Card('2S'), Card('KS')] self.assertEqual(HoldemPoker.fast_hand_strength(cards), Strength.Flush) cards = [Card('AS'), Card('AC'), Card('9D'), Card('9S'), Card('9H')] self.assertEqual(HoldemPoker.fast_hand_strength(cards), Strength.FullHouse) cards = [Card('AS'), Card('AH'), Card('9S'), Card('AC'), Card('AD')] self.assertEqual(HoldemPoker.fast_hand_strength(cards), Strength.Quad) cards = [Card('QS'), Card('8S'), Card('9S'), Card('JS'), Card('TS')] self.assertEqual(HoldemPoker.fast_hand_strength(cards), Strength.StraightFlush) cards = [Card('QS'), Card('AS'), Card('KS'), Card('JS'), Card('TS')] self.assertEqual(HoldemPoker.fast_hand_strength(cards), Strength.RoyalFlush) deck = Deck() for _ in range(100): deck.shuffle() cards = [ deck.next(), deck.next(), deck.next(), deck.next(), deck.next() ] self.assertEqual(HoldemPoker.fast_hand_strength(cards), HandStrength.strength(*cards).strength)
def create(res: BasePokerDecisionAnswer, money: int, pot: int, call: int, bb: int, step: Step, cards: CardsPair, board: Cards, players_on_table: int, players_active: int, players_not_moved: int) -> PokerDecision6: if money < 0: raise ValueError(f'Money must be > 0, gived {money}') if pot < 0: raise ValueError(f'Pot must be > 0, gived {pot}') if call < 0: raise ValueError(f'Call must be > 0, gived {call}') if bb < 0: raise ValueError(f'Big blinds must be > 0, gived {bb}') if pot <= call and step != Step.Preflop: raise ValueError( f'Pot must be > call, gived call {call} pot {pot}') if type(res) is not PokerDecisionAnswer3: raise ValueError( f'Result must ne instance of PokerDecisionAnswer, gived {res}') pr = HoldemPoker.probability(cards, board) strength = HandStrength.get_strength(cards, board) outs: float = HoldemPoker.calculate_outs( cards, board)[0] / HoldemPoker.MAX_OUTS des = PokerDecision6() des.set_answer(res) des.probability_to_win = pr des.my_money = money des.money_in_pot = pot des.money_to_call = call des.big_blind = bb if step == Step.Preflop: des.is_preflop = 1 elif step == Step.Flop: des.is_flop = 1 elif step == Step.Turn: des.is_turn = 1 elif step == Step.River: des.is_river = 1 else: raise ValueError('bad step', step) int_strength: int = strength.value if int_strength < 0: raise ValueError('strength is < 0', int_strength, strength) des.strength[int_strength] = 1 rank: int = cards.first.rank.value - 2 if rank < 0: raise ValueError('rank is < 0', rank, cards.first.rank) des.first[rank] = 1 rank: int = cards.second.rank.value - 2 if rank < 0: raise ValueError('rank is < 0', rank, cards.second.rank) des.second[rank] = 1 if cards.suitability == Suitability.Suited: des.have_suited_cards = 1 if players_on_table < 2 or players_on_table > 10: raise ValueError('bad players on table:', players_active) if players_active < 2 or players_active > 10: raise ValueError('bad players active:', players_active) if players_active > players_on_table: raise ValueError('bad players active:', players_active, 'with players on table:', players_on_table) if players_not_moved < 0 or players_not_moved >= players_active: raise ValueError('bad players not moved:', players_not_moved, 'with players active:', players_active) des.players_on_table[players_on_table - 2] = 1 des.players_playing[players_on_table - 2] = 1 des.players_not_moved[players_not_moved] = 1 des.outs = outs return des
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 create(res: BasePokerDecisionAnswer, money: int, pot: int, call: int, bb: int, step: Step, cards: CardsPair, board: Cards) -> PokerDecision5: if money < 0: raise ValueError(f'Money must be > 0, gived {money}') if pot < 0: raise ValueError(f'Pot must be > 0, gived {pot}') if call < 0: raise ValueError(f'Call must be > 0, gived {call}') if bb < 0: raise ValueError(f'Big blinds must be > 0, gived {bb}') if pot <= call and step != Step.Preflop: raise ValueError(f'Pot must be > call, gived call {call} pot {pot}') if type(res) is not PokerDecisionAnswer3: raise ValueError(f'Result must ne instance of PokerDecisionAnswer, gived {res}') pr = HoldemPoker.probability(cards, board) strength = HandStrength.get_strength(cards, board) des = PokerDecision5() des.set_answer(res) des.probability_to_win = pr des.my_money = money des.money_in_pot = pot des.money_to_call = call des.big_blind = bb if step == Step.Preflop: des.is_preflop = 1 elif step == Step.Flop: des.is_flop = 1 elif step == Step.Turn: des.is_turn = 1 elif step == Step.River: des.is_river = 1 else: raise ValueError('bad step', step) int_strength: int = strength.value if int_strength < 0: raise ValueError('strength is < 0', int_strength, strength) des.strength[int_strength] = 1 rank: int = cards.first.rank.value - 2 if rank < 0: raise ValueError('rank is < 0', rank, cards.first.rank) des.first[rank] = 1 rank: int = cards.second.rank.value - 2 if rank < 0: raise ValueError('rank is < 0', rank, cards.second.rank) des.second[rank] = 1 if cards.suitability == Suitability.Suited: des.have_suited_cards = 1 return des
def create(res: BasePokerDecisionAnswer, money: int, pot: int, call: int, bb: int, step: Step, cards: CardsPair, board: Cards) -> PokerDecision4: if money < 0: raise ValueError(f'Money must be > 0, gived {money}') if pot < 0: raise ValueError(f'Pot must be > 0, gived {pot}') if call < 0: raise ValueError(f'Call must be > 0, gived {call}') if bb < 0: raise ValueError(f'Big blinds must be > 0, gived {bb}') if pot <= call and step != Step.Preflop: raise ValueError(f'Pot must be > call, gived call {call} pot {pot}') if type(res) is not PokerDecisionAnswer3: raise ValueError(f'Result must ne instance of PokerDecisionAnswer, gived {res}') pr = HoldemPoker.probability(cards, board) strength = HandStrength.get_strength(cards, board) des = PokerDecision4() des.set_answer(res) des.probability_to_win = pr des.my_money = money des.money_in_pot = pot des.money_to_call = call des.big_blind = bb if step == Step.Preflop: des.is_preflop = 1 elif step == Step.Flop: des.is_flop = 1 elif step == Step.Turn: des.is_turn = 1 elif step == Step.River: des.is_river = 1 else: raise ValueError('bad step', step) if strength == Strength.RoyalFlush: des.have_royal_flush = 1 elif strength == Strength.StraightFlush: des.have_straight_flush = 1 elif strength == Strength.Quad: des.have_quad = 1 elif strength == Strength.FullHouse: des.have_full_house = 1 elif strength == Strength.Flush: des.have_flush = 1 elif strength == Strength.Straight: des.have_straight = 1 elif strength == Strength.Set: des.have_set = 1 elif strength == Strength.Pairs: des.have_two_pairs = 1 elif strength == Strength.Pair: des.have_pair = 1 elif strength == Strength.Nothing: des.have_nothing = 1 else: raise ValueError('bad hand strength', strength) return des
def convert(self) -> None: if not exists('games'): mkdir('games') if not exists('games/converted'): mkdir('games/converted') current_date = datetime.now() if self.date == '' or self.time == '': date = current_date.strftime('%Y/%m/%d') time = current_date.strftime('%H:%M:%S') else: date = self.date time = self.time year, month, day = date.split('/') if len(month) == 1: month = '0' + month if len(day) == 1: day = '0' + day hour, minute, second = time.split(':') if len(hour) == 1: hour = '0' + hour if len(minute) == 1: minute = '0' + minute if len(second) == 1: second = '0' + second folder_name = f'{year}-{month}-{day}_{hour}-{minute}-{second} 1 {self.seats} {len(self.hands)} {self.name}' folder_name = folder_name.strip() Debug.parser(f'Converting {folder_name}') path = PokerGame.path_to_converted_games + PokerGame.converted_games_folder + '/' + folder_name chat_path = PokerGame.path_to_converted_games + PokerGame.converted_chat_folder + '/' + folder_name if exists(path): rmtree(path) if exists(chat_path): rmtree(chat_path) table_folder = f'/0 {len(self.hands)}' path += table_folder makedirs(path) makedirs(chat_path) time = datetime(int(year), int(month), int(day), int(hour), int(minute), int(second), 0) network = BaseNetwork() chat_messages: List[Tuple[datetime, str]] = [] for num, hand in enumerate(self.hands): converted: List[Tuple[datetime, str]] = [] hand.switch_to_step(Step.Preflop) events: Iterator[Event] = iter(hand.curr_events) game = Game(0, self.seats, self.seats, 0) table = game.final_table table.is_final = hand.is_final table.id = hand.table_id table.players.total_seats = self.seats table.board.hand = num + 1 table.blinds.ante = hand.ante table.blinds.small_blind = hand.small_blind table.blinds.big_blind = hand.big_blind game.average_stack = int( mean(player.money for player in hand.players)) game.players_left = hand.players_left players: List[Player] = [] find: Dict[int, Player] = dict() for seat in range(1, self.seats + 1): player = sorted(player for player in hand.players if player.seat == seat) if not player: player = None elif len(player) == 1: player = player[0] else: raise ValueError('Two players with same seat') if player is not None: new_player = DummyPlayer(player.seat, player.name, player.money) new_player.in_game = True new_player.cards = player.cards players += [new_player] find[player.seat] = new_player else: players += [None] game.top_9 = sorted([p for p in players if p is not None], key=lambda p: p.money, reverse=True) table.players.players = players json_message = loads(network.init_hand(None, table, game)) for curr in json_message['players']: if curr['id'] is not None: pl = max(pl for pl in hand.players if pl.seat == curr['id']) curr['disconnected'] = not pl.is_active else: curr['disconnected'] = False init_message = dumps(json_message) converted += [(time, init_message)] time = time + timedelta(seconds=Delay.InitHand) converted += [(time, network.deal_cards())] time = time + timedelta(seconds=0) converted += [(time, network.open_cards(table))] time = time + timedelta(seconds=Delay.DealCards) event = next(events) if hand.ante > 0: paid: List[Tuple[Player, int]] = [] while event.event == Event.Ante: try: paid += [(find[event.player.seat], event.money)] except KeyError: pass event = next(events) converted += [(time, network.ante(paid))] time = time + timedelta(seconds=Delay.Ante) converted += [(time, network.collect_money())] time = time + timedelta(seconds=Delay.CollectMoney) try: button: Player = find[hand.button_seat] except KeyError: continue blinds_info: List[Tuple[Player, int]] = [] if event.event == Event.SmallBlind: try: blinds_info += [(find[event.player.seat], event.money)] except KeyError: pass event = next(events) if event.event == Event.BigBlind: try: blinds_info += [(find[event.player.seat], event.money)] except KeyError: pass event = next(events) converted += [(time, network.blinds(button, blinds_info))] time = time + timedelta(seconds=Delay.Blinds) if hand.sit_during_game: for player in hand.sit_during_game: converted += [(time, network.add_player( DummyPlayer(player.seat, player.name, player.money), player.seat - 1))] time = time + timedelta(seconds=Delay.AddPlayer) avoid_in_first_iteration = True need_to_collect_money = True while True: if hand.curr_step == Step.River: break elif not avoid_in_first_iteration: hand.next_step() need_to_continue = False if hand.curr_step == Step.Flop and \ hand.board.flop1 is not None and \ hand.board.flop2 is not None and \ hand.board.flop3 is not None: converted += [(time, network.flop(hand.board.flop1, hand.board.flop2, hand.board.flop3))] time = time + timedelta(seconds=Delay.Flop) need_to_continue = True elif hand.curr_step == Step.Turn and hand.board.turn is not None: converted += [(time, network.turn(hand.board.turn))] time = time + timedelta(seconds=Delay.Turn) need_to_continue = True elif hand.curr_step == Step.River and hand.board.river is not None: converted += [(time, network.river(hand.board.river))] time = time + timedelta(seconds=Delay.River) need_to_continue = True events = iter(hand.curr_events) try: event: PokerEvent = next(events) except StopIteration: if need_to_continue: continue else: break else: avoid_in_first_iteration = False while True: need_continue = True while need_continue: try: _ = find[event.player.seat] except KeyError: try: event = next(events) except StopIteration: need_continue = False else: continue except AttributeError: break else: break else: break if event.event == Event.Fold or \ event.event == Event.Check or \ event.event == Event.Call or \ event.event == Event.Raise or \ event.event == Event.Allin: if event.event == Event.Call or \ event.event == Event.Raise or \ event.event == Event.Allin: need_to_collect_money = True player = find[event.player.seat] player.gived = event.money converted += [(time, network.switch_decision(player))] time = time + timedelta(seconds=Delay.SwitchDecision + Delay.DummyMove) converted += [ (time, network.made_decision(player, event.event.to_result())) ] time = time + timedelta(seconds=Delay.MadeDecision) elif event.event == Event.WinMoney: if need_to_collect_money: converted += [(time, network.collect_money())] time = time + timedelta(seconds=Delay.CollectMoney) need_to_collect_money = False converted += [ (time, network.give_money(find[event.player.seat], event.money)) ] time = time + timedelta(seconds=Delay.GiveMoney) elif event.event == Event.ReturnMoney: if sum(e.event == Event.Allin or e.event == Event.Raise or e.event == Event.Call or e.event == Event.SmallBlind or e.event == Event.BigBlind for e in hand.curr_events) == 1: need_to_collect_money = False converted += [ (time, network.back_excess_money(find[event.player.seat], event.money)) ] time = time + timedelta(seconds=Delay.ExcessMoney) elif event.event == Event.ChatMessage: chat_message = network.send({ 'type': 'chat', 'text': f'{event.player.name}: {event.message}' }) converted += [(time, chat_message)] chat_messages += [(time, chat_message)] time = time + timedelta(seconds=0) elif event.event == Event.ObserverChatMessage: chat_message = network.send({ 'type': 'chat', 'text': f'{event.player.name} [observer]: {event.message}' }) converted += [(time, chat_message)] chat_messages += [(time, chat_message)] time = time + timedelta(seconds=0) elif event.event == Event.Disconnected: converted += [(time, network.send({ 'type': 'disconnected', 'id': event.player.seat }))] time = time + timedelta(seconds=0) chat_message = network.send({ 'type': 'chat', 'text': f'{event.player.name} disconnected' }) converted += [(time, chat_message)] chat_messages += [(time, chat_message)] time = time + timedelta(seconds=0) elif event.event == Event.Connected: converted += [(time, network.send({ 'type': 'connected', 'id': event.player.seat }))] time = time + timedelta(seconds=0) chat_message = network.send({ 'type': 'chat', 'text': f'{event.player.name} connected' }) converted += [(time, chat_message)] chat_messages += [(time, chat_message)] time = time + timedelta(seconds=0) elif event.event == Event.FinishGame: if event.money == 0: chat_message = network.send({ 'type': 'chat', 'text': f'{event.player.name} finished {event.message}' }) else: chat_message = network.send({ 'type': 'chat', 'text': f'{event.player.name} ' f'finished {event.message} and get ' f'${event.money // 100}.{event.money % 100}' }) converted += [(time, chat_message)] chat_messages += [(time, chat_message)] time = time + timedelta(seconds=0) if event.message != '1st': converted += [(time, network.delete_player( find[event.player.seat]))] time = time + timedelta(seconds=Delay.DeletePlayer) else: raise ValueError(f'Undefined event id {event.event}') need_continue = True while need_continue: try: event = next(events) _ = find[event.player.seat] except StopIteration: time = time + timedelta(seconds=Delay.EndOfRound) if need_to_collect_money: converted += [(time, network.collect_money())] time = time + timedelta( seconds=Delay.CollectMoney) need_to_collect_money = False need_continue = False except KeyError: continue except AttributeError: break else: break else: break results: List[Tuple[Hand, Player, str]] = [] for player in hand.players: if player.cards is not None: if hand.board.state == Step.Preflop: if not player.cards.initialized(): curr_hand = HandStrength.strength1( player.cards.first) else: curr_hand = HandStrength.strength2( player.cards.first, player.cards.second) elif hand.board.state == Step.Flop: if not player.cards.initialized(): curr_hand = HandStrength.strength4( player.cards.first, hand.board.flop1, hand.board.flop2, hand.board.flop3) else: curr_hand = HandStrength.strength( player.cards.first, player.cards.second, hand.board.flop1, hand.board.flop2, hand.board.flop3) else: cards = hand.board.get() if not player.cards.initialized(): cards += [player.cards.first] else: cards += [player.cards.first, player.cards.second] curr_hand = HandStrength.max_strength(cards) try: results += [(curr_hand, find[player.seat], '')] except KeyError: pass results.sort(reverse=True, key=lambda x: x[0].safe_value) converted += [(time, network.hand_results(hand.board, results))] time = time + timedelta(seconds=Delay.HandResults) converted += [(time, network.clear())] time = time + timedelta(seconds=Delay.Clear) output = '' for d, s in converted: output += '%s %s %s %s %s %s %s' % (d.year, d.month, d.day, d.hour, d.minute, d.second, d.microsecond) output += '\n' output += s output += '\n' open(path + '/%s' % (num, ), 'w').write(output) chat_output = '' for d, s in chat_messages: chat_output += '%s %s %s %s %s %s %s' % (d.year, d.month, d.day, d.hour, d.minute, d.second, d.microsecond) chat_output += '\n' chat_output += s chat_output += '\n' open(chat_path + table_folder, 'w').write(chat_output)
def create(res: BasePokerDecisionAnswer, money: int, pot: int, call: int, bb: int, step: Step, cards: CardsPair, board: Cards, players_on_table: int, players_active: int, players_not_moved: int, max_playing_stack: int, average_stack_on_table: int, players: List[MockPlayer], folded_players: List[str], my_position: PokerPosition) -> PokerDecision10: if money < 0: raise ValueError(f'Money must be > 0, gived {money}') if pot < 0: raise ValueError(f'Pot must be > 0, gived {pot}') if call < 0: raise ValueError(f'Call must be > 0, gived {call}') if bb < 0: raise ValueError(f'Big blinds must be > 0, gived {bb}') if pot <= call and step != Step.Preflop: raise ValueError( f'Pot must be > call, gived call {call} pot {pot}') if type(res) is not PokerDecisionAnswer3: raise ValueError( f'Result must ne instance of PokerDecisionAnswer, gived {res}') pr = HoldemPoker.probability(cards, board) strength = HandStrength.get_strength(cards, board) outs: float = HoldemPoker.calculate_outs( cards, board)[0] / HoldemPoker.MAX_OUTS des = PokerDecision10() des.set_answer(res) des.probability_to_win = pr des.my_money = money des.money_in_pot = pot des.money_to_call = call des.big_blind = bb if step == Step.Preflop: des.is_preflop = 1 elif step == Step.Flop: des.is_flop = 1 elif step == Step.Turn: des.is_turn = 1 elif step == Step.River: des.is_river = 1 else: raise ValueError('bad step', step) int_strength: int = strength.value if int_strength < 0: raise ValueError('strength is < 0', int_strength, strength) des.strength[int_strength] = 1 rank: int = cards.first.rank.value - 2 if rank < 0: raise ValueError('rank is < 0', rank, cards.first.rank) des.first[rank] = 1 rank: int = cards.second.rank.value - 2 if rank < 0: raise ValueError('rank is < 0', rank, cards.second.rank) des.second[rank] = 1 if cards.suitability == Suitability.Suited: des.have_suited_cards = 1 if players_on_table < 2 or players_on_table > 10: raise ValueError('bad players on table:', players_active) if players_active < 2 or players_active > 10: raise ValueError('bad players active:', players_active) if players_active > players_on_table: raise ValueError('bad players active:', players_active, 'with players on table:', players_on_table) if players_not_moved < 0 or players_not_moved >= players_active: raise ValueError('bad players not moved:', players_not_moved, 'with players active:', players_active) des.players_on_table[players_on_table - 2] = 1 des.players_playing[players_on_table - 2] = 1 des.players_not_moved[players_not_moved] = 1 des.outs = outs des.max_playing_stack = max_playing_stack des.average_stack_on_table = average_stack_on_table curr_raisers: Dict[Tuple[str, PokerPosition], PlayerStatistics] = PokerDecision10.CurrRaisers curr_callers: Dict[Tuple[str, PokerPosition], PlayerStatistics] = PokerDecision10.CurrCallers curr_folders: Dict[Tuple[str, PokerPosition], PlayerStatistics] = PokerDecision10.CurrFolders curr_checkers: Dict[Tuple[str, PokerPosition], PlayerStatistics] = PokerDecision10.CurrCheckers raisers = [] callers = [] folders = [] checkers = [] for player in players: if player.name not in folded_players: raisers += [ curr_raisers[player.name, player.position].get_stats() ] callers += [ curr_callers[player.name, player.position].get_stats() ] folders += [ curr_folders[player.name, player.position].get_stats() ] checkers += [ curr_checkers[player.name, player.position].get_stats() ] des.max_raiser = max(raisers) des.min_raiser = min(raisers) des.avg_raiser = mean(raisers) des.max_caller = max(callers) des.min_caller = min(callers) des.avg_caller = mean(callers) des.max_folder = max(folders) des.min_folder = min(folders) des.avg_folder = mean(folders) des.max_checker = max(checkers) des.min_checker = min(checkers) des.avg_checker = mean(checkers) des.my_position_is_early = my_position is PokerPosition.Early des.my_position_is_middle = my_position is PokerPosition.Middle des.my_position_is_late = my_position is PokerPosition.Late des.my_position_is_blinds = my_position is PokerPosition.Blinds if step.value >= Step.Flop.value: cards_sorted = sorted(board[0:3], reverse=True) des.flop1[cards_sorted[0].rank.value - 2] = 1 des.flop2[cards_sorted[1].rank.value - 2] = 1 des.flop3[cards_sorted[2].rank.value - 2] = 1 suits = sorted(board[0:3], key=lambda card: card.suit.value) if suits[0].suit == suits[1].suit == suits[2].suit: des.flop_3_suited = 1 elif suits[0].suit == suits[1].suit or suits[1].suit == suits[ 2].suit: des.flop_2_suited = 1 elif suits[0].suit != suits[1].suit != suits[2].suit != suits[ 0].suit: des.flop_rainbow = 1 else: raise ValueError(f'bad sorted suits {suits}') if step.value >= Step.Turn.value: des.turn[board[3].rank.value - 2] = 1 suits = sorted(board[0:4], key=lambda card: card.suit.value) if suits[0].suit == suits[1].suit == suits[2].suit == suits[3].suit: des.turn_4_suited = 1 elif suits[0].suit == suits[1].suit == suits[2].suit: des.turn_3_suited = 1 elif suits[1].suit == suits[2].suit == suits[3].suit: des.turn_3_suited = 1 elif suits[0].suit == suits[1].suit and suits[2].suit == suits[ 3].suit: des.turn_2_suited_and_other_2 = 1 elif suits[0].suit == suits[ 1].suit and suits[2].suit != suits[3].suit: des.turn_2_suited_2_not = 1 elif suits[1].suit == suits[ 2].suit and suits[0].suit != suits[3].suit: des.turn_2_suited_2_not = 1 elif suits[2].suit == suits[ 3].suit and suits[0].suit != suits[1].suit: des.turn_2_suited_2_not = 1 elif len(set([suit.suit.value for suit in suits])) == 4: des.turn_rainbow = 1 else: raise ValueError(f'bad suits {suits}') if step == Step.River: des.river[board[4].rank.value - 2] = 1 suits = sorted(board, key=lambda card: card.suit.value) diff_suits = len(set([suit.suit.value for suit in suits])) if diff_suits == 1: des.river_5_suited = 1 elif diff_suits == 2 and suits[0].suit == suits[1].suit == suits[ 2].suit == suits[3].suit: des.river_4_suited = 1 elif diff_suits == 2 and suits[1].suit == suits[2].suit == suits[ 3].suit == suits[4].suit: des.river_4_suited = 1 elif diff_suits == 2 and suits[0].suit == suits[1].suit == suits[ 2].suit and suits[3].suit == suits[4].suit: des.river_3_suited_and_other_2 = 1 elif diff_suits == 2 and suits[2].suit == suits[3].suit == suits[ 4].suit and suits[0].suit == suits[1].suit: des.river_3_suited_and_other_2 = 1 elif diff_suits == 3 and suits[0].suit == suits[1].suit == suits[ 2].suit and suits[3].suit != suits[4].suit: des.river_3_suited_2_not = 1 elif diff_suits == 3 and suits[1].suit == suits[2].suit == suits[ 3].suit and suits[0].suit != suits[4].suit: des.river_3_suited_2_not = 1 elif diff_suits == 3 and suits[2].suit == suits[3].suit == suits[ 4].suit and suits[0].suit != suits[1].suit: des.river_3_suited_2_not = 1 elif diff_suits == 3 and suits[0].suit == suits[1].suit and suits[ 2].suit == suits[3].suit: des.river_2_suited_and_2_suited = 1 elif diff_suits == 3 and suits[0].suit == suits[1].suit and suits[ 3].suit == suits[4].suit: des.river_2_suited_and_2_suited = 1 elif diff_suits == 3 and suits[1].suit == suits[2].suit and suits[ 3].suit == suits[4].suit: des.river_2_suited_and_2_suited = 1 elif diff_suits == 4: des.river_only_2_suited = 1 else: raise ValueError(f'bad suits {diff_suits} {suits}') return des
def create(res: BasePokerDecisionAnswer, money: int, pot: int, call: int, bb: int, step: Step, cards: CardsPair, board: Cards, players_on_table: int, players_active: int, players_not_moved: int, max_playing_stack: int, average_stack_on_table: int, players: List[MockPlayer], folded_players: List[str], my_position: PokerPosition) -> PokerDecision9: if money < 0: raise ValueError(f'Money must be > 0, gived {money}') if pot < 0: raise ValueError(f'Pot must be > 0, gived {pot}') if call < 0: raise ValueError(f'Call must be > 0, gived {call}') if bb < 0: raise ValueError(f'Big blinds must be > 0, gived {bb}') if pot <= call and step != Step.Preflop: raise ValueError( f'Pot must be > call, gived call {call} pot {pot}') if type(res) is not PokerDecisionAnswer3: raise ValueError( f'Result must ne instance of PokerDecisionAnswer, gived {res}') pr = HoldemPoker.probability(cards, board) strength = HandStrength.get_strength(cards, board) outs: float = HoldemPoker.calculate_outs( cards, board)[0] / HoldemPoker.MAX_OUTS des = PokerDecision9() des.set_answer(res) des.probability_to_win = pr des.my_money = money des.money_in_pot = pot des.money_to_call = call des.big_blind = bb if step == Step.Preflop: des.is_preflop = 1 elif step == Step.Flop: des.is_flop = 1 elif step == Step.Turn: des.is_turn = 1 elif step == Step.River: des.is_river = 1 else: raise ValueError('bad step', step) int_strength: int = strength.value if int_strength < 0: raise ValueError('strength is < 0', int_strength, strength) des.strength[int_strength] = 1 rank: int = cards.first.rank.value - 2 if rank < 0: raise ValueError('rank is < 0', rank, cards.first.rank) des.first[rank] = 1 rank: int = cards.second.rank.value - 2 if rank < 0: raise ValueError('rank is < 0', rank, cards.second.rank) des.second[rank] = 1 if cards.suitability == Suitability.Suited: des.have_suited_cards = 1 if players_on_table < 2 or players_on_table > 10: raise ValueError('bad players on table:', players_active) if players_active < 2 or players_active > 10: raise ValueError('bad players active:', players_active) if players_active > players_on_table: raise ValueError('bad players active:', players_active, 'with players on table:', players_on_table) if players_not_moved < 0 or players_not_moved >= players_active: raise ValueError('bad players not moved:', players_not_moved, 'with players active:', players_active) des.players_on_table[players_on_table - 2] = 1 des.players_playing[players_on_table - 2] = 1 des.players_not_moved[players_not_moved] = 1 des.outs = outs des.max_playing_stack = max_playing_stack des.average_stack_on_table = average_stack_on_table curr_raisers: Dict[Tuple[str, PokerPosition], PlayerStatistics] = PokerDecision9.CurrRaisers curr_callers: Dict[Tuple[str, PokerPosition], PlayerStatistics] = PokerDecision9.CurrCallers curr_folders: Dict[Tuple[str, PokerPosition], PlayerStatistics] = PokerDecision9.CurrFolders curr_checkers: Dict[Tuple[str, PokerPosition], PlayerStatistics] = PokerDecision9.CurrCheckers raisers = [] callers = [] folders = [] checkers = [] for player in players: if player.name not in folded_players: raisers += [ curr_raisers[player.name, player.position].get_stats() ] callers += [ curr_callers[player.name, player.position].get_stats() ] folders += [ curr_folders[player.name, player.position].get_stats() ] checkers += [ curr_checkers[player.name, player.position].get_stats() ] des.max_raiser = max(raisers) des.min_raiser = min(raisers) des.avg_raiser = mean(raisers) des.max_caller = max(callers) des.min_caller = min(callers) des.avg_caller = mean(callers) des.max_folder = max(folders) des.min_folder = min(folders) des.avg_folder = mean(folders) des.max_checker = max(checkers) des.min_checker = min(checkers) des.avg_checker = mean(checkers) des.my_position_is_early = my_position is PokerPosition.Early des.my_position_is_middle = my_position is PokerPosition.Middle des.my_position_is_late = my_position is PokerPosition.Late des.my_position_is_blinds = my_position is PokerPosition.Blinds return des