コード例 #1
0
    def isJipinghu(self, pattern, tiles, tileArr, magicTiles):

        useforColor = tileArr
        if len(magicTiles) > 0:
            useforColor[magicTiles[0]] = 0

        hasfeng = 0
        for tile in MTile.traverseTile(MTile.TILE_FENG):
            if tileArr[tile]:
                hasfeng += 1
                break
        if MTile.getColorCount(useforColor) - hasfeng <= 1:
            return False

        kecount = 0
        shuncount = 0
        bothok = 0
        for p in pattern:
            if len(p) == 3:
                magiccount = 0
                for x in p:
                    if len(magicTiles) > 0 and x == magicTiles[0]:
                        magiccount += 1
                if magiccount >= 2:
                    bothok += 1
                else:
                    if p[0] == p[1] or p[0] == p[2] or p[1] == p[2]:
                        kecount += 1
                    else:
                        shuncount += 1

        kecount += len(tiles[MHand.TYPE_PENG])
        kecount += len(tiles[MHand.TYPE_GANG])

        ftlog.debug('MWinRuleJiPingHu.isJipinghu kecount:', kecount, 'shuncount:', shuncount, 'bothok:', bothok)

        # 排除掉碰碰胡
        if shuncount == 0:
            return False
        # 排除掉三元
        haszhong = 0
        for tile in [35, 36, 37]:
            if tileArr[tile] > 0:
                haszhong += 1
        if haszhong == 3:
            return False
        # 排除掉四喜
        hasfeng = 0
        for tile in [31, 32, 33, 34]:
            if tileArr[tile] > 0:
                hasfeng += 1
        if hasfeng == 4:
            return False

        if shuncount > 0 and kecount > 0:
            ftlog.debug('MWinRuleJiPingHu.isJipinghu True')
            return True

        return False
コード例 #2
0
 def getCardNumByType(cls, tileArr, tileType):
     """
     获取某一个花色的张数
     """
     num = 0
     for tile in MTile.traverseTile(tileType):
         num += tileArr[tile]
     return num
