示例#1
0
 def get_all_pairs() -> List[CardsPair]:
     pairs: List[CardsPair] = []
     for card1 in Card.cards_52():
         for card2 in Card.cards_52():
             if card1 > card2:
                 pairs += [CardsPair(card1, card2)]
     return pairs
    def process_flop(self, text: str) -> None:
        self.game.curr_hand.switch_to_step(Step.Flop)

        every_line = iter(text.strip().split('\n'))
        first_line = next(every_line)

        match = self.parser.find_flop.search(first_line)

        if match is None:
            raise ValueError(f'Bad first line in process flop: {text}')

        flop1 = Card(match.group(1).upper())
        flop2 = Card(match.group(2).upper())
        flop3 = Card(match.group(3).upper())

        self.game.curr_hand.set_flop_cards(flop1, flop2, flop3)

        self.process_actions(every_line)
    def process_flop(self, text: str):
        if self.is_broken_hand:
            return
        self.game.curr_hand.switch_to_step(Step.Flop)
        self.call_amount = 0

        lines = iter(text.strip().split('\n'))
        line = next(lines)

        match = self.parser.find_flop.search(line)

        if match is None:
            raise ValueError(f'Bad first line in process flop: {text}')

        flop1 = Card(match.group(1).upper())
        flop2 = Card(match.group(2).upper())
        flop3 = Card(match.group(3).upper())

        self.game.curr_hand.set_flop_cards(flop1, flop2, flop3)

        self.process_actions(lines)
示例#4
0
 def test_str_cards(self):
     self.assertEqual(Card('KD').card, 'KD')
     self.assertEqual(Card('QC').card, 'QC')
     self.assertEqual(Card('8H').card, '8H')
     self.assertEqual(Card('4C').card, '4C')
     self.assertEqual(Card('7S').card, '7S')
     self.assertEqual(Card('2H').card, '2H')
示例#5
0
 def test_short_cards(self):
     self.assertEqual(Card('4C').r, '4')
     self.assertEqual(Card('7C').r, '7')
     self.assertEqual(Card('JH').r, 'J')
     self.assertEqual(Card('4C').s, 'C')
     self.assertEqual(Card('7S').s, 'S')
     self.assertEqual(Card('JH').s, 'H')
    def process_river(self, text: str) -> None:
        self.game.curr_hand.switch_to_step(Step.River)

        every_line = iter(text.strip().split('\n'))
        first_line = next(every_line)

        match = self.parser.find_river.search(first_line)

        if match is None:
            raise ValueError(f'Bad first line in process river: {text}')

        river_card = Card(match.group(1).upper())
        self.game.curr_hand.set_river_card(river_card)

        self.process_actions(every_line)
    def process_turn(self, text: str) -> None:
        self.game.curr_hand.switch_to_step(Step.Turn)
        self.call_amount = 0

        every_line = iter(text.strip().split('\n'))
        first_line = next(every_line)

        match = self.parser.find_turn.search(first_line)

        if match is None:
            raise ValueError(f'Bad first line in process turn: {text}')

        turn_card = Card(match.group(1).upper())
        self.game.curr_hand.set_turn_card(turn_card)

        self.process_actions(every_line)
