Пример #1
0
    def isSanQi(self):
        """是否三七边"""
        # 1,2,3 拿出来,剩下的能不能胡
        # 7,8,9 拿出来 剩下的能不能胡
        handTile = copy.deepcopy(
            self.playerAllTiles[self.winSeatId][MHand.TYPE_HAND])
        handTile.extend(self.playerAllTiles[self.winSeatId][MHand.TYPE_HU])

        if MTile.getValue(self.winTile) == 7 and self.winTile < 30 and (
                self.winTile + 1) in handTile and (self.winTile +
                                                   2) in handTile:
            handTile.remove(self.winTile)
            handTile.remove(self.winTile + 1)
            handTile.remove(self.winTile + 2)
            res, _ = MWin.isHu(handTile)
            ftlog.debug('weihai_one_result.isSanQi result: ', res)
            return res
        elif MTile.getValue(self.winTile) == 3 and self.winTile < 30 and (
                self.winTile - 1) in handTile and self.winTile - 2 in handTile:
            handTile.remove(self.winTile)
            handTile.remove(self.winTile - 1)
            handTile.remove(self.winTile - 2)
            res, _ = MWin.isHu(handTile)
            ftlog.debug('weihai_one_result.isSanQi result: ', res)
            return res
        else:
            ftlog.debug('weihai_one_result.isSanQi result: False')
            return False
Пример #2
0
    def isDadiaoche(self, tiles):
        """
        大吊车:胡牌时自己手上只有一张牌,且胡的是二五八
        """
        handTile = tiles[MHand.TYPE_HAND]
        huTile = tiles[MHand.TYPE_HU][0]
        handTile.extend(tiles[MHand.TYPE_HU])
        if len(handTile) == 2 and huTile < MTile.TILE_DONG_FENG and (
                MTile.getValue(huTile) == 2 or MTile.getValue(huTile) == 5
                or MTile.getValue(huTile) == 8):
            return True, [handTile]

        return False, []
    def chooseBestDropTile(self, tiles, leftTiles, mostColor):
        '''
        从若干最小分值的牌中选择一个最合适的
        附加权重:
        1)自身权重
        1、9的本身附加权重为0
        2,8的附件权重为1
        3,4,5,6,7的附件权重为2
        2)剩余牌数权重
        剩余牌数的附件权重每张为1
        3)花色权重
        花色之间的比较,花色较多的一方去加权重为1,花色较少的一方附件权重为0
        '''
        if len(tiles) == 1:
            return tiles[0]

        tiles.sort()
        values = [0 for _ in tiles]

        minTile = 0
        minValue = 0

        for index in range(len(tiles)):
            tile = tiles[index]

            if (MTile.getValue(tile) == 1) or (MTile.getValue(tile) == 9):
                values[index] += 0
            elif (MTile.getValue(tile) == 2) or (MTile.getValue(tile) == 8):
                values[index] += 1
            else:
                values[index] += 2

            tileCount = 0
            for _t in leftTiles:
                if _t == tile:
                    tileCount += 1
            values[index] += tileCount

            if MTile.getColor(tile) == mostColor:
                values[index] += 1

            if (minTile == 0) or (minValue > values[index]):
                minTile = tile
                minValue = values[index]

        ftlog.debug('chooseBestDropTile tiles:', tiles, ' leftTiles:',
                    leftTiles, ' mostColor:', mostColor, ' values:', values,
                    ' minTile:', minTile, ' minValue:', minValue)

        return minTile
Пример #4
0
    def isSanQi(self, winTile=None):

        for wn in self.winNodes:
            if wn['winTile'] == self.winTile:
                patterns = wn['pattern']
                ftlog.debug('MJixiOneResult.isBian winTile:', self.winTile,
                            ' winPatterns:', patterns)
                for p in patterns:
                    if len(p) == 2:
                        continue

                    if p[0] == p[1]:
                        continue

                    if (self.winTile in p) and (p.index(self.winTile)
                                                == 0) and MTile.getValue(
                                                    self.winTile) == 7:
                        return True

                    if (self.winTile in p) and (p.index(self.winTile)
                                                == 2) and MTile.getValue(
                                                    self.winTile) == 3:
                        return True

        # 宝牌情况处理
        if self.isMagicTile():
            for wn in self.winNodes:
                winTile = wn['winTile']
                patterns = wn['pattern']
                for p in patterns:
                    if len(p) == 2:
                        continue

                    if p[0] == p[1]:
                        continue

                    if (winTile
                            in p) and (p.index(winTile)
                                       == 0) and MTile.getValue(winTile) == 7:
                        return True

                    if (winTile
                            in p) and (p.index(winTile)
                                       == 2) and MTile.getValue(winTile) == 3:
                        return True

        return False
Пример #5
0
 def isZhangYiSe(self, seatId):
     tiles = MHand.copyAllTilesToList(self.playerAllTiles[self.winSeatId])
     if len(tiles) % 2 > 0:
         tiles.extend(self.playerAllTiles[self.winSeatId][MHand.TYPE_HU])
     for tile in tiles:
         if (tile >= MTile.TILE_DONG_FENG) or (MTile.getValue(tile) % 3 !=
                                               2):
             return False
     return True
Пример #6
0
    def isHu(self,
             tiles,
             tile,
             isTing,
             getTileType,
             magicTiles=[],
             tingNodes=[],
             winSeatId=0):
        ftlog.debug(self.TAG, '.isHu tiles:', tiles, ' tile:', tile,
                    ' isTing:', isTing, ' getTileType:', getTileType,
                    ' magicTiles:', magicTiles, ' tingNodes:', tingNodes,
                    ' winSeatId:', winSeatId)
        # 平度麻将即可以听也可以不听,听牌后,校验tingNodes即可,无其他限制条件
        if isTing:
            #[{'winTile': 16, 'winTileCount': 0, 'pattern': [[16, 17, 18], [12, 12]]}, {'winTile': 19, 'winTileCount': 0, 'pattern': [[17, 18, 19], [12, 12]]}]
            for tingNode in tingNodes:
                if tingNode['winTile'] == tile:
                    pattern = tingNode['pattern']
                    return True, pattern

        # 检查2,5,8将

        # 平度麻将允许胡七对
        resultQiDui, patternQiDui = MWin.isQiDui(tiles[MHand.TYPE_HAND])
        if resultQiDui:
            for pattern in patternQiDui:
                tile = pattern[0]
                if tile > MTile.TILE_NINE_TIAO:
                    continue

                if MTile.getValue(pattern[0]) % 3 == 2:
                    return True, patternQiDui

            return False, []

        # 挑出2,5,8将,看剩下的牌是否能胡牌
        jiangPatterns = [[MTile.TILE_TWO_WAN, MTile.TILE_TWO_WAN],
                         [MTile.TILE_FIVE_WAN, MTile.TILE_FIVE_WAN],
                         [MTile.TILE_EIGHT_WAN, MTile.TILE_EIGHT_WAN],
                         [MTile.TILE_TWO_TONG, MTile.TILE_TWO_TONG],
                         [MTile.TILE_FIVE_TONG, MTile.TILE_FIVE_TONG],
                         [MTile.TILE_EIGHT_TONG, MTile.TILE_EIGHT_TONG],
                         [MTile.TILE_TWO_TIAO, MTile.TILE_TWO_TIAO],
                         [MTile.TILE_FIVE_TIAO, MTile.TILE_FIVE_TIAO],
                         [MTile.TILE_EIGHT_TIAO, MTile.TILE_EIGHT_TIAO]]

        for jiangPat in jiangPatterns:
            result, pattern = MWin.isHuWishSpecialJiang(
                tiles[MHand.TYPE_HAND], jiangPat)
            if result:
                return result, pattern
        return False, []
Пример #7
0
 def isDuanYao(self, tableConfig):
     '''
     判断手牌是否为断幺
     '''
     # 房间配置为0,则没有全幺九
     if not tableConfig.get(MFTDefine.DUANYAOJIU_DOUBLE, 0):
         ftlog.debug('MSiChuanTilePattern.isDuanYao False because roomConfig')
         return False
     
     tiles = MHand.copyAllTilesToListButHu(self.playerAllTiles)
     ftlog.debug('MSiChuanTilePattern.isDuanYao tiles:', tiles)
     for tile in tiles:
         tileValue = MTile.getValue(tile)
         if tileValue == 1 or tileValue == 9:
             ftlog.debug('MSiChuanTilePattern.isDuanYao : False')
             return False
     ftlog.debug('MSiChuanTilePattern.isDuanYao: True')
     return True
Пример #8
0
    def isDadiaoche(self):
        """
        大吊车:胡牌时自己手上只有一张牌,且胡的是二五八
        """
        handTile = copy.deepcopy(
            self.playerAllTiles[self.winSeatId][MHand.TYPE_HAND])
        if len(handTile) % 3 != 2:
            handTile.extend(self.playerAllTiles[self.winSeatId][MHand.TYPE_HU])
        huTile = self.playerAllTiles[self.winSeatId][MHand.TYPE_HU][0]
        ftlog.debug('MYantaiOneResult.isDadiaoche handTile:', handTile,
                    ' huTile:', huTile)

        if (len(handTile) == 2) and (huTile < MTile.TILE_DONG_FENG) and (
                MTile.getValue(huTile) % 3 == 2):
            ftlog.debug('MYantaiOneResult.isDadiaoche result: True')
            return True

        ftlog.debug('MYantaiOneResult.isDadiaoche result: False')
        return False
Пример #9
0
    def isDadiaoche(self):
        """
        大吊车:胡牌时自己手上只有一张牌,且胡的是二五八
        """
        handTile = copy.deepcopy(self.playerAllTiles[self.winSeatId][MHand.TYPE_HAND])
        if len(handTile) % 3 != 2:
            handTile.extend(self.playerAllTiles[self.winSeatId][MHand.TYPE_HU])
        huTile = self.playerAllTiles[self.winSeatId][MHand.TYPE_HU][0]
        ftlog.debug('MYantaiOneResult.isDadiaoche handTile:', handTile
                    , ' huTile:', huTile)

        if (len(handTile) == 2):
            if self.tableTileMgr.tableConfig.get(MTDefine.ONLY_JIANG_258, 0) == 1:
                if (huTile < MTile.TILE_DONG_FENG) and (MTile.getValue(huTile) % 3 == 2):
                    return True
                else:
                    return False
            else:
                return  True

        ftlog.debug('MYantaiOneResult.isDadiaoche result: False')
        return False
Пример #10
0
    def isBian(self):
        """是否夹牌"""
        if not self.isWinTile():
            return False

        for wn in self.winNodes:
            if wn['winTile'] == self.winTile:
                patterns = wn['pattern']
                ftlog.debug('MHaerbinOneResult.isBian winTile:', self.winTile,
                            ' winPatterns:', patterns)
                for p in patterns:
                    if len(p) == 2:
                        continue

                    if p[0] == p[1]:
                        continue

                    # 三七边
                    if (self.winTile in p) \
                        and (p.index(self.winTile) == 0) \
                        and (MTile.getValue(p[1]) == 8) \
                        and (MTile.getValue(p[2]) == 9):
                        ftlog.debug('MHaerbinOneResult.isBian winTile:',
                                    self.winTile, ' winPatterns:', patterns,
                                    ' 7 bian')
                        return True
                    if (self.winTile in p) \
                        and (p.index(self.winTile) == 2) \
                        and (MTile.getValue(p[0]) == 1) \
                        and (MTile.getValue(p[1]) == 2):
                        ftlog.debug('MHaerbinOneResult.isBian winTile:',
                                    self.winTile, ' winPatterns:', patterns,
                                    ' 3 bian')
                        return True

        # 宝牌情况处理
        if self.isMagicTile():
            for wn in self.winNodes:
                winTile = wn['winTile']
                patterns = wn['pattern']
                for p in patterns:
                    if len(p) == 2:
                        continue

                    if p[0] == p[1]:
                        continue

                    # 三七边
                    if (winTile in p) \
                        and (p.index(winTile) == 0) \
                        and (MTile.getValue(p[1]) == 8) \
                        and (MTile.getValue(p[2]) == 9):
                        ftlog.debug('MHaerbinOneResult.isBian winTile:',
                                    self.winTile, ' winPatterns:', patterns,
                                    ' 7 bian')
                        return True
                    if (winTile in p) \
                        and (p.index(winTile) == 2) \
                        and (MTile.getValue(p[0]) == 1) \
                        and (MTile.getValue(p[1]) == 2):
                        ftlog.debug('MHaerbinOneResult.isBian winTile:',
                                    self.winTile, ' winPatterns:', patterns,
                                    ' 3 bian')
                        return True

        return False