コード例 #3
0
    def getBestDropTile(cls,
                        tiles_player_hand,
                        tiles_left,
                        playMode,
                        tile,
                        isTing,
                        magicTiles,
                        absenceColor,
                        tingRule=None,
                        seatId=0):
        """
        手牌的价值,根据玩家自己的手牌和已经出的牌,计算手牌价值
        参数:
            tiles_player_hand - 用户的手牌
            tiles_droped - 牌桌上已经打出的牌和玩家手里已经成型的牌,这部分牌不再参与计算牌的可能性
        计算方法:
        1)没有的手牌,权值为0
        2)有的手牌,初始权值为4 * count + 1 * left
        3)左右相邻的手牌,增加权重 3 * count
        4)左右隔一张的手牌,增加权重 2 * count
        """
        ftlog.debug('MTileValue.getBestDropTile tiles_player_hand:',
                    tiles_player_hand, ' tiles_left:', tiles_left,
                    ' playMode:', playMode, ' tile:', tile, ' isTing:', isTing,
                    ' magicTiles:', magicTiles, ' tingRule:', tingRule,
                    ' seatId:', seatId)

        if isTing:
            # 听牌后,直接打出摸到的牌
            return tile, 0

        tiles_value_Arr, tiles_player_Arr = cls.getHandTilesValue(
            tiles_player_hand, tiles_left)
        # 放大癞子牌的作用
        for mTile in magicTiles:
            tiles_value_Arr[mTile] = tiles_value_Arr[mTile] * 100

        # 如果有一门花色大于9张牌,放大该门花色牌的价值,便于去做清一色番型
        allTiles = MHand.copyAllTilesToList(tiles_player_hand)
        wans = MTile.filterTiles(allTiles, MTile.TILE_WAN)
        if len(wans) >= 9:
            for tile in MTile.traverseTile(MTile.TILE_WAN):
                tiles_value_Arr[tile] += 10

        tongs = MTile.filterTiles(allTiles, MTile.TILE_TONG)
        if len(tongs) >= 9:
            for tile in MTile.traverseTile(MTile.TILE_TONG):
                tiles_value_Arr[tile] += 10

        tiaos = MTile.filterTiles(allTiles, MTile.TILE_TIAO)
        if len(tiaos) >= 9:
            for tile in MTile.traverseTile(MTile.TILE_TIAO):
                tiles_value_Arr[tile] += 10

        fengs = MTile.filterTiles(allTiles, MTile.TILE_FENG)
        if len(fengs) >= 9:
            for tile in MTile.traverseTile(MTile.TILE_FENG):
                tiles_value_Arr[tile] += 10

        # 减小缺牌的作用
        for tile in range(len(tiles_value_Arr)):
            if MTile.getColor(tile) == absenceColor:
                tiles_value_Arr[tile] -= 100

        # [{'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 tingRule:
            canTing, tingResults = tingRule.canTing(tiles_player_hand,
                                                    tiles_left, tile,
                                                    magicTiles)
            ftlog.debug(canTing)
            ftlog.debug(tingResults)

            if canTing:
                for tingResult in tingResults:
                    dropTile = tingResult['dropTile']
                    winNodes = tingResult['winNodes']
                    outs = 0
                    for winNode in winNodes:
                        outs += winNode['winTileCount']
                    tiles_value_Arr[dropTile] = (0 - outs)

        minTile = 0
        minValue = 0
        for index in range(MTile.TILE_MAX_VALUE):
            if tiles_player_Arr[index] > 0:
                if minTile == 0:
                    minTile = index
                    minValue = tiles_value_Arr[index]
                    continue

                if minValue > tiles_value_Arr[index]:
                    minValue = tiles_value_Arr[index]
                    minTile = index

        ftlog.debug('MTileValue.getBestDropTile minTile:', minTile,
                    ' tileValue:', tiles_value_Arr[minTile])
        return minTile, tiles_value_Arr[minTile]