示例#8
0
    def calculate_outs(hidden: CardsPair, common: Cards) -> Tuple[int, Cards]:

        if len(common) == 5 or not common:
            return 0, []

        cards: Cards = [hidden.first, hidden.second] + common

        curr_hand_strength = HoldemPoker.fast_max_strength(cards)

        outs: int = 0
        outs_cards = []

        for card in Card.cards_52():

            if card not in cards:

                new_hand_strength = HoldemPoker.fast_max_strength(cards + [card])

                if new_hand_strength > curr_hand_strength:
                    outs += 1
                    outs_cards += [card]

        return outs, outs_cards
    def test_fast_hand_strength(self):

        cards = [Card('AS'), Card('8C'), Card('9D'), Card('2S'), Card('KD')]
        self.assertEqual(HoldemPoker.fast_hand_strength(cards),
                         Strength.Nothing)

        cards = [Card('AS'), Card('AC'), Card('9D'), Card('2S'), Card('KD')]
        self.assertEqual(HoldemPoker.fast_hand_strength(cards), Strength.Pair)

        cards = [Card('AS'), Card('AC'), Card('9D'), Card('9S'), Card('KD')]
        self.assertEqual(HoldemPoker.fast_hand_strength(cards), Strength.Pairs)

        cards = [Card('AS'), Card('KC'), Card('9D'), Card('9S'), Card('9H')]
        self.assertEqual(HoldemPoker.fast_hand_strength(cards), Strength.Set)

        cards = [Card('JS'), Card('QC'), Card('KD'), Card('9S'), Card('TH')]
        self.assertEqual(HoldemPoker.fast_hand_strength(cards),
                         Strength.Straight)

        cards = [Card('AS'), Card('8S'), Card('9S'), Card('2S'), Card('KS')]
        self.assertEqual(HoldemPoker.fast_hand_strength(cards), Strength.Flush)

        cards = [Card('AS'), Card('AC'), Card('9D'), Card('9S'), Card('9H')]
        self.assertEqual(HoldemPoker.fast_hand_strength(cards),
                         Strength.FullHouse)

        cards = [Card('AS'), Card('AH'), Card('9S'), Card('AC'), Card('AD')]
        self.assertEqual(HoldemPoker.fast_hand_strength(cards), Strength.Quad)

        cards = [Card('QS'), Card('8S'), Card('9S'), Card('JS'), Card('TS')]
        self.assertEqual(HoldemPoker.fast_hand_strength(cards),
                         Strength.StraightFlush)

        cards = [Card('QS'), Card('AS'), Card('KS'), Card('JS'), Card('TS')]
        self.assertEqual(HoldemPoker.fast_hand_strength(cards),
                         Strength.RoyalFlush)

        deck = Deck()
        for _ in range(100):
            deck.shuffle()
            cards = [
                deck.next(),
                deck.next(),
                deck.next(),
                deck.next(),
                deck.next()
            ]
            self.assertEqual(HoldemPoker.fast_hand_strength(cards),
                             HandStrength.strength(*cards).strength)
示例#10
0
    def __str__(self):

        cards = self.get()
        return Card.str(cards) if cards else 'no cards'
示例#11
0
 def test_rank(self):
     self.assertEqual(Card('TH').rank, Rank.Ten)
     self.assertEqual(Card('5H').rank, Rank.Five)
     self.assertEqual(Card('AS').rank, Rank.Ace)
示例#12
0
 def test_equals(self):
     self.assertEqual(Card('AS'), Card('AS'))
     self.assertNotEqual(Card('AS'), Card('AC'))
示例#13
0
 def test_convert(self):
     for card1 in Card.cards_52():
         for card2 in Card.cards_52():
             self.assertEqual(card1 == card2, card1.convert() == card2.convert())
示例#14
0
 def test_compare_cards(self):
     self.assertGreater(Card('AD'), Card('KC'))
     self.assertGreater(Card('QD'), Card('2C'))
     self.assertGreater(Card('7H'), Card('4D'))
     self.assertGreater(Card('TS'), Card('9S'))
示例#15
0
 def test_there_is_all_cards_different(self):
     cards = Card.cards_52()
     self.assertEqual(len(set(cards)), 52)
示例#16
0
 def __init__(self):
     self.cards: Cards = Card.cards_52()
     self.used: Cards = []