Пример #11
0
 def hasExtendMao(cls, tiles, alreadyHave = 0):
     extendMaos = []
     if alreadyHave & MTDefine.MAO_DAN_DNXBZFB:
         es = []
         for tile in tiles:
             if MTile.isFeng(tile) or MTile.isArrow(tile):
                 es.append(tile)
         if len(es) > 0:
             faNode = {}
             faNode['type'] = MTDefine.MAO_DAN_DNXBZFB
             faNode['extends'] = es
             faNode['name'] = MTDefine.MAO_DAN_DNXBZFB_NAME
             extendMaos.append(faNode)
             
     if alreadyHave & MTDefine.MAO_DAN_DNXB:
         es = []
         for tile in tiles:
             if MTile.isFeng(tile):
                 es.append(tile)
         if len(es) > 0:
             faNode = {}
             faNode['type'] = MTDefine.MAO_DAN_DNXB
             faNode['extends'] = es
             faNode['name'] = MTDefine.MAO_DAN_DNXB_NAME
             extendMaos.append(faNode)
             
     if alreadyHave & MTDefine.MAO_DAN_ZFB:
         es = []
         for tile in tiles:
             if MTile.isArrow(tile):
                 es.append(tile)
         if len(es) > 0:
             faNode = {}
             faNode['type'] = MTDefine.MAO_DAN_ZFB
             faNode['extends'] = es
             faNode['name'] = MTDefine.MAO_DAN_ZFB_NAME
             extendMaos.append(faNode)
             
     if alreadyHave & MTDefine.MAO_DAN_YAO:
         es = []
         for tile in tiles:
             if MTile.getValue(tile) == 1:
                 es.append(tile)
         if len(es) > 0:
             faNode = {}
             faNode['type'] = MTDefine.MAO_DAN_YAO
             faNode['extends'] = es
             faNode['name'] = MTDefine.MAO_DAN_YAO_NAME
             extendMaos.append(faNode)
             
     if alreadyHave & MTDefine.MAO_DAN_JIU:
         es = []
         for tile in tiles:
             if MTile.getValue(tile) == 9:
                 es.append(tile)
         if len(es) > 0:
             faNode = {}
             faNode['type'] = MTDefine.MAO_DAN_JIU
             faNode['extends'] = es
             faNode['name'] = MTDefine.MAO_DAN_JIU_NAME
             extendMaos.append(faNode)
             
     return extendMaos
Пример #12
0
 def isSanQi(self, winTile=None):
     if winTile == None:
         winTile = self.winTile
     if MTile.getValue(winTile) == 3 or MTile.getValue(winTile) == 7:
         return True
     return False
Пример #13
0
 def checkMao(cls, pattern, maoType, maoDanSetting):
     ftlog.debug('MMao.checkMao pattern:', pattern
                 , ' maoType:', maoType
                 , ' maoDanSetting:', maoDanSetting)
     
     values = []
     if maoType & MTDefine.MAO_DAN_DNXBZFB: #乱锚
         if not maoDanSetting & MTDefine.MAO_DAN_DNXBZFB:
             return False
         
         for tile in pattern:
             if MTile.isArrow(tile) or MTile.isFeng(tile):
                 values.append(tile) #取消对相同牌的检查
             else:
                 return False
     elif maoType & MTDefine.MAO_DAN_DNXB:
         if not maoDanSetting & MTDefine.MAO_DAN_DNXB:
             return False
         
         for tile in pattern:
             if MTile.isFeng(tile):
                 if tile not in values:
                     values.append(tile)
                 continue
             else:
                 return False
     elif maoType & MTDefine.MAO_DAN_ZFB:
         if not maoDanSetting & MTDefine.MAO_DAN_ZFB:
             return False
         
         for tile in pattern:
             if MTile.isArrow(tile):
                 if tile not in values:
                     values.append(tile)
                 continue
             else:
                 return False
             
     elif maoType & MTDefine.MAO_DAN_YAO:
         if not maoDanSetting & MTDefine.MAO_DAN_YAO:
             return False
         
         for tile in pattern:
             if MTile.getValue(tile) == 1:
                 if tile not in values:
                     values.append(tile)
                 continue
             else:
                 return False
     
     elif maoType & MTDefine.MAO_DAN_JIU:
         if not maoDanSetting & MTDefine.MAO_DAN_JIU:
             return False
         
         for tile in pattern:
             if MTile.getValue(tile) == 9:
                 if tile not in values:
                     values.append(tile)
                 continue
             else:
                 return False
             
     ftlog.debug('MMao.checkMao pattern:', pattern
                 , ' maoType:', maoType)        
     return len(values) >= 3
Пример #14
0
    def isBu(cls, tileArr, resultArr, magicArr, tileType, hasJiang, allowZFB):
        """判断某个花色是否是三朴,缺的牌从癞子中获取,如果没有癞子牌了,也形不成三朴,和牌失败"""
        if 0 == cls.getCardNumByType(tileArr, tileType):
            # 这个花色没有牌
            return True, hasJiang

        #ftlog.debug('check card:', MTile.traverseTile(tileType))
        for tileIndex in MTile.traverseTile(tileType):
            if tileArr[tileIndex] == 0:
                continue

            if tileArr[tileIndex] >= 3:
                # 刻,没有占用癞子
                tileArr[tileIndex] -= 3
                resultTmp, hasJiang = cls.isBu(tileArr, resultArr, magicArr,
                                               tileType, hasJiang, allowZFB)
                if resultTmp:
                    resultArr.append([tileIndex, tileIndex, tileIndex])
                    return True, hasJiang
                # 还原手牌,继续判断
                tileArr[tileIndex] += 3

            if (tileArr[tileIndex] == 2) and (len(magicArr) >= 1):
                # 对子,尝试加一张癞子组成刻
                tileArr[tileIndex] -= 2
                mTile = magicArr.pop(-1)
                #                 ftlog.debug('[11M]magicArr pop:', mTile, ' after pop:', magicArr)
                resultTmp, hasJiang = cls.isBu(tileArr, resultArr, magicArr,
                                               tileType, hasJiang, allowZFB)
                if resultTmp:
                    resultArr.append([tileIndex, tileIndex, mTile])
                    return True, hasJiang

                # 还原手牌,继续判断
                tileArr[tileIndex] += 2
                magicArr.append(mTile)
#                 ftlog.debug('[11M]magicArr push:', mTile, ' after push:', magicArr)

            if (tileArr[tileIndex] == 1) and (len(magicArr) >= 2):
                # 单张,尝试加两张癞子组成刻
                tileArr[tileIndex] -= 1
                mTile1 = magicArr.pop(-1)
                mTile2 = magicArr.pop(-1)
                #                 ftlog.debug('[1MM] magicArr pop1:', mTile1, ' pop2:', mTile2, ' after pop:', magicArr)
                resultTmp, hasJiang = cls.isBu(tileArr, resultArr, magicArr,
                                               tileType, hasJiang, allowZFB)
                if resultTmp:
                    resultArr.append([tileIndex, mTile1, mTile2])
                    return True, hasJiang
                # 还原手牌,继续判断
                tileArr[tileIndex] += 1
                magicArr.append(mTile1)
                magicArr.append(mTile2)
#                 ftlog.debug('[1MM] magicArr push1:', mTile1, ' push2:', mTile2, ' after push:', magicArr)

            if not hasJiang and \
                tileArr[tileIndex] > 0 and \
                (tileArr[tileIndex] + len(magicArr) >= 2):
                tileArr[tileIndex] -= 1
                isMagicJiang = False
                jiangTile = tileIndex
                if tileArr[tileIndex] > 0:
                    tileArr[tileIndex] -= 1
                else:
                    isMagicJiang = True
                    jiangTile = magicArr.pop(-1)
#                     ftlog.debug('[1M] magicArr pop:', jiangTile, ' after pop:', magicArr)

                oldJiang = hasJiang
                resultTmp, hasJiang = cls.isBu(tileArr, resultArr, magicArr,
                                               tileType, True, allowZFB)
                if resultTmp:
                    resultArr.append([tileIndex, jiangTile])
                    hasJiang = True
                    return True, hasJiang
                else:
                    # 还原将牌标记
                    hasJiang = oldJiang

                # 还原手牌
                tileArr[tileIndex] += 1
                if isMagicJiang:
                    magicArr.append(jiangTile)
#                     ftlog.debug('[1M] magicArr append:', jiangTile, ' after append:', magicArr)
                else:
                    tileArr[tileIndex] += 1

            #是否允许中发白作为顺牌,暂时没有考虑赖子的情况,后续可以修改添加
            if not allowZFB:
                if tileIndex >= MTile.TILE_DONG_FENG:
                    # 风箭牌不能组成顺
                    return False, hasJiang
            else:
                if tileIndex == MTile.TILE_HONG_ZHONG:
                    if tileArr[tileIndex] > 0 and tileArr[
                            tileIndex + 1] > 0 and tileArr[tileIndex + 2] > 0:
                        pattern = [tileIndex, tileIndex + 1, tileIndex + 2]
                        tileArr[tileIndex] -= 1
                        tileArr[tileIndex + 1] -= 1
                        tileArr[tileIndex + 2] -= 1

                        resultTmp, hasJiang = cls.isBu(tileArr, resultArr,
                                                       magicArr, tileType,
                                                       hasJiang, allowZFB)
                        if resultTmp:
                            resultArr.append(pattern)
                            return True, hasJiang
                elif tileIndex >= MTile.TILE_DONG_FENG:
                    return False, hasJiang

            # 提取顺牌组合
            if tileArr[tileIndex] > 0 and tileType != MTile.TILE_FENG:
                # 测试顺子 0 1 2
                if MTile.getValue(tileIndex) <= 7:
                    tile0 = tileIndex
                    needMagic = 0
                    is1Magic = False
                    is2Magic = False
                    if tileArr[tileIndex + 1] == 0:
                        needMagic += 1
                        is1Magic = True
                    if tileArr[tileIndex + 2] == 0:
                        needMagic += 1
                        is2Magic = True

                    if needMagic <= len(magicArr):
                        pattern = [tile0, None, None]
                        tileArr[tileIndex] -= 1

                        if is1Magic:
                            pattern[1] = (magicArr.pop(-1))
                        else:
                            pattern[1] = (tileIndex + 1)
                            tileArr[tileIndex + 1] -= 1

                        if is2Magic:
                            pattern[2] = (magicArr.pop(-1))
                        else:
                            pattern[2] = (tileIndex + 2)
                            tileArr[tileIndex + 2] -= 1

#                         if is1Magic and is2Magic:
#                             ftlog.debug('[1MM] magicArr pop1:', pattern[1], ' pop2:', pattern[2], ' after pop:', magicArr)
#                         elif is1Magic:
#                             ftlog.debug('[1M3] magicArr pop1:', pattern[1], ' after pop:', magicArr)
#                         elif is2Magic:
#                             ftlog.debug('[12M] magicArr pop2:', pattern[2], ' after pop:', magicArr)

                        resultTmp, hasJiang = cls.isBu(tileArr, resultArr,
                                                       magicArr, tileType,
                                                       hasJiang, allowZFB)
                        if resultTmp:
                            resultArr.append(pattern)
                            return True, hasJiang

                        # 还原手牌
                        tileArr[tileIndex] += 1
                        if is1Magic:
                            magicArr.append(pattern[1])
                        else:
                            tileArr[tileIndex + 1] += 1

                        if is2Magic:
                            magicArr.append(pattern[2])
                        else:
                            tileArr[tileIndex + 2] += 1

#                         if is1Magic and is2Magic:
#                             ftlog.debug('[1MM] magicArr append1:', pattern[1], ' append2:', pattern[2], ' after append:', magicArr)
#                         elif is1Magic:
#                             ftlog.debug('[1M3] magicArr append1:', pattern[1], ' after append:', magicArr)
#                         elif is2Magic:
#                             ftlog.debug('[12M] magicArr append2:', pattern[2], ' after append:', magicArr)

# 测试顺子 -1 0 1
                if MTile.getValue(tileIndex) <= 8 and MTile.getValue(
                        tileIndex) >= 2:
                    tile1 = tileIndex
                    needMagic = 0
                    is0Magic = False
                    is2Magic = False
                    if tileArr[tileIndex - 1] == 0:
                        needMagic += 1
                        is0Magic = True
                    if tileArr[tileIndex + 1] == 0:
                        needMagic += 1
                        is2Magic = True

                    if needMagic <= len(magicArr):
                        pattern = [None, tile1, None]
                        tileArr[tileIndex] -= 1

                        if is0Magic:
                            pattern[0] = (magicArr.pop(-1))
                        else:
                            pattern[0] = (tileIndex - 1)
                            tileArr[tileIndex - 1] -= 1

                        if is2Magic:
                            pattern[2] = (magicArr.pop(-1))
                        else:
                            #猜测有问题,导致pattern 长度为4 包含None
                            #pattern.append(tileIndex + 1)
                            pattern[2] = (tileIndex + 1)
                            tileArr[tileIndex + 1] -= 1

