예제 #1
0
 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)
예제 #2
0
 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')
예제 #3
0
    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)
예제 #4
0
    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()
예제 #5
0
    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')
예제 #6
0
    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)
예제 #7
0
    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
예제 #8
0
    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()
예제 #9
0
    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
예제 #10
0
    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}')
예제 #11
0
    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
예제 #12
0
    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()
예제 #13
0
    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)
예제 #14
0
 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"]}')
예제 #15
0
 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'))
예제 #16
0
    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
예제 #17
0
    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}')
예제 #18
0
    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
예제 #19
0
    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
예제 #20
0
    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
예제 #21
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
예제 #22
0
 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')
예제 #23
0
 def load(path: str) -> PokerGame:
     Debug.parser(f'Loading {path}')
     return load(open(PokerGame.path_to_parsed_games + path, 'rb'))
예제 #24
0
    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
예제 #25
0
    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)
예제 #26
0
    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}')
예제 #27
0
    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
예제 #28
0
    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
예제 #29
0
    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
예제 #30
0
 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)