def search_in_dir(path: str, line: str) -> None: games = listdir(PokerGame.path_to_raw_games + path) for game_path in games: game_path = f'{path}/{game_path}' text_game = open(PokerGame.path_to_raw_games + game_path, 'r', encoding='utf-8').read().strip() if line in text_game: Debug.parser('FOUND', line, ':', game_path)
def test_import_loop(self): modules = UnitTesting.find_modules('src') with self.assertRaises(ImportError): import_module('123') modules_count = 0 for module in modules: # print('import', module) modules_count += 1 import_module(module) Debug.unit_test(f'\nSUCCESSFULLY IMPORTED {modules_count} MODULES\n')
def infinite_resitting(self) -> None: while not self.game_finished and not self.game_broken: try: self.resit_players() except IndexError: Debug.resitting('Cannot resit - index error') else: sleep(0.01)
def do_one_hand(self) -> None: if self.blinds.next_hand(): Debug.game_progress(f'Blinds are: {self.blinds.small_blind} ' f'{self.blinds.big_blind} {self.blinds.ante}') Debug.game_progress(f'Start hand {self.tables[0].board.hand} tables = {len(self.tables)} ' f'players = {sum(table.players.count for table in self.tables)}') for table in self.tables: table.run()
def init(): Debug.play_manager('Start initialization') PlayManager._bank_of_plays = [] if not exists(f'{PlayManager.PlayPath}'): mkdir(f'{PlayManager.PlayPath}') if not Settings.game_mode == Mode.Evolution and 'all' in listdir( f'{PlayManager.PlayPath}'): PlayManager._initialized = True PlayManager._bank_of_plays = load( open(f'{PlayManager.PlayPath}/all', 'rb')) for play in PlayManager._bank_of_plays: play.busy = False PlayManager.GenCount = len(PlayManager._bank_of_plays) Debug.play_manager('End initialization (short way)') return generations = listdir(f'{PlayManager.PlayPath}') for gen_path in generations: if gen_path == 'all': continue Debug.play_manager(f'Initialize generation {gen_path}') exemplars = listdir(f'{PlayManager.PlayPath}/{gen_path}') for ex_path in exemplars: Debug.play_manager(f'Initialize exemplar {gen_path} {ex_path}') play: Play = load( open(f'{PlayManager.PlayPath}/{gen_path}/{ex_path}', 'rb')) if play.generation != int(gen_path): raise ValueError( f'Generation path {gen_path} does not work') if play.exemplar != int(ex_path): raise ValueError(f'Exemplar path {ex_path} does not work') play.busy = False PlayManager._bank_of_plays += [play] PlayManager._initialized = True PlayManager.fill_zero_gens() dump(PlayManager._bank_of_plays, open(f'{PlayManager.PlayPath}/all', 'wb')) Debug.play_manager('End initialization')
def blinds_increased(self): Debug.game_progress(f'Blinds are: {self.blinds.small_blind} ' f'{self.blinds.big_blind} {self.blinds.ante}') small = self.blinds.small_blind big = self.blinds.big_blind ante = self.blinds.ante for table in self.tables: if table.online: table.network.blinds_increased(small, big, ante) sleep(Delay.BlindsIncreased)
def get_parser(text, game): match = PokerStars.identifier.search(text) if match is not None: Debug.parser('Found PokerStars game') game.game_source = GameSource.PokerStars return PokerStarsParsing(game) match = Poker888.identifier.search(text) if match is not None: Debug.parser('Found Poker888 game') game.game_source = GameSource.Poker888 return Poker888Parsing(game) match = Poker888.identifier_snap.search(text) if match is not None: Debug.parser('Found Poker888 Snap Poker game') game.game_source = GameSource.Poker888 return Poker888Parsing(game, True) match = PartyPoker.identifier.search(text) if match is not None: Debug.parser('Found PartyPoker game') game.game_source = GameSource.PartyPoker return PartyPokerParsing(game) return None
def delete_bad_plays(): if not PlayManager._initialized: PlayManager.init() if Settings.game_mode == Mode.Evolution: indexes_to_delete = [] for index, play in enumerate(PlayManager._bank_of_plays): if (play.total_plays > 10 and play.average_places > 0.8 and play.value() < 1 or play.total_plays > 50 and play.average_places > 0.45 and play.value() < 2 or play.total_plays > 100 and play.average_places > 0.40 and play.value() < 3 or play.total_plays > 200 and play.average_places > 0.35 and play.value() < 4 or play.total_plays > 300 and play.average_places > 0.30 and play.value() < 5 or play.total_plays > 400 and play.average_places > 0.25 and play.value() < 6 or play.total_plays > 500 and play.average_places > 0.20 and play.value() < 7 or play.total_plays > 600 and play.average_places > 0.15 and play.value() < 8 or play.total_plays > 700 and play.average_places > 0.13 and play.value() < 9 or play.total_plays > 800 and play.average_places > 0.12 and play.value() < 10): indexes_to_delete += [index] remove( f'{PlayManager.PlayPath}/{play.generation}/{play.exemplar}' ) Debug.play_manager( f'Delete bad play gen {play.generation} ' f'ex {play.exemplar} after {play.total_plays} games ' f'wins {play.wins} avg {int(play.average_places * 1000)} ' f'new games {len(play.plays_history)} value {round(play.value(), 2)}' ) for index in reversed(indexes_to_delete): NameManager.add_name(PlayManager._bank_of_plays[index].name) del PlayManager._bank_of_plays[index] PlayManager.fill_zero_gens()
def network_process(self): Debug.game_manager(f'Game {self.id}: ready to listen game') while True: try: request = self.network.receive() Debug.game_manager(f'Game {self.id}: message {request}') if request['type'] == 'add player' and not self.game_started: Debug.game_manager(f'Game {self.id}: add player') if self.add_real_player(request['name']): self.network.send({'type': 'start game'}) Thread(target=lambda: self.wait_for_end(), name=f'Game {self.id}: wait for end').start() Thread( target=lambda: self.send_players_left(), name=f'Game {self.id}: send players left').start() else: self.network.send({ 'type': 'update players', 'left': self.players_count }) elif request[ 'type'] == 'delete player' and not self.game_started: Debug.game_manager(f'Game {self.id}: delete player') self.delete_player(request['name']) elif request['type'] == 'break': Debug.game_manager(f'Game {self.id}: break game') self.break_game() if self.thread: self.thread.join() self.network.send({'type': 'broken'}) except ValueError: continue except IndexError: continue
def standings(count: int = -1): if not PlayManager._initialized: PlayManager.init() if count == -1: count = len(PlayManager._bank_of_plays) Debug.evolution(f'Top {count} exemplars of evolution:') for place, play in enumerate( sorted([ play for play in PlayManager._bank_of_plays if len(play.plays_history) > 10 and play.value() > 1 ], key=lambda p: p.value(), reverse=True)[:count]): Debug.evolution(f'{place + 1:<2}) {play}')
def parse_game(path: str) -> Optional[PokerGame]: game = PokerGame() text_game = open(PokerGame.path_to_raw_games + path, 'r', encoding='utf-8').read().strip() game.source = path Debug.parser('\nStarting to analyse ' + path) parser = GameParser.get_parser(text_game, game) if parser is None: Debug.parser('Cannot parse game - can not identify') return None parser.process_game(text_game) game.approximate_players_left() game.add_final_table_marks() return game
def run(self) -> None: for num in range(self.games): game = Game(0, self.players, self.seats, self.money, self.blinds_scheme) for _ in range(game.total_players): game.add_bot_player() Debug.evolution(f'Start game #{num + 1}') game.start_game() PlayManager.standings(10) PlayManager.delete_bad_plays() if (num + 1) % 100 == 0: PlayManager.save_all_plays() PlayManager.save_all_plays()
def print_result(self) -> None: results = [] for player in self.players.all_players(): if player.money > player.money_start_of_hand: results += [ f'{player.name} wins {player.money - player.money_start_of_hand}' ] Debug.table( f'Table {self.id} hand {self.board.hand}: ' f'player {player.name} wins {player.money - player.money_start_of_hand} ' f'and has {player.money} money') elif player.money < player.money_start_of_hand: results += [ f'{player.name} loses {player.money_start_of_hand - player.money}' ] Debug.table( f'Table {self.id} hand {self.board.hand}: ' f'player {player.name} loses {player.money_start_of_hand - player.money} ' f'and has {player.money} money') else: Debug.table( f'Table {self.id} hand {self.board.hand}: player {player.name} has {player.money} money' ) if self.online: self.network.money_results(results) sleep(Delay.MoneyResults)
def delete_game(self, request: dict): if request['id'] in self.tournaments: del self.tournaments[request['id']] Debug.game_manager('Game manager: successful delete tournament') elif request['id'] in self.quick_games: del self.quick_games[request['id']] Debug.game_manager('Game manager: successful delete quick game') else: Debug.game_manager( f'Game manager: BAD ID FOR DELETING GAME: {request["id"]}')
def learning(self, path: str) -> None: x = self._data.decisions.get_data() y = self._data.decisions.get_answers() Debug.learning(f'Start learning from {y.size} samples') x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25) mlp = MLPClassifier(hidden_layer_sizes=(200, 100, 100)) mlp.fit(x_train, y_train) Debug.learning('train', mlp.score(x_train, y_train)) Debug.learning('test ', mlp.score(x_test, y_test)) if not exists('networks'): mkdir('networks') dump(mlp, open(f'networks/{path}', 'wb'))
def print_places(self) -> None: for player in self.players: if player.lose_time is None: player.set_lose_time() if player.controlled: player.network.win() Debug.evolution(f'Game wins {player.name}') sorted_players = sorted(self.players, key=lambda p: p.lose_time, reverse=True) if not Debug.Standings: for place, player in enumerate(sorted_players[:10]): Debug.evolution(f'{place+1:>4}) {player.play}') plays = {} if Settings.game_mode == Mode.Testing: if exists('networks/plays'): plays = load(open('networks/plays', 'rb')) for place, player in enumerate(sorted_players): Debug.standings(f'{place+1:>4}) {player.name}') if not player.controlled: player.play.set_place(place + 1, self.players_count) if Settings.game_mode == Mode.Testing: if player.play.name in plays: plays[player.play.name] += [place + 1] else: plays[player.play.name] = [place + 1] if player.play.exemplar == 0: print('Net', player.play.name, ':', place + 1, f' ({round(mean(plays[player.play.name]), 2)})') if Settings.game_mode == Mode.Testing: dump(plays, open('networks/plays', 'wb')) self.game_finished = True
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}')
def _decide(self, *, step: Step, to_call: int, min_raise: int, board: Cards, online: bool, **_) -> Tuple[Option, int]: if step == Step.Preflop: curr_play: BasePlay = self.play.preflop elif step == Step.Flop: curr_play: BasePlay = self.play.flop elif step == Step.Turn: curr_play: BasePlay = self.play.turn elif step == Step.River: curr_play: BasePlay = self.play.river else: raise ValueError(f'Undefined step id {step}') if self.remaining_money() > min_raise * 3 and random( ) < curr_play.bluff: bluff = int(min_raise * (1 + random())) Debug.decision( f'609 {self.name} raise bluff {bluff}; bluff = {curr_play.bluff}' ) if online: sleep(uniform(0.5, uniform(1, 2))) return Option.Raise, bluff probability = HoldemPoker.probability(self.cards, board) if probability < curr_play.min_probability_to_play: if to_call == 0 or to_call == self.gived: Debug.decision( f'617 {self.name} check on low ' f'prob = {probability}; ' f'bet coefficient = {curr_play.bet} ' f'to call = {to_call} self.gived = {self.gived}') if online: sleep(uniform(0.5, 1)) return Option.CheckCall, 0 else: Debug.decision(f'624 {self.name} fold low probability; ' f'prob = {probability}; ' f'min = {curr_play.min_probability_to_play}') if online: sleep(uniform(0.5, 1)) return Option.Fold, 0 if probability > curr_play.min_probability_to_all_in and random( ) < curr_play.probability_to_all_in: if self.remaining_money() <= to_call: Debug.decision( f'630 {self.name} call all in {self.gived} on high ' f'prob = {probability}; ' f'min = {curr_play.min_probability_to_all_in}') if online: sleep(uniform(1, uniform(1.5, 3))) else: Debug.decision(f'631 {self.name} all in {self.gived} on high ' f'prob = {probability}; ' f'min = {curr_play.min_probability_to_all_in}') if online: sleep(uniform(1, uniform(1.5, 3))) return Option.Raise, self.remaining_money() bet = int( min(probability * curr_play.bet_, 1) * self.remaining_money()) if bet == self.remaining_money(): if self.remaining_money() <= to_call: Debug.decision( f'632 {self.name} call all in {self.gived} on high bet ' f'prob = {probability}; ' f'min = {curr_play.min_probability_to_all_in}') if online: sleep(uniform(2, uniform(3, 5))) else: Debug.decision( f'640 {self.name} all in {self.gived} on high bet ' f'prob = {probability}; ' f'bet coefficient = {curr_play.bet}') if online: sleep(uniform(2, uniform(3, 5))) return Option.Raise, bet if to_call > bet: if to_call == 0 or self.gived == to_call: Debug.decision( f'643 {self.name} check while can not raise bet = {bet}') if online: sleep(uniform(0.5, uniform(1, 3))) return Option.CheckCall, 0 else: Debug.decision(f'647 {self.name} fold on low bet ' f'prob = {probability}; ' f'bet coefficient = {curr_play.bet} ' f'bet = {bet}') if online: sleep(uniform(1, uniform(2, 4))) return Option.Fold, 0 if min_raise > bet: if to_call == 0 or self.gived == to_call: Debug.decision(f'656 {self.name} check on mid bet ' f'prob = {probability}; ' f'bet coefficient = {curr_play.bet} ' f'bet = {bet}') if online: sleep(uniform(0.5, uniform(1, 2))) return Option.CheckCall, 0 else: Debug.decision(f'666 {self.name} call {to_call} on mid bet ' f'prob = {probability}; ' f'bet coefficient = {curr_play.bet} ' f'bet = {bet}') if online: sleep(uniform(2, uniform(4, 6))) return Option.CheckCall, to_call else: raise_bet = int( min(probability * curr_play.bet_ * curr_play.reduced_raise, 1) * self.remaining_money()) if raise_bet <= self.gived: if to_call == 0 or self.gived == to_call: Debug.decision( f'670 {self.name} check while thinks about raise {raise_bet}' ) if online: sleep(uniform(1, uniform(2, 3))) return Option.CheckCall, 0 else: Debug.decision( f'672 {self.name} fold while thinks about raise {raise_bet}' ) if online: sleep(uniform(2, uniform(4, 6))) return Option.Fold, 0 if raise_bet < to_call: if to_call == 0 or self.gived == to_call: Debug.decision( f'673 {self.name} check while thinks about raise {raise_bet}' ) if online: sleep(uniform(1, uniform(2, 3))) return Option.CheckCall, 0 else: Debug.decision( f'677 {self.name} fold while thinks about raise {raise_bet}' ) if online: sleep(uniform(2, uniform(4, 6))) return Option.Fold, 0 if raise_bet < min_raise: if to_call == 0 or to_call == self.gived: Debug.decision( f'656 {self.name} check while thinks about raise {raise_bet}' ) if online: sleep(uniform(0.5, uniform(1, 2))) return Option.CheckCall, 0 else: Debug.decision( f'682 {self.name} call {to_call} while thinks about raise {raise_bet}' ) if online: sleep(uniform(3, uniform(6, 8))) return Option.CheckCall, to_call if raise_bet == self.remaining_money(): if raise_bet <= to_call: Debug.decision(f'684 {self.name} call all in {self.gived}') if online: sleep(uniform(2, uniform(4, 6))) else: Debug.decision( f'687 {self.name} all in {self.gived} while thinks about raise {raise_bet}' ) if online: sleep(uniform(1, uniform(2, 3))) return Option.Raise, raise_bet if to_call == 0 and random() < curr_play.check_: Debug.decision( f'690 {self.name} cold check wanted to raise {raise_bet} ' f'check probability {curr_play.check}') if online: sleep(uniform(0.5, uniform(1, 2))) return Option.CheckCall, 0 elif to_call != 0 and random() < curr_play.call: if self.remaining_money() <= to_call: Debug.decision( f'691 {self.name} cold call all in {self.gived}') if online: sleep(uniform(2, uniform(4, 6))) return Option.CheckCall, self.remaining_money() else: Debug.decision( f'692 {self.name} cold call {to_call} while wanted to raise {raise_bet} ' f'call probability {curr_play.call}') if online: sleep(uniform(2, uniform(4, 6))) return Option.CheckCall, to_call if self.remaining_money() <= raise_bet: if self.remaining_money() <= to_call: Debug.decision(f'693 {self.name} call all in {self.gived}') if online: sleep(uniform(2, uniform(4, 6))) else: Debug.decision( f'694 {self.name} raise all in {self.gived}') if online: sleep(uniform(2, uniform(4, 6))) return Option.Raise, self.remaining_money() else: Debug.decision( f'695 {self.name} raise {raise_bet} on high bet ' f'prob = {probability}; ' f'bet coefficient = {curr_play.bet} ' f'bet = {bet}') if online: sleep(uniform(3, uniform(6, 9))) return Option.Raise, raise_bet
def get_decisions(game: PokerGame, hand: PokerHand) -> List[BasePokerDecision]: decisions: List[BasePokerDecision] = [] pot_size = 0 money: Dict[str, int] = {p.name: p.money for p in hand.players} bb: int = hand.big_blind Debug.datasets(')' * 20) for n, v in money.items(): Debug.datasets(f'{n} - {v}') Debug.datasets('(' * 20) for step, stage in hand: Debug.datasets('NEW STEP', step) gived: Dict[str, int] = {p.name: 0 for p in hand.players} if step == Step.Preflop: raise_amount = hand.big_blind else: raise_amount = 0 for act in stage: if act.event.is_statement(): continue Debug.datasets(act, raise_amount) if act.event == Event.Ante: pot_size += act.money money[act.player.name] -= act.money elif act.event == Event.SmallBlind: pot_size += act.money gived[act.player.name] = act.money money[act.player.name] -= act.money elif act.event == Event.BigBlind: pot_size += act.money gived[act.player.name] = act.money money[act.player.name] -= act.money elif act.event == Event.Fold: if act.player.cards is not None and act.player.cards.initialized( ) and not act.player.is_loser: pr = HoldemPoker.probability( act.player.cards, hand.board.get_from_step(step)) my_money = money[act.player.name] to_call = raise_amount - gived[act.player.name] des = PokerDecision.create(PokerDecisionAnswer.Fold, pr, my_money, pot_size, to_call, bb, step) decisions += [des] elif act.event == Event.Check: if act.player.cards is not None and act.player.cards.initialized( ) and not act.player.is_loser: pr = HoldemPoker.probability( act.player.cards, hand.board.get_from_step(step)) my_money = money[act.player.name] to_call = raise_amount - gived[act.player.name] des = PokerDecision.create( PokerDecisionAnswer.CheckCall, pr, my_money, pot_size, to_call, bb, step) decisions += [des] elif act.event == Event.Call: if act.player.cards is not None and act.player.cards.initialized( ) and not act.player.is_loser: pr = HoldemPoker.probability( act.player.cards, hand.board.get_from_step(step)) my_money = money[act.player.name] if raise_amount > my_money + gived[act.player.name]: to_call = my_money else: to_call = raise_amount - gived[act.player.name] des = PokerDecision.create( PokerDecisionAnswer.CheckCall, pr, my_money, pot_size, to_call, bb, step) decisions += [des] pot_size += act.money - gived[act.player.name] money[ act.player.name] -= act.money - gived[act.player.name] gived[act.player.name] = act.money elif act.event == Event.Raise or act.event == Event.Allin: if act.player.cards is not None and act.player.cards.initialized( ) and not act.player.is_loser: pr = HoldemPoker.probability( act.player.cards, hand.board.get_from_step(step)) my_money = money[act.player.name] to_call = raise_amount - gived[act.player.name] des = PokerDecision.create(PokerDecisionAnswer.Raise, pr, my_money, pot_size, to_call, bb, step) decisions += [des] pot_size += act.money - gived[act.player.name] money[ act.player.name] -= act.money - gived[act.player.name] gived[act.player.name] = act.money if raise_amount < act.money: raise_amount = act.money elif act.event == Event.ReturnMoney: pot_size -= act.money else: raise ValueError('you forget about', act.event) Debug.datasets(')' * 20) for n, v in gived.items(): Debug.datasets(f'{n}: {money[n]} ({v})') Debug.datasets('(' * 20) Debug.datasets('*' * 20) for des in decisions: Debug.datasets(des) Debug.datasets('_' * 20) return decisions
def _decide(self, *, step: Step, to_call: int, min_raise: int, board: Cards, online: bool, **_) -> Tuple[Option, int]: Debug.input_decision() Debug.input_decision(f'you have {self.get_cards()}') if step != Step.Preflop: Debug.input_decision(f'on table {Card.str(board)}') Debug.input_decision( f'your combination: {HandStrength.max_strength(self.cards.get() + board)}' ) Debug.input_decision( f'probability to win: {HoldemPoker.probability(self.cards, board)}' ) outs, outs_cards = HoldemPoker.calculate_outs(self.cards, board) Debug.input_decision( f'outs: {outs} - {" ".join([card.card for card in outs_cards])}') Debug.input_decision() available_decisions = [(Result.Fold, )] Debug.input_decision('1 - fold') if self.remaining_money() > to_call: if to_call == 0 or self.gived == to_call: available_decisions += [(Result.Check, )] Debug.input_decision(f'2 - check') else: available_decisions += [(Result.Call, to_call)] Debug.input_decision( f'2 - call {to_call} you called {self.gived} remains {to_call - self.gived}' ) if min_raise < self.remaining_money(): available_decisions += [(Result.Raise, min_raise, self.remaining_money())] Debug.input_decision( f'3 - raise from {min_raise} to {self.remaining_money()}') else: available_decisions += [(Result.Allin, self.remaining_money())] Debug.input_decision( f'3 - all in {self.remaining_money()} you called ' f'{self.gived} remains {self.money}') else: available_decisions += [(Result.Call, self.remaining_money())] Debug.input_decision(f'2 - call all in {self.remaining_money()}') answer = self.network.input_decision(available_decisions) if answer[0] == '1': return Option.Fold, 0 elif answer[0] == '2': if self.remaining_money() > to_call: if to_call == 0 or self.gived == to_call: return Option.CheckCall, 0 else: return Option.CheckCall, to_call else: return Option.CheckCall, self.remaining_money() elif answer[0] == '3': if self.remaining_money() > to_call: if len(answer) == 2: raised_money = int(answer[1]) return Option.Raise, raised_money else: return Option.Raise, self.remaining_money() else: return Option.Fold, 0
def get_decisions(game: PokerGame, hand: PokerHand) -> List[BasePokerDecision]: if game != PokerDecision10.CurrGame: PokerDecision10.CurrGame = game PokerDecision10.CurrRaisers = dict() PokerDecision10.CurrCallers = dict() PokerDecision10.CurrFolders = dict() PokerDecision10.CurrCheckers = dict() 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 for player in hand.players: key = (player.name, player.position) if key not in curr_raisers: curr_raisers[key] = PlayerStatistics() if key not in curr_callers: curr_callers[key] = PlayerStatistics() if key not in curr_folders: curr_folders[key] = PlayerStatistics() if key not in curr_checkers: curr_checkers[key] = PlayerStatistics() decisions: List[BasePokerDecision] = [] pot_size = 0 players_on_table = len(hand.players) players_active = players_on_table folded_players: List[str] = [] money: Dict[str, int] = {p.name: p.money for p in hand.players} average_money_on_table: int = int( sum(p.money for p in hand.players) / len(hand.players)) max_money_on_table: int = max(p.money for p in hand.players) bb: int = hand.big_blind Debug.datasets(')' * 20) for n, v in money.items(): Debug.datasets(f'{n} - {v}') Debug.datasets('(' * 20) for step, stage in hand: Debug.datasets('NEW STEP', step) gived: Dict[str, int] = {p.name: 0 for p in hand.players} players_not_moved = players_active - 1 # myself don`t count so minus 1 if step == Step.Preflop: raise_amount = hand.big_blind else: raise_amount = 0 for act in stage: if act.event.is_statement(): continue Debug.datasets(act, raise_amount) folder = curr_folders[act.player.name, act.player.position] caller = curr_callers[act.player.name, act.player.position] raiser = curr_raisers[act.player.name, act.player.position] checker = curr_checkers[act.player.name, act.player.position] if act.event == Event.Ante: pot_size += act.money money[act.player.name] -= act.money elif act.event == Event.SmallBlind: pot_size += act.money gived[act.player.name] = act.money money[act.player.name] -= act.money elif act.event == Event.BigBlind: pot_size += act.money gived[act.player.name] = act.money money[act.player.name] -= act.money elif act.event == Event.Fold: if act.player.cards is not None and act.player.cards.initialized( ) and not act.player.is_loser: my_money = money[act.player.name] to_call = raise_amount - gived[act.player.name] des = PokerDecision10.create( PokerDecisionAnswer3.Fold, my_money, pot_size, to_call, bb, step, act.player.cards, hand.board.get_from_step(step), players_on_table, players_active, players_not_moved, max_money_on_table, average_money_on_table, hand.players, folded_players, act.player.position, ) decisions += [des] if step == Step.Preflop: folder.activate() caller.skip() raiser.skip() if raise_amount == 0 or raise_amount == gived[ act.player.name]: checker.skip() players_active -= 1 players_not_moved -= 1 folded_players += [act.player.name] elif act.event == Event.Check: if act.player.cards is not None and act.player.cards.initialized( ) and not act.player.is_loser: my_money = money[act.player.name] to_call = raise_amount - gived[act.player.name] des = PokerDecision10.create( PokerDecisionAnswer3.CheckCall, my_money, pot_size, to_call, bb, step, act.player.cards, hand.board.get_from_step(step), players_on_table, players_active, players_not_moved, max_money_on_table, average_money_on_table, hand.players, folded_players, act.player.position, ) decisions += [des] if step == Step.Preflop: folder.skip() checker.activate() raiser.skip() players_not_moved -= 1 elif act.event == Event.Call: if act.player.cards is not None and act.player.cards.initialized( ) and not act.player.is_loser: my_money = money[act.player.name] if raise_amount > my_money + gived[act.player.name]: to_call = my_money else: to_call = raise_amount - gived[act.player.name] des = PokerDecision10.create( PokerDecisionAnswer3.CheckCall, my_money, pot_size, to_call, bb, step, act.player.cards, hand.board.get_from_step(step), players_on_table, players_active, players_not_moved, max_money_on_table, average_money_on_table, hand.players, folded_players, act.player.position, ) decisions += [des] if step == Step.Preflop: folder.skip() caller.activate() raiser.skip() pot_size += act.money - gived[act.player.name] money[ act.player.name] -= act.money - gived[act.player.name] gived[act.player.name] = act.money players_not_moved -= 1 elif act.event == Event.Raise or act.event == Event.Allin: if act.player.cards is not None and act.player.cards.initialized( ) and not act.player.is_loser: my_money = money[act.player.name] to_call = raise_amount - gived[act.player.name] actually_raised = act.money - gived[act.player.name] pot_sized_raise = actually_raised / pot_size if my_money == actually_raised: answer = PokerDecisionAnswer3.AllIn elif pot_sized_raise < 0.25: answer = PokerDecisionAnswer3.RaiseSmall elif pot_sized_raise < 0.75: answer = PokerDecisionAnswer3.RaiseMedium else: answer = PokerDecisionAnswer3.RaiseALot des = PokerDecision10.create( answer, my_money, pot_size, to_call, bb, step, act.player.cards, hand.board.get_from_step(step), players_on_table, players_active, players_not_moved, max_money_on_table, average_money_on_table, hand.players, folded_players, act.player.position, ) decisions += [des] if step == Step.Preflop: folder.skip() caller.skip() raiser.activate() if raise_amount == 0 or raise_amount == gived[ act.player.name]: checker.skip() pot_size += act.money - gived[act.player.name] money[ act.player.name] -= act.money - gived[act.player.name] gived[act.player.name] = act.money if raise_amount < act.money: raise_amount = act.money players_not_moved = players_active - 2 # without raiser and myself elif act.event == Event.ReturnMoney: pot_size -= act.money else: raise ValueError('you forget about', act.event) Debug.datasets(')' * 20) for n, v in gived.items(): Debug.datasets(f'{n}: {money[n]} ({v})') Debug.datasets('(' * 20) Debug.datasets('*' * 20) for des in decisions: Debug.datasets(des) Debug.datasets('_' * 20) return decisions
def add_data_set(self, games_path: str) -> None: self._data.add_data_from_folder(games_path) Debug.learning('data set contains', len(self._data.decisions), 'decisions with answers')
def load(path: str) -> PokerGame: Debug.parser(f'Loading {path}') return load(open(PokerGame.path_to_parsed_games + path, 'rb'))
def _decide(self, *, step: Step, to_call: int, min_raise: int, board: Cards, pot: int, bb: int, strength: Strength, players_on_table: int, players_active: int, players_not_moved: int, **_) -> Tuple[Option, int]: 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) evaluation = HoldemPoker.probability(self.cards, board) outs: float = HoldemPoker.calculate_outs(self.cards, board)[0] first: Rank = self.cards.first.rank second: Rank = self.cards.second.rank prediction = self.nn.predict( self.create_input( evaluation, self.money / pot, to_call / pot, bb / pot, step is Step.Preflop, step is Step.Flop, step is Step.Turn, step is Step.River, strength is Strength.Nothing, strength is Strength.Pair, strength is Strength.Pairs, strength is Strength.Set, strength is Strength.Straight, strength is Strength.Flush, strength is Strength.FullHouse, strength is Strength.Quad, strength is Strength.StraightFlush, strength is Strength.RoyalFlush, first is Rank.Two, first is Rank.Three, first is Rank.Four, first is Rank.Five, first is Rank.Six, first is Rank.Seven, first is Rank.Eight, first is Rank.Nine, first is Rank.Ten, first is Rank.Jack, first is Rank.Queen, first is Rank.King, first is Rank.Ace, second is Rank.Two, second is Rank.Three, second is Rank.Four, second is Rank.Five, second is Rank.Six, second is Rank.Seven, second is Rank.Eight, second is Rank.Nine, second is Rank.Ten, second is Rank.Jack, second is Rank.Queen, second is Rank.King, second is Rank.Ace, self.cards.suitability is Suitability.Suited, players_on_table == 2, players_on_table == 3, players_on_table == 4, players_on_table == 5, players_on_table == 6, players_on_table == 7, players_on_table == 8, players_on_table == 9, players_on_table == 10, players_active == 2, players_active == 3, players_active == 4, players_active == 5, players_active == 6, players_active == 7, players_active == 8, players_active == 9, players_active == 10, players_not_moved == 0, players_not_moved == 1, players_not_moved == 2, players_not_moved == 3, players_not_moved == 4, players_not_moved == 5, players_not_moved == 6, players_not_moved == 7, players_not_moved == 8, players_not_moved == 9, outs / HoldemPoker.MAX_OUTS)) Debug.decision("NEURAL NETWORK 7 START THINK") Debug.decision('evaluation =', evaluation) Debug.decision('pot =', pot) Debug.decision('money =', self.money) Debug.decision('to_call =', to_call) Debug.decision('bb =', bb) Debug.decision('step =', step) Debug.decision('strength =', strength) Debug.decision('first =', first) Debug.decision('second =', second) Debug.decision('suited =', self.cards.suitability) Debug.decision('players_on_table =', players_on_table) Debug.decision('players_active =', players_active) Debug.decision('players_not_moved =', players_not_moved) Debug.decision('outs =', outs) answer: PokerDecisionAnswer3 = PokerDecisionAnswer3(prediction[0]) Debug.decision('ANSWER =', answer) Debug.decision("NEURAL NETWORK 7 END THINK") raise_amount = 0 if answer is PokerDecisionAnswer3.AllIn: raise_amount = self.remaining_money() elif answer is PokerDecisionAnswer3.RaiseSmall: raise_amount = (0.1 + 0.25 * random()) * pot elif answer is PokerDecisionAnswer3.RaiseMedium: raise_amount = (0.25 + 0.4 * random()) * pot elif answer is PokerDecisionAnswer3.RaiseALot: raise_amount = (0.6 + 0.6 * random()) * pot return answer.as_option(), raise_amount
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 log(self, player: Optional[Player], result: Result, money: int = 0): init = f'Table {self.id} hand {self.board.hand}: ' if result == Result.Ante: Debug.table(init + f'player {player.name} paid ante {money}') elif result == Result.Button: Debug.table(init + f'button on {player.name}') elif result == Result.SmallBlind: Debug.table(init + f'player {player.name} paid small blind {money}') elif result == Result.BigBlind: Debug.table(init + f'player {player.name} paid big blind {money}') elif result == Result.MoveToPot: if player is not None: Debug.table(init + f'player {player.name} paid to pot {money}') else: Debug.table(init + f'total pot = {self.pot}') elif result == Result.ReturnMoney: Debug.table(init + f'{money} money back to {player.name}') elif result == Result.Fold: Debug.table(init + f'player {player.name} folded') elif result == Result.Check: Debug.table(init + f'player {player.name} checked') elif result == Result.Call: Debug.table(init + f'player {player.name} call {player.gived}') elif result == Result.Raise: Debug.table(init + f'player {player.name} raise {player.gived}') elif result == Result.Allin: Debug.table(init + f'player {player.name} all-in {player.gived}')
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 infinite(self): Debug.game_manager('Game manager: ready to listen') while True: try: request = self.network.receive() Debug.game_manager(f'Game manager: message {request}') if request['type'] == 'create tournament': Debug.game_manager('Game manager: create tournament') self.create_tournament(request) Debug.game_manager('Game manager: tournament created') elif request['type'] == 'create quick game': Debug.game_manager('Game manager: create quick game') self.create_quick_game(request) Debug.game_manager('Game manager: quick game created') elif request['type'] == 'delete game': Debug.game_manager('Game manager: delete game') self.delete_game(request) Debug.game_manager('Game manager: game deleted') except ValueError: continue except IndexError: continue
def get_decisions(game: PokerGame, hand: PokerHand) -> List[BasePokerDecision]: decisions: List[BasePokerDecision] = [] pot_size = 0 players_on_table = len(hand.players) players_active = players_on_table money: Dict[str, int] = {p.name: p.money for p in hand.players} bb: int = hand.big_blind Debug.datasets(')' * 20) for n, v in money.items(): Debug.datasets(f'{n} - {v}') Debug.datasets('(' * 20) for step, stage in hand: Debug.datasets('NEW STEP', step) gived: Dict[str, int] = {p.name: 0 for p in hand.players} players_not_moved = players_active - 1 # myself don`t count so minus 1 if step == Step.Preflop: raise_amount = hand.big_blind else: raise_amount = 0 for act in stage: if act.event.is_statement(): continue Debug.datasets(act, raise_amount) if act.event == Event.Ante: pot_size += act.money money[act.player.name] -= act.money elif act.event == Event.SmallBlind: pot_size += act.money gived[act.player.name] = act.money money[act.player.name] -= act.money elif act.event == Event.BigBlind: pot_size += act.money gived[act.player.name] = act.money money[act.player.name] -= act.money elif act.event == Event.Fold: if act.player.cards is not None and act.player.cards.initialized( ) and not act.player.is_loser: my_money = money[act.player.name] to_call = raise_amount - gived[act.player.name] des = PokerDecision6.create( PokerDecisionAnswer3.Fold, my_money, pot_size, to_call, bb, step, act.player.cards, hand.board.get_from_step(step), players_on_table, players_active, players_not_moved, ) decisions += [des] players_active -= 1 players_not_moved -= 1 elif act.event == Event.Check: if act.player.cards is not None and act.player.cards.initialized( ) and not act.player.is_loser: my_money = money[act.player.name] to_call = raise_amount - gived[act.player.name] des = PokerDecision6.create( PokerDecisionAnswer3.CheckCall, my_money, pot_size, to_call, bb, step, act.player.cards, hand.board.get_from_step(step), players_on_table, players_active, players_not_moved, ) decisions += [des] players_not_moved -= 1 elif act.event == Event.Call: if act.player.cards is not None and act.player.cards.initialized( ) and not act.player.is_loser: my_money = money[act.player.name] if raise_amount > my_money + gived[act.player.name]: to_call = my_money else: to_call = raise_amount - gived[act.player.name] des = PokerDecision6.create( PokerDecisionAnswer3.CheckCall, my_money, pot_size, to_call, bb, step, act.player.cards, hand.board.get_from_step(step), players_on_table, players_active, players_not_moved, ) decisions += [des] pot_size += act.money - gived[act.player.name] money[ act.player.name] -= act.money - gived[act.player.name] gived[act.player.name] = act.money players_not_moved -= 1 elif act.event == Event.Raise or act.event == Event.Allin: if act.player.cards is not None and act.player.cards.initialized( ) and not act.player.is_loser: my_money = money[act.player.name] to_call = raise_amount - gived[act.player.name] actually_raised = act.money - gived[act.player.name] pot_sized_raise = actually_raised / pot_size if my_money == actually_raised: answer = PokerDecisionAnswer3.AllIn elif pot_sized_raise < 0.25: answer = PokerDecisionAnswer3.RaiseSmall elif pot_sized_raise < 0.75: answer = PokerDecisionAnswer3.RaiseMedium else: answer = PokerDecisionAnswer3.RaiseALot des = PokerDecision6.create( answer, my_money, pot_size, to_call, bb, step, act.player.cards, hand.board.get_from_step(step), players_on_table, players_active, players_not_moved, ) decisions += [des] pot_size += act.money - gived[act.player.name] money[ act.player.name] -= act.money - gived[act.player.name] gived[act.player.name] = act.money if raise_amount < act.money: raise_amount = act.money players_not_moved = players_active - 2 # without raiser and myself elif act.event == Event.ReturnMoney: pot_size -= act.money else: raise ValueError('you forget about', act.event) Debug.datasets(')' * 20) for n, v in gived.items(): Debug.datasets(f'{n}: {money[n]} ({v})') Debug.datasets('(' * 20) Debug.datasets('*' * 20) for des in decisions: Debug.datasets(des) Debug.datasets('_' * 20) return decisions
def add_data_from_game(self, game: PokerGame) -> None: Debug.learning('Start eject data from game', game.name) for hand in game.hands: self.add_data_from_hand(game, hand)