コード例 #4
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
コード例 #5
0
    def getBestDropTile(self,
                        tiles_player_hand,
                        tiles_left,
                        tile,
                        isTing,
                        magicTiles,
                        absenceColor,
                        tingRule=None):
        """
        手牌的价值,根据玩家自己的手牌和已经出的牌,计算手牌价值
        参数:
            tiles_player_hand - 用户的手牌
            tiles_droped - 牌桌上已经打出的牌和玩家手里已经成型的牌,这部分牌不再参与计算牌的可能性
        计算方法:
        1)没有的手牌,权值为0
        2)有的手牌,初始权值为4 * count + 1 * left
        3)左右相邻的手牌,增加权重 3 * count
        4)左右隔一张的手牌,增加权重 2 * count
        """
        ftlog.debug(
            'MDropCardStrategyJipinghu.getBestDropTile tiles_player_hand:',
            tiles_player_hand, ' tiles_left:', tiles_left, ' tile:', tile,
            ' isTing:', isTing, ' magicTiles:', magicTiles, ' absenceColor:',
            absenceColor, ' tingRule:', tingRule)

        if isTing:
            # 听牌后,直接打出摸到的牌
            return tile, 0

        doQing, qingColor = self.doQingYiSe(tiles_player_hand, tiles_left)
        tiles_value_Arr, tiles_player_Arr = MTileValue.getHandTilesValue(
            tiles_player_hand, tiles_left)
        # 放大癞子牌的作用
        for mTile in magicTiles:
            tiles_value_Arr[mTile] = tiles_value_Arr[mTile] * 100

        # 如果有一门花色大于9张牌,放大该门花色牌的价值,便于去做清一色番型
        if doQing:
            for tile in MTile.traverseTile(qingColor):
                tiles_value_Arr[tile] += 10

        # 减小缺牌的作用
        for tile in range(len(tiles_value_Arr)):
            if MTile.getColor(tile) == absenceColor:
                tiles_value_Arr[tile] -= 100
                continue

            if doQing and MTile.getColor(tile) != qingColor:
                tiles_value_Arr[tile] -= 10
                continue

        # [{'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 tingRule:
            canTing, tingResults = tingRule.canTing(tiles_player_hand,
                                                    tiles_left, tile,
                                                    magicTiles)
            ftlog.debug(canTing)
            ftlog.debug(tingResults)

            if canTing:
                totalValue = 0
                for tingResult in tingResults:
                    dropTile = tingResult['dropTile']
                    winNodes = tingResult['winNodes']
                    for winNode in winNodes:
                        totalValue += winNode['winTileCount'] * winNode[
                            'winFan']

                for tingResult in tingResults:
                    dropTile = tingResult['dropTile']
                    winNodes = tingResult['winNodes']
                    dropValue = 0
                    for winNode in winNodes:
                        dropValue += winNode['winTileCount'] * winNode['winFan']
                    tiles_value_Arr[dropTile] = (totalValue - dropValue)

                    if doQing and (MTile.getColor(dropTile) == qingColor) and (
                            tiles_value_Arr[dropTile] != -4):
                        # 优先打出非清一色颜色的上听牌
                        tiles_value_Arr[dropTile] += (totalValue /
                                                      len(tingResults))

                ftlog.debug(
                    'MDropCardStrategyJipinghu.getBestDropTile adjust tileValue by ting:',
                    tiles_value_Arr, ' tingResults:', tingResults,
                    ' totalValue:', totalValue)

        minTile = 0
        minValue = 0
        for index in range(MTile.TILE_MAX_VALUE):
            if tiles_player_Arr[index] > 0:
                if minTile == 0:
                    minTile = index
                    minValue = tiles_value_Arr[index]
                    continue

                if minValue > tiles_value_Arr[index]:
                    minValue = tiles_value_Arr[index]
                    minTile = index

        ftlog.debug('MDropCardStrategyJipinghu.getBestDropTile minTile:',
                    minTile, ' tileValue:', tiles_value_Arr[minTile])
        return minTile, tiles_value_Arr[minTile]