#                         if is0Magic and is2Magic:
#                             ftlog.debug('[M1M] magicArr pop0:', pattern[0], ' pop2:', pattern[2], ' after pop:', magicArr)
#                         elif is0Magic:
#                             ftlog.debug('[M23] magicArr pop1:', pattern[0], ' after pop:', magicArr)
#                         elif is2Magic:
#                             ftlog.debug('[12M] magicArr pop2:', pattern[2], ' after pop:', magicArr)

                        resultTmp, hasJiang = cls.isBu(tileArr, resultArr,
                                                       magicArr, tileType,
                                                       hasJiang, allowZFB)
                        if resultTmp:
                            resultArr.append(pattern)
                            return True, hasJiang

                        # 还原手牌
                        tileArr[tileIndex] += 1
                        if is0Magic:
                            magicArr.append(pattern[0])
                        else:
                            tileArr[tileIndex - 1] += 1

                        if is2Magic:
                            magicArr.append(pattern[2])
                        else:
                            tileArr[tileIndex + 1] += 1

#                         if is0Magic and is2Magic:
#                             ftlog.debug('[M1M] magicArr append0:', pattern[0], ' append2:', pattern[2], ' after append:', magicArr)
#                         elif is0Magic:
#                             ftlog.debug('[M23] magicArr append0:', pattern[0], ' after append:', magicArr)
#                         elif is2Magic:
#                             ftlog.debug('[12M] magicArr append2:', pattern[2], ' after append:', magicArr)

# 测试顺子 -2 -1 0
                if MTile.getValue(tileIndex) >= 3:
                    tile2 = tileIndex
                    needMagic = 0
                    is0Magic = False
                    is1Magic = False
                    if tileArr[tileIndex - 2] == 0:
                        needMagic += 1
                        is0Magic = True
                    if tileArr[tileIndex - 1] == 0:
                        needMagic += 1
                        is1Magic = True

                    if needMagic <= len(magicArr):
                        pattern = [None, None, tile2]
                        tileArr[tileIndex] -= 1

                        if is0Magic:
                            pattern[0] = (magicArr.pop(-1))
                        else:
                            pattern[0] = (tileIndex - 2)
                            tileArr[tileIndex - 2] -= 1

                        if is1Magic:
                            pattern[1] = (magicArr.pop(-1))
                        else:
                            pattern[1] = (tileIndex - 1)
                            tileArr[tileIndex - 1] -= 1

#                         if is0Magic and is1Magic:
#                             ftlog.debug('[MM3] magicArr pop0:', pattern[0], ' pop1:', pattern[1], ' after pop:', magicArr)
#                         elif is0Magic:
#                             ftlog.debug('[M23] magicArr pop0:', pattern[0], ' after pop:', magicArr)
#                         elif is1Magic:
#                             ftlog.debug('[1M3] magicArr pop1:', pattern[1], ' after pop:', magicArr)

                        resultTmp, hasJiang = cls.isBu(tileArr, resultArr,
                                                       magicArr, tileType,
                                                       hasJiang, allowZFB)
                        if resultTmp:
                            resultArr.append(pattern)
                            return True, hasJiang

                        # 还原手牌
                        tileArr[tileIndex] += 1
                        if is0Magic:
                            magicArr.append(pattern[0])
                        else:
                            tileArr[tileIndex - 2] += 1

                        if is1Magic:
                            magicArr.append(pattern[1])
                        else:
                            tileArr[tileIndex - 1] += 1


#                         if is0Magic and is1Magic:
#                             ftlog.debug('[MM3] magicArr append0:', pattern[0], ' append1:', pattern[1], ' after append:', magicArr)
#                         elif is0Magic:
#                             ftlog.debug('[M23] magicArr append0:', pattern[0], ' after append:', magicArr)
#                         elif is1Magic:
#                             ftlog.debug('[1M3] magicArr append1:', pattern[1], ' after append:', magicArr)

# 无和牌可能
        return False, hasJiang
Пример #15
0
    def hasChi(self, tiles, tile):
        """是否有吃牌解
        
        参数说明;
        tiles - 玩家的所有牌,包括手牌,吃牌,碰牌,杠牌,胡牌
        tile - 待吃的牌
        """
        if tile >= MTile.TILE_DONG_FENG:
            return []

        #是否允许会牌参与,如果不允许,删除会牌
        tilesForChi = copy.deepcopy(tiles[MHand.TYPE_HAND])
        if not self.tableTileMgr.allowMagicChiPengGang():
            magicTile = self.tableTileMgr.getMagicTile()
            while magicTile in tilesForChi:
                tilesForChi.remove(magicTile)

        chiSolutions = MChi.hasChi(tilesForChi, tile)
        magicTiles = self.tableTileMgr.getMagicTiles(False)
        if len(magicTiles) == 0:
            return chiSolutions

        if not self.tableTileMgr.canUseMagicTile(MTableState.TABLE_STATE_CHI):
            return chiSolutions

        magicTile = magicTiles[0]
        tileArr = MTile.changeTilesToValueArr(tiles[MHand.TYPE_HAND])
        magicCount = tileArr[magicTile]
        tileArr[magicTile] = 0
        ftlog.debug('MChiRule.hasChi tile:', tile, ' magicCount:', magicCount)

        if magicCount == 0 or (tileArr[tile] == 0):
            return chiSolutions

        if MTile.getValue(tile) <= 7:
            # +1[-] +2[+] ==> [tile, magic, tile+2]
            if tileArr[tile + 1] == 0 and tileArr[tile + 2] > 0:
                chiSolutions.append([tile, magicTile, tile + 2])

            # +1[+] +2[-] ==> [tile, tile + 1, magicTile]
            if tileArr[tile + 1] > 0 and tileArr[tile + 2] == 0:
                chiSolutions.append([tile, tile + 1, magicTile])

            if (tileArr[tile + 1] +
                    tileArr[tile + 2]) == 0 and magicCount >= 2:
                chiSolutions.append([tile, magicTile, magicTile])

        if MTile.getValue(tile) >= 3:
            # -2[+] -1[-] ==> [tile - 2, magicTile, tile]
            if tileArr[tile - 2] > 0 and tileArr[tile - 1] == 0:
                chiSolutions.append([tile - 2, magicTile, tile])

            # -2[0] -1[+] ==> [magicTile, tile - 1, tile]
            if tileArr[tile - 2] == 0 and tileArr[tile - 1] > 0:
                chiSolutions.append([magicTile, tile - 1, tile])

            if (tileArr[tile - 2] +
                    tileArr[tile - 1]) == 0 and magicCount >= 2:
                chiSolutions.append([magicTile, magicTile, tile])

        if MTile.getValue(tile) >= 2 and MTile.getValue(tile) <= 8:
            # -1[-] 1[+] ==> magicTile, tile, tile + 1
            if tileArr[tile - 1] == 0 and tileArr[tile + 1] > 0:
                chiSolutions.append([magicTile, tile, tile + 1])

            # -1[+] 1[-] ==> [tile - 1, tile, magicTile]
            if tileArr[tile - 1] > 0 and tileArr[tile + 1] == 0:
                chiSolutions.append([tile - 1, tile, magicTile])

            if (tileArr[tile + 1] +
                    tileArr[tile - 1]) == 0 and magicCount >= 2:
                chiSolutions.append([magicTile, tile, magicTile])

        return chiSolutions
Пример #16
0
    def isTeDaJia(self, winPattern, tingNodes, tiles, currWintile, curSeatId):
        winCount = 0
        isJiaCount = 0
        bianMulti = self.tableConfig.get(MTDefine.BIAN_MULTI, 0)
        for wn in tingNodes:
            winTile = wn['winTile']
            winCount = winCount + 1
            patterns = wn['pattern']
            ftlog.debug('MWinRuleJixi.isTaDaJia winTile:', winTile,
                        ' winPatterns:', patterns)
            for p in patterns:
                if len(p) == 2:
                    continue

                if p[0] == p[1]:
                    continue

                # 夹牌
                if (wn['winTile'] in p) and len(p) == 3 and p[0] != p[1]:
                    if (p[1] == winTile) or (bianMulti and
                                             (MTile.getValue(winTile) == 3 or
                                              MTile.getValue(winTile) == 7)):
                        isJiaCount = isJiaCount + 1

        #只能是夹牌 并且不能作为他用
        if winCount > 1 or isJiaCount <= 0:
            ftlog.debug('MWinRuleJixi.isTaDaJia winTile:', winTile,
                        'winCount:', winCount, 'isJiaCount:', isJiaCount)
            return False

        # 他人的碰牌
        isInOtherPeng = False

        for (seatId, playerTiles) in self.allPlayerTiles.items():
            if seatId != curSeatId:
                playerPengTiles = playerTiles[MHand.TYPE_PENG]
                for pattern in playerPengTiles:
                    if pattern[0] == currWintile:
                        isInOtherPeng = True
                        break

        isInSelfKe = False
        playerPengTiles = tiles[MHand.TYPE_PENG]
        for pattern in playerPengTiles:
            if pattern[0] == currWintile:
                isInSelfKe = True
                break

        #自己的手牌
        if not isInSelfKe:
            playerHandTiles = tiles[MHand.TYPE_HAND]
            winTileInHandCount = 0
            for tile in playerHandTiles:
                if tile == currWintile:
                    winTileInHandCount = winTileInHandCount + 1
                    if winTileInHandCount == 3:
                        isInSelfKe = True
                        break

        if not (isInSelfKe or isInOtherPeng):
            ftlog.debug('MWinRuleJixi.isTaDaJia winTile:', currWintile,
                        'isInSelfKe:', isInSelfKe, 'isInOtherPeng:',
                        isInOtherPeng)
            return False

        return True
Пример #17
0
 def hasMao(cls, tiles, maoDanSetting, alreadyHave = 0):
     ftlog.debug('MMao.hasMao tiles:', tiles
                 , ' maoDanSetting:', maoDanSetting
                 , ' alreadyHave:', alreadyHave)
     maos = []
     
     if (maoDanSetting & MTDefine.MAO_DAN_DNXBZFB) and (not (alreadyHave & MTDefine.MAO_DAN_DNXBZFB)):
         pattern = []
         values = []
         for tile in tiles:
             if MTile.isFeng(tile) or MTile.isArrow(tile):
                 pattern.append(tile)
                 if tile not in values:
                     values.append(tile)
                     
         if len(values) >= 3:
             luanMao = {}
             luanMao['type'] = MTDefine.MAO_DAN_DNXBZFB
             luanMao['pattern'] = values
             luanMao['name'] = MTDefine.MAO_DAN_DNXBZFB_NAME
             maos.append(luanMao)
             
     if (maoDanSetting & MTDefine.MAO_DAN_DNXB) and \
         (not (alreadyHave & MTDefine.MAO_DAN_DNXB) and \
         (not (maoDanSetting & MTDefine.MAO_DAN_DNXBZFB))):
         pattern = []
         values = []
         for tile in tiles:
             if MTile.isFeng(tile):
                 pattern.append(tile)
                 if tile not in values:
                     values.append(tile)
                     
         if len(values) >= 3:
             fengMao = {}
             fengMao['type'] = MTDefine.MAO_DAN_DNXB
             fengMao['pattern'] = values
             fengMao['name'] = MTDefine.MAO_DAN_DNXB_NAME
             maos.append(fengMao)
             
     if (maoDanSetting & MTDefine.MAO_DAN_ZFB) and \
         (not (alreadyHave & MTDefine.MAO_DAN_ZFB)) and \
         (not (maoDanSetting & MTDefine.MAO_DAN_DNXBZFB)):
         pattern = []
         values = []
         for tile in tiles:
             if MTile.isArrow(tile):
                 pattern.append(tile)
                 if tile not in values:
                     values.append(tile)
                     
         if len(values) >= 3:
             arrowMao = {}
             arrowMao['type'] = MTDefine.MAO_DAN_ZFB
             arrowMao['pattern'] = values
             arrowMao['name'] = MTDefine.MAO_DAN_ZFB_NAME
             maos.append(arrowMao)
             
     if (maoDanSetting & MTDefine.MAO_DAN_YAO) and (not (alreadyHave & MTDefine.MAO_DAN_YAO)):
         pattern = []
         values = []
         for tile in tiles:
             if MTile.getValue(tile) == 1:
                 pattern.append(tile)
                 if tile not in values:
                     values.append(tile)
         if len(values) >= 3:
             yaoMao = {}
             yaoMao['type'] = MTDefine.MAO_DAN_YAO
             yaoMao['pattern'] = values
             yaoMao['name'] = MTDefine.MAO_DAN_YAO_NAME
             maos.append(yaoMao)
             
     if (maoDanSetting & MTDefine.MAO_DAN_JIU) and (not (alreadyHave & MTDefine.MAO_DAN_JIU)):
         pattern = []
         values = []
         for tile in tiles:
             if MTile.getValue(tile) == 9:
                 pattern.append(tile)
                 if tile not in values:
                     values.append(tile)
                     
         if len(values) >= 3:
             jiuMao = {}
             jiuMao['type'] = MTDefine.MAO_DAN_JIU
             jiuMao['pattern'] = values
             jiuMao['name'] = MTDefine.MAO_DAN_JIU_NAME
             maos.append(jiuMao)
     
     ftlog.debug('MMao.hasMao tiles:', tiles
                 , ' maoDanSetting:', maoDanSetting
                 , ' maos:', maos)    
     return maos
