Ejemplo n.º 1
0
 def __init__(self, card_type_list=[CardType.WAN]):
     self.card_range = []
     for t in card_type_list:
         self.card_range.append([
             Card.cal_card_val(t, 1),
             Card.cal_card_val(t, CARD_SIZE[t] - 1)
         ])
Ejemplo n.º 2
0
    def param_check(self, **kwargs):  # 参数验证
        act_params = kwargs.get("act_params")
        if 1 != len(act_params):
            # 同时只允许有一个玩家发生暗杠操作
            logger.debug(u"act_an_gang_error:%s", str(act_params))
            return

        seat_id = list(act_params.keys())[0]
        params = act_params[seat_id]
        # TODO 此处需要接受参数 用户选择暗杠牌值
        used_card = params.get("used_card")[0]
        # card_val = self.game_data.last_chu_card_val

        if not used_card:
            logger.error("an_gang params error: %s", str([seat_id, params]))
            return

        hand_card = self.players[seat_id].hand_card
        if 4 != hand_card.hand_card_info[Card.cal_card_type(used_card)][
                Card.cal_card_digit(used_card)]:
            logger.error("an_gang params error: %s", str([seat_id, params]))
            return

        self.seat_id = seat_id
        self.used_card = used_card
        return 1
Ejemplo n.º 3
0
 def has_card(self, card_val):
     """
     是否有指定的手牌
     :param card_val:
     :return: 返回张数
     """
     return self.hand_card_info[Card.cal_card_type(card_val)][
         Card.cal_card_digit(card_val)]
Ejemplo n.º 4
0
 def add_hand_card_by_vals(self, card_vals=[]):
     if not card_vals:
         return
     for v in card_vals:
         card_type = Card.cal_card_type(v)
         card_digit = Card.cal_card_digit(v)
         self.hand_card_info[card_type][card_digit] += 1
         self.hand_card_info[card_type][0] += 1
     self.last_card_val = card_vals[-1]
Ejemplo n.º 5
0
 def get_can_peng_info_by_handcard(self, card, hand_card):
     """
     判断某张牌是否可以碰
     :param card: 待判断的牌
     :param cur_card_list: 当前手牌
     :return: 返回是否可碰牌
     """
     card_type = Card.cal_card_type(card)
     card_digit = Card.cal_card_digit(card)
     return 2 <= hand_card.hand_card_info[card_type][card_digit]
Ejemplo n.º 6
0
 def get_can_dian_gang_info_by_handcard(self, card, hand_card):
     """
     判断某张牌是否可以杠(点杠)
     :param card: 待判断的牌
     :param cur_card_list: 当前手牌
     :return: 返回是否可杠牌
     """
     card_type = Card.cal_card_type(card)
     card_digit = Card.cal_card_digit(card)
     return 4 == hand_card.hand_card_info[card_type][card_digit]
Ejemplo n.º 7
0
    def can_bu_gang(self, hand_card):
        """是否可以补杠"""
        all_types = CardType.all_type()
        can_bu_gang_cards = []
        for t in all_types:
            if 1 > hand_card.hand_card_info[t][0]:
                continue
            for i in range(1, CARD_SIZE[t]):
                if 1 == hand_card.hand_card_info[t][i]:
                    card_val = Card.cal_card_val(t, i)
                    for peng_group in hand_card.peng_card_vals:
                        if card_val in peng_group:
                            if self.players[self.seat_id].ting_info:
                                # 玩家处于听牌状态, 判断补杠后会否破坏牌型
                                temp_cards = self.players[
                                    self.seat_id].hand_card.hand_card_vals
                                temp_cards.remove(card_val)
                                temp_cards.append(LAI_ZI)
                                ting_cards = self.card_analyse.get_can_ting_info_by_val(
                                    temp_cards)
                                ret = []
                                for k in ting_cards.keys():
                                    ret.extend(ting_cards[k])
                                if not set(self.players[self.seat_id].ting_info
                                           .keys()).issubset(set(ret)):
                                    # 如果新的听牌结果不包含原有听牌结果,则不能点杠
                                    print(
                                        "seat=%s, card_val=%s, ting_cards=%s , can't ting!"
                                        % (self.seat_id, card_val, ting_cards))
                                else:
                                    can_bu_gang_cards.append(card_val)
                            else:
                                can_bu_gang_cards.append(card_val)

        return can_bu_gang_cards