コード例 #6
0
    def getBestDropTile(self,
                        tiles_player_hand,
                        tiles_left,
                        tile,
                        isTing,
                        magicTiles,
                        extend={}):
        """
        手牌的价值,根据玩家自己的手牌和已经出的牌,计算手牌价值
        参数:
            tiles_player_hand - 用户的手牌
            tiles_droped - 牌桌上已经打出的牌和玩家手里已经成型的牌,这部分牌不再参与计算牌的可能性
        计算方法:
        1)没有的手牌,权值为0
        2)有的手牌,初始权值为4 * count + 1 * left
        3)左右相邻的手牌,增加权重 3 * count
        4)左右隔一张的手牌,增加权重 2 * count
        """
        ftlog.debug(
            'MDropCardStrategyXuezhan.getBestDropTile tiles_player_hand:',
            tiles_player_hand, ' tiles_left:', tiles_left, ' tile:', tile,
            ' isTing:', isTing, ' magicTiles:', magicTiles, ' extend:', extend)

        if isTing:
            # 听牌后,直接打出摸到的牌
            return tile, 0

        tiles_value_Arr, tiles_player_Arr = MTileValue.getHandTilesValue(
            tiles_player_hand, tiles_left)

        # 如果有缺牌,打出缺牌
        seatId = extend.get('seatId', 0)
        abColors = extend.get('absenceColor', [])
        absenceColor = MTile.TILE_FENG
        if len(abColors) > 0:
            absenceColor = abColors[seatId]

        abMinTile = 0
        abMinValue = 0
        for tile in MTile.traverseTile(absenceColor):
            if tiles_player_Arr[tile] > 0:
                if abMinTile == 0:
                    abMinTile = tile
                    abMinValue = tiles_value_Arr[tile]
                    continue

                if abMinValue > tiles_value_Arr[tile]:
                    abMinValue = tiles_value_Arr[tile]
                    abMinTile = tile
        if abMinTile:
            ftlog.debug('has Absence, drop the min absence tile:', abMinTile,
                        ' abMinValue:', abMinValue)
            return abMinTile, abMinValue

        seatId = extend.get('seatId', None)
        abColors = extend.get('absenceColor', None)
        doQing, qingColor = self.doQingYiSe(tiles_player_hand, tiles_left,
                                            seatId, abColors)
        # 放大癞子牌的作用
        for mTile in magicTiles:
            tiles_value_Arr[mTile] = tiles_value_Arr[mTile] * 100

        # 如果有一门花色大于9张牌,放大该门花色牌的价值,便于去做清一色番型
        if doQing:
            colors = [MTile.TILE_WAN, MTile.TILE_TONG, MTile.TILE_TIAO]
            colors.remove(absenceColor)
            colors.remove(qingColor)
            dMinTiles = []
            dMinValue = 0
            for tile in MTile.traverseTile(colors[0]):
                if tiles_player_Arr[tile] > 0:
                    if len(dMinTiles) == 0:
                        dMinValue = tiles_value_Arr[tile]
                        dMinTiles.append(tile)
                        continue

                    if dMinValue > tiles_value_Arr[tile]:
                        dMinValue = tiles_value_Arr[tile]
                        dMinTiles = [tile]
                    elif dMinValue == tiles_value_Arr[tile]:
                        dMinTiles.append(tile)

            if len(dMinTiles) > 0:
                ftlog.debug('doQingYiSe, qingColor:', qingColor, ' dMinTiles:',
                            dMinTiles, ' dMinValue:', dMinValue)
                return self.chooseBestDropTile(dMinTiles, tiles_left,
                                               qingColor), dMinValue

        tingRule = extend.get('tingRule', None)
        # [{'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 tingRule:
            canTing, tingResults = tingRule.canTing(tiles_player_hand,
                                                    tiles_left, tile,
                                                    magicTiles)
            ftlog.debug(canTing)
            ftlog.debug(tingResults)

            if canTing:
                totalValue = 0
                for tingResult in tingResults:
                    # 对dropTile的价值重新考虑
                    dropTile = tingResult['dropTile']
                    tiles_value_Arr[dropTile] = 0

                    winNodes = tingResult['winNodes']
                    for winNode in winNodes:
                        totalValue += winNode['winTileCount'] * winNode[
                            'winFan']

                for tingResult in tingResults:
                    dropTile = tingResult['dropTile']
                    winNodes = tingResult['winNodes']
                    dropValue = 0
                    for winNode in winNodes:
                        dropValue += winNode['winTileCount'] * winNode['winFan']
                    tiles_value_Arr[dropTile] += (-dropValue)

                    if doQing and (MTile.getColor(dropTile) == qingColor):
                        # 优先打出非清一色颜色的上听牌
                        tiles_value_Arr[dropTile] += (totalValue /
                                                      len(tingResults))

                    ftlog.debug(
                        'MDropCardStrategyXuezhan.getBestDropTile dropTile:',
                        dropTile, ' dropTileValue:', tiles_value_Arr[dropTile])

                ftlog.debug(
                    'MDropCardStrategyXuezhan.getBestDropTile adjust tileValue by ting:',
                    tiles_value_Arr, ' tingResults:', tingResults,
                    ' totalValue:', totalValue)

        minTiles = []
        minValue = 0
        for index in range(MTile.TILE_MAX_VALUE):
            if tiles_player_Arr[index] > 0:
                if (len(minTiles) == 0) or (minValue > tiles_value_Arr[index]):
                    minValue = tiles_value_Arr[index]
                    minTiles = [index]
                elif minValue == tiles_value_Arr[index]:
                    minTiles.append(index)

        ftlog.debug('MDropCardStrategyJipinghu.getBestDropTile minTiles:',
                    minTiles, ' tileValue:', minValue)
        return self.chooseBestDropTile(minTiles, tiles_left,
                                       qingColor), minValue