Пример #18
0
    def isHu(self,
             tiles,
             tile,
             isTing,
             getTileType,
             magicTiles=[],
             tingNodes=[],
             winSeatId=0):
        ftlog.debug(self.TAG, '.isHu tiles:', tiles, ' tile:', tile,
                    ' isTing:', isTing, ' getTileType:', getTileType,
                    ' magicTiles:', magicTiles, ' tingNodes:', tingNodes,
                    ' winSeatId:', winSeatId)
        # 平度麻将即可以听也可以不听,听牌后,校验tingNodes即可,无其他限制条件
        if isTing:
            #[{'winTile': 16, 'winTileCount': 0, 'pattern': [[16, 17, 18], [12, 12]]}, {'winTile': 19, 'winTileCount': 0, 'pattern': [[17, 18, 19], [12, 12]]}]
            for tingNode in tingNodes:
                if tingNode['winTile'] == tile:
                    pattern = tingNode['pattern']
                    return True, pattern

        # 烟台麻将允许胡七对
        resultQiDui, patternQiDui = MWin.isQiDui(tiles[MHand.TYPE_HAND])
        if resultQiDui:
            if self.tableConfig[MTDefine.ONLY_JIANG_258]:
                ftlog.debug('MWinRuleYantai.isHu checkQiDui with 258')
                for pattern in patternQiDui:
                    tile = pattern[0]
                    if tile > MTile.TILE_NINE_TIAO:
                        continue

                    if MTile.getValue(pattern[0]) % 3 == 2:
                        return True, patternQiDui

                return False, []
            return True, patternQiDui

        # 烟台麻将允许胡十三幺
        self.tilePatternChecker.setPlayerAllTiles(tiles)
        if self.tilePatternChecker.isShisanyao():
            if self.tableConfig[MTDefine.ONLY_JIANG_258]:
                ftlog.debug(
                    'MWinRuleYantai.isHu isShisanyao with 258, return False')
                return False, []
            return True, tiles[MHand.TYPE_HAND]

        # 烟台麻将允许胡风一色
        allTiles = MHand.copyAllTilesToList(tiles)
        allArr = MTile.changeTilesToValueArr(allTiles)
        colorCount = MTile.getColorCount(allArr)
        resultFeng, patternFeng = MWin.isLuanFengyise(tiles[MHand.TYPE_HAND],
                                                      colorCount)
        if resultFeng:
            if self.tableConfig[MTDefine.ONLY_JIANG_258]:
                ftlog.debug(
                    'MWinRuleYantai.isHu isLuanFengyise with 258, return False'
                )
                return False, []
            return True, patternFeng

        # 挑出2,5,8将,看剩下的牌是否能胡牌
        if self.tableConfig[MTDefine.ONLY_JIANG_258]:
            jiangPatterns = [[MTile.TILE_TWO_WAN, MTile.TILE_TWO_WAN],
                             [MTile.TILE_FIVE_WAN, MTile.TILE_FIVE_WAN],
                             [MTile.TILE_EIGHT_WAN, MTile.TILE_EIGHT_WAN],
                             [MTile.TILE_TWO_TONG, MTile.TILE_TWO_TONG],
                             [MTile.TILE_FIVE_TONG, MTile.TILE_FIVE_TONG],
                             [MTile.TILE_EIGHT_TONG, MTile.TILE_EIGHT_TONG],
                             [MTile.TILE_TWO_TIAO, MTile.TILE_TWO_TIAO],
                             [MTile.TILE_FIVE_TIAO, MTile.TILE_FIVE_TIAO],
                             [MTile.TILE_EIGHT_TIAO, MTile.TILE_EIGHT_TIAO]]
            ftlog.debug('MWinRuleYantai.isHu with 258')
            for jiangPat in jiangPatterns:
                result, pattern = MWin.isHuWishSpecialJiang(
                    tiles[MHand.TYPE_HAND], jiangPat)
                if result:
                    return result, pattern

            return False, []
        else:
            result, pattern = MWin.isHu(tiles[MHand.TYPE_HAND])
            return result, pattern
Пример #19
0
    def canTing(self, tiles, leftTiles, tile, magicTiles=[], winSeatId=0):
        """子类必须实现
        参数:
        1)tiles 该玩家的手牌
        2)leftTiles 剩余手牌
        返回值:
        是否可以听牌,听牌详情
        """
        handCount = len(tiles[MHand.TYPE_HAND])
        if handCount < 5:
            return False, []

        isTing, tingResults = MTing.canTing(self.tilePatternChecker,
                                            self.tableTileMgr,
                                            MTile.cloneTiles(tiles), leftTiles,
                                            self.winRuleMgr, tile, magicTiles,
                                            winSeatId)
        ftlog.debug('MTingMudanjiangRule.MTing.canTing isTing:', isTing,
                    ' tingResults:', tingResults)
        #         [{'dropTile': 11, 'winNodes': [{'winTile': 1, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [1, 2, 3]]}, {'winTile': 2, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [3, 4, 5], [2, 2]]}, {'winTile': 4, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [2, 3, 4]]}, {'winTile': 5, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [5, 5], [2, 3, 4]]}, {'winTile': 7, 'winTileCount': 1, 'pattern': [[6, 6], [5, 6, 7], [5, 6, 7], [2, 3, 4]]}, {'winTile': 8, 'winTileCount': 1, 'pattern': [[6, 7, 8], [6, 6, 6], [5, 5], [2, 3, 4]]}]}]

        if not isTing:
            return False, []

        chiCount = len(tiles[MHand.TYPE_CHI])
        pengCount = len(tiles[MHand.TYPE_PENG])
        gangCount = len(tiles[MHand.TYPE_GANG])

        mingGangCount = 0
        anGangCount = 0
        #计算明杠个数,因为暗杠不算开门
        if gangCount != 0:
            mingGangCount, anGangCount = MTile.calcGangCount(
                tiles[MHand.TYPE_GANG])
        ftlog.debug('MTingMudanjiangRule.gang tiles:', tiles[MHand.TYPE_GANG],
                    ' mingGangCount=', mingGangCount, ' anGangCount=',
                    anGangCount)

        #daKouConfig = self.getTableConfig(MTDefine.DA_KOU, 0)
        daKouConfig = 1
        ftlog.debug('.canTing daKouConfig:', daKouConfig)
        if daKouConfig != 1:
            if (chiCount + pengCount + mingGangCount) == 0:
                return False, []

        # 检查刻,刻的来源,碰牌/明杠牌/手牌
        keCount = pengCount + mingGangCount + anGangCount
        # 必须有顺牌
        shunCount = chiCount

        newTingResults = []
        for tingResult in tingResults:
            newWinNodes = []
            winNodes = tingResult['winNodes']
            for winNode in winNodes:
                newTiles = MTile.cloneTiles(tiles)
                newTiles[MHand.TYPE_HAND].remove(tingResult['dropTile'])
                newTiles[MHand.TYPE_HAND].append(winNode['winTile'])
                tileArr = MTile.changeTilesToValueArr(
                    MHand.copyAllTilesToList(newTiles))
                #       ftlog.debug( 'MTingMudanjiangRule.canTing tileArr:', tileArr )

                # 清一色不可以听牌/和牌
                if self.getTableConfig(MTDefine.YISE_CAN_TING, 0) != 1:
                    newTileArr = copy.deepcopy(tileArr)
                    newTileArr[MTile.TILE_HONG_ZHONG] = 0
                    colorCount = MTile.getColorCount(newTileArr)
                    if colorCount == 1:
                        # 清一色不能和牌
                        ftlog.debug('MTingMudanjiangRule.canTing colorCount:',
                                    colorCount, ' can not win, continue....')
                        continue

                # 检查牌中的幺/九
                # 1软 听牌可以没有19,只要胡牌带19就可以
                # 2硬 听牌时就要有19
                RuanYaoJiuConfig = self.getTableConfig(MTDefine.RUAN_YAO_JIU,
                                                       1)
                if RuanYaoJiuConfig == 0:
                    #硬幺九 :听牌必须有19
                    #tileArr 减去 winNode['winTile'] 后判断
                    tileArr[winNode['winTile']] -= 1
                    yaoCount = tileArr[MTile.TILE_ONE_WAN] + tileArr[
                        MTile.TILE_ONE_TONG] + tileArr[MTile.TILE_ONE_TIAO]
                    jiuCount = tileArr[MTile.TILE_NINE_WAN] + tileArr[
                        MTile.TILE_NINE_TONG] + tileArr[MTile.TILE_NINE_TIAO]
                    zhongCount = tileArr[MTile.TILE_HONG_ZHONG]
                    ftlog.debug('MTingMudanjiangRule.canTing : YING yaoCount:',
                                yaoCount, 'jiuCount', jiuCount, 'zhongCount',
                                zhongCount)
                    if (yaoCount + jiuCount + zhongCount) <= 0:
                        continue
                else:
                    #软幺九 :只要胡牌有19就行
                    yaoCount = tileArr[MTile.TILE_ONE_WAN] + tileArr[
                        MTile.TILE_ONE_TONG] + tileArr[MTile.TILE_ONE_TIAO]
                    jiuCount = tileArr[MTile.TILE_NINE_WAN] + tileArr[
                        MTile.TILE_NINE_TONG] + tileArr[MTile.TILE_NINE_TIAO]
                    zhongCount = tileArr[MTile.TILE_HONG_ZHONG]
                    ftlog.debug('MTingMudanjiangRule.canTing : RUAN yaoCount:',
                                yaoCount, 'jiuCount', jiuCount, 'zhongCount',
                                zhongCount)
                    if (yaoCount + jiuCount + zhongCount) == 0:
                        continue

                patterns = winNode['pattern']
                winTile = winNode['winTile']

                #夹起步(顺牌只能和夹和3,7) 除单吊
                chunJiaConfig = self.getTableConfig(MTDefine.MIN_MULTI, 0)
                if chunJiaConfig:
                    hasJia = False

                    bianMulti = self.tableConfig.get(MTDefine.BIAN_MULTI, 0)
                    if bianMulti:
                        if MTile.getValue(
                                winTile
                        ) == 3 and winTile < MTile.TILE_DONG_FENG:
                            newTilesBian = copy.deepcopy(newTiles)
                            # 1,2,3
                            if ((winTile - 2)
                                    in newTilesBian[MHand.TYPE_HAND]) and (
                                        (winTile - 1)
                                        in newTilesBian[MHand.TYPE_HAND]):
                                newTilesBian[MHand.TYPE_HAND].remove(winTile -
                                                                     2)
                                newTilesBian[MHand.TYPE_HAND].remove(winTile -
                                                                     1)
                                newTilesBian[MHand.TYPE_HAND].remove(winTile)
                                newTilesBian[MHand.TYPE_CHI].append(
                                    [winTile - 2, winTile - 1, winTile])
                                rBian, rPattern = self.winRuleMgr.isHu(
                                    newTilesBian, winTile, True,
                                    MWinRule.WIN_BY_MYSELF, magicTiles)
                                if rBian:
                                    ftlog.debug(
                                        'MTingMudanjiangRule isJia 3 Bian : ',
                                        newTilesBian, ' patterns:', rPattern)
                                    hasJia = True

                        if not hasJia and MTile.getValue(
                                winTile
                        ) == 7 and winTile < MTile.TILE_DONG_FENG:
                            newTiles37 = copy.deepcopy(newTiles)
                            # 7,8,9
                            if ((winTile + 1)
                                    in newTiles37[MHand.TYPE_HAND]) and (
                                        (winTile + 2)
                                        in newTiles37[MHand.TYPE_HAND]):
                                newTiles37[MHand.TYPE_HAND].remove(winTile + 1)
                                newTiles37[MHand.TYPE_HAND].remove(winTile + 2)
                                newTiles37[MHand.TYPE_HAND].remove(winTile)
                                newTiles37[MHand.TYPE_CHI].append(
                                    [winTile, winTile + 1, winTile + 2])
                                rQi, qiPattern = self.winRuleMgr.isHu(
                                    newTiles37, winTile, True,
                                    MWinRule.WIN_BY_MYSELF, magicTiles)
                                if rQi:
                                    ftlog.debug(
                                        'MTingMudanjiangRule isJia 7 Bian : ',
                                        newTiles37, ' pattern:', qiPattern)
                                    hasJia = True

                    danDiaoJia = self.tableConfig.get(MTDefine.DAN_DIAO_JIA, 1)
                    if not hasJia and danDiaoJia:
                        newTilesDan = copy.deepcopy(newTiles)
                        ftlog.debug(
                            'MTingMudanjiangRule isJia in >> danDiao : ',
                            newTilesDan)
                        # 5,5
                        if winTile in newTilesDan[MHand.TYPE_HAND]:
                            rDan, danPattern = MWin.isHuWishSpecialJiang(
                                newTilesDan[MHand.TYPE_HAND],
                                [winTile, winTile], magicTiles)
                            if rDan:
                                ftlog.debug(
                                    'MTingMudanjiangRule isJia danDiao : ',
                                    newTilesDan, ' winTile:', winTile,
                                    ' pattern:', danPattern)
                                hasJia = True

                    if not hasJia:
                        newTilesJia = copy.deepcopy(newTiles)
                        # 2,3,4
                        if ((winTile - 1)
                                in newTilesJia[MHand.TYPE_HAND]) and (
                                    (winTile + 1)
                                    in newTilesJia[MHand.TYPE_HAND]):
                            newTilesJia[MHand.TYPE_HAND].remove(winTile + 1)
                            newTilesJia[MHand.TYPE_HAND].remove(winTile - 1)
                            newTilesJia[MHand.TYPE_HAND].remove(winTile)
                            newTilesJia[MHand.TYPE_CHI].append(
                                [winTile - 1, winTile, winTile + 1])
                            rJia, jiaPattern = self.winRuleMgr.isHu(
                                newTilesJia, winTile, True,
                                MWinRule.WIN_BY_MYSELF, magicTiles)
                            if rJia:
                                ftlog.debug('MTingMudanjiangRule isJia : ',
                                            newTilesJia, ' pattern:',
                                            jiaPattern)
                                hasJia = True

                    # winNodes中的patterns只是胡牌的一种方式,不是全部的胡牌解,判断夹牌,只使用patterns的组合会有遗漏的情况
                    # 合理的做法是先把夹拿出来,在判断剩下的牌是否能胡。
                    if not hasJia:
                        ftlog.debug(
                            'MTingMudanjiangRule.canTing :, can not win tile:',
                            winNode['winTile'], ', not has jia continue....')
                        continue

                patterns = winNode['pattern']
                checkKeCount = keCount + self.getKeCount(patterns)
                checkShunCount = shunCount + self.getShunCount(patterns)
                ftlog.debug('MTingMudanjiangRule.canTing checkKeCount:',
                            checkKeCount, ' checkShunCount:', checkShunCount)

                if checkKeCount and checkShunCount:
                    newWinNodes.append(winNode)

            if len(newWinNodes) > 0:
                newTingResult = {}
                newTingResult['dropTile'] = tingResult['dropTile']
                newTingResult['winNodes'] = newWinNodes
                newTingResults.append(newTingResult)

        return len(newTingResults) > 0, newTingResults