Ejemplo n.º 8
0
    def get_can_chi_info_by_val(self, card, cur_card_list):
        """
        判断某张牌是否可以吃
        :param card: 待判断的牌
        :param cur_card_list: 当前手牌
        :return: 返回吃牌的组合[[], [], ...]
        """
        if not Card.has_shun(card):
            return []
        tmp = []
        for i in range(card + 2, card - 3, -1):
            if i in tmp:
                continue
            if i == card:
                tmp.append(i)
            else:
                if i in cur_card_list:
                    tmp.append(i)

        result = []
        num = len(tmp)
        if 3 > num:
            return []
        for j in range(num - 2):
            if self.hu_analyse.shun(tmp[j:j + 3]):
                result.append(tmp[j:j + 3])
        return result
Ejemplo n.º 9
0
 def bu_hua(self):
     """检查是否补花"""
     hua_card = []
     for c in self.drew_cardvals:
         if CardType.HUA == Card.cal_card_type(c):
             hua_card.append(c)
     if not hua_card:
         return 0
     logger.debug('补花:%d', len(hua_card))
     # 将花牌从手牌中移除
     self.players[self.seat_id].hand_card.del_hand_card_by_val(hua_card[0])
     # 将补花数量添加进手牌中
     self.players[self.seat_id].hand_card.hua_card_vals.extend(hua_card)
     # 通知所有人有玩家补花
     notify_all_desk_player(self.desk_id, PUSH_GAME_BU_HUA, {
         "seat_id": self.seat_id,
         "hua_card_list": hua_card
     })
     timer_manager_ins.add_timer(self.desk_id,
                                 self.seat_id,
                                 GlobalConfig().bu_hua_show_time,
                                 t_type=TimerType.KEEP,
                                 call_type=CallbackFuncType.FUNC_DRAW_CARD,
                                 call_params={
                                     "seat_id": self.seat_id,
                                     "card_num": len(hua_card),
                                     "is_last": True
                                 })
     return 1
Ejemplo n.º 10
0
 def bu_hua(self, seat_id, card_list=[]):
     """检查是否补花"""
     hua_card = []
     tmp_card_list = copy.deepcopy(card_list)
     for c in tmp_card_list:
         if CardType.HUA == Card.cal_card_type(c):
             hua_card.append(c)
             card_list.remove(c)
     if not hua_card:
         return 0
     logger.debug('发牌补花:%d', len(hua_card))
     new_cards = []
     temp_hua = copy.deepcopy(hua_card)
     while temp_hua:
         cards = self.card_dealer.draw_cards(num=len(temp_hua),
                                             is_last=True)
         temp_hua = []
         for c in cards:
             if CardType.HUA == Card.cal_card_type(c):
                 temp_hua.append(c)
                 hua_card.append(c)
             else:
                 new_cards.append(c)
     card_list.extend(new_cards)
     # 将补花数量添加进手牌中 hua_card_vals 中
     self.players[seat_id].hand_card.hua_card_vals.extend(hua_card)
     for p in self.players:
         if p.seat_id == seat_id:
             notify_single_user(self.desk_id,
                                p.seat_id,
                                message_ids.PUSH_GAME_DEAL_BU_HUA,
                                data={
                                    "seat_id": seat_id,
                                    "hua_card": hua_card,
                                    "bu_cards": new_cards
                                })
         else:
             notify_single_user(self.desk_id,
                                p.seat_id,
                                message_ids.PUSH_GAME_DEAL_BU_HUA,
                                data={
                                    "seat_id": seat_id,
                                    "hua_card": hua_card,
                                    "bu_cards": [BLACK] * len(new_cards)
                                })
     return 1
Ejemplo n.º 11
0
 def trans_non_num_card_to_gap(self, card_list):
     """
     将非数字牌(风,箭,字,花)值转换成 间断的,避免误判为顺子
     :param card_list:
     :return:
     """
     result = []
     for c in card_list:
         if c == LAI_ZI:
             result.append(c)
             continue
         t = Card.cal_card_type(c)
         if CardType.HUA == t:
             continue
         if t in [CardType.FENG, CardType.JIAN]:
             result.append(Card.cal_card_val(t, Card.cal_card_digit(c) * 3))
         else:
             result.append(c)
     return result
Ejemplo n.º 12
0
 def hand_card_vals(self):
     ret = []
     for k, v in self.hand_card_info.items():
         if v[0] == 0:
             continue
         for i in range(1, CARD_SIZE[k]):
             if v[i] == 0:
                 continue
             for j in range(0, v[i]):
                 ret.append(Card.cal_card_val(k, i))
     return ret
Ejemplo n.º 13
0
    def clear_data(self):
        self.card_count = 0
        self.all_card_vals = []

        for t in self.types:
            for d in range(1, CARD_SIZE[t]):
                for k in range(0, 4 if t != CardType.HUA else 1):
                    self.all_card_vals.append(Card.cal_card_val(t, d))
                    self.card_count += 1
        self.left_index = 0
        self.right_index = self.card_count - 1