コード例 #7
0
    def getBestDropTile(self,
                        tiles_player_hand,
                        tiles_left,
                        tile,
                        isTing,
                        magicTiles,
                        extend={}):
        """
        手牌的价值,根据玩家自己的手牌和已经出的牌,计算手牌价值
        参数:
            tiles_player_hand - 用户的手牌
            tiles_droped - 牌桌上已经打出的牌和玩家手里已经成型的牌,这部分牌不再参与计算牌的可能性
        计算方法:
        1)没有的手牌,权值为0
        2)有的手牌,初始权值为4 * count + 1 * left
        3)左右相邻的手牌,增加权重 3 * count
        4)左右隔一张的手牌,增加权重 2 * count
        
        该套策略可用于推倒胡
        """
        if isTing:
            # 听牌后,直接打出摸到的牌
            ftlog.debug('alReady ting, drop tile directly:', tile)
            return tile, 0

        tiles_value_Arr, tiles_player_Arr = MTileValue.getHandTilesValue(
            tiles_player_hand, tiles_left)

        # 如果有缺牌,打出缺牌
        seatId = extend.get('seatId', 0)
        abColors = extend.get('absenceColor', [])
        absenceColor = MTile.TILE_FENG
        if len(abColors) > 0:
            absenceColor = abColors[seatId]

        abMinTile = 0
        abMinValue = 0
        for tile in MTile.traverseTile(absenceColor):
            if tiles_player_Arr[tile] > 0:
                if abMinTile == 0:
                    abMinTile = tile
                    abMinValue = tiles_value_Arr[tile]
                    continue

                if abMinValue > tiles_value_Arr[tile]:
                    abMinValue = tiles_value_Arr[tile]
                    abMinTile = tile
        if abMinTile:
            ftlog.debug('has Absence, drop the min absence tile:', abMinTile,
                        ' abMinValue:', abMinValue)
            return abMinTile, abMinValue

        # 放大癞子牌的作用
        for mTile in magicTiles:
            tiles_value_Arr[mTile] = tiles_value_Arr[mTile] * 100

        tingRule = extend.get('tingRule', None)
        # [{'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 tingRule:
            canTing, tingResults = tingRule.canTing(tiles_player_hand,
                                                    tiles_left, tile,
                                                    magicTiles)
            ftlog.debug(canTing)
            ftlog.debug(tingResults)

            if canTing:
                totalValue = 0

                for tingResult in tingResults:
                    dropTile = tingResult['dropTile']
                    tiles_value_Arr[dropTile] = 0

                    winNodes = tingResult['winNodes']
                    for winNode in winNodes:
                        totalValue += winNode['winTileCount'] * winNode[
                            'winFan']

                for tingResult in tingResults:
                    dropTile = tingResult['dropTile']
                    winNodes = tingResult['winNodes']
                    dropValue = 0
                    for winNode in winNodes:
                        dropValue += winNode['winTileCount'] * winNode['winFan']
                    tiles_value_Arr[dropTile] += (-dropValue)

        minTile = 0
        minValue = 0
        for index in range(MTile.TILE_MAX_VALUE):
            if tiles_player_Arr[index] > 0:
                if minTile == 0:
                    minTile = index
                    minValue = tiles_value_Arr[index]
                    continue

                if minValue >= tiles_value_Arr[index]:
                    # 优先打高数值的牌,风
                    minValue = tiles_value_Arr[index]
                    minTile = index

        ftlog.debug('MDropCardStrategy.getBestDropTile ', ' tile:', tile,
                    ' magicTiles:', magicTiles, ' isTing:', isTing,
                    ' tiles_player_hand:', tiles_player_hand, ' tileValues:',
                    tiles_value_Arr, ' tiles_left:', tiles_left, ' minTile:',
                    minTile, ' minTileValue:', minValue)

        return minTile, tiles_value_Arr[minTile]