Пример #20
0
 def checkMao(cls, pattern, maoType, maoDanSetting):
     ftlog.debug('MMao.checkMao pattern:', pattern
                 , ' maoType:', maoType
                 , ' maoDanSetting:', maoDanSetting)
     
     values = []
     if maoType & MTDefine.MAO_DAN_DNXBZFB: #乱锚
         if not maoDanSetting & MTDefine.MAO_DAN_DNXBZFB:
             return False
         
         for tile in pattern:
             if MTile.isArrow(tile) or MTile.isFeng(tile):
                 values.append(tile) #取消对相同牌的检查
             else:
                 return False
     elif maoType & MTDefine.MAO_DAN_DNXB:
         if not maoDanSetting & MTDefine.MAO_DAN_DNXB:
             return False
         
         for tile in pattern:
             if MTile.isFeng(tile):
                 if tile not in values:
                     values.append(tile)
                 continue
             else:
                 return False
     elif maoType & MTDefine.MAO_DAN_ZFB:
         if not maoDanSetting & MTDefine.MAO_DAN_ZFB:
             return False
         
         for tile in pattern:
             if MTile.isArrow(tile):
                 if tile not in values:
                     values.append(tile)
                 continue
             else:
                 return False
             
     elif maoType & MTDefine.MAO_DAN_YAO:
         if not maoDanSetting & MTDefine.MAO_DAN_YAO:
             return False
         
         for tile in pattern:
             if MTile.getValue(tile) == 1:
                 if tile not in values:
                     values.append(tile)
                 continue
             else:
                 return False
     
     elif maoType & MTDefine.MAO_DAN_JIU:
         if not maoDanSetting & MTDefine.MAO_DAN_JIU:
             return False
         
         for tile in pattern:
             if MTile.getValue(tile) == 9:
                 if tile not in values:
                     values.append(tile)
                 continue
             else:
                 return False
             
     ftlog.debug('MMao.checkMao pattern:', pattern
                 , ' maoType:', maoType)        
     return len(values) >= 3
Пример #21
0
 def isJia5(self):
     """是否夹五"""
     res = self.isJia() and (MTile.getValue(self.winTile)
                             == 5) and (self.winTile < 30)
     ftlog.debug('weihai_one_result.isJia5 result: ', res)
     return res