Ejemplo n.º 14
0
 def is_this_type(self, hand_card, card_analyse):
     used_card_type = [CardType.WAN]  # 此游戏中使用的花色
     union_card = hand_card.union_card_info
     gang_lst = []
     gang_lst.extend(hand_card.dian_gang_card_vals)
     gang_lst.extend(hand_card.bu_gang_card_vals)
     gang_lst.extend(hand_card.an_gang_card_vals)
     ret = []  # 手里有4张的牌集
     for i, count in enumerate(union_card[CardType.WAN]):
         if i == 0 and count < 4:
             return False
         if count == 4 and Card.cal_card_val(CardType.WAN,
                                             i) not in gang_lst:
             ret.append(Card.cal_card_val(CardType.WAN, i))
     if not ret:
         return False
     gang_lst = self.get_gang_lst(hand_card)
     for i in ret:
         if i in gang_lst:
             return False
     return True
Ejemplo n.º 15
0
    def union_hand_card(self):
        """
        将现有手牌联合在一起
        :return:
        """
        all_types = CardType.all_type()
        for t in all_types:
            self.union_card_info[t] = [0 for _ in range(CARD_SIZE[t])]

        tmp_hand_card = copy.deepcopy(self.hand_card_for_settle_show)
        for card_group in tmp_hand_card:
            if 4 == len(card_group):
                card_group[1] = card_group[0]
                card_group[2] = card_group[0]
                card_group[3] = card_group[0]
                card_group.pop()
            for card_val in card_group:
                if card_val:
                    card_type = Card.cal_card_type(card_val)
                    card_digit = Card.cal_card_digit(card_val)
                    self.union_card_info[card_type][card_digit] += 1
                    self.union_card_info[card_type][0] += 1
Ejemplo n.º 16
0
    def param_check(self, **kwargs):      # 参数验证
        act_params = kwargs.get("act_params")
        if 1 != len(act_params):
            # 同时只允许有一个玩家发生点杠操作
            logger.debug(u"act_diangang_error:%s", str(act_params))
            return

        seat_id = list(act_params.keys())[0]
        params = act_params[seat_id]

        card_val = self.game_data.last_chu_card_val

        if not card_val or -1 == self.game_data.last_chu_card_seat_id:
            logger.error("dian_gang params error: %s", str([seat_id, params]))
            return

        hand_card = self.players[seat_id].hand_card
        if 3 != hand_card.hand_card_info[Card.cal_card_type(card_val)][Card.cal_card_digit(card_val)]:
            logger.error("dian_gang params error: %s", str([seat_id, params]))
            return

        self.seat_id = seat_id
        self.hand_card = self.game_data.players[seat_id].hand_card
        return 1
Ejemplo n.º 17
0
    def can_an_gang(self, hand_card):
        """是否可以暗杠"""
        if self.players[self.seat_id].ting_info:
            # 玩家处于听牌状态
            return []
        all_types = CardType.all_type()
        can_an_gang_cards = []
        for t in all_types:
            if 4 > hand_card.hand_card_info[t][0]:
                continue
            for i in range(1, CARD_SIZE[t]):
                if 4 == hand_card.hand_card_info[t][i]:
                    can_an_gang_cards.append(Card.cal_card_val(t, i))

        return can_an_gang_cards
Ejemplo n.º 18
0
    def get_hu_detail(self, card_list):
        """
        胡牌判断
        :param card_list: 牌值列表
        :return: 返回所有胡牌详细信息[胡法1, 胡法2, ...]
                胡法1 = [[将牌], [[顺子/刻子1], [顺子/刻子2], ...]]]
        """
        temp_card_list = copy.deepcopy(card_list)
        rst = []
        for c in temp_card_list:
            if CardType.HUA == Card.cal_card_type(c):
                # 如果牌中有花,则不能为屁胡
                return rst

        num_len = len(card_list)
        if num_len % 3 == 2:
            card_list.sort(key=lambda x: -x)
            card_list = self.trans_non_num_card_to_gap(card_list)
            jiang = []
            tmpset = set()

            # 首先求出所有的将牌组合
            for i in range(num_len - 1):
                for j in range(i + 1, num_len):
                    if card_list[i] == card_list[
                            j] or card_list[i] + card_list[j] > LAI_ZI:
                        if card_list[i] * LAI_ZI + card_list[j] not in tmpset:
                            jiang.append([card_list[i], card_list[j]])
                            tmpset.add(card_list[i] * LAI_ZI + card_list[j])
            for it in jiang:
                tmp = self._delete(card_list, it)
                jp = [x for x in tmp if x >= LAI_ZI]
                lp = [x for x in tmp if x < LAI_ZI]
                # jp = filter(lambda x: x >= LAI_ZI, tmp)
                # lp = filter(lambda x: x < LAI_ZI, tmp)
                rst += list(map(lambda x: [it, x], self.hu(jp, lp)))
            rst = self.trans_non_num_card_from_gap_plus(rst)
        return rst