示例#17
0
 def test_suit(self):
     self.assertEqual(Card('TH').suit, Suit.Hearts)
     self.assertEqual(Card('TC').suit, Suit.Clubs)
     self.assertEqual(Card('TD').suit, Suit.Diamonds)
     self.assertEqual(Card('TS').suit, Suit.Spades)
    def process_actions(self, lines):
        while True:

            try:
                line = next(lines).strip()
            except StopIteration:
                return

            match = self.parser.find_dealt_cards.search(line)

            if match is not None:
                name = match.group(1)
                first_card = Card(match.group(2).upper())
                second_card = Card(match.group(3).upper())
                pair = CardsPair(first_card, second_card)
                self.game.curr_hand.set_cards(name, pair)
                continue

            match = self.parser.find_uncalled_bet.search(line)

            if match is not None:
                money = int(match.group(1))
                name = match.group(2)
                self.game.curr_hand.add_decision(name, Event.ReturnMoney,
                                                 money)
                continue

            match = self.parser.find_collect_pot.search(line)

            if match is not None:
                name = match.group(1)
                money = int(match.group(2))
                self.game.curr_hand.add_decision(name, Event.WinMoney, money)
                continue

            match = self.parser.find_collect_side_pot.search(line)

            if match is not None:
                name = match.group(1)
                money = int(match.group(2))
                self.game.curr_hand.add_decision(name, Event.WinMoney, money)
                continue

            match = self.parser.find_collect_side_pot_n.search(line)

            if match is not None:
                name = match.group(1)
                money = int(match.group(2))
                self.game.curr_hand.add_decision(name, Event.WinMoney, money)
                continue

            match = self.parser.find_collect_main_pot.search(line)

            if match is not None:
                name = match.group(1)
                money = int(match.group(2))
                self.game.curr_hand.add_decision(name, Event.WinMoney, money)
                continue

            match = self.parser.find_show_cards.search(line)

            if match is not None:
                name = match.group(1)
                cards = match.group(2)

                if len(cards) == 5:
                    card1, card2 = map(str.upper, cards.split())
                    pair = CardsPair(Card(card1), Card(card2))

                elif len(cards) == 2:
                    only_card = Card(cards.upper())
                    pair = CardsPair(only_card)

                else:
                    raise ValueError(f'Bad cards shown: {line}')

                self.game.curr_hand.set_cards(name, pair)
                continue

            match = self.parser.find_is_connected.search(line)

            if match is not None:
                name = match.group(1)
                self.game.curr_hand.add_decision(name, Event.Connected, 0)
                continue

            match = self.parser.find_is_disconnected.search(line)

            if match is not None:
                name = match.group(1)
                try:
                    self.game.curr_hand.add_decision(name, Event.Disconnected,
                                                     0)
                except ValueError:
                    pass
                continue

            match = self.parser.find_is_sitting_out.search(line)

            if match is not None:
                name = match.group(1)
                try:
                    self.game.curr_hand.add_decision(name, Event.Disconnected,
                                                     0)
                except ValueError:
                    pass
                continue

            match = self.parser.find_said.search(line)

            if match is not None:
                name = match.group(1)
                msg = match.group(2)
                try:
                    self.game.curr_hand.add_decision(name, Event.ChatMessage,
                                                     0, msg)
                except ValueError:
                    self.game.curr_hand.add_decision(name,
                                                     Event.ObserverChatMessage,
                                                     0, msg)
                continue

            match = self.parser.find_observer_said.search(line)

            if match is not None:
                name = match.group(1)
                msg = match.group(2)
                self.game.curr_hand.add_decision(name,
                                                 Event.ObserverChatMessage, 0,
                                                 msg)
                continue

            match = self.parser.find_finished.search(line)

            if match is not None:
                name = match.group(1)
                place = match.group(2)
                self.game.curr_hand.add_decision(name, Event.FinishGame, 0,
                                                 place)
                match = self.parser.find_place.search(place)
                self.game.curr_hand.players_left = int(match.group(1))
                continue

            match = self.parser.find_received.search(line)

            if match is not None:
                name = match.group(1)
                place = match.group(2)
                earn = int(match.group(3).replace('.', ''))
                self.game.curr_hand.add_decision(name, Event.FinishGame, earn,
                                                 place)
                match = self.parser.find_place.search(place)
                self.game.curr_hand.players_left = int(match.group(1))
                continue

            match = self.parser.find_received_fpp.search(line)

            if match is not None:
                name = match.group(1)
                place = match.group(2)
                earn = int(match.group(3))
                self.game.curr_hand.add_decision(name, Event.FinishGame, earn,
                                                 place)
                match = self.parser.find_place.search(place)
                self.game.curr_hand.players_left = int(match.group(1))
                continue

            match = self.parser.find_winner.search(line)

            if match is not None:
                name = match.group(1)
                earn = int(match.group(2).replace('.', ''))
                self.game.curr_hand.add_decision(name, Event.FinishGame, earn,
                                                 '1st')
                continue

            match = self.parser.find_does_not_show.search(line)

            if match is not None:
                continue

            match = self.parser.find_has_returned.search(line)

            if match is not None:
                name = match.group(1)
                try:
                    self.game.curr_hand.add_decision(name, Event.Connected, 0)
                except ValueError:
                    pass
                continue

            match = self.parser.find_has_timed_out.search(line)

            if match is not None:
                continue

            match = self.parser.find_timed_disconnected.search(line)

            if match is not None:
                name = match.group(1)
                self.game.curr_hand.add_decision(name, Event.Disconnected, 0)
                continue

            match = self.parser.find_timed_being_disconnected.search(line)

            if match is not None:
                name = match.group(1)
                self.game.curr_hand.add_decision(name, Event.Disconnected, 0)
                continue

            match = self.parser.find_finished_the_tournament.search(line)

            if match is not None:
                continue

            match = self.parser.find_eliminated_and_bounty.search(line)

            if match is not None:
                continue

            match = self.parser.find_eliminated_and_bounty_first.search(line)

            if match is not None:
                continue

            match = self.parser.find_eliminated_and_bounty_split.search(line)

            if match is not None:
                continue

            match = self.parser.find_rebuy_and_receive_chips.search(line)

            if match is not None:
                continue

            match = self.parser.find_rebuy_for_starcoins.search(line)

            if match is not None:
                continue

            match = self.parser.find_addon_and_receive_chips.search(line)

            if match is not None:
                continue

            match = self.parser.find_addon_for_starcoins.search(line)

            if match is not None:
                continue

            match = self.parser.find_skip_break_and_resuming.search(line)

            if match is not None:
                continue

            match = self.parser.find_wins_entry_to_tournament.search(line)

            if match is not None:
                continue

            match = self.parser.find_add_chips.search(line)

            if match is not None:
                continue

            if match is not None:
                name = match.group(1)
                self.game.curr_hand.add_decision(name, Event.Disconnected, 0)
                continue

            match = self.parser.find_shows_in_show_down.search(line)

            if match is not None:
                name = match.group(1)
                card1 = Card(match.group(2).upper())
                card2 = Card(match.group(3).upper())
                self.game.curr_hand.set_cards(name, CardsPair(card1, card2))
                continue

            match = self.parser.find_fold_showing_cards.search(line)

            if match is not None:
                name = match.group(1)
                cards = match.group(2)

                if len(cards) == 5:
                    card1, card2 = map(str.upper, cards.split())
                    pair = CardsPair(Card(card1), Card(card2))

                elif len(cards) == 2:
                    only_card = Card(cards.upper())
                    pair = CardsPair(only_card)

                else:
                    raise ValueError(f'Bad cards shown: {line}')

                self.game.curr_hand.set_cards(name, pair)
                continue

            match = self.parser.find_mucks_hand.search(line)

            if match is not None:
                continue

            match = self.parser.find_action.search(line)

            try:
                name = match.group(1)
                action = match.group(2)
            except AttributeError:
                print('Cannot parse line:', line)
                raise

            try:
                result, money = self.parse_action(
                    self.game.curr_hand.get_player(name),
                    self.game.curr_hand.curr_step, action)
            except ValueError:
                print('Bad action: ' + line)
                raise

            self.game.curr_hand.add_decision(name, result, money)
    def process_actions(self, lines):
        while True:

            try:
                line = next(lines).strip()
            except StopIteration:
                return

            if not line:
                return

            match = self.parser.find_dealt_cards.search(line)

            if match is not None:
                name = match.group(1)
                first_card = Card(match.group(2).upper())
                second_card = Card(match.group(3).upper())
                pair = CardsPair(first_card, second_card)
                self.game.curr_hand.set_cards(name, pair)
                continue

            match = self.parser.find_fold.search(line)

            if match is not None:
                name = match.group(1)
                self.game.curr_hand.add_decision(name, Event.Fold, 0)
                continue

            match = self.parser.find_call.search(line)

            if match is not None:
                name = match.group(1)
                money = int(match.group(2).replace(',', ''))
                self.total_pot += money
                self.game.curr_hand.add_decision(name, Event.Call,
                                                 self.call_amount)
                continue

            match = self.parser.find_call_2.search(line)

            if match is not None:
                name = match.group(1)
                money = int(match.group(2).replace('\xa0', ''))
                self.total_pot += money
                self.game.curr_hand.add_decision(name, Event.Call,
                                                 self.call_amount)
                continue

            match = self.parser.find_check.search(line)

            if match is not None:
                name = match.group(1)
                self.game.curr_hand.add_decision(name, Event.Check, 0)
                continue

            match = self.parser.find_bet.search(line)

            if match is not None:
                name = match.group(1)
                money = int(match.group(2).replace(',', ''))
                self.call_amount = money
                self.total_pot += money
                self.game.curr_hand.add_decision(name, Event.Raise, money)
                continue

            match = self.parser.find_bet_2.search(line)

            if match is not None:
                name = match.group(1)
                money = int(match.group(2).replace('\xa0', ''))
                self.call_amount = money
                self.total_pot += money
                self.game.curr_hand.add_decision(name, Event.Raise, money)
                continue

            match = self.parser.find_raise.search(line)

            if match is not None:
                name = match.group(1)
                money = int(match.group(2).replace(',', ''))
                self.total_pot += money
                self.call_amount = self.game.curr_hand.get_player(name).gived(
                    self.game.curr_hand.curr_step) + money
                try:
                    self.game.curr_hand.add_decision(name, Event.Raise,
                                                     self.call_amount)
                except ValueError:
                    print('Can not add decision: ' + line)
                    raise
                continue

            match = self.parser.find_raise_2.search(line)

            if match is not None:
                name = match.group(1)
                money = int(match.group(2).replace('\xa0', ''))
                self.total_pot += money
                self.call_amount = self.game.curr_hand.get_player(name).gived(
                    self.game.curr_hand.curr_step) + money
                try:
                    self.game.curr_hand.add_decision(name, Event.Raise,
                                                     self.call_amount)
                except ValueError:
                    print('Can not add decision: ' + line)
                    raise
                continue

            match = self.parser.find_did_not_show.search(line)

            if match is not None:
                continue

            match = self.parser.find_win_money.search(line)

            if match is not None:
                name = match.group(1)
                money = int(match.group(2).replace(',', ''))
                self.game.curr_hand.add_decision(name, Event.WinMoney, money)
                self.game.curr_hand.add_winner(name)
                continue

            match = self.parser.find_win_money_2.search(line)

            if match is not None:
                name = match.group(1)
                money = int(match.group(2).replace('\xa0', ''))
                self.game.curr_hand.add_decision(name, Event.WinMoney, money)
                self.game.curr_hand.add_winner(name)
                continue

            match = self.parser.find_show_cards.search(line)

            if match is not None:
                name = match.group(1)
                card1 = Card(match.group(2).upper())
                card2 = Card(match.group(3).upper())
                pair = CardsPair(card1, card2)
                self.game.curr_hand.set_cards(name, pair)
                self.game.curr_hand.goes_to_showdown = True
                continue

            match = self.parser.find_muck_cards.search(line)

            if match is not None:
                name = match.group(1)
                card1 = Card(match.group(2).upper())
                card2 = Card(match.group(3).upper())
                pair = CardsPair(card1, card2)
                self.game.curr_hand.set_cards(name, pair)
                self.game.curr_hand.add_loser(name)
                continue

            raise ValueError('Undefined action: ' + line)
    def process_summary(self, text: str) -> None:
        every_line = iter(text.strip().split('\n'))
        line = next(every_line).strip()

        if not line.startswith('Total pot'):
            raise ValueError(f'Bad first line of summary: {text}')

        if 'Main pot' in line:
            match = self.parser.find_total_pot_with_main_pot.search(line)
        else:
            match = self.parser.find_total_pot.search(line)

        try:
            total_pot = int(match.group(1))
        except AttributeError:
            raise ValueError(f'Bad total pot: {line}')

        self.game.curr_hand.total_pot = total_pot

        line = next(every_line)

        if line.startswith('Board'):
            line = next(every_line)

        if not line.startswith('Seat'):
            raise ValueError(f'Bad second/third line of summary: {text}')

        while line.startswith('Seat'):

            if line.endswith("folded before Flop (didn't bet)") or \
                    line.endswith('folded before Flop') or \
                    line.endswith('folded on the Flop') or \
                    line.endswith('folded on the Turn') or \
                    line.endswith('folded on the River'):

                try:
                    line = next(every_line)
                except StopIteration:
                    return

                continue

            if ' (button) ' in line:
                line = line.replace(' (button) ', ' ')
            if ' (big blind) ' in line:
                line = line.replace(' (big blind) ', ' ')
            if ' (small blind) ' in line:
                line = line.replace(' (small blind) ', ' ')

            match = self.parser.find_collected_pot_summary.search(line)

            if match is not None:

                name = match.group(1)
                win_player_cards = self.game.curr_hand.get_player(name).cards
                if win_player_cards is not None and win_player_cards.initialized(
                ):
                    self.game.curr_hand.add_winner(name)

            else:

                match = self.parser.find_lost.search(line)

                if match is not None:
                    name = match.group(1)
                    card1 = Card(match.group(2).upper())
                    card2 = Card(match.group(3).upper())
                    self.game.curr_hand.set_cards(name,
                                                  CardsPair(card1, card2))
                    self.game.curr_hand.add_loser(name)

                else:

                    match = self.parser.find_won.search(line)

                    if match is not None:
                        name = match.group(1)
                        card1 = Card(match.group(2).upper())
                        card2 = Card(match.group(3).upper())
                        self.game.curr_hand.set_cards(name,
                                                      CardsPair(card1, card2))
                        self.game.curr_hand.add_winner(name)

                    else:

                        match = self.parser.find_mucked_cards.search(line)

                        if match is not None:
                            name = match.group(1)
                            card1 = Card(match.group(2).upper())
                            card2 = Card(match.group(3).upper())
                            self.game.curr_hand.set_cards(
                                name, CardsPair(card1, card2))
                            self.game.curr_hand.add_loser(name)

                        else:
                            raise ValueError(
                                f'Bad summary processing line: {line}')

            try:
                line = next(every_line)
            except StopIteration:
                return

        self.process_actions(every_line)