Пример #22
0
    def calcWin(self):
        """
        鸡西算番规则:
        """
        scoreBase = self.tableConfig.get(MTDefine.WIN_BASE, 1)
        ftlog.debug('MJixiOneResult.calcWin scoreBase:', scoreBase)
        self.results['type'] = MOneResult.KEY_TYPE_NAME_HU

        name = ''
        index = 0
        score = [0 for _ in range(self.playerCount)]
        fanPattern = [[] for _ in range(self.playerCount)]
        winMode = [MOneResult.WIN_MODE_LOSS for _ in range(self.playerCount)]
        # 在和牌时统计自摸,点炮,最大番数
        resultStat = [[] for _ in range(self.playerCount)]
        isBaoPei = False  # 是否包赔,如果是包赔 那么兑奖也要包赔

        resultStat[self.winSeatId].append({MOneResult.STAT_WIN: 1})
        # 正常和牌
        if not self.wuDuiHu:
            isZiMo = (self.lastSeatId == self.winSeatId)
            if isZiMo:
                resultStat[self.winSeatId].append({MOneResult.STAT_ZIMO: 1})
            isJia = self.isJia()
            isBian = self.isBian()
            isDanDiao = self.isDanDiao()
            isMagic = self.isMagicTile()
            isQiDui = self.isQiDui(isMagic)
            isPiao = self.isPiao()
            isQingYiSe = self.isQingYiSe()
            isTeDaJia = self.isTeDaJia(isJia, isBian)
            isSanQi = self.isSanQi()
            ftlog.debug('MJixiOneResult.calcWin isJia:', isJia, ' isBian:',
                        isBian, ' isDanDiao', isDanDiao, ' isQiDui:', isQiDui,
                        ' isPiao:', isPiao, ' isQingYiSe:', isQingYiSe,
                        ' isSanQi:', isSanQi)

            self.clearWinFanPattern()

            # 高级番型处理(清一色 通宝 宝中宝)
            isBaoZhongBao = False
            isTongBao = False
            if self.magicAfertTing:  # 听牌之后是宝牌 直接和牌
                # 宝中宝 宝夹
                bianMulti = self.tableConfig.get(MTDefine.BIAN_MULTI, 0)
                if (isBian and isSanQi and bianMulti
                        and len(self.winNodes) == 1):
                    isBaoZhongBao = True

                elif isJia:
                    # 如果是摸的宝是winNodes里面的夹,就是宝中宝,否则是宝边
                    magicTileInJia = False
                    for wn in self.winNodes:
                        patterns = wn['pattern']
                        for p in patterns:
                            if len(p) == 2:
                                continue
                            if p[0] == p[1]:
                                continue

                            if (self.winTile in p) and (p.index(
                                    self.winTile)) == 1:
                                magicTileInJia = True

                    if magicTileInJia:
                        isBaoZhongBao = True
                    else:
                        isTongBao = True

                elif isDanDiao:
                    # 如果是摸的宝是winNodes里面的对子,就是宝中宝,否则是宝边
                    magicTileInPair = False
                    for wn in self.winNodes:
                        patterns = wn['pattern']
                        for p in patterns:
                            if len(p) != 2:
                                continue

                            if p[0] == p[1] and (self.winTile in p):
                                magicTileInPair = True

                    if magicTileInPair:
                        isBaoZhongBao = True
                    else:
                        isTongBao = True

                # 通宝 宝边
                else:
                    ftlog.debug('MJixiOneResult.calcWin  isTongBao = True:')
                    isTongBao = True

            if isBaoZhongBao:
                nameBaoZhongBao = self.fanXing[self.BAOZHONGBAOJIA]['name']
                indexBaoZhongBao = self.fanXing[self.BAOZHONGBAOJIA]['index']
                self.addWinFanPattern(nameBaoZhongBao, indexBaoZhongBao)
                index += self.fanXing[self.BAOZHONGBAOJIA]['index']
                ftlog.debug('MJixiOneResult.calcWin MagicAfertTing name:',
                            nameBaoZhongBao, ' index:', indexBaoZhongBao)
            elif isTongBao:
                nameTongBao = self.fanXing[self.BAOBIAN]['name']
                indexTongBao = self.fanXing[self.BAOBIAN]['index']
                self.addWinFanPattern(nameTongBao, indexTongBao)
                index += self.fanXing[self.BAOBIAN]['index']
                # 计算基本番型
                name, tempindex = self.calcBaseFan(isTeDaJia, False, False,
                                                   False, isQiDui, isPiao)
                index += tempindex
                ftlog.debug('MJixiOneResult.calcWin BaseFan name:', name,
                            ' index:', index)
            elif isZiMo:  # 自摸番型处理(自摸 摸宝[2番] 杠开 )
                if isMagic:
                    index += self.fanXing[self.MOBAO]['index']
                    self.addWinFanPattern(self.fanXing[self.MOBAO]['name'],
                                          self.fanXing[self.MOBAO]['index'])
                    resultStat[self.winSeatId].append(
                        {MOneResult.STAT_MOBAO: 1})
                else:
                    index += self.fanXing[self.ZIMO]['index']

                # 计算基本番型
                name, tempindex = self.calcBaseFan(isTeDaJia, isJia, isBian,
                                                   isDanDiao, isQiDui, isPiao)
                index += tempindex
                ftlog.debug('MJixiOneResult.calcWin ZiMoFan index:', index)
            elif isZiMo == False:  # 点炮胡
                # 计算基本番型
                name, tempindex = self.calcBaseFan(isTeDaJia, isJia, isBian,
                                                   isDanDiao, isQiDui, isPiao)
                index += tempindex
                ftlog.debug('MJixiOneResult.calcWin 点炮胡 index:', index)

            if isQingYiSe:
                if isTeDaJia or isQiDui or isPiao or isBaoZhongBao:
                    nameQingYiSe = self.fanXing[self.QINGYISE_1]['name']
                    indexQingYiSe = self.fanXing[self.QINGYISE_1]['index']
                    self.addWinFanPattern(nameQingYiSe, indexQingYiSe)
                    index += self.fanXing[self.QINGYISE_1]['index']
                else:
                    nameQingYiSe = self.fanXing[self.QINGYISE]['name']
                    indexQingYiSe = self.fanXing[self.QINGYISE]['index']
                    self.addWinFanPattern(nameQingYiSe, indexQingYiSe)
                    index += self.fanXing[self.QINGYISE]['index']
                ftlog.debug('MJixiOneResult.calcWin QingYiSeFan name:',
                            nameQingYiSe, ' index:', indexQingYiSe)

            if self.bankerSeatId == self.winSeatId:
                index += 1
                ftlog.debug('MJixiOneResult.calcWin name:', name, ' index:',
                            index, ' type:', type, ' bankerSeatId:',
                            self.bankerSeatId, ' winSeatId:', self.winSeatId)

            scoreIndex = self.tableConfig.get(
                MTDefine.FAN_LIST, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
            ftlog.debug('MJixiOneResult.calcWin scoreIndex:', scoreIndex)

            biMenFanConfig = self.tableConfig.get(MTDefine.BI_MEN_FAN, 0)
            # 当前局番型处理
            # 输赢模式 输家番型统计
            for seatId in range(self.playerCount):
                if seatId == self.winSeatId:
                    winModeValue = MOneResult.WIN_MODE_PINGHU
                    # 自摸
                    if self.lastSeatId == self.winSeatId:
                        winModeValue = MOneResult.WIN_MODE_ZIMO
                    if isMagic and (not self.magicAfertTing):
                        winModeValue = MOneResult.WIN_MODE_mobao
                    if isBaoZhongBao:
                        winModeValue = MOneResult.WIN_MODE_baozhongbao
                    if self.magicAfertTing:
                        if self.tableConfig.get(MTDefine.DUI_BAO, 0) == 1:
                            winModeValue = MOneResult.WIN_MODE_LOUHU
                    if self.gangKai:
                        winModeValue = MOneResult.WIN_MODE_GANGKAI
                        self.addWinFanPattern(
                            self.fanXing[self.GANGKAI]['name'],
                            self.fanXing[self.GANGKAI]['index'])
                    if self.qiangGang:
                        winModeValue = MOneResult.WIN_MODE_QIANGGANGHU
                        self.addWinFanPattern(
                            self.fanXing[self.QIANGGANG]['name'],
                            self.fanXing[self.QIANGGANG]['index'])
                    if self.daFeng:
                        winModeValue = MOneResult.WIN_MODE_guadafeng

                    winMode[seatId] = winModeValue
                    fanPattern[self.winSeatId] = self.winFanPattern
                elif seatId == self.lastSeatId:
                    winModeValue = MOneResult.WIN_MODE_DIANPAO
                    winMode[seatId] = winModeValue
                    resultStat[seatId].append({MOneResult.STAT_DIANPAO: 1})
                    fanPattern[seatId] = []
                    # 点炮包庄
                    if self.tingState[seatId] == 0:
                        winModeValue = MOneResult.WIN_MODE_DIANPAO_BAOZHUANG
                        winMode[seatId] = winModeValue
                    # 闭门
                    if self.menState[seatId] == 1 and biMenFanConfig:
                        looseFanName = self.fanXing[self.BIMEN]['name']
                        looseFanIndex = self.fanXing[self.BIMEN]['index']
                        fanPattern[seatId].append(
                            [looseFanName.strip(),
                             str(looseFanIndex) + "番"])

                else:
                    fanPattern[seatId] = []
                    # 闭门
                    if self.menState[seatId] == 1 and biMenFanConfig:
                        looseFanName = self.fanXing[self.BIMEN]['name']
                        looseFanIndex = self.fanXing[self.BIMEN]['index']
                        fanPattern[seatId].append(
                            [looseFanName.strip(),
                             str(looseFanIndex) + "番"])

            if not self.tianHu:
                score = [index for _ in range(self.playerCount)]
                if self.lastSeatId != self.winSeatId:
                    if self.tingState[self.lastSeatId]:
                        ftlog.debug(
                            'MJixiOneResult.calcWin dianpao index is zero becouse is Ting'
                        )
                    else:
                        # 改成点炮都不翻倍
                        # score[self.lastSeatId] += 1
                        ftlog.debug('MJixiOneResult.calcWin dianpao score:',
                                    score)

                if self.bankerSeatId != self.winSeatId:
                    score[self.bankerSeatId] += 1
                    ftlog.debug(
                        'MJixiOneResult.calcWin zhuangjia double score:',
                        score, ' bankerSeatId:', self.bankerSeatId,
                        ' winSeatId:', self.winSeatId)

                for seatId in range(len(self.menState)):
                    if biMenFanConfig and self.menState[
                            seatId] == 1 and seatId != self.winSeatId:
                        score[seatId] += 1
                        ftlog.debug(
                            'MJixiOneResult.calcWin menqing double score:',
                            score, ' menState:', self.menState)

                winScore = 0
                for seatId in range(len(score)):
                    if seatId != self.winSeatId:
                        newIndex = score[seatId]
                        score[seatId] = -scoreIndex[newIndex]
                        winScore += scoreIndex[newIndex]
                score[self.winSeatId] = winScore
                ftlog.debug('MJixiOneResult.calcWin score before baopei:',
                            score)

                if self.lastSeatId != self.winSeatId:
                    if self.tingState[self.lastSeatId] == 0:
                        isBaoPei = True
                        # 包赔
                        for seatId in range(len(score)):
                            if seatId != self.winSeatId and seatId != self.lastSeatId:
                                s = score[seatId]
                                score[seatId] = 0
                                score[self.lastSeatId] += s
                        ftlog.debug(
                            'MJixiOneResult.calcWin dianpaobaozhuang score:',
                            score, ' lastSeatId:', self.lastSeatId,
                            ' winSeatId:', self.winSeatId, ' tingState:',
                            self.tingState)
            else:
                index = self.fanXing[self.TIANHU]['index']
                score = [index for _ in range(self.playerCount)]
                scoreIndex = self.tableConfig.get(
                    MTDefine.FAN_LIST, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
                ftlog.debug('MJixiOneResult.calcWin scoreIndex:', scoreIndex)
                winScore = 0
                for seatId in range(len(score)):
                    if seatId != self.winSeatId:
                        newIndex = score[seatId]
                        score[seatId] = -scoreIndex[newIndex]
                        winScore += scoreIndex[newIndex]
                score[self.winSeatId] = winScore
                # fanPattern = [[] for _ in range(self.playerCount)]
                winMode = [
                    MOneResult.WIN_MODE_LOSS for _ in range(self.playerCount)
                ]
                winMode[self.winSeatId] = MOneResult.WIN_MODE_TIANHU
                resultStat[self.winSeatId].append(
                    {MOneResult.STAT_ZUIDAFAN: index})
        else:
            name = self.fanXing[self.WUDUIHU]['name']
            index = self.fanXing[self.WUDUIHU]['index']
            self.addWinFanPattern(name, index)
            fanPattern[self.winSeatId] = self.winFanPattern
            score = [10 for _ in range(self.playerCount)]
            winScore = 0
            for seatId in range(len(score)):
                if seatId != self.winSeatId:
                    loseScore = score[seatId]
                    score[seatId] = -loseScore
                    winScore += loseScore
            score[self.winSeatId] = winScore
            # fanPattern = [[] for _ in range(self.playerCount)]
            winMode = [
                MOneResult.WIN_MODE_LOSS for _ in range(self.playerCount)
            ]
            winMode[self.winSeatId] = MOneResult.WIN_MODE_WUDUIHU

        # 最高128分封顶
        for seatId in range(len(score)):
            if seatId != self.winSeatId:
                if abs(score[seatId]) > self.MAX_SCORE_LIMIT:
                    ftlog.debug('MJixiOneResult.calcWin limit max score :',
                                score[seatId], ' seatId:', seatId)
                    score[self.winSeatId] = score[self.winSeatId] - (
                        abs(score[seatId]) - self.MAX_SCORE_LIMIT)
                    score[seatId] = -self.MAX_SCORE_LIMIT

        # 兑奖
        awardInfos = []
        awardScores = [0 for _ in range(self.playerCount)]
        awardTiles = self.awardTiles
        if len(awardTiles) == 0:
            ftlog.debug('MJixiOneResult.calcWin award tile is zero')
        else:
            awardScore = 0
            for awardTile in awardTiles:
                tileValue = MTile.getValue(awardTile)
                realScore = 0
                if tileValue == 1 or awardTile == MTile.TILE_HONG_ZHONG:
                    realScore = 10
                    awardScore += realScore
                else:
                    realScore = tileValue
                    awardScore += realScore
                awardInfo = {'awardTile': awardTile, 'awardScore': realScore}
                awardInfos.append(awardInfo)

            for seatId in range(len(score)):
                if seatId != self.winSeatId:
                    if isBaoPei:  # 兑奖包赔处理
                        score[self.lastSeatId] -= awardScore
                        awardScores[self.lastSeatId] -= awardScore
                    else:
                        score[seatId] -= awardScore
                        awardScores[seatId] = -awardScore
                    score[self.winSeatId] += awardScore
                    awardScores[self.winSeatId] += awardScore

        # 单局最佳统计(分数)
        resultStat[self.winSeatId].append(
            {MOneResult.STAT_ZUIDAFAN: score[self.winSeatId]})

        self.results[self.KEY_TYPE] = '和牌'
        self.results[self.KEY_NAME] = name
        ftlog.debug('MJixiOneResult.calcWin result score:', score)
        self.results[self.KEY_SCORE] = score
        ftlog.debug('MJixiOneResult.calcWin result winMode:', winMode)
        self.results[self.KEY_WIN_MODE] = winMode
        self.results[self.KEY_STAT] = resultStat
        ftlog.debug('MJixiOneResult.calcWin result fanPattern:', fanPattern)
        self.results[self.KEY_FAN_PATTERN] = fanPattern
        self.results[self.KEY_AWARD_INFO] = awardInfos
        self.results[self.KEY_AWARD_SCORE] = awardScores
Пример #23
0
    def isHu(self,
             tiles,
             tile,
             isTing,
             getTileType,
             magicTiles=[],
             tingNodes=[],
             winSeatId=0):
        ftlog.debug(self.TAG, '.isHu tiles:', tiles, ' tile:', tile,
                    ' isTing:', isTing, ' getTileType:', getTileType,
                    ' magicTiles:', magicTiles, ' tingNodes:', tingNodes,
                    ' winSeatId:', winSeatId)

        if self.tableTileMgr.isPassHuTileBySeatId(winSeatId, tile):
            return False, []

        # 济南麻将允许胡七对
        qiduiTiles = copy.deepcopy(tiles)
        resultQiDui, patternQiDui = MWin.isQiDui(qiduiTiles[MHand.TYPE_HAND])
        if resultQiDui:
            if self.tableConfig[MTDefine.ONLY_JIANG_258]:
                for pattern in patternQiDui:
                    tile = pattern[0]
                    if tile > MTile.TILE_NINE_TIAO:
                        continue

                    # 选了258将判断这里,而且不能是风牌
                    if (MTile.getValue(pattern[0]) % 3
                            == 2) and pattern[0] < MTile.TILE_DONG_FENG:
                        return True, patternQiDui
                return False, []
            else:
                return resultQiDui, patternQiDui

        # 花胡
        if getTileType == MWinRule.WIN_BY_MYSELF:
            flowerTiles = copy.deepcopy(tiles)
            resFlowerHu, patternFlowerHu = MWin.isFlowerHu(flowerTiles)
            if resFlowerHu:
                return resFlowerHu, patternFlowerHu

        # 全将
        jiangTiles = copy.deepcopy(tiles)
        resQuanj, patternQuanj = MWin.isQuanJiang(jiangTiles)
        if resQuanj:
            return resQuanj, patternQuanj

        # 十三不靠
        if not self.tableConfig[MTDefine.ONLY_JIANG_258]:
            bukaoTiles = copy.deepcopy(tiles)
            res13Bukao, pattern13Bukao = MWin.is13BuKao(
                bukaoTiles[MHand.TYPE_HAND])
            if res13Bukao:
                return res13Bukao, pattern13Bukao

        # 挑出2,5,8将,看剩下的牌是否能胡牌
        if self.tableConfig[MTDefine.ONLY_JIANG_258]:
            jiangPatterns = [[MTile.TILE_TWO_WAN, MTile.TILE_TWO_WAN],
                             [MTile.TILE_FIVE_WAN, MTile.TILE_FIVE_WAN],
                             [MTile.TILE_EIGHT_WAN, MTile.TILE_EIGHT_WAN],
                             [MTile.TILE_TWO_TONG, MTile.TILE_TWO_TONG],
                             [MTile.TILE_FIVE_TONG, MTile.TILE_FIVE_TONG],
                             [MTile.TILE_EIGHT_TONG, MTile.TILE_EIGHT_TONG],
                             [MTile.TILE_TWO_TIAO, MTile.TILE_TWO_TIAO],
                             [MTile.TILE_FIVE_TIAO, MTile.TILE_FIVE_TIAO],
                             [MTile.TILE_EIGHT_TIAO, MTile.TILE_EIGHT_TIAO]]

            jiangTiles = copy.deepcopy(tiles)
            for jiangPat in jiangPatterns:
                result, pattern = MWin.isHuWishSpecialJiang(
                    jiangTiles[MHand.TYPE_HAND], jiangPat)
                if result:
                    return result, pattern
        else:
            newTiles = copy.deepcopy(tiles)
            result, pattern = MWin.isHu(newTiles[MHand.TYPE_HAND])
            return result, pattern

        return False, []
Пример #24
0
    def isBian(self):
        """是否夹牌"""
        for wn in self.winNodes:
            if wn['winTile'] == self.winTile:
                patterns = wn['pattern']
                ftlog.debug('MMudanjiangOneResult.isBian winTile:',
                            self.winTile, ' winPatterns:', patterns)
                for p in patterns:
                    if len(p) == 2:
                        continue

                    if p[0] == p[1]:
                        continue

                    # 三七边
                    if (self.winTile in p) \
                        and (p.index(self.winTile) == 0) \
                        and (MTile.getValue(p[1]) == 8) \
                        and (MTile.getValue(p[2]) == 9):
                        ftlog.debug('MMudanjiangOneResult.isBian winTile:',
                                    self.winTile, ' winPatterns:', patterns,
                                    ' 7 bian')
                        return True
                    if (self.winTile in p) \
                        and (p.index(self.winTile) == 2) \
                        and (MTile.getValue(p[0]) == 1) \
                        and (MTile.getValue(p[1]) == 2):
                        ftlog.debug('MMudanjiangOneResult.isBian winTile:',
                                    self.winTile, ' winPatterns:', patterns,
                                    ' 3 bian')
                        return True

        # 宝牌情况处理
        hongZongBaoConfig = self.tableConfig.get(MTDefine.HONG_ZHONG_BAO, 0)
        ftlog.debug('MMudanjiangOneResult.isBian checkMagic, isMagicTile:',
                    self.isMagicTile(), ' isHongZhong:', self.isHongZhong(),
                    ' hongZongBaoConfig:', hongZongBaoConfig, ' daFeng:',
                    self.daFeng, ' magicAfertTing:', self.magicAfertTing)
        if self.isMagicTile() or (self.isHongZhong() and hongZongBaoConfig
                                  ) or self.daFeng or self.magicAfertTing:
            for wn in self.winNodes:
                winTile = wn['winTile']
                patterns = wn['pattern']
                for p in patterns:
                    if len(p) == 2:
                        continue

                    if p[0] == p[1]:
                        continue

                    # 三七边
                    if (winTile in p) \
                        and (p.index(winTile) == 0) \
                        and (MTile.getValue(p[1]) == 8) \
                        and (MTile.getValue(p[2]) == 9):
                        ftlog.debug('MMudanjiangOneResult.isBian winTile:',
                                    self.winTile, ' winPatterns:', patterns,
                                    ' 7 bian')
                        return True
                    if (winTile in p) \
                        and (p.index(winTile) == 2) \
                        and (MTile.getValue(p[0]) == 1) \
                        and (MTile.getValue(p[1]) == 2):
                        ftlog.debug('MMudanjiangOneResult.isBian winTile:',
                                    self.winTile, ' winPatterns:', patterns,
                                    ' 3 bian')
                        return True

        return False
Пример #25
0
 def hasMao(cls, tiles, maoDanSetting, alreadyHave = 0):
     ftlog.debug('MMao.hasMao tiles:', tiles
                 , ' maoDanSetting:', maoDanSetting
                 , ' alreadyHave:', alreadyHave)
     maos = []
     
     if (maoDanSetting & MTDefine.MAO_DAN_DNXBZFB) and (not (alreadyHave & MTDefine.MAO_DAN_DNXBZFB)):
         pattern = []
         values = []
         for tile in tiles:
             if MTile.isFeng(tile) or MTile.isArrow(tile):
                 pattern.append(tile)
                 if tile not in values:
                     values.append(tile)
                     
         if len(values) >= 3:
             luanMao = {}
             luanMao['type'] = MTDefine.MAO_DAN_DNXBZFB
             luanMao['pattern'] = values
             luanMao['name'] = MTDefine.MAO_DAN_DNXBZFB_NAME
             maos.append(luanMao)
             
     if (maoDanSetting & MTDefine.MAO_DAN_DNXB) and \
         (not (alreadyHave & MTDefine.MAO_DAN_DNXB) and \
         (not (maoDanSetting & MTDefine.MAO_DAN_DNXBZFB))):
         pattern = []
         values = []
         for tile in tiles:
             if MTile.isFeng(tile):
                 pattern.append(tile)
                 if tile not in values:
                     values.append(tile)
                     
         if len(values) >= 3:
             fengMao = {}
             fengMao['type'] = MTDefine.MAO_DAN_DNXB
             fengMao['pattern'] = values
             fengMao['name'] = MTDefine.MAO_DAN_DNXB_NAME
             maos.append(fengMao)
             
     if (maoDanSetting & MTDefine.MAO_DAN_ZFB) and \
         (not (alreadyHave & MTDefine.MAO_DAN_ZFB)) and \
         (not (maoDanSetting & MTDefine.MAO_DAN_DNXBZFB)):
         pattern = []
         values = []
         for tile in tiles:
             if MTile.isArrow(tile):
                 pattern.append(tile)
                 if tile not in values:
                     values.append(tile)
                     
         if len(values) >= 3:
             arrowMao = {}
             arrowMao['type'] = MTDefine.MAO_DAN_ZFB
             arrowMao['pattern'] = values
             arrowMao['name'] = MTDefine.MAO_DAN_ZFB_NAME
             maos.append(arrowMao)
             
     if (maoDanSetting & MTDefine.MAO_DAN_YAO) and (not (alreadyHave & MTDefine.MAO_DAN_YAO)):
         pattern = []
         values = []
         for tile in tiles:
             if MTile.getValue(tile) == 1:
                 pattern.append(tile)
                 if tile not in values:
                     values.append(tile)
         if len(values) >= 3:
             yaoMao = {}
             yaoMao['type'] = MTDefine.MAO_DAN_YAO
             yaoMao['pattern'] = values
             yaoMao['name'] = MTDefine.MAO_DAN_YAO_NAME
             maos.append(yaoMao)
             
     if (maoDanSetting & MTDefine.MAO_DAN_JIU) and (not (alreadyHave & MTDefine.MAO_DAN_JIU)):
         pattern = []
         values = []
         for tile in tiles:
             if MTile.getValue(tile) == 9:
                 pattern.append(tile)
                 if tile not in values:
                     values.append(tile)
                     
         if len(values) >= 3:
             jiuMao = {}
             jiuMao['type'] = MTDefine.MAO_DAN_JIU
             jiuMao['pattern'] = values
             jiuMao['name'] = MTDefine.MAO_DAN_JIU_NAME
             maos.append(jiuMao)
     
     ftlog.debug('MMao.hasMao tiles:', tiles
                 , ' maoDanSetting:', maoDanSetting
                 , ' maos:', maos)    
     return maos
Пример #26
0
    def canTing(self, tiles, leftTiles, tile, magicTiles=[], winSeatId=0):
        """子类必须实现
        参数:
        1)tiles 该玩家的手牌
        2)leftTiles 剩余手牌
        返回值:
        是否可以听牌,听牌详情
        """
        handCount = len(tiles[MHand.TYPE_HAND])

        isTing, tingResults = MTing.canTing(self.tilePatternChecker,
                                            self.tableTileMgr,
                                            MTile.cloneTiles(tiles), leftTiles,
                                            self.winRuleMgr, tile, magicTiles,
                                            winSeatId)
        ftlog.debug('MTingJixiRule.canTing tiles:', tiles, 'tile:', tile)
        ftlog.debug('MTingJixiRule.MTing.canTing isTing:', isTing,
                    ' tingResults:', tingResults)
        #         [{'dropTile': 11, 'winNodes': [{'winTile': 1, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [1, 2, 3]]}, {'winTile': 2, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [3, 4, 5], [2, 2]]}, {'winTile': 4, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [2, 3, 4]]}, {'winTile': 5, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [5, 5], [2, 3, 4]]}, {'winTile': 7, 'winTileCount': 1, 'pattern': [[6, 6], [5, 6, 7], [5, 6, 7], [2, 3, 4]]}, {'winTile': 8, 'winTileCount': 1, 'pattern': [[6, 7, 8], [6, 6, 6], [5, 5], [2, 3, 4]]}]}]
        #tingResults: [{'dropTile': 23, 'winNodes': [{'winTile': 12, 'winTileCount': 0, 'pattern': [[13, 14, 15], [12, 12, 12], [29, 29], [25, 25, 25]]}, {'winTile': 29, 'winTileCount': 1, 'pattern': [[13, 14, 15], [12, 12], [29, 29, 29], [25, 25, 25]]}]}]

        if not isTing:
            return False, []

        # 检查刻,刻的来源,碰牌/明杠牌/手牌
        pengCount = len(tiles[MHand.TYPE_PENG])
        gangCount = len(tiles[MHand.TYPE_GANG])
        keCount = pengCount + gangCount

        newTingResults = []
        for tingResult in tingResults:
            newWinNodes = []
            winNodes = tingResult['winNodes']
            for winNode in winNodes:
                newTiles = MTile.cloneTiles(tiles)
                newTiles[MHand.TYPE_HAND].remove(tingResult['dropTile'])
                newTiles[MHand.TYPE_HAND].append(winNode['winTile'])
                tileArr = MTile.changeTilesToValueArr(
                    MHand.copyAllTilesToList(newTiles))
                patterns = winNode['pattern']
                isQiDui = self.isQiDui(patterns, newTiles)
                isPiaoHu = self.isPiaoHu(patterns, newTiles)

                #飘和七对可以手把一
                if (isPiaoHu or isQiDui):
                    if handCount < 2:
                        continue
                else:
                    if handCount < 5:
                        continue

                # 飘和七小对不需要1,9,如果不是飘也不是七小对:
                # 检查牌中的幺/九
                # 1软 听牌可以没有19,只要胡牌带19就可以
                # 2硬 听牌时就要有19
                if not (isPiaoHu or isQiDui):
                    RuanYaoJiuConfig = self.getTableConfig(
                        MTDefine.RUAN_YAO_JIU, 1)
                    if RuanYaoJiuConfig == 0:
                        #硬幺九 :听牌必须有19
                        #tileArr 减去 winNode['winTile'] 后判断
                        tileArr[winNode['winTile']] -= 1
                        yaoCount = tileArr[MTile.TILE_ONE_WAN] + tileArr[
                            MTile.TILE_ONE_TONG] + tileArr[MTile.TILE_ONE_TIAO]
                        jiuCount = tileArr[MTile.TILE_NINE_WAN] + tileArr[
                            MTile.TILE_NINE_TONG] + tileArr[
                                MTile.TILE_NINE_TIAO]
                        zhongCount = tileArr[MTile.TILE_HONG_ZHONG]
                        ftlog.debug('MTingJixiRule.canTing : YING yaoCount:',
                                    yaoCount, 'jiuCount', jiuCount,
                                    'zhongCount', zhongCount)
                        if (yaoCount + jiuCount + zhongCount) <= 0:
                            continue
                    else:
                        #软幺九 :只要胡牌有19就行
                        yaoCount = tileArr[MTile.TILE_ONE_WAN] + tileArr[
                            MTile.TILE_ONE_TONG] + tileArr[MTile.TILE_ONE_TIAO]
                        jiuCount = tileArr[MTile.TILE_NINE_WAN] + tileArr[
                            MTile.TILE_NINE_TONG] + tileArr[
                                MTile.TILE_NINE_TIAO]
                        zhongCount = tileArr[MTile.TILE_HONG_ZHONG]
                        ftlog.debug('MTingJixiRule.canTing : RUAN yaoCount:',
                                    yaoCount, 'jiuCount', jiuCount,
                                    'zhongCount', zhongCount)
                        if (yaoCount + jiuCount + zhongCount) == 0:
                            continue

                #夹起步(顺牌只能和夹和3,7) 不能和两头 可以单吊
                chunJiaConfig = self.getTableConfig(MTDefine.MIN_MULTI, 0)
                if chunJiaConfig:
                    bianMulti = self.tableConfig.get(MTDefine.BIAN_MULTI, 0)
                    danDiaoJia = self.tableConfig.get(MTDefine.DAN_DIAO_JIA, 1)
                    hasJia = False
                    for pattern in patterns:
                        if winNode['winTile'] in pattern:
                            if len(pattern) == 3 and pattern[0] != pattern[1]:
                                if pattern.index(winNode['winTile']) == 2:
                                    if bianMulti:
                                        if MTile.getValue(
                                                winNode['winTile']) == 3:
                                            hasJia = True
                                            break
                                if pattern.index(winNode['winTile']) == 0:
                                    if bianMulti:
                                        if MTile.getValue(
                                                winNode['winTile']) == 7:
                                            hasJia = True
                                            break

                                if pattern.index(winNode['winTile']) == 1:
                                    hasJia = True
                                    break

                            #单吊
                            if len(pattern) == 2 and pattern[0] == pattern[
                                    1] and danDiaoJia:
                                hasJia = True
                                break

                    if not hasJia:
                        ftlog.debug(
                            'MTingHaerbinRule.canTing :, can not win tile:',
                            winNode['winTile'], ', not has jia continue....')
                        continue

                patterns = winNode['pattern']
                checkKeCount = keCount + self.getKeCount(patterns)
                ftlog.debug('MTingJixiRule.canTing keCount:', keCount)

                #胡牌必须有刻牌 七小对除外
                if checkKeCount or isQiDui:
                    newWinNodes.append(winNode)

            if len(newWinNodes) > 0:
                newTingResult = {}
                newTingResult['dropTile'] = tingResult['dropTile']
                newTingResult['winNodes'] = newWinNodes
                newTingResults.append(newTingResult)

        ftlog.debug('MTingJixiRule.canTing :len(newTingResults) ',
                    len(newTingResults), 'newTingResults', newTingResults)
        return len(newTingResults) > 0, newTingResults
Пример #27
0
    def canTing(self, tiles, leftTiles, tile, magicTiles=[], winSeatId=0):
        """子类必须实现
        参数:
        1)tiles 该玩家的手牌
        2)leftTiles 剩余手牌
        返回值:
        是否可以听牌,听牌详情
        """
        handCount = len(tiles[MHand.TYPE_HAND])
        if handCount < 5:
            return False, []

        isTing, tingResults = MTing.canTing(self.tilePatternChecker,
                                            self.tableTileMgr,
                                            MTile.cloneTiles(tiles), leftTiles,
                                            self.winRuleMgr, tile, magicTiles,
                                            winSeatId)
        ftlog.debug('MTingHaerbinRule.MTing.canTing isTing:', isTing,
                    ' tingResults:', tingResults)
        #         [{'dropTile': 11, 'winNodes': [{'winTile': 1, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [1, 2, 3]]}, {'winTile': 2, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [3, 4, 5], [2, 2]]}, {'winTile': 4, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [2, 3, 4]]}, {'winTile': 5, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [5, 5], [2, 3, 4]]}, {'winTile': 7, 'winTileCount': 1, 'pattern': [[6, 6], [5, 6, 7], [5, 6, 7], [2, 3, 4]]}, {'winTile': 8, 'winTileCount': 1, 'pattern': [[6, 7, 8], [6, 6, 6], [5, 5], [2, 3, 4]]}]}]

        if not isTing:
            return False, []

        chiCount = len(tiles[MHand.TYPE_CHI])
        pengCount = len(tiles[MHand.TYPE_PENG])
        gangCount = len(tiles[MHand.TYPE_GANG])

        mingGangCount = 0
        anGangCount = 0
        #计算明杠个数,因为暗杠不算开门
        if gangCount != 0:
            mingGangCount, anGangCount = MTile.calcGangCount(
                tiles[MHand.TYPE_GANG])
        ftlog.debug('MTingHaerbinRule.gang tiles:', tiles[MHand.TYPE_GANG],
                    ' mingGangCount=', mingGangCount, ' anGangCount=',
                    anGangCount)

        if (chiCount + pengCount + mingGangCount) == 0:
            return False, []

        # 检查刻,刻的来源,碰牌/明杠牌/手牌
        keCount = pengCount + mingGangCount + anGangCount
        # 必须有顺牌
        shunCount = chiCount

        newTingResults = []
        for tingResult in tingResults:
            newWinNodes = []
            winNodes = tingResult['winNodes']
            for winNode in winNodes:
                newTiles = MTile.cloneTiles(tiles)
                newTiles[MHand.TYPE_HAND].remove(tingResult['dropTile'])
                newTiles[MHand.TYPE_HAND].append(winNode['winTile'])
                tileArr = MTile.changeTilesToValueArr(
                    MHand.copyAllTilesToList(newTiles))
                #       ftlog.debug( 'MTingHaerbinRule.canTing tileArr:', tileArr )

                # 清一色不可以听牌/和牌
                if self.getTableConfig(MTDefine.YISE_CAN_TING, 0) != 1:
                    newTileArr = copy.deepcopy(tileArr)
                    newTileArr[MTile.TILE_HONG_ZHONG] = 0
                    colorCount = MTile.getColorCount(newTileArr)
                    if colorCount == 1:
                        # 清一色不能和牌
                        ftlog.debug('MTingHaerbinRule.canTing colorCount:',
                                    colorCount, ' can not win, continue....')
                        continue

                # 检查牌中的幺/九
                # 1软 听牌可以没有19,只要胡牌带19就可以
                # 2硬 听牌时就要有19
                RuanYaoJiuConfig = self.getTableConfig(MTDefine.RUAN_YAO_JIU,
                                                       1)
                if RuanYaoJiuConfig == 0:
                    #硬幺九 :听牌必须有19
                    #tileArr 减去 winNode['winTile'] 后判断
                    tileArr[winNode['winTile']] -= 1
                    yaoCount = tileArr[MTile.TILE_ONE_WAN] + tileArr[
                        MTile.TILE_ONE_TONG] + tileArr[MTile.TILE_ONE_TIAO]
                    jiuCount = tileArr[MTile.TILE_NINE_WAN] + tileArr[
                        MTile.TILE_NINE_TONG] + tileArr[MTile.TILE_NINE_TIAO]
                    zhongCount = tileArr[MTile.TILE_HONG_ZHONG]
                    ftlog.debug('MTingJixiRule.canTing : YING yaoCount:',
                                yaoCount, 'jiuCount', jiuCount, 'zhongCount',
                                zhongCount)
                    if (yaoCount + jiuCount + zhongCount) <= 0:
                        continue
                else:
                    #软幺九 :只要胡牌有19就行
                    yaoCount = tileArr[MTile.TILE_ONE_WAN] + tileArr[
                        MTile.TILE_ONE_TONG] + tileArr[MTile.TILE_ONE_TIAO]
                    jiuCount = tileArr[MTile.TILE_NINE_WAN] + tileArr[
                        MTile.TILE_NINE_TONG] + tileArr[MTile.TILE_NINE_TIAO]
                    zhongCount = tileArr[MTile.TILE_HONG_ZHONG]
                    ftlog.debug('MTingJixiRule.canTing : RUAN yaoCount:',
                                yaoCount, 'jiuCount', jiuCount, 'zhongCount',
                                zhongCount)
                    if (yaoCount + jiuCount + zhongCount) == 0:
                        continue

                patterns = winNode['pattern']
                #夹起步(顺牌只能和夹和3,7) 除单吊
                chunJiaConfig = self.getTableConfig(MTDefine.MIN_MULTI, 0)
                if chunJiaConfig:
                    bianMulti = self.tableConfig.get(MTDefine.BIAN_MULTI, 0)
                    danDiaoJia = self.tableConfig.get(MTDefine.DAN_DIAO_JIA, 1)
                    hasJia = False
                    for pattern in patterns:
                        if winNode['winTile'] in pattern:
                            if len(pattern) == 3 and pattern[0] != pattern[1]:
                                if pattern.index(winNode['winTile']) == 2:
                                    if bianMulti:
                                        if MTile.getValue(
                                                winNode['winTile']) == 3:
                                            hasJia = True
                                            break
                                if pattern.index(winNode['winTile']) == 0:
                                    if bianMulti:
                                        if MTile.getValue(
                                                winNode['winTile']) == 7:
                                            hasJia = True
                                            break

                                if pattern.index(winNode['winTile']) == 1:
                                    hasJia = True
                                    break

                            #单吊
                            if len(pattern) == 2 and pattern[0] == pattern[
                                    1] and danDiaoJia:
                                hasJia = True
                                break

                    if not hasJia:
                        ftlog.debug(
                            'MTingHaerbinRule.canTing :, can not win tile:',
                            winNode['winTile'], ', not has jia continue....')
                        continue

                patterns = winNode['pattern']
                checkKeCount = keCount + self.getKeCount(patterns)
                checkShunCount = shunCount + self.getShunCount(patterns)
                ftlog.debug('MTingHaerbinRule.canTing keCount:', keCount,
                            ' shunCount:', shunCount)

                if checkKeCount and checkShunCount:
                    newWinNodes.append(winNode)

            if len(newWinNodes) > 0:
                newTingResult = {}
                newTingResult['dropTile'] = tingResult['dropTile']
                newTingResult['winNodes'] = newWinNodes
                newTingResults.append(newTingResult)

        return len(newTingResults) > 0, newTingResults
Пример #28
0
 def hasExtendMao(cls, tiles, alreadyHave = 0):
     extendMaos = []
     if alreadyHave & MTDefine.MAO_DAN_DNXBZFB:
         es = []
         for tile in tiles:
             if MTile.isFeng(tile) or MTile.isArrow(tile):
                 es.append(tile)
         if len(es) > 0:
             faNode = {}
             faNode['type'] = MTDefine.MAO_DAN_DNXBZFB
             faNode['extends'] = es
             faNode['name'] = MTDefine.MAO_DAN_DNXBZFB_NAME
             extendMaos.append(faNode)
             
     if alreadyHave & MTDefine.MAO_DAN_DNXB:
         es = []
         for tile in tiles:
             if MTile.isFeng(tile):
                 es.append(tile)
         if len(es) > 0:
             faNode = {}
             faNode['type'] = MTDefine.MAO_DAN_DNXB
             faNode['extends'] = es
             faNode['name'] = MTDefine.MAO_DAN_DNXB_NAME
             extendMaos.append(faNode)
             
     if alreadyHave & MTDefine.MAO_DAN_ZFB:
         es = []
         for tile in tiles:
             if MTile.isArrow(tile):
                 es.append(tile)
         if len(es) > 0:
             faNode = {}
             faNode['type'] = MTDefine.MAO_DAN_ZFB
             faNode['extends'] = es
             faNode['name'] = MTDefine.MAO_DAN_ZFB_NAME
             extendMaos.append(faNode)
             
     if alreadyHave & MTDefine.MAO_DAN_YAO:
         es = []
         for tile in tiles:
             if MTile.getValue(tile) == 1:
                 es.append(tile)
         if len(es) > 0:
             faNode = {}
             faNode['type'] = MTDefine.MAO_DAN_YAO
             faNode['extends'] = es
             faNode['name'] = MTDefine.MAO_DAN_YAO_NAME
             extendMaos.append(faNode)
             
     if alreadyHave & MTDefine.MAO_DAN_JIU:
         es = []
         for tile in tiles:
             if MTile.getValue(tile) == 9:
                 es.append(tile)
         if len(es) > 0:
             faNode = {}
             faNode['type'] = MTDefine.MAO_DAN_JIU
             faNode['extends'] = es
             faNode['name'] = MTDefine.MAO_DAN_JIU_NAME
             extendMaos.append(faNode)
             
     return extendMaos
Пример #29
0
 def hasChi(self, tiles, tile):
     """是否有吃牌解
     
     参数说明;
     tiles - 玩家的所有牌,包括手牌,吃牌,碰牌,杠牌,胡牌
     tile - 待吃的牌
     """
     if tile >= MTile.TILE_DONG_FENG:
         return []
     
     #是否允许会牌参与,如果不允许,删除会牌
     tilesForChi = copy.deepcopy(tiles[MHand.TYPE_HAND])
     if not self.tableTileMgr.allowMagicChiPengGang():
         magicTile = self.tableTileMgr.getMagicTile()
         while magicTile in tilesForChi:
             tilesForChi.remove(magicTile)
     
     chiSolutions = MChi.hasChi(tilesForChi, tile)
     magicTiles = self.tableTileMgr.getMagicTiles(False)
     if len(magicTiles) == 0:
         return chiSolutions
     
     if not self.tableTileMgr.canUseMagicTile(MTableState.TABLE_STATE_CHI):
         return chiSolutions
     
     magicTile = magicTiles[0]
     tileArr = MTile.changeTilesToValueArr(tiles[MHand.TYPE_HAND])
     magicCount = tileArr[magicTile]
     tileArr[magicTile] = 0
     ftlog.debug('MChiRule.hasChi tile:', tile, ' magicCount:', magicCount)
     
     if magicCount == 0 or (tileArr[tile] == 0):
         return chiSolutions
     
     if MTile.getValue(tile) <= 7:
         # +1[-] +2[+] ==> [tile, magic, tile+2]
         if tileArr[tile + 1] == 0 and tileArr[tile + 2] > 0:
             chiSolutions.append([tile, magicTile, tile + 2])
             
         # +1[+] +2[-] ==> [tile, tile + 1, magicTile]
         if tileArr[tile + 1] > 0 and tileArr[tile + 2] == 0:
             chiSolutions.append([tile, tile + 1, magicTile])
             
         if (tileArr[tile + 1] + tileArr[tile + 2]) == 0 and magicCount >= 2:
             chiSolutions.append([tile, magicTile, magicTile])
             
     if MTile.getValue(tile) >= 3:
         # -2[+] -1[-] ==> [tile - 2, magicTile, tile]
         if tileArr[tile - 2] > 0 and tileArr[tile - 1] == 0:
             chiSolutions.append([tile - 2, magicTile, tile])
             
         # -2[0] -1[+] ==> [magicTile, tile - 1, tile]
         if tileArr[tile - 2] == 0 and tileArr[tile - 1] > 0:
             chiSolutions.append([magicTile, tile - 1, tile])
             
         if (tileArr[tile - 2] + tileArr[tile - 1]) == 0 and magicCount >= 2:
             chiSolutions.append([magicTile, magicTile, tile])
             
             
     if MTile.getValue(tile) >= 2 and MTile.getValue(tile) <= 8:
         # -1[-] 1[+] ==> magicTile, tile, tile + 1
         if tileArr[tile - 1] == 0 and tileArr[tile + 1] > 0:
             chiSolutions.append([magicTile, tile, tile + 1])
             
         # -1[+] 1[-] ==> [tile - 1, tile, magicTile]
         if tileArr[tile - 1] > 0 and tileArr[tile + 1] == 0:
             chiSolutions.append([tile - 1, tile, magicTile])
             
         if (tileArr[tile + 1] + tileArr[tile - 1]) == 0 and magicCount >= 2:
             chiSolutions.append([magicTile, tile, magicTile])
             
     return chiSolutions