Example #1
0
 def format_hand(self, extra_tile):
     hand = '{} + {}'.format(Tile.t136_to_g(self.tiles136),
                             Tile.t136_to_g([extra_tile]))
     if self.is_open_hand:
         melds = []
         for meld in self.meld136:
             melds.append('{}'.format(meld.tiles_graph))
         hand += ' + [{}]'.format(','.join(melds))
     return hand
Example #2
0
    def _handle_liuju(self, msg):
        self._round_end_info_to_file("    [R{}T{}] NO ONE WINS, NO MORE TILES...".format(
            self.game_table.round_number, len(self.game_table.bot.discard34))
        )
        self.both_log("    NO ONE WINS, NO MORE TILES...\n")
        self.drawer and self.drawer.liuju()

        opp_tiles_dict = {}
        for i in range(1, 4):
            opp_tiles = TenhouParser.parse_opp_tiles(msg, i)
            if opp_tiles and len(opp_tiles) > 0:
                opp_tiles_dict[i] = opp_tiles
        if len(opp_tiles_dict) > 0:
            for k, v in opp_tiles_dict.items():
                tiles34 = [t // 4 for t in v]
                self._round_end_info_to_file("        FT-P{}:{}:{}\n".format(k, Tile.t34_to_g(tiles34), tiles34))
                p_melds = [meld.tiles for meld in self.game_table.get_player(k).meld136]
                p_melds += [v]
                self._log(Tile.t136_to_g(p_melds))
                if self.drawer:
                    self.drawer.update_opp(p_melds, k, True)

        # prd_str = '        WP '
        # for i in range(1, 4):
        #     waitings = self.game_table.get_player(i).waiting_prediction
        #     prd_str += "• P{}:{}:{} ".format(i, waitings, Tile.t34_to_g(waitings))
        # prd_str += '\n'
        # self._round_end_info_to_file(prd_str)

        self.logger_obj.flush_buffer()
        self._wait_for_a_while()
        sleep(2)
        self._send('<NEXTREADY />')
Example #3
0
 def str_hand_tiles(self):
     hand = Tile.t136_to_g(self.tiles136)
     if self.is_open_hand:
         melds = []
         for meld in self.meld136:
             melds.append('{}'.format(meld.tiles_graph))
         hand += ' + [{}]'.format(','.join(melds))
     return hand
Example #4
0
 def _handle_new_bonus_indicator(self, msg):
     tile = TenhouParser.parse_bonus_indicator(msg)
     # save data to objects
     self.game_table.add_bonus_indicator(tile)
     # display in logs
     new_bi_msg = '    New bonus tile indicator revealed: {}'.format(Tile.t136_to_g([tile]))
     self.both_log(new_bi_msg)
     # display in GUI
     self.drawer and self.drawer.add_bonus_indicator(tile)
     self.drawer and self.drawer.set_remain(self.game_table.count_remaining_tiles)
Example #5
0
    def _handle_meld_call(self, msg, meld_tile):
        player_hand = self.game_table.bot.format_hand(meld_tile) if meld_tile else ''
        meld = TenhouParser.parse_meld(msg)

        if meld.by_whom != 0:
            self.game_table.call_meld(meld.by_whom, meld)
            meld_msg = '    [Player {}] called meld: {}'.format(meld.by_whom, meld)
            self.both_log(meld_msg)
            if self.drawer:
                p_melds = [meld.tiles for meld in self.game_table.get_player(meld.by_whom).meld136]
                self.drawer.update_opp(p_melds, meld.by_whom)

        if meld.by_whom == 0:
            self.game_table.bot.call_meld(meld)
            if meld.type != Meld.KAN and meld.type != Meld.CHANKAN:

                discard_tile_136 = self.game_table.bot.to_discard_tile()
                own_hand_msg = '        [Bot] hand tiles: {}'.format(player_hand)
                discard_msg = '        [Bot] discards tile {} after called meld'.format(
                    Tile.t136_to_g([discard_tile_136]))
                self.both_log(own_hand_msg)
                self.both_log(discard_msg)
                self._stream_log('')
                self._send('<D p="{}"/>'.format(discard_tile_136))
                self.game_table.discard_tile(0, discard_tile_136)
                self.game_table.bot.tiles136.remove(discard_tile_136)

                if self.drawer:
                    self.drawer.discard(discard_tile_136, 0)
                    self.drawer.update_self(self.game_table.bot.tiles136,
                                            [meld.tiles for meld in self.game_table.bot.meld136])
            else:
                if self.drawer:
                    self.drawer.update_self(self.game_table.bot.tiles136,
                                            [meld.tiles for meld in self.game_table.bot.meld136])

        if callable(getattr(self.game_table.bot, 'handle_opponent_discard', None)):
            for i in range(1, 4):
                self.game_table.bot.handle_opponent_discard(i)
Example #6
0
 def __str__(self):
     bonus_tile_indicator_repr = Tile.t136_to_g(self.bonus_indicator)
     return 'Round number:{0}, Honba sticks:{1}, Bonus tile indicator:{2}'.format(
         self.round_number, self.honba_sticks, bonus_tile_indicator_repr)
Example #7
0
 def tiles_graph(self):
     return Tile.t136_to_g(self.tiles)
Example #8
0
 def __str__(self):
     return '{}, {}'.format(self.type, Tile.t136_to_g(self.tiles),
                            self.tiles)
Example #9
0
    def _handle_opponent_discard(self, msg):
        opponent_seat = TenhouParser.parse_opponent_seat(msg)
        if opponent_seat == 0:
            # if hasattr(self.game_table.bot, "update_part"):
            #     self.game_table.bot.update_part()
            return -1

        tile = TenhouParser.parse_tile(msg)
        opp_obj = self.game_table.get_player(opponent_seat)

        discard_tag = ['d', 'e', 'f', 'g']  # lower case alphabet means the player discards whatever he had drawn...
        was_direct = discard_tag[opponent_seat] in msg
        opp_obj.add_discard_type(was_direct)

        if hasattr(self.game_table.bot, "handle_opponent_discard"):
            self.game_table.bot.handle_opponent_discard(opponent_seat)

        self.game_table.discard_tile(opponent_seat, tile)
        self.drawer and self.drawer.discard(tile, opponent_seat)
        discard_msg = "    [Player {}] discards: {} + {}".format(opponent_seat, Tile.t34_to_g(opp_obj.discard34[:-1]), Tile.t136_to_g([tile]))
        discard_msg += ", melds: {}".format(Tile.t34_to_g(opp_obj.meld34)) if opp_obj.meld34 else ""
        self.both_log(discard_msg)

        # check meld call for bot
        if 't=' in msg:
            # check kan
            if 't="3"' in msg or 't="7"' in msg:
                if self.game_table.bot.should_call_kan(tile, True)[0] == Meld.KAN:
                    self._send('<N type="2" />')
                    kan_msg = '    [Bot] called an open kan: {}'.format(Tile.t34_to_g([tile // 4] * 4))
                    self.both_log(kan_msg)
                    return -1
            # check chow/pon
            may_call_chi = (msg[1].lower() == 'g')
            meld, tile_to_discard = self.game_table.bot.try_to_call_meld(tile, may_call_chi)
            if meld:
                meld_type = '3' if meld.type == Meld.CHI else '1'
                self_tiles = [t for t in meld.tiles if t != meld.called_tile]
                self._send('<N type="{}" hai0="{}" hai1="{}" />'.format(meld_type, self_tiles[0], self_tiles[1]))
                self.game_table.count_remaining_tiles += 1
                return tile
            else:
                self._wait_for_a_while()
                self._send('<N />')

        self.drawer and self.drawer.set_remain(self.game_table.count_remaining_tiles)

        return -2
Example #10
0
    def _handle_draw_tile(self, msg):
        drawn_tile_136 = TenhouParser.parse_tile(msg)
        self.drawer and self.drawer.draw(drawn_tile_136)

        if not self.game_table.bot.reach_status:
            # print own hand tiles
            own_hand_str = '    [Bot] draws a tile: {}'.format(self.game_table.bot.format_hand(drawn_tile_136))
            self.game_table.bot.draw_tile(drawn_tile_136)
            self._stream_log('')
            self.both_log(own_hand_str)
            self._wait_for_a_while()

            # check if bot can call reach
            can_call_reach, to_discard_136 = self.game_table.bot.can_call_reach()
            if can_call_reach:
                self._send('<REACH hai="{}"/>'.format(to_discard_136))
                self.game_table.bot.call_reach()
                self._wait_for_a_while()

            # check if bot can call a kan set
            kan_type, kaned_tile136 = self.game_table.bot.should_call_kan(drawn_tile_136, False)
            if kan_type and self.game_table.count_remaining_tiles > 0:
                meld_type = 5 if kan_type == Meld.CHANKAN else 4
                self._send('<N type="{}" hai="{}"/>'.format(meld_type, kaned_tile136))
                return True

            # bot decides what to discard
            discard_tile_136 = self.game_table.bot.to_discard_tile()
            self.game_table.bot.tiles136.remove(discard_tile_136)
            discard_msg = '    [Bot] discards: {} + {}'.format(
                Tile.t34_to_g(self.game_table.bot.discard34),
                Tile.t136_to_g([discard_tile_136])
            )
            self.both_log(discard_msg)
            bot_hand_msg = '    [Bot] hand tiles after discarding: {}'.format(
                self.game_table.bot.str_hand_tiles()
            )
            self.both_log(bot_hand_msg)
        else:
            discard_tile_136 = drawn_tile_136
            own_hand_str = '    Own hand: {}'.format(self.game_table.bot.format_hand(drawn_tile_136))
            self._stream_log('')
            self.both_log(own_hand_str)

            if callable(getattr(self.game_table.bot, 'log_opponents_prediction', None)):
                self.game_table.bot.log_opponents_prediction()
            if callable(getattr(self.game_table.bot, 'show_riichi_waiting', None)):
                self.game_table.bot.show_riichi_waiting()

            discard_msg = '        🤖[Bot(Richii) discards]: {} + {}'.format(
                Tile.t34_to_g(self.game_table.bot.discard34), Tile.t136_to_g([discard_tile_136])
            )
            self.both_log(discard_msg)

        self._send('<D p="{}"/>'.format(int(discard_tile_136)))
        self.game_table.discard_tile(0, discard_tile_136)

        remain_tiles_msg = '    Remaining tiles: {}'.format(self.game_table.count_remaining_tiles)
        self._stream_log('')
        self.both_log(remain_tiles_msg)

        self._flush_buffer()

        self.drawer and self.drawer.set_remain(self.game_table.count_remaining_tiles)
        self._stream_log('')

        self.drawer and self.drawer.discard(discard_tile_136, 0)

        self.game_table.bot.tiles136 = sorted(self.game_table.bot.tiles136)

        self.drawer and self.drawer.update_self(self.game_table.bot.tiles136,
                                                [meld.tiles for meld in self.game_table.bot.meld136])

        return False
Example #11
0
    def _handle_round_end(self, msg=''):
        self.logger_obj.flush_buffer()
        self.logger_obj.add_line('')
        self.logger_obj.add_line("    {}".format(msg))

        # parse message
        who = int(TenhouParser.get_attribute_value(msg, 'who'))
        from_whom = int(TenhouParser.get_attribute_value(msg, 'fromWho'))
        win_tile_136 = int(TenhouParser.get_attribute_value(msg, 'machi'))
        hand_tiles_136 = TenhouParser.parse_initial_hand(msg)
        win_score = TenhouParser.parse_win_score(msg)
        if win_tile_136 in hand_tiles_136:
            hand_tiles_136.remove(win_tile_136)

        # save in logs
        who_str = "{}{}".format(
            who, "(Riichi)" if self.game_table.get_player(who).reach_status else ""
        )
        from_whom_str = "{}{}".format(
            from_whom, "(Riichi)" if self.game_table.get_player(from_whom).reach_status else ""
        )
        res_str = "    [Round-{} Turn-{} Dealer-{}]\n".format(
            self.game_table.round_number, len(self.game_table.bot.discard34), self.game_table.dealer_seat
        )
        res_str += "        [Win]:{}  [By]:{}  [Score]:{}  [Tile]:{} {} \n".format(
            who_str, from_whom_str, win_score, win_tile_136 // 4, Tile.t34_to_g(win_tile_136 // 4)
        )
        hand_tiles_34 = [t // 4 for t in hand_tiles_136] if who != 0 else self.game_table.bot.hand34
        win_tile_34 = win_tile_136 // 4
        meld_tiles_34 = self.game_table.get_player(who).meld34
        res_str += " " * 8 + "[Winning Hand] "
        res_str += "{}+{}+{}".format(
            Tile.t34_to_g(hand_tiles_34), ''.join([Tile.t34_to_g(m) for m in meld_tiles_34]), Tile.t34_to_g(win_tile_34)
        )
        res_str += "  {}+{}+{}\n".format(
            hand_tiles_34, ''.join(["{}".format(m) for m in meld_tiles_34]), win_tile_34
        )
        self._round_end_info_to_file(res_str)

        # display in logs
        if from_whom == who:
            win_msg = "    Player {} wins by own drawn tile {}".format(
                who, Tile.t34_to_g(win_tile_136 // 4)
            )
        else:
            win_msg = "    Player {} wins from player {}'s discard {}".format(
                who, from_whom, Tile.t34_to_g(win_tile_136 // 4)
            )
        self.both_log(win_msg)

        win_melds = self.game_table.get_player(who).meld34
        win_tiles_msg = "    {} {}+ {}, {}p".format(
            Tile.t136_to_g(hand_tiles_136),
            "+{}".format(Tile.t34_to_g(win_melds)) if len(win_melds) > 0 else '',
            Tile.t136_to_g(win_tile_136),
            win_score
        )
        self.both_log(win_tiles_msg)
        self.both_log('')

        # display in GUI
        if self.drawer:
            from_whom != who and self.drawer.lose(from_whom, win_score)
            from_whom != who and self.drawer.yong(who, win_score)
            from_whom == who and self.drawer.zimo(who, win_score)
            if who != 0:
                p_melds = [meld.tiles for meld in self.game_table.get_player(who).meld136]
                p_melds += [hand_tiles_136]
                p_melds += [[win_tile_136]]
                self.drawer.update_opp(p_melds, who, True)
            else:
                self.drawer.draw(win_tile_136)

        self._flush_buffer()
        self._wait_for_a_while()
        sleep(2)
        self._send('<NEXTREADY />')