示例#21
0
 def test_str_cards_list(self):
     self.assertEqual(Card.str([Card('AS'), Card('QD'), Card('2C')]), 'AS QD 2C')
    def process_actions(self, lines):
        while True:

            try:
                line = next(lines).strip()
            except StopIteration:
                return

            if not line:
                return

            match = self.parser.find_dealt_cards.search(line)

            if match is not None:
                name = match.group(1)
                first_card = Card(match.group(2).upper())
                second_card = Card(match.group(3).upper())
                pair = CardsPair(first_card, second_card)
                self.game.curr_hand.set_cards(name, pair)
                continue

            match = self.parser.find_fold.search(line)

            if match is not None:
                name = match.group(1)
                try:
                    self.game.curr_hand.add_decision(name, Event.Fold, 0)
                except ValueError:
                    pass
                continue

            match = self.parser.find_call.search(line)

            if match is not None:
                name = match.group(1)
                money = int(match.group(2).replace(',', ''))
                self.total_pot += money
                self.game.curr_hand.add_decision(name, Event.Call,
                                                 self.call_amount)
                continue

            match = self.parser.find_check.search(line)

            if match is not None:
                name = match.group(1)
                self.game.curr_hand.add_decision(name, Event.Check, 0)
                continue

            match = self.parser.find_bet.search(line)

            if match is not None:
                name = match.group(1)
                money = int(match.group(2).replace(',', ''))
                self.call_amount = money
                self.total_pot += money
                self.game.curr_hand.add_decision(name, Event.Raise, money)
                continue

            match = self.parser.find_raise.search(line)

            if match is not None:
                name = match.group(1)
                money = int(match.group(2).replace(',', ''))
                self.total_pot += money
                self.call_amount = self.game.curr_hand.get_player(name).gived(
                    self.game.curr_hand.curr_step) + money
                self.game.curr_hand.add_decision(name, Event.Raise,
                                                 self.call_amount)
                continue

            match = self.parser.find_all_in.search(line)

            if match is not None:
                name = match.group(1)
                money = int(match.group(2).replace(',', ''))
                self.total_pot += money
                self.call_amount = self.game.curr_hand.get_player(name).gived(
                    self.game.curr_hand.curr_step) + money
                self.game.curr_hand.add_decision(name, Event.Raise,
                                                 self.call_amount)
                continue

            match = self.parser.find_did_not_show.search(line)

            if match is not None:
                continue

            match = self.parser.find_win_money.search(line)

            if match is not None:
                name = match.group(1)
                money = int(match.group(2).replace(',', ''))
                self.game.curr_hand.add_decision(name, Event.WinMoney, money)
                self.game.curr_hand.add_winner(name)
                continue

            match = self.parser.find_show_cards.search(line)

            if match is not None:
                name = match.group(1)
                card1 = Card(match.group(2).upper())
                card2 = Card(match.group(3).upper())
                pair = CardsPair(card1, card2)
                self.game.curr_hand.set_cards(name, pair)
                self.game.curr_hand.goes_to_showdown = True
                continue

            match = self.parser.find_finished.search(line)

            if match is not None:
                name = match.group(1)
                place = match.group(2)
                self.game.curr_hand.add_decision(name, Event.FinishGame, 0,
                                                 place)
                continue

            match = self.parser.find_knocked_out.search(line)

            if match is not None:
                continue

            match = self.parser.find_join_game.search(line)

            if match is not None:
                continue

            match = self.parser.find_use_bank_time.search(line)

            if match is not None:
                continue

            match = self.parser.find_did_not_respond.search(line)

            if match is not None:
                continue

            match = self.parser.find_not_respond_disconnected.search(line)

            if match is not None:
                name = match.group(1)
                self.game.curr_hand.add_decision(name, Event.Disconnected, 0)
                continue

            match = self.parser.find_moved_from_other_table.search(line)

            if match is not None:
                continue

            match = self.parser.find_break.search(line)

            if match is not None:
                continue

            match = self.parser.find_activate_bank.search(line)

            if match is not None:
                continue

            match = self.parser.find_reconnected.search(line)

            if match is not None:
                continue

            match = self.parser.find_disconnected_wait.search(line)

            if match is not None:
                continue

            match = self.parser.find_level_moves.search(line)

            if match is not None:
                continue

            match = self.parser.find_chat_message.search(line)

            if match is not None:
                name = match.group(1)
                message = match.group(2)
                try:
                    self.game.curr_hand.add_decision(name, Event.ChatMessage,
                                                     0, message)
                except ValueError:
                    self.game.curr_hand.add_decision(name,
                                                     Event.ObserverChatMessage,
                                                     0, message)
                continue

            match = self.parser.find_end_of_hand.search(line)

            if match is not None:
                self.game.curr_hand.total_pot = self.total_pot
                break

            raise ValueError('Undefined action: ' + line)