Ejemplo n.º 19
0
    def param_check(self, **kwargs):      # 参数验证
        act_params = kwargs.get("act_params")
        if 1 != len(act_params):
            # 同时只允许有一个玩家发生出牌操作
            logger.debug(u"act_chu_error:%s", str(act_params))
            return

        seat_id = list(act_params.keys())[0]
        params = act_params[seat_id]

        card_val = params.get("card", None)
        if isinstance(card_val, list):
            card_val = card_val[0]
        if not card_val:
            logger.debug(u"chu_card error: card_val=%s", str(card_val))
            return
        if 1 > self.players[seat_id].hand_card.hand_card_info[Card.cal_card_type(card_val)][Card.cal_card_digit(card_val)]:
            logger.debug(u"chu_card error: not hava card %s", str([seat_id, params]))
            return

        self.seat_id = seat_id
        self.chu_cardval = card_val
        return 1
Ejemplo n.º 20
0
    def trans_non_num_card_from_gap(self, card_list):
        """
        将间断的非数字牌(风,箭,字,花)值转换成原始值
        :param card_list:
        :return:
        """
        ret = [[] for _ in range(len(card_list))]
        for f, cards in enumerate(card_list):
            jiang = copy.deepcopy(cards[0])
            other_card = copy.deepcopy(cards[1])

            jiang_vals = jiang[0] if jiang[0] == jiang[
                1] else jiang[0] + jiang[1] - LAI_ZI
            jiang_type = Card.cal_card_type(jiang_vals)
            jiang_lst = []
            for index, j in enumerate(jiang):
                if jiang_type in [CardType.FENG, CardType.JIAN
                                  ] and jiang[index] != LAI_ZI:
                    jiang_lst.append(
                        Card.cal_card_val(
                            jiang_type,
                            Card.cal_card_digit(jiang[index]) // 3))
                else:
                    jiang_lst.append(j)
            ret[f].append(jiang_lst)

            shun_ke_lst = []
            for shun_ke in other_card:
                tmp_shun_ke = copy.deepcopy(shun_ke)
                for index, i in enumerate(tmp_shun_ke):
                    if i == LAI_ZI:
                        continue
                    t = Card.cal_card_type(i)
                    if t in [CardType.FENG, CardType.JIAN]:
                        tmp_shun_ke[index] = Card.cal_card_val(
                            t,
                            Card.cal_card_digit(i) // 3)
                shun_ke_lst.append(tmp_shun_ke)
            ret[f].append(shun_ke_lst)

        return ret
Ejemplo n.º 21
0
    def trans_non_num_card_from_gap_plus(self, card_list):
        """
        将间断的非数字牌(风,箭,字,花)值转换成原始值
        :param card_list:
        :return:
        """
        ret = [[] for _ in range(len(card_list))]  # 最终输出结果集
        for f, cards in enumerate(card_list):
            jiang = cards[0]
            other_card = cards[1]
            ret_jiang = []  # 结果的将牌
            ret_other_card = []  # 结果的顺和刻

            for j in jiang:
                jiang_type = Card.cal_card_type(j)
                if jiang_type in [CardType.FENG, CardType.JIAN]:
                    ret_jiang.append(
                        Card.cal_card_val(jiang_type,
                                          Card.cal_card_digit(j) // 3))
                else:
                    ret_jiang.append(j)
            ret[f].append(ret_jiang)

            for shun_ke in other_card:
                sk_lst = []
                for i in shun_ke:
                    sk_type = Card.cal_card_type(i)
                    if sk_type in [CardType.FENG, CardType.JIAN]:
                        sk_lst.append(
                            Card.cal_card_val(sk_type,
                                              Card.cal_card_digit(i) // 3))
                    else:
                        sk_lst.append(i)
                ret_other_card.append(sk_lst)
            ret[f].append(ret_other_card)

        return ret
Ejemplo n.º 22
0
 def del_hand_card_by_val(self, card_val):
     self.del_hand_card_by_type(Card.cal_card_type(card_val),
                                Card.cal_card_digit(card_val))