示例#1
0
    def getHandTilesValue(cls, tiles_player_hand, tiles_left):
        """计算手牌价值
        
        返回值:
        1)每张牌的价值
        2)手牌花色个数的数组
        """
        tiles_player_Arr = MTile.changeTilesToValueArr(tiles_player_hand[MHand.TYPE_HAND])
        tiles_left_Arr = MTile.changeTilesToValueArr(tiles_left)

        # 权值初始化    
        tiles_value_Arr = [0 for _ in range(40)]
        for index in range(MTile.TILE_MAX_VALUE):
            if tiles_player_Arr[index] == 0:
                continue
            tiles_value_Arr[index] = tiles_player_Arr[index] * 4 + tiles_left_Arr[index]
            if index < 30:
                if index % 10 < 9:
                    tiles_value_Arr[index] += tiles_player_Arr[index + 1] * 3
                if index % 10 < 8:
                    tiles_value_Arr[index] += tiles_player_Arr[index + 2] * 2
                if index % 10 > 1:
                    tiles_value_Arr[index] += tiles_player_Arr[index - 1] * 3
                if index % 10 > 2:
                    tiles_value_Arr[index] += tiles_player_Arr[index - 2] * 2

        return tiles_value_Arr, tiles_player_Arr
示例#2
0
    def isPairs(cls, tiles, magicTiles):
        if len(tiles[MHand.TYPE_CHI]) != 0:
            return False
        if len(tiles[MHand.TYPE_PENG]) != 0:
            return False
        if len(tiles[MHand.TYPE_GANG]) != 0:
            return False
        pairTiles = copy.deepcopy(tiles[MHand.TYPE_HAND])

        haveMagicCount = 0
        for magicTile in magicTiles:
            while magicTile in pairTiles:
                pairTiles.remove(magicTile)
                haveMagicCount += 1
        ftlog.debug("win_rule_zhaotong::isPairs pairTiles = ", pairTiles, "haveMagicCount =", haveMagicCount)
        tileArr = MTile.changeTilesToValueArr(pairTiles)
        for count in tileArr:
            if count % 2 == 0:
                continue
            else:
                if haveMagicCount <= 0:
                    return False
                else:
                    haveMagicCount -= 1
                    continue
        return True
示例#3
0
    def isPiao(self):
        playerChiTiles = self.playerAllTiles[self.winSeatId][MHand.TYPE_CHI]
        if len(playerChiTiles) > 0:
            return False

        isHasKe = False
        playerPengTiles = self.playerAllTiles[self.winSeatId][MHand.TYPE_PENG]
        if len(playerPengTiles) > 0:
            isHasKe = True

        playerGangTiles = self.playerAllTiles[self.winSeatId][MHand.TYPE_GANG]
        if len(playerGangTiles) > 0:
            isHasKe = True

        playerHandTiles = self.playerAllTiles[self.winSeatId][MHand.TYPE_HAND]
        newPlayerHandTiles = MTile.cloneTiles(playerHandTiles)
        newPlayerHandTilesArr = MTile.changeTilesToValueArr(newPlayerHandTiles)
        for playerHandTileCount in newPlayerHandTilesArr:
            if playerHandTileCount == 3:
                isHasKe = True
                break

        if not isHasKe:
            return False

        for wn in self.winNodes:
            # if wn['winTile'] == self.winTile:
            patterns = wn['pattern']
            ftlog.debug('MJixiOneResult.isPiao winTile:', self.winTile, ' winPatterns:', patterns)
            for p in patterns:
                if len(p) == 3 and p[0] != p[1]:
                    return False

        return True
示例#4
0
文件: chi.py 项目: zhaozw/hall37
    def hasChi(cls, tiles, tile):
        """是否可以吃
        吃牌的判断中,tile已经在tiles中
        参数:
            tiles - 手牌
            tile - 待吃的牌
        返回值:吃牌选择
            最多三种解
            
        例子:
            [[2, 3, 4], [3, 4, 5], [4, 5, 6
        """
        tileArr = MTile.changeTilesToValueArr(tiles)
        result = []
        # 第一种情况 001
        if (tile % 10) >= 3:
            if tileArr[tile - 2] > 0 and tileArr[tile - 1] > 0 and tileArr[tile] > 0:
                solution = [tile - 2, tile - 1, tile]
                result.append(solution)

        # 第二种情况 010
        if (tile % 10) >= 2 and (tile % 10) < 9:
            if tileArr[tile - 1] > 0 and tileArr[tile] > 0 and tileArr[tile + 1] > 0:
                solution = [tile - 1, tile, tile + 1]
                result.append(solution)

        # 第三种情况 100
        if (tile % 10) < 8:
            if tileArr[tile] > 0 and tileArr[tile + 1] > 0 and tileArr[tile + 2] > 0:
                solution = [tile, tile + 1, tile + 2]
                result.append(solution)

        return result
示例#5
0
文件: win.py 项目: zhaozw/hall37
    def isHu(cls, hand_tiles, magicTiles=list()):
        """
        胡牌判断,只判断手牌,杠牌,吃牌,碰牌不在内
           杠牌、吃牌、碰牌已成型,不用另外计算
        * 肯定包含将牌
        * 剩下的牌里不会有暗杠牌
        * 杠牌/吃牌/碰牌是已经成型的牌,按成型的样式计算积分,不再重新计算
        :param magicTiles 赖子牌
        :return 是否胡了
        """
        tileArr = MTile.changeTilesToValueArr(hand_tiles)
        magicArr = []
        for magicTile in magicTiles:
            magicArr.extend([magicTile for _ in range(tileArr[magicTile])])
            tileArr[magicTile] = 0

        resultArr = []
        tileTypes = [MTile.TILE_WAN, MTile.TILE_TONG, MTile.TILE_TIAO, MTile.TILE_FENG]
        hasJiang = False
        winResult = False

        for tileType in tileTypes:
            winResult, hasJiang, _tArr, _rArr, _mArr = cls.isHuWithMagic(tileArr, resultArr, magicArr, hasJiang,
                                                                         tileType)
            if not winResult:
                return False, []
            else:
                tileArr = copy.deepcopy(_tArr)
                resultArr = copy.deepcopy(_rArr)
                magicArr = copy.deepcopy(_mArr)

        if winResult and not hasJiang and len(magicArr) >= 2:
            hasJiang = True
        return hasJiang and winResult, resultArr
示例#6
0
 def hasPeng(cls, tiles, tile):
     """
     是否可以碰
     判断之前tile已经加到tiles中
     tiles - 手牌
     tile - 待碰的牌
     """
     tileArr = MTile.changeTilesToValueArr(tiles)
     if tileArr[tile] >= 3:
         return True
     return False
示例#7
0
    def isHu(self, tiles, tile, isTing, getTileType, magicTiles=list(), tingNodes=list()):
        result, rePattern = MWin.isHu(tiles[MHand.TYPE_HAND])
        if not result:
            return False, []

        # 分析花色
        tileArr = MTile.changeTilesToValueArr(MHand.copyAllTilesToList(tiles))
        colors = MTile.getColorCount(tileArr)
        ftlog.debug('MWinRuleSichuan.isHu colors:', colors)

        if colors <= 2:
            # 花色缺门,可以和
            return True, rePattern
        return False, []
示例#8
0
    def hasPeng(self, tiles, tile):
        """
        是否有碰牌解
        
        参数说明;
        tiles - 玩家的所有牌,包括手牌,吃牌,碰牌,杠牌,胡牌
        tile - 待碰的牌
        """
        pengSolutions = []
        normalPeng = MPeng.hasPeng(tiles[MHand.TYPE_HAND], tile)
        if normalPeng:
            pengSolutions.append([tile, tile, tile])

        magics = self.tableTileMgr.getMagicTiles(False)
        tileArr = MTile.changeTilesToValueArr(tiles[MHand.TYPE_HAND])
        tileArr, magicTiles = self.tableTileMgr.exculeMagicTiles(
            tileArr, magics)
        magicCount = len(magicTiles)
        if magicCount == 0:
            return pengSolutions

        if not self.tableTileMgr.canUseMagicTile(MTableState.TABLE_STATE_PENG):
            return pengSolutions

        magicPengMaxCount = self.tableTileMgr.magicPengMaxCount
        if magicPengMaxCount > 3 or magicPengMaxCount < 0:
            magicPengMaxCount = 3

        ftlog.debug('MPengRule.hasPeng tile:', tile, ' tileCount:',
                    tileArr[tile], ' magicCount:', magicCount,
                    'magicPengMaxCount', magicPengMaxCount)

        if (magicCount == 0) or (tileArr[tile]
                                 == 0) or (magicPengMaxCount <= 0):
            return pengSolutions

        if magicCount >= 1 and tileArr[tile] >= 2 and magicPengMaxCount >= 1:
            # 使用一个癞子
            pattern1 = [tile, tile, magicTiles[0]]
            pattern1.sort()
            pengSolutions.append(pattern1)

        if magicCount >= 2 and tileArr[tile] >= 1 and magicPengMaxCount >= 2:
            # 使用两个癞子
            pattern2 = [tile, magicTiles[0], magicTiles[1]]
            pattern2.sort()
            pengSolutions.append(pattern2)

        return pengSolutions
示例#9
0
    def isWuDuiHu(self, allTiles, winTile):
        huSeatId = -1
        for seatId, playerTiles in enumerate(allTiles):
            handTiles = playerTiles[MHand.TYPE_HAND]
            handTilesArr = MTile.changeTilesToValueArr(handTiles)
            huSeatId = seatId
            for handTile in handTiles:
                if handTilesArr[handTile] >= 2:
                    huSeatId = -1
                    break

        if huSeatId >= 0:
            return True, huSeatId

        return False, -1
示例#10
0
    def isWuDuiHu(self, allTiles, winTile):
        huSeatId = -1
        for seatId, playerTiles in enumerate(allTiles):
            handTiles = playerTiles[MHand.TYPE_HAND]
            handTilesArr = MTile.changeTilesToValueArr(handTiles)
            huSeatId = seatId
            for handTile in handTiles:
                if handTilesArr[handTile] >= 2:
                    huSeatId = -1
                    break

        if huSeatId >= 0:
            return True, huSeatId

        return False, -1
示例#11
0
 def isPairsCheck(self, tiles, magicTiles):
     """判断七对型胡牌"""
     # 不能吃碰杠
     if len(tiles[MHand.TYPE_CHI]) != 0:
         return False, 0, 0, 0, 0
     if len(tiles[MHand.TYPE_PENG]) != 0:
         return False, 0, 0, 0, 0
     if len(tiles[MHand.TYPE_GANG]) != 0:
         return False, 0, 0, 0, 0
     # 用赖子给其他牌配对
     pairTiles = copy.deepcopy(tiles[MHand.TYPE_HAND])
     fourCount = 0
     specialFourCount = 0
     twoCount = 0
     haveMagicCount = 0
     for magicTile in magicTiles:
         while magicTile in pairTiles:
             pairTiles.remove(magicTile)
             haveMagicCount += 1
     tileArr = MTile.changeTilesToValueArr(pairTiles)
     for count in tileArr:
         if count % 2 == 0:
             if count == 4:
                 fourCount += 1
             elif count == 2:
                 twoCount += 1
             continue
         else:
             if haveMagicCount <= 0:
                 return False, 0, 0, 0, 0
             else:
                 haveMagicCount -= 1
                 if count == 3:
                     specialFourCount += 1
                     fourCount += 1
                 elif count == 1:
                     twoCount += 1
                 continue
     # 配对结束,赖子必须剩偶数个
     if haveMagicCount % 2 == 0:
         # 尽量凑4个的
         while haveMagicCount >= 2 and twoCount >= 1:
             twoCount -= 1
             specialFourCount += 1
             fourCount += 1
             haveMagicCount -= 2
         return True, haveMagicCount, fourCount, twoCount, specialFourCount
     return False, 0, 0, 0, 0
示例#12
0
    def hasPeng(self, tiles, tile):
        """
        是否有碰牌解
        
        参数说明;
        tiles - 玩家的所有牌,包括手牌,吃牌,碰牌,杠牌,胡牌
        tile - 待碰的牌
        """
        pengSolutions = []
        normalPeng = MPeng.hasPeng(tiles[MHand.TYPE_HAND], tile)
        if normalPeng:
            pengSolutions.append([tile, tile, tile])

        magics = self.tableTileMgr.getMagicTiles(False)
        tileArr = MTile.changeTilesToValueArr(tiles[MHand.TYPE_HAND])
        tileArr, magicTiles = self.tableTileMgr.exculeMagicTiles(tileArr, magics)
        magicCount = len(magicTiles)
        if magicCount == 0:
            return pengSolutions

        if not self.tableTileMgr.canUseMagicTile(MTableState.TABLE_STATE_PENG):
            return pengSolutions

        magicPengMaxCount = self.tableTileMgr.magicPengMaxCount
        if magicPengMaxCount > 3 or magicPengMaxCount < 0:
            magicPengMaxCount = 3

        ftlog.debug('MPengRule.hasPeng tile:', tile
                    , ' tileCount:', tileArr[tile]
                    , ' magicCount:', magicCount
                    , 'magicPengMaxCount', magicPengMaxCount)

        if (magicCount == 0) or (tileArr[tile] == 0) or (magicPengMaxCount <= 0):
            return pengSolutions

        if magicCount >= 1 and tileArr[tile] >= 2 and magicPengMaxCount >= 1:
            # 使用一个癞子
            pattern1 = [tile, tile, magicTiles[0]]
            pattern1.sort()
            pengSolutions.append(pattern1)

        if magicCount >= 2 and tileArr[tile] >= 1 and magicPengMaxCount >= 2:
            # 使用两个癞子
            pattern2 = [tile, magicTiles[0], magicTiles[1]]
            pattern2.sort()
            pengSolutions.append(pattern2)

        return pengSolutions
示例#13
0
    def isQiDui(self):
        playerChiTiles = self.playerAllTiles[self.winSeatId][MHand.TYPE_CHI]
        if len(playerChiTiles) > 0:
            return False

        playerPengTiles = self.playerAllTiles[self.winSeatId][MHand.TYPE_PENG]
        if len(playerPengTiles) > 0:
            return False

        playerGangTiles = self.playerAllTiles[self.winSeatId][MHand.TYPE_GANG]
        if len(playerGangTiles) > 0:
            return False

        for wn in self.winNodes:
            if wn['winTile'] == self.winTile:
                patterns = wn['pattern']
                ftlog.debug('MJixiOneResult.isQiDui winTile:', self.winTile, ' winPatterns:', patterns)
                for p in patterns:
                    if len(p) == 3:
                        return False

        # 宝牌情况
        if self.isMagicTile():
            for wn in self.winNodes:
                winTile = wn['winTile']
                patterns = wn['pattern']
                for p in patterns:
                    if (winTile in p) and len(p) == 3:
                        return False

        handTiles = self.playerAllTiles[self.winSeatId][MHand.TYPE_HAND]
        newHandTiles = MTile.cloneTiles(handTiles)
        ftlog.debug('MTingJixiRule.MTing.canTing isQiDui handTiles:', handTiles, 'isMagic:', self.isMagicTile(),
                    'winTile:', self.winTile)
        newHandTiles.append(self.winTile)
        handTilesArr = MTile.changeTilesToValueArr(newHandTiles)
        duiCount = 0
        for index in range(len(handTilesArr)):
            if handTilesArr[index] == 2:
                duiCount += 1
            elif handTilesArr[index] == 4:
                duiCount += 2

        if duiCount == 7 or (duiCount == 6 and self.isMagicTile()):  # 宝牌情况
            return True

        return False
示例#14
0
    def isLanPaiHu(cls, tiles, magicTiles):
        """先做简单的牌型检查,如果符合再进行细节判断"""
        if len(tiles[MHand.TYPE_CHI]) != 0:
            return False
        if len(tiles[MHand.TYPE_PENG]) != 0:
            return False
        if len(tiles[MHand.TYPE_GANG]) != 0:
            return False
        # 去除手牌赖子,并计数
        haveMagicCount = 0
        lanpaiTiles = copy.deepcopy(tiles[MHand.TYPE_HAND])
        for magicTile in magicTiles:
            while magicTile in lanpaiTiles:
                lanpaiTiles.remove(magicTile)
                haveMagicCount += 1
        tileArr = MTile.changeTilesToValueArr(lanpaiTiles)
        # 去除赖子后手牌数不能有超过2张的
        for count in tileArr:
            if count <= 1:
                continue
            else:
                return False

        # 去除赖子后不重复字牌加赖子数要大于等于5,并且可用赖子数=字牌+赖子-5
        # canUseMagicCount = haveMagicCount
        tempFengTiles = MTile.traverseTile(MTile.TILE_FENG)
        fengArr = tileArr[tempFengTiles[0]:tempFengTiles[len(tempFengTiles) -
                                                         1] + 1]

        # 检查字牌种类和每种的数量,之前因为已经判断过数量小于等于1,这里不再重复
        fengCount = 0
        for count in fengArr:
            if count == 1:
                fengCount += 1

        # 如果字牌每种不超过1张且有五种,开始判断其它花色
        if fengCount + haveMagicCount >= 5:
            # 分别判断三种花色
            if cls.checkBukao(tileArr, MTile.TILE_WAN) and cls.checkBukao(
                    tileArr, MTile.TILE_TONG) and cls.checkBukao(
                        tileArr, MTile.TILE_TIAO):
                return True
        else:
            return False

        return False
示例#15
0
 def isPairsCheck(self, tiles, magicTiles):
     """判断七对型胡牌"""
     # 不能吃碰杠
     if len(tiles[MHand.TYPE_CHI]) != 0:
         return False, 0, 0, 0
     if len(tiles[MHand.TYPE_PENG]) != 0:
         return False, 0, 0, 0
     if len(tiles[MHand.TYPE_GANG]) != 0:
         return False, 0, 0, 0
     # 用赖子给其他牌配对
     pairTiles = copy.deepcopy(tiles[MHand.TYPE_HAND])
     fourCount = 0
     twoCount = 0
     haveMagicCount = 0
     for magicTile in magicTiles:
         while magicTile in pairTiles:
             pairTiles.remove(magicTile)
             haveMagicCount += 1
     tileArr = MTile.changeTilesToValueArr(pairTiles)
     for count in tileArr:
         if count % 2 == 0:
             if count == 4:
                 fourCount += 1
             elif count == 2:
                 twoCount += 1
             continue
         else:
             if haveMagicCount <= 0:
                 return False, 0, 0, 0
             else:
                 haveMagicCount -= 1
                 if count == 3:
                     fourCount += 1
                 elif count == 1:
                     twoCount += 1
                 continue
     # 配对结束,赖子必须剩偶数个
     if haveMagicCount % 2 == 0:
         # 尽量凑4个的
         while haveMagicCount >= 2 and twoCount >= 1:
             twoCount -= 1
             fourCount += 1
             haveMagicCount -= 2
         return True, haveMagicCount, fourCount, twoCount
     return False, 0, 0, 0
示例#16
0
    def isQidui(self, tiles):
        handTiles = copy.deepcopy(tiles[MHand.TYPE_HAND])
        handTilesArr = MTile.changeTilesToValueArr(handTiles)

        if len(handTiles) != 14:
            return False, []

        pattern = []
        for tile in range(MTile.TILE_MAX_VALUE):
            if handTilesArr[tile] == 1 or handTilesArr[tile] == 3:
                # 只要出现单数,必然不是七对
                return False, []
            if handTilesArr[tile] == 2:
                pattern.append([tile, tile])
            if handTilesArr[tile] == 4:
                # 和KawuxingOneResult配合
                pattern.extend([[tile, tile], [tile, tile]])
        return True, pattern
示例#17
0
    def isHu(self, tiles, last_tile, isTing, getTileType, magicTiles=list(), tingNodes=list()):
        hu_tiles = HuTiles()
        handTileArr = MTile.changeTilesToValueArr(tiles[MHand.TYPE_HAND])
        if not M14.find_first(handTileArr, hu_tiles,
                              M14.is7Dui if self.dui7 else M14.justPass,
                              M14.isPHu,
                              ):
            # 基本的胡牌类型都挂了
            return False, None
        dui_list = handTileArr.tiles_dui()
        if len(dui_list) == 0:
            # 没有将牌
            return False, []
        if len(hu_tiles) != 7 and not set(zip(*dui_list)[0]) & MWinRuleJiNan.JIANG:
            # 没有2,5,8将牌
            return False, []

        return True, hu_tiles
示例#18
0
    def isLanPaiCheck(self, tiles, magicTiles):
        """先做简单的牌型检查,如果符合再进行细节判断"""
        if len(tiles[MHand.TYPE_HAND]) != 14:
            return False, 0, 0
        ftlog.debug("isLanPaiCheck handcard is ok")
        # 去除手牌赖子,并计数
        haveMagicCount = 0
        lanpaiTiles = copy.deepcopy(tiles[MHand.TYPE_HAND])
        for magicTile in magicTiles:
            while magicTile in lanpaiTiles:
                lanpaiTiles.remove(magicTile)
                haveMagicCount += 1
        ftlog.debug("isLanPaiCheck haveMagicCount =", haveMagicCount, "lanpaiTiles =", lanpaiTiles)
        tileArr = MTile.changeTilesToValueArr(lanpaiTiles)
        # 去除赖子后手牌数不能有超过2张的
        for count in tileArr:
            if count <= 1:
                continue
            else:
                return False, 0, 0

        # 去除赖子后不重复字牌加赖子数要大于等于5,并且可用赖子数=字牌+赖子-5
        # canUseMagicCount = haveMagicCount
        tempFengTiles = MTile.traverseTile(MTile.TILE_FENG)
        fengArr = tileArr[tempFengTiles[0]:tempFengTiles[len(tempFengTiles) - 1] + 1]
        ftlog.debug("isLanPaiCheck fengArr =", fengArr)
        # 检查字牌种类和每种的数量,之前因为已经判断过数量小于等于1,这里不再重复
        fengCount = 0
        for count in fengArr:
            if count == 1:
                fengCount += 1

        # 如果字牌每种不超过1张且有五种,开始判断其它花色
        if fengCount + haveMagicCount >= 5:
            # 分别判断三种花色
            ftlog.debug("isLanPaiCheck checkBukao begin tileArr = ", tileArr)
            if self.checkBukao(tileArr, MTile.TILE_WAN) and self.checkBukao(tileArr,
                                                                            MTile.TILE_TONG) and self.checkBukao(
                    tileArr, MTile.TILE_TIAO):
                return True, fengCount, haveMagicCount
        else:
            return False, 0, 0

        return False, 0, 0
示例#19
0
    def isLanPaiHu(cls, tiles, magicTiles):
        """先做简单的牌型检查,如果符合再进行细节判断"""
        if len(tiles[MHand.TYPE_CHI]) != 0:
            return False
        if len(tiles[MHand.TYPE_PENG]) != 0:
            return False
        if len(tiles[MHand.TYPE_GANG]) != 0:
            return False
        # 去除手牌赖子,并计数
        haveMagicCount = 0
        lanpaiTiles = copy.deepcopy(tiles[MHand.TYPE_HAND])
        for magicTile in magicTiles:
            while magicTile in lanpaiTiles:
                lanpaiTiles.remove(magicTile)
                haveMagicCount += 1
        tileArr = MTile.changeTilesToValueArr(lanpaiTiles)
        # 去除赖子后手牌数不能有超过2张的
        for count in tileArr:
            if count <= 1:
                continue
            else:
                return False

        # 去除赖子后不重复字牌加赖子数要大于等于5,并且可用赖子数=字牌+赖子-5
        # canUseMagicCount = haveMagicCount
        tempFengTiles = MTile.traverseTile(MTile.TILE_FENG)
        fengArr = tileArr[tempFengTiles[0]:tempFengTiles[len(tempFengTiles) - 1] + 1]

        # 检查字牌种类和每种的数量,之前因为已经判断过数量小于等于1,这里不再重复
        fengCount = 0
        for count in fengArr:
            if count == 1:
                fengCount += 1

        # 如果字牌每种不超过1张且有五种,开始判断其它花色
        if fengCount + haveMagicCount >= 5:
            # 分别判断三种花色
            if cls.checkBukao(tileArr, MTile.TILE_WAN) and cls.checkBukao(tileArr, MTile.TILE_TONG) and cls.checkBukao(
                    tileArr, MTile.TILE_TIAO):
                return True
        else:
            return False

        return False
示例#20
0
    def isHu(self,
             tiles,
             tile,
             isTing,
             getTileType,
             magicTiles=list(),
             tingNodes=list()):
        result, rePattern = MWin.isHu(tiles[MHand.TYPE_HAND])
        if not result:
            return False, []

        # 分析花色
        tileArr = MTile.changeTilesToValueArr(MHand.copyAllTilesToList(tiles))
        colors = MTile.getColorCount(tileArr)
        ftlog.debug('MWinRuleSichuan.isHu colors:', colors)

        if colors <= 2:
            # 花色缺门,可以和
            return True, rePattern
        return False, []
示例#21
0
 def calcFanDaduizi(self, fanData, nowTiles, magicTiles, magicTileCount,
                    winTile, seatId, lastSeatId):
     """计算大对子番型"""
     fan = fanData.get('fan', 0)
     patterns = fanData.get('patterns', [])
     isUnique = fanData.get('isUnique', False)
     isSpecial = fanData.get('isSpecial', False)
     isDaduizi = False
     # 大对子,门前不能有吃,手牌多加一个赖子,能保证都是3张
     if len(nowTiles[MHand.TYPE_CHI]) == 0:
         duiziTiles = copy.deepcopy(nowTiles[MHand.TYPE_HAND])
         for magicTile in magicTiles:
             while magicTile in duiziTiles:
                 duiziTiles.remove(magicTile)
         # 如果点炮胡,需要给牌堆里加回去一张赖子,并当普通牌处理
         if seatId != lastSeatId and winTile in magicTiles:
             duiziTiles.append(winTile)
         duiziArr = MTile.changeTilesToValueArr(duiziTiles)
         ftlog.debug("MYunnanOneResult duiziArr = ", duiziArr)
         cardTypeCount = 0
         # 假设多一张赖子
         duiziMagicCount = magicTileCount + 1
         for index in range(len(duiziArr)):
             if duiziArr[index] != 0:
                 cardTypeCount += 1
                 if duiziArr[index] < 3:
                     duiziMagicCount = duiziMagicCount - (3 -
                                                          duiziArr[index])
         if cardTypeCount <= 5 and duiziMagicCount >= 0:
             if not isUnique:
                 patterns.append(self.fanXing[self.DUIDUIHU]['name'])
                 fan += self.fanXing[self.DUIDUIHU]['index']
                 ftlog.debug("MYunnanOneResult fanxing = ", patterns,
                             "fan = ", fan)
                 isDaduizi = True
                 isSpecial = True
     fanData['isUnique'] = isUnique
     fanData['fan'] = fan
     fanData['isSpecial'] = isSpecial
     return fan, patterns, isUnique, isDaduizi
示例#22
0
    def isHu(cls, hand_tiles, magicTiles=list()):
        """
        胡牌判断,只判断手牌,杠牌,吃牌,碰牌不在内
           杠牌、吃牌、碰牌已成型,不用另外计算
        * 肯定包含将牌
        * 剩下的牌里不会有暗杠牌
        * 杠牌/吃牌/碰牌是已经成型的牌,按成型的样式计算积分,不再重新计算
        :param magicTiles 赖子牌
        :return 是否胡了
        """
        tileArr = MTile.changeTilesToValueArr(hand_tiles)
        magicArr = []
        for magicTile in magicTiles:
            magicArr.extend([magicTile for _ in range(tileArr[magicTile])])
            tileArr[magicTile] = 0

        resultArr = []
        tileTypes = [
            MTile.TILE_WAN, MTile.TILE_TONG, MTile.TILE_TIAO, MTile.TILE_FENG
        ]
        hasJiang = False
        winResult = False

        for tileType in tileTypes:
            winResult, hasJiang, _tArr, _rArr, _mArr = cls.isHuWithMagic(
                tileArr, resultArr, magicArr, hasJiang, tileType)
            if not winResult:
                return False, []
            else:
                tileArr = copy.deepcopy(_tArr)
                resultArr = copy.deepcopy(_rArr)
                magicArr = copy.deepcopy(_mArr)

        if winResult and not hasJiang and len(magicArr) >= 2:
            hasJiang = True
        return hasJiang and winResult, resultArr
示例#23
0
文件: chi.py 项目: zhaozw/hall37
    def hasChi(cls, tiles, tile):
        """是否可以吃
        吃牌的判断中,tile已经在tiles中
        参数:
            tiles - 手牌
            tile - 待吃的牌
        返回值:吃牌选择
            最多三种解
            
        例子:
            [[2, 3, 4], [3, 4, 5], [4, 5, 6
        """
        tileArr = MTile.changeTilesToValueArr(tiles)
        result = []
        # 第一种情况 001
        if (tile % 10) >= 3:
            if tileArr[tile - 2] > 0 and tileArr[tile -
                                                 1] > 0 and tileArr[tile] > 0:
                solution = [tile - 2, tile - 1, tile]
                result.append(solution)

        # 第二种情况 010
        if (tile % 10) >= 2 and (tile % 10) < 9:
            if tileArr[tile - 1] > 0 and tileArr[tile] > 0 and tileArr[tile +
                                                                       1] > 0:
                solution = [tile - 1, tile, tile + 1]
                result.append(solution)

        # 第三种情况 100
        if (tile % 10) < 8:
            if tileArr[tile] > 0 and tileArr[tile + 1] > 0 and tileArr[tile +
                                                                       2] > 0:
                solution = [tile, tile + 1, tile + 2]
                result.append(solution)

        return result
示例#24
0
    def canTing(self, tiles, leftTiles, tile, magicTiles=[]):
        """子类必须实现
        参数:
        1)tiles 该玩家的手牌
        2)leftTiles 剩余手牌
        返回值:
        是否可以听牌,听牌详情
        """
        handCount = len(tiles[MHand.TYPE_HAND])

        if len(tiles[MHand.TYPE_CHI]) == 0 and len(tiles[MHand.TYPE_PENG]) == 0 and len(tiles[MHand.TYPE_GANG]) == 0:
            isTing, tingResults = self.tingQiDui(tiles, tile, leftTiles)
            if isTing:
                ftlog.debug('MTingJixiRule.MTing.canTing tingQiDui tingResults:', tingResults)
                return isTing, tingResults

                #         ftlog.debug( 'MTingJixiRule.canTing 0 tiles:', tiles )
        isTing, tingResults = MTing.canTing(MTile.cloneTiles(tiles), leftTiles, self.winRuleMgr, tile, magicTiles)
        #         ftlog.debug( 'MTingJixiRule.canTing 1 tiles:', tiles )
        ftlog.debug('MTingJixiRule.MTing.canTing isTing:', isTing, ' tingResults:', tingResults)

        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 = False
                isPiaoHu = self.isPiaoHu(patterns, newTiles)

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

                # 夹起步(顺牌只能和夹和3,7) 不能和两头 可以单吊
                chunJiaConfig = self.getTableConfig(MTDefine.MIN_MULTI, 0)
                if chunJiaConfig:
                    bianMulti = self.tableConfig.get(MTDefine.BIAN_MULTI, 0)
                    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]:
                                hasJia = True
                                break

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

                zhongCount = tileArr[MTile.TILE_HONG_ZHONG]

                # 检查牌中的幺/九
                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]

                # 飘和七小对不需要1,9
                if (yaoCount + jiuCount + zhongCount) == 0 and (not isPiaoHu) and (not isQiDui):
                    continue

                patterns = winNode['pattern']
                checkKeCount = keCount + self.getKeCount(patterns)
                ftlog.debug('MTingHaerbinRule.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)

        return len(newTingResults) > 0, newTingResults
示例#25
0
    def isHu(self, tiles, tile, isTing, getTileType, magicTiles=[], tingNodes=[]):
        """
        tiles:玩家所有的牌,但是手牌是加入了要胡的那张牌的
        """
        # 昭通无听牌
        ftlog.debug('MWinRuleZhaotong.isHu tiles:', tiles
                    , ' tile:', tile
                    , ' magicTils:', magicTiles
                    , ' getTileType:', getTileType)

        if getTileType != MWinRule.WIN_BY_MYSELF and MTableTile.isMagicTile(tile, magicTiles):
            # 如果是听用,不能胡
            return False, []

            # 先查花色
        playerAllTiles = []
        playerAllTiles.extend(tiles[MHand.TYPE_HAND])
        for chi in tiles[MHand.TYPE_CHI]:
            playerAllTiles.extend(chi)
        for peng in tiles[MHand.TYPE_PENG]:
            playerAllTiles.extend(peng)
        for gang in tiles[MHand.TYPE_GANG]:
            playerAllTiles.extend(gang['pattern'])
        colorStateWithMagic = MTile.getColorCount(MTile.changeTilesToValueArr(playerAllTiles))
        magicCount, tempTiles = MTableTile.getMagicTileCountInTiles(playerAllTiles, magicTiles)
        colorState = MTile.getColorCount(MTile.changeTilesToValueArr(tempTiles))
        ftlog.debug("MWinRuleZhaotong.isHu colorState = ", colorState
                    , "playerAllTiles = ", playerAllTiles
                    , "tempTiles = ", tempTiles
                    , "colorStateWithMagic = ", colorStateWithMagic
                    , "magicCount = ", magicCount)
        # 必须缺一门才能胡牌
        if colorState >= 3:
            ftlog.debug("MWinRuleZhaotong.isHu men >= 3 can not hu")
            return False, []

        result1, pattern1 = MWinRuleZhaotong.checkHuByMagicTiles(tiles, magicTiles)
        #         result2, pattern2 = MWinRuleZhaotong.checkHuByMagicTiles(tiles, [])
        #         if colorStateWithMagic >= 3:
        #             if result1 and not result2:
        #                 return result1, pattern1
        #             else:
        #                 return False, []
        #         else:
        #             if result1:
        #                 return result1, pattern1
        #             else:
        #                 return False, []
        if result1:
            return result1, pattern1
        #             if getTileType != MWinRule.WIN_BY_MYSELF:
        #                 hasMagic = False
        #                 for magicTile in magicTiles:
        #                     if magicTile in tiles[MHand.TYPE_HAND]:
        #                         hasMagic = True
        #                 if hasMagic:
        #                     # 点炮和抢杠胡要检查是不是叫听用,如果叫听用,可以胡任意牌,采用抽3张牌测试的方式,如果通过就认为是叫听用
        #                     testTiles = []
        #                     if tile/10 == 0:
        #                         testTiles.append(2)
        #                         testTiles.append(6)
        #                         testTiles.append(9)
        #                     elif tile/10 == 1:
        #                         testTiles.append(12)
        #                         testTiles.append(14)
        #                         testTiles.append(17)
        #                     elif tile/10 == 2:
        #                         testTiles.append(22)
        #                         testTiles.append(24)
        #                         testTiles.append(28)
        #                     else:
        #                         return False, []
        #                     dandiao = True
        #                     for testTile in testTiles:
        #                         tempDandiao = copy.deepcopy(tiles)
        #                         if tile in tempDandiao[MHand.TYPE_HAND]:
        #                             tempDandiao[MHand.TYPE_HAND].remove(tile)
        #                         tempDandiao[MHand.TYPE_HAND].append(testTile)
        #                         resultDandiao, _ = MWinRuleZhaotong.checkHuByMagicTiles(tempDandiao, magicTiles)
        #                         if not resultDandiao:
        #                             dandiao = False
        #                     if not dandiao:
        #                         return result1, pattern1
        #                 else:
        #                     return result1, pattern1
        #             else:
        #                 return result1, pattern1
        return False, []
示例#26
0
    def hasGang(self, tiles, curTile, state):
        """判断杠牌"""
        handTiles = tiles[MHand.TYPE_HAND]
        tileArr = MTile.changeTilesToValueArr(handTiles)
        magics = self.tableTileMgr.getMagicTiles(False)
        tileArr, magicTiles = self.tableTileMgr.exculeMagicTiles(
            tileArr, magics)
        magicCount = len(magicTiles)
        magicGangMaxCount = self.tableTileMgr.magicGangMaxCount
        if magicGangMaxCount > 4 or magicGangMaxCount < 0:
            magicGangMaxCount = 4

        gangs = []
        # 带有癞子的杠
        for tile in range(MTile.TILE_MAX_VALUE):
            if tileArr[tile] == 4:
                pattern = [tile, tile, tile, tile]
                if (curTile
                        in pattern) and (state & MTableState.TABLE_STATE_DROP):
                    gangs.append({
                        "pattern": pattern,
                        "style": MPlayerTileGang.MING_GANG,
                        "tile": tile
                    })
                else:
                    gangs.append({
                        "pattern": pattern,
                        "style": MPlayerTileGang.AN_GANG,
                        "tile": tile
                    })
            if tileArr[tile] >= 3 and magicCount >= 1:
                pattern = [tile, tile, tile, magicTiles[0]]
                pattern.sort()
                if (curTile in pattern) and (curTile not in magicTiles) and (
                        state & MTableState.TABLE_STATE_DROP
                ) and magicGangMaxCount >= 1:
                    gangs.append({
                        "pattern": pattern,
                        "style": MPlayerTileGang.MING_GANG,
                        "tile": tile
                    })
                else:
                    gangs.append({
                        "pattern": pattern,
                        "style": MPlayerTileGang.AN_GANG,
                        "tile": tile
                    })
            if tileArr[tile] >= 2 and magicCount >= 2:
                pattern = [tile, tile, magicTiles[0], magicTiles[1]]
                pattern.sort()
                if (curTile in pattern) and (curTile not in magicTiles) and (
                        state & MTableState.TABLE_STATE_DROP
                ) and magicGangMaxCount >= 2:
                    gangs.append({
                        "pattern": pattern,
                        "style": MPlayerTileGang.MING_GANG,
                        "tile": tile
                    })
                else:
                    gangs.append({
                        "pattern": pattern,
                        "style": MPlayerTileGang.AN_GANG,
                        "tile": tile
                    })
            if tileArr[tile] >= 1 and magicCount >= 3:
                pattern = [tile, magicTiles[0], magicTiles[1], magicTiles[2]]
                pattern.sort()
                if (curTile in pattern) and (curTile not in magicTiles) and (
                        state & MTableState.TABLE_STATE_DROP
                ) and magicGangMaxCount >= 3:
                    gangs.append({
                        "pattern": pattern,
                        "style": MPlayerTileGang.MING_GANG,
                        "tile": tile
                    })
                else:
                    gangs.append({
                        "pattern": pattern,
                        "style": MPlayerTileGang.AN_GANG,
                        "tile": tile
                    })

        # 赖子作为普通牌来杠,暂时不处理多类赖子的情况
        if magicCount >= 4 and len(magics) == 1:
            pattern = [
                magicTiles[0], magicTiles[1], magicTiles[2], magicTiles[3]
            ]
            pattern.sort()
            if (curTile in pattern) and (state & MTableState.TABLE_STATE_DROP):
                gangs.append({
                    "pattern": pattern,
                    "style": MPlayerTileGang.MING_GANG,
                    "tile": curTile
                })
            else:
                gangs.append({
                    "pattern": pattern,
                    "style": MPlayerTileGang.AN_GANG,
                    "tile": magicTiles[0]
                })

        # 补杠
        if not (state & MTableState.TABLE_STATE_DROP):
            for pengPattern in tiles[MHand.TYPE_PENG]:
                for tile in pengPattern:
                    if tile not in magicTiles and tile in handTiles:
                        gangPattern = copy.deepcopy(pengPattern)
                        gangPattern.append(tile)
                        gangs.append({
                            "pattern": gangPattern,
                            "style": MPlayerTileGang.MING_GANG,
                            "tile": tile
                        })
                        break
            # 用赖子补杠,目前只处理一个赖子补杠
            for pengPattern in tiles[MHand.TYPE_PENG]:
                ftlog.debug('MGangRule.hasGang:pengPattern',
                            tiles[MHand.TYPE_PENG])
                if magicCount >= 1:
                    # 有赖子的杠,注意三个赖子碰补杠也在这里处理
                    gangPattern2 = copy.deepcopy(pengPattern)
                    tile2 = magicTiles[0]
                    gangPattern2.append(tile2)
                    gangs.append({
                        "pattern": gangPattern2,
                        "style": MPlayerTileGang.MING_GANG,
                        "tile": tile2
                    })

        ftlog.debug('MGangRule.hasGang:', gangs)
        return gangs
示例#27
0
    def hasGang(self, tiles, curTile, state):
        """判断杠牌"""
        handTiles = tiles[MHand.TYPE_HAND]
        tileArr = MTile.changeTilesToValueArr(handTiles)
        magics = self.tableTileMgr.getMagicTiles(False)
        tileArr, magicTiles = self.tableTileMgr.exculeMagicTiles(tileArr, magics)
        magicCount = len(magicTiles)
        magicGangMaxCount = self.tableTileMgr.magicGangMaxCount
        if magicGangMaxCount > 4 or magicGangMaxCount < 0:
            magicGangMaxCount = 4

        gangs = []
        # 带有癞子的杠
        for tile in range(MTile.TILE_MAX_VALUE):
            if tileArr[tile] == 4:
                pattern = [tile, tile, tile, tile]
                if (curTile in pattern) and (state & MTableState.TABLE_STATE_DROP):
                    gangs.append({"pattern": pattern, "style": MPlayerTileGang.MING_GANG, "tile": tile})
                else:
                    gangs.append({"pattern": pattern, "style": MPlayerTileGang.AN_GANG, "tile": tile})
            if tileArr[tile] >= 3 and magicCount >= 1:
                pattern = [tile, tile, tile, magicTiles[0]]
                pattern.sort()
                if (curTile in pattern) and (curTile not in magicTiles) and (
                    state & MTableState.TABLE_STATE_DROP) and magicGangMaxCount >= 1:
                    gangs.append({"pattern": pattern, "style": MPlayerTileGang.MING_GANG, "tile": tile})
                else:
                    gangs.append({"pattern": pattern, "style": MPlayerTileGang.AN_GANG, "tile": tile})
            if tileArr[tile] >= 2 and magicCount >= 2:
                pattern = [tile, tile, magicTiles[0], magicTiles[1]]
                pattern.sort()
                if (curTile in pattern) and (curTile not in magicTiles) and (
                    state & MTableState.TABLE_STATE_DROP) and magicGangMaxCount >= 2:
                    gangs.append({"pattern": pattern, "style": MPlayerTileGang.MING_GANG, "tile": tile})
                else:
                    gangs.append({"pattern": pattern, "style": MPlayerTileGang.AN_GANG, "tile": tile})
            if tileArr[tile] >= 1 and magicCount >= 3:
                pattern = [tile, magicTiles[0], magicTiles[1], magicTiles[2]]
                pattern.sort()
                if (curTile in pattern) and (curTile not in magicTiles) and (
                    state & MTableState.TABLE_STATE_DROP) and magicGangMaxCount >= 3:
                    gangs.append({"pattern": pattern, "style": MPlayerTileGang.MING_GANG, "tile": tile})
                else:
                    gangs.append({"pattern": pattern, "style": MPlayerTileGang.AN_GANG, "tile": tile})

        # 赖子作为普通牌来杠,暂时不处理多类赖子的情况
        if magicCount >= 4 and len(magics) == 1:
            pattern = [magicTiles[0], magicTiles[1], magicTiles[2], magicTiles[3]]
            pattern.sort()
            if (curTile in pattern) and (state & MTableState.TABLE_STATE_DROP):
                gangs.append({"pattern": pattern, "style": MPlayerTileGang.MING_GANG, "tile": curTile})
            else:
                gangs.append({"pattern": pattern, "style": MPlayerTileGang.AN_GANG, "tile": magicTiles[0]})

        # 补杠
        if not (state & MTableState.TABLE_STATE_DROP):
            for pengPattern in tiles[MHand.TYPE_PENG]:
                for tile in pengPattern:
                    if tile not in magicTiles and tile in handTiles:
                        gangPattern = copy.deepcopy(pengPattern)
                        gangPattern.append(tile)
                        gangs.append({"pattern": gangPattern, "style": MPlayerTileGang.MING_GANG, "tile": tile})
                        break
            # 用赖子补杠,目前只处理一个赖子补杠
            for pengPattern in tiles[MHand.TYPE_PENG]:
                ftlog.debug('MGangRule.hasGang:pengPattern', tiles[MHand.TYPE_PENG])
                if magicCount >= 1:
                    # 有赖子的杠,注意三个赖子碰补杠也在这里处理
                    gangPattern2 = copy.deepcopy(pengPattern)
                    tile2 = magicTiles[0]
                    gangPattern2.append(tile2)
                    gangs.append({"pattern": gangPattern2, "style": MPlayerTileGang.MING_GANG, "tile": tile2})

        ftlog.debug('MGangRule.hasGang:', gangs)
        return gangs
示例#28
0
    def tingQiDui(self, tiles, cur_tile, leftTiles):
        """
        检查是否可以听七小对
        二种牌型可听
        * 别人打牌 五对(包括杠) 一刻 粘一张
        * 自己上牌 六对(包括杠) 两个单张
        :param tiles 手牌
        :param cur_tile 刚刚摸的牌
        :param leftTiles: 全局剩余的牌
        :return
          [
            {
              'isQiDui' : 1
              'dropTile' : 11, # 出牌`一筒`
              'winNodes' : [{ # 听牌细节
                  'winTile' : 1, # 听`一万`
                  'winTileCount' : 3, # 剩`三张一万`
                  'pattern' : [
                    [6, 6], # 听牌的条件
                    ...
                  ]
                }]
            }
          ]
        """
        ftlog.debug('MTingHaerbinJixi.MTing.tingQiDui handTiles:',
                    tiles[MHand.TYPE_HAND], ' tile:', cur_tile)
        handTiles = tiles[MHand.TYPE_HAND]
        newHandTiles = MTile.cloneTiles(handTiles)
        # 不考虑摸牌
        newHandTiles.remove(cur_tile)
        if len(newHandTiles) < 13:
            # 手牌不够
            return False, []

        newHandTilesArr = MTile.changeTilesToValueArr(newHandTiles)
        duiCount = 0
        singleTiles = []
        duiPattern = []
        for tile, number in newHandTilesArr.tile_items():
            if number == 2:
                # 对
                duiCount += 1
                duiPattern.append([tile, tile])
            elif number == 4:
                # 杠算两对
                duiCount += 2
                duiPattern.append([tile, tile])
                duiPattern.append([tile, tile])
            elif number == 3:
                # 碰
                if tile != cur_tile:
                    # 摸牌不能凑杠 有单张了
                    singleTiles.append(tile)
                duiPattern.append([tile, tile])
            elif tile != cur_tile:
                # 摸牌不能凑对 有单张了
                singleTiles.append(tile)
            else:
                duiPattern.append([cur_tile, cur_tile])

        if len(singleTiles) != 2:
            # 单张过多不能听七对
            # 单张过少则已经可以胡牌(不能听了)
            # ftlog.debug('MTingJixiRule.MTing.canTing tingQiDui the singleTiles count error: ', len(singleTiles))
            return False, []

        # 站牌处理 手里有五对 并且有一张或三张上的牌 那么可以听 方案就是剩下的两张
        newLeftTilesArr = MTile.changeTilesToValueArr(leftTiles)
        tingResult = [
            {  # 听第2张单牌
                'isQiDui':
                1,
                'dropTile':
                singleTiles[0],
                'winNodes': [{
                    'winTile':
                    singleTiles[1],
                    'winTileCount':
                    newLeftTilesArr[singleTiles[1]],
                    'pattern':
                    duiPattern + [[singleTiles[1], singleTiles[1]]]
                }]
            },
            {  # 听第1张单牌
                'isQiDui':
                1,
                'dropTile':
                singleTiles[1],
                'winNodes': [{
                    'winTile':
                    singleTiles[0],
                    'winTileCount':
                    newLeftTilesArr[singleTiles[0]],
                    'pattern':
                    duiPattern + [[singleTiles[0], singleTiles[0]]]
                }]
            }
        ]

        return True, tingResult
示例#29
0
    def calcScore(self):
        """算分"""

        # 序列化
        self.serialize()

        # 牌型数据都在tabletilemgr里面可以取到
        playerAllTiles = [[] for _ in range(self.playerCount)]
        playerAllTilesArr = [[] for _ in range(self.playerCount)]
        playerHandTiles = [[] for _ in range(self.playerCount)]
        for player in self.tableTileMgr.players:
            # 按手牌格式的数组
            playerAllTiles[player.curSeatId] = player.copyTiles()
            # 合到一个数组中
            playerAllTilesArr[player.curSeatId].extend(MHand.copyAllTilesToList(playerAllTiles[player.curSeatId]))
            # 只获取手牌                
            playerHandTiles[player.curSeatId] = player.copyHandTiles()
        ftlog.debug("playerHandTiles", playerHandTiles)
        ftlog.debug("playerAllTiles", playerAllTiles)
        ftlog.debug("playerAllTilesArr", playerAllTilesArr)
        ftlog.debug("self.winTile", self.winTile)
        self.results[self.KEY_TYPE] = ''
        self.results[self.KEY_NAME] = ''
        self.results[self.KEY_SCORE] = [0 for _ in range(self.playerCount)]
        self.results[self.KEY_WIN_TILE] = [0 for _ in range(self.playerCount)]
        self.results[self.KEY_WIN_MODE] = [MOneResult.WIN_MODE_LOSS for _ in range(self.playerCount)]
        # 在和牌时统计自摸,点炮,最大番数
        self.results[self.KEY_STAT] = [[] for _ in range(self.playerCount)]
        self.results[self.KEY_FAN_PATTERN] = [[] for _ in range(self.playerCount)]
        fanArr = [0 for _ in range(self.playerCount)]
        baseScore = 1

        # 流局不走后面的结算,确保没有设置的值不会被使用
        if self.resultType == self.RESULT_FLOW:
            self.results[self.KEY_TYPE] = MOneResult.KEY_TYPE_NAME_FLOW
            ftlog.debug("MYunnanOneResult calcScore Type = RESULT_FLOW return")
            return

        self.results[self.KEY_TYPE] = MOneResult.KEY_TYPE_NAME_HU

        if len(self.winSeats) <= 0:
            ftlog.debug("MYunnanOneResult self.winSeats error no winner")
            return
        ftlog.debug("MYunnanOneResultCalcScore self.winSeats = ", self.winSeats)

        if self.lastSeatId not in self.winSeats:
            self.results[self.KEY_WIN_MODE][self.lastSeatId] = MOneResult.WIN_MODE_DIANPAO

        # 计算胡牌者的番型和分数
        for seatId in self.winSeats:
            # 番型
            patterns = []
            fan = 0
            ftlog.debug('MajiangTableLogic.gameWin.yipaoduoxiang dealwith seatId:'
                        , seatId
                        , 'lastSeatId:', self.lastSeatId
                        , 'winSeatId:', self.winSeatId
                        , 'self.winSeats:', self.winSeats
                        , 'self.actionID:', self.actionID
                        )
            ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan, "seatId = ", seatId)
            if seatId == self.lastSeatId:
                self.results[self.KEY_WIN_MODE][seatId] = MOneResult.WIN_MODE_ZIMO
            else:
                self.results[self.KEY_WIN_MODE][seatId] = MOneResult.WIN_MODE_PINGHU
            magicTiles = self.tableTileMgr.getMagicTiles()
            tempArrColor = copy.deepcopy(playerAllTilesArr[seatId])
            # colorState里面要去掉赖子包含的花色
            magicTileCount = 0
            for magicTile in magicTiles:
                while magicTile in tempArrColor:
                    tempArrColor.remove(magicTile)
                    magicTileCount += 1
            # 重新处理一次花色,不算赖子
            oldColorState = copy.deepcopy(self.colorState)
            ftlog.debug("MYunnanOneResultCalcScore tempArrColor = ", tempArrColor)
            ftlog.debug("MYunnanOneResultCalcScore self.colorState1 = ", self.colorState)
            self.colorState[seatId] = MTile.getColorCount(MTile.changeTilesToValueArr(tempArrColor))
            ftlog.debug("MYunnanOneResultCalcScore self.colorState2 = ", self.colorState)
            isUnique = False

            # 七对和五六七星烂,十风,十三幺,四幺鸡
            # 取出dropTiles来判断是否十风和十三幺
            dropTiles = self.tableTileMgr.dropTiles[seatId]
            nowTiles = playerAllTiles[seatId]
            nowTiles[MHand.TYPE_HAND].append(self.winTile)

            # 杠上花和杠上炮
            ftlog.debug("MYunnanOneResultCalcScorelatestGangState = ", self.latestGangState)
            ftlog.debug("MYunnanOneResultCalcScorelatestGangState self.winSeatId:= ", self.winSeatId)
            ftlog.debug("MYunnanOneResultCalcScorelatestGangState seatId:= ", seatId)
            ftlog.debug("MYunnanOneResultCalcScorelatestGangState self.lastSeatId:= ", self.lastSeatId)

            if self.latestGangState != -1:
                if self.latestGangState == seatId:
                    # 杠牌的是自己
                    wumeihuaTiles = copy.deepcopy(nowTiles)
                    if self.winTile in wumeihuaTiles[MHand.TYPE_HAND]:
                        wumeihuaTiles[MHand.TYPE_HAND].remove(self.winTile)
                    wumeihuaTiles[MHand.TYPE_HAND].append(MTile.TILE_FIVE_TONG)
                    result, _ = MWinRuleYunnan.checkHuByMagicTiles(wumeihuaTiles, magicTiles)
                    if result and (self.winTile == MTile.TILE_FIVE_TONG or self.winTile in magicTiles):
                        # 五梅花,包括幺鸡当五筒
                        if not isUnique:
                            patterns.append(self.fanXing[self.GANGSHANGHUAWUMEIHUA]['name'])
                            fan += self.fanXing[self.GANGSHANGHUAWUMEIHUA]['index']
                            ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
                    else:
                        if not isUnique:
                            patterns.append(self.fanXing[self.GANGSHANGHUA]['name'])
                            fan += self.fanXing[self.GANGSHANGHUA]['index']
                            ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
                elif self.latestGangState == self.lastSeatId:
                    # 杠牌的是别人
                    if not isUnique:
                        patterns.append(self.fanXing[self.GANGSHANGPAO]['name'])
                        fan += self.fanXing[self.GANGSHANGPAO]['index']
                        ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)

            # 四幺鸡,必须是自摸,必须是手牌
            if nowTiles[MHand.TYPE_HAND].count(MTile.TILE_ONE_TIAO) == 4 and (seatId == self.lastSeatId):
                if not isUnique:
                    self.results[self.KEY_WIN_MODE][seatId] = MYunnanOneResult.WIN_MODE_SIYAOJI
                    patterns = []
                    patterns.append(self.fanXing[self.SIYAOJI]['name'])
                    isUnique = True
                    fan = 0
                    fan += self.fanXing[self.SIYAOJI]['index']
                    ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)

            ftlog.debug("MYunnanOneResult dropTiles = ", dropTiles, "nowTiles = ", nowTiles)
            if self.isShifeng(dropTiles, nowTiles):
                if not isUnique:
                    self.results[self.KEY_WIN_MODE][seatId] = MYunnanOneResult.WIN_MODE_SHIFENG
                    patterns.append(self.fanXing[self.SHIFENG]['name'])
                    fan = 0
                    fan += self.fanXing[self.SHIFENG]['index']
                    ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
                    isUnique = True
                    self.setDropHuFlag(1)
            if self.isShisanyao(dropTiles, nowTiles):
                if not isUnique:
                    self.results[self.KEY_WIN_MODE][seatId] = MYunnanOneResult.WIN_MODE_SHISANYAO
                    patterns.append(self.fanXing[self.SHISANYAO]['name'])
                    fan = 0
                    fan += self.fanXing[self.SHISANYAO]['index']
                    ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
                    isUnique = True
                    self.setDropHuFlag(1)
            ftlog.debug("MYunnanOneResult check lanpai nowTiles =", nowTiles, "magicTiles =", magicTiles)
            result, fengCount, lanPanMagicCount = self.isLanPaiCheck(nowTiles, magicTiles)
            lanPaiPatternForWuji = False
            if result:
                lanPaiPatternForWuji = True
                if fengCount + lanPanMagicCount >= 7:
                    # 七星烂
                    if not isUnique:
                        patterns.append(self.fanXing[self.QIXINGLAN]['name'])
                        fan += self.fanXing[self.QIXINGLAN]['index']
                        ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
                elif fengCount + lanPanMagicCount >= 6:
                    # 六星烂
                    if not isUnique:
                        patterns.append(self.fanXing[self.LIUXINGLAN]['name'])
                        fan += self.fanXing[self.LIUXINGLAN]['index']
                        ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
                elif fengCount + lanPanMagicCount >= 5:
                    # 五星烂
                    if not isUnique:
                        patterns.append(self.fanXing[self.WUXINGLAN]['name'])
                        fan += self.fanXing[self.WUXINGLAN]['index']
                        ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
            # 七对必须门清
            isPairs = False
            if self.menState[seatId] == 1:
                if seatId == self.lastSeatId:
                    # 自摸
                    pairResult, leftMagicCount, fourCount, _ = self.isPairsCheck(nowTiles, magicTiles)
                    if pairResult:
                        isPairs = True
                        if fourCount >= 1:
                            if not isUnique:
                                patterns.append(self.fanXing[self.LONGZHUABEI]['name'])
                                fan += self.fanXing[self.LONGZHUABEI]['index']
                                ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
                        else:
                            # 小七对
                            if not isUnique:
                                patterns.append(self.fanXing[self.XIAOQIDUI]['name'])
                                fan += self.fanXing[self.XIAOQIDUI]['index']
                                ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
                else:
                    # 点炮
                    if self.winTile in magicTiles:
                        transferTiles = copy.deepcopy(nowTiles)
                        magicCount = 0
                        for magicTile in magicTiles:
                            while magicTile in transferTiles[MHand.TYPE_HAND]:
                                transferTiles[MHand.TYPE_HAND].remove(magicTile)
                                transferTiles[MHand.TYPE_HAND].append(0)
                                magicCount += 1
                            if magicCount >= 1:
                                transferTiles[MHand.TYPE_HAND].remove(0)
                                transferTiles[MHand.TYPE_HAND].append(magicTile)
                        pairResult, leftMagicCount, fourCount, _ = self.isPairsCheck(transferTiles, [0])
                        if pairResult:
                            isPairs = True
                            if leftMagicCount >= 2:
                                if not isUnique:
                                    patterns.append(self.fanXing[self.LONGZHUABEI]['name'])
                                    fan += self.fanXing[self.LONGZHUABEI]['index']
                                    ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
                            else:
                                # 小七对
                                if not isUnique:
                                    patterns.append(self.fanXing[self.XIAOQIDUI]['name'])
                                    fan += self.fanXing[self.XIAOQIDUI]['index']
                                    ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
                    else:
                        pairResult, leftMagicCount, fourCount, _ = self.isPairsCheck(nowTiles, magicTiles)
                        if pairResult:
                            isPairs = True
                            if nowTiles[MHand.TYPE_HAND].count(self.winTile) + leftMagicCount >= 3:
                                # 一定是龙爪背
                                if not isUnique:
                                    patterns.append(self.fanXing[self.LONGZHUABEI]['name'])
                                    fan += self.fanXing[self.LONGZHUABEI]['index']
                                    ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
                            else:
                                # 小七对
                                if not isUnique:
                                    patterns.append(self.fanXing[self.XIAOQIDUI]['name'])
                                    fan += self.fanXing[self.XIAOQIDUI]['index']
                                    ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)

                                    # 杠数
                                    #         if len(self.playerGangTiles[seatId]) == 1:
                                    #             if not isUnique:
                                    #                 self.results[self.KEY_NAME] = self.fanXing[self.YIGANG]['name']
                                    #                 patterns.append(self.fanXing[self.YIGANG]['name'])
                                    #                 fan += self.fanXing[self.YIGANG]['index']
                                    #                 ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
                                    #         el
            if len(self.playerGangTiles[seatId]) == 2:
                if not isUnique:
                    self.results[self.KEY_NAME] = self.fanXing[self.LIANGGANG]['name']
                    patterns.append(self.fanXing[self.LIANGGANG]['name'])
                    fan += self.fanXing[self.LIANGGANG]['index']
                    ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
            elif len(self.playerGangTiles[seatId]) == 3:
                if not isUnique:
                    self.results[self.KEY_NAME] = self.fanXing[self.SANGANG]['name']
                    patterns.append(self.fanXing[self.SANGANG]['name'])
                    fan += self.fanXing[self.SANGANG]['index']
                    ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
            elif len(self.playerGangTiles[seatId]) == 4:
                if not isUnique:
                    self.results[self.KEY_NAME] = self.fanXing[self.SIGANG]['name']
                    patterns.append(self.fanXing[self.SIGANG]['name'])
                    fan += self.fanXing[self.SIGANG]['index']
                    ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)

            # 字一色
            ziyiseWuji = False
            if self.colorState[seatId] == 0:
                if self.getZiTypeCountBySeatId(seatId) > 0:
                    ziyiseWuji = True
                    if not isUnique:
                        self.results[self.KEY_NAME] = self.fanXing[self.ZIYISE]['name']
                        patterns.append(self.fanXing[self.ZIYISE]['name'])
                        fan += self.fanXing[self.ZIYISE]['index']
                        ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)

            # 大对子,门前不能有吃,手牌多加一个赖子,能保证都是3张
            if len(nowTiles[MHand.TYPE_CHI]) == 0:
                duiziTiles = copy.deepcopy(nowTiles[MHand.TYPE_HAND])
                for magicTile in magicTiles:
                    while magicTile in duiziTiles:
                        duiziTiles.remove(magicTile)
                # 如果点炮胡,需要给牌堆里加回去一张赖子,并当普通牌处理
                if seatId != self.lastSeatId and self.winTile in magicTiles:
                    duiziTiles.append(self.winTile)
                duiziArr = MTile.changeTilesToValueArr(duiziTiles)
                ftlog.debug("MYunnanOneResult duiziArr = ", duiziArr)
                cardTypeCount = 0
                # 假设多一张赖子
                duiziMagicCount = magicTileCount + 1
                for index in range(len(duiziArr)):
                    if duiziArr[index] != 0:
                        cardTypeCount += 1
                        if duiziArr[index] < 3:
                            duiziMagicCount = duiziMagicCount - (3 - duiziArr[index])
                if cardTypeCount <= 5 and duiziMagicCount >= 0:
                    patterns.append(self.fanXing[self.DADUIZI]['name'])
                    fan += self.fanXing[self.DADUIZI]['index']
                    ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
                    # 清一色和混一色
            qingyiseForWuji = False
            if self.colorState[seatId] == 1:
                qingyiseForWuji = True
                if self.getZiTypeCountBySeatId(seatId) > 0:
                    if not isUnique:
                        self.results[self.KEY_NAME] = self.fanXing[self.HUNYISE]['name']
                        patterns.append(self.fanXing[self.HUNYISE]['name'])
                        fan += self.fanXing[self.HUNYISE]['index']
                        ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
                else:
                    if not isUnique:
                        self.results[self.KEY_NAME] = self.fanXing[self.QINGYISE]['name']
                        patterns.append(self.fanXing[self.QINGYISE]['name'])
                        fan += self.fanXing[self.QINGYISE]['index']
                        ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)


                        # 不求人 门清并自摸
            # 暗杠也算门清,重新计算
            # 烂牌和七对牌型时不计算不求人
            if not lanPaiPatternForWuji and not isPairs:
                isMenQing = False
                gangInfo = playerAllTiles[seatId][MHand.TYPE_GANG]
                chiInfo = playerAllTiles[seatId][MHand.TYPE_CHI]
                pengInfo = playerAllTiles[seatId][MHand.TYPE_PENG]
                if len(chiInfo) == 0 and len(pengInfo) == 0:
                    isMenQing = True
                    for gang in gangInfo:
                        if gang['style'] == 1:
                            isMenQing = False
                if isMenQing and seatId == self.lastSeatId:
                    if not isUnique:
                        self.results[self.KEY_WIN_MODE][seatId] = MYunnanOneResult.WIN_MODE_BUQIUREN
                        patterns.append(self.fanXing[self.BUQIUREN]['name'])
                        fan += self.fanXing[self.BUQIUREN]['index']
                        ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)

            # 全求人 最后手里只有一张牌 单钓 不能有暗杠
            if len(playerHandTiles[seatId]) == 1 and seatId != self.lastSeatId:
                noAnGang = True
                for gangInfo in nowTiles[MHand.TYPE_GANG]:
                    if gangInfo.has_key('style'):
                        gangStyle = gangInfo.get('style', 1)
                        if gangStyle == 0:
                            noAnGang = False
                            break;
                if noAnGang:
                    if not isUnique:
                        patterns.append(self.fanXing[self.QUANQIUREN]['name'])
                        fan += self.fanXing[self.QUANQIUREN]['index']
                        ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)

                        # 三元和混三元
            sanyuanForWuji = False
            baibanCount = self.getZiCountByTypeBySeatId(seatId, MTile.TILE_BAI_BAN)
            hongzhongCount = self.getZiCountByTypeBySeatId(seatId, MTile.TILE_HONG_ZHONG)
            facaiCount = self.getZiCountByTypeBySeatId(seatId, MTile.TILE_FA_CAI)
            sanyuanMagicCount = nowTiles[MHand.TYPE_HAND].count(MTile.TILE_ONE_TIAO)
            if baibanCount + sanyuanMagicCount >= 2 \
                    and hongzhongCount + sanyuanMagicCount >= 2 \
                    and facaiCount + sanyuanMagicCount >= 2:
                if baibanCount + hongzhongCount + sanyuanMagicCount >= 5 \
                        and baibanCount + facaiCount + sanyuanMagicCount >= 5 \
                        and hongzhongCount + facaiCount + sanyuanMagicCount >= 5:
                    if baibanCount + hongzhongCount + facaiCount + sanyuanMagicCount >= 8:
                        if self.colorState[seatId] == 1 and self.noFengPai(seatId):
                            # 混三元
                            if not isUnique:
                                sanyuanForWuji = True
                                patterns.append(self.fanXing[self.HUNSANYUAN]['name'])
                                fan += self.fanXing[self.HUNSANYUAN]['index']
                                ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
                        else:
                            # 三元
                            if not isUnique:
                                patterns.append(self.fanXing[self.SANYUAN]['name'])
                                fan += self.fanXing[self.SANYUAN]['index']
                                ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)

            # 无鸡
            isWuji = False
            wujiTiles = copy.deepcopy(nowTiles)
            # 手牌不要赖子能胡
            result0, _ = MWinRuleYunnan.checkHuByMagicTiles(wujiTiles, [])
            for temp in nowTiles[MHand.TYPE_CHI]:
                wujiTiles[MHand.TYPE_HAND].extend(temp)
            for temp in nowTiles[MHand.TYPE_PENG]:
                wujiTiles[MHand.TYPE_HAND].extend(temp)
            ftlog.debug("MYunnanOneResult wujiTiles = ", wujiTiles)
            # 加上碰吃,不要赖子也能胡
            result1, _ = MWinRuleYunnan.checkHuByMagicTiles(wujiTiles, [])
            wujiMagicCount = playerAllTilesArr[seatId].count(MTile.TILE_ONE_TIAO)
            ftlog.debug("MYunnanOneResult wujiTiles = ", wujiTiles, "result1=", result1)
            result2 = True
            # 算杠,不是4个幺鸡都是有赖子
            for magicTile in magicTiles:
                for gangInfo in wujiTiles[MHand.TYPE_GANG]:
                    wujiGangMagicCount = 0
                    if gangInfo.has_key('pattern'):
                        tempGangInfo = copy.deepcopy(gangInfo['pattern'])
                        while magicTile in tempGangInfo:
                            tempGangInfo.remove(magicTile)
                            wujiGangMagicCount += 1
                        if wujiGangMagicCount != 4 and wujiGangMagicCount != 0:
                            result2 = False
                            break
            ftlog.debug("MYunnanOneResult wujiTiles = ", wujiTiles
                        , "result1=", result1
                        , "result2=", result2
                        , "result0=", result0)
            if result1 and result2 and result0:
                isWuji = True
            if isWuji:
                if wujiMagicCount > 0:
                    canXiaojiguiwei = True
                    # 小鸡归位,要排除赖子应用在其它番型导致小鸡归位和其它番型不同存的情况
                    ftlog.debug("MYunnanOneResult canXiaojiguiwei oldColorState", oldColorState
                                , "lanPaiPatternForWuji", lanPaiPatternForWuji
                                , "qingyiseForWuji", qingyiseForWuji
                                , "ziyiseWuji", ziyiseWuji
                                , "sanyuanForWuji", sanyuanForWuji)

                    if lanPaiPatternForWuji:
                        # 如果是烂牌的小鸡归位,重新检查在没有赖子的情况能不能胡
                        resultNoMagic, fengCountNoMagic, lanPanMagicCountNoMagic = self.isLanPaiCheck(nowTiles, [])
                        if lanPanMagicCount > 0:
                            # 带赖子的六星烂,如果无赖子判定能胡,那就可以胡五星烂+小鸡归位
                            if self.fanXing[self.LIUXINGLAN]['name'] in patterns and resultNoMagic:
                                patterns.remove(self.fanXing[self.LIUXINGLAN]['name'])
                                fan -= self.fanXing[self.LIUXINGLAN]['index']
                                patterns.append(self.fanXing[self.WUXINGLAN]['name'])
                                fan += self.fanXing[self.WUXINGLAN]['index']
                                canXiaojiguiwei = True
                            elif self.fanXing[self.QIXINGLAN][
                                'name'] in patterns and resultNoMagic and fengCountNoMagic >= 7:
                                canXiaojiguiwei = True
                            else:
                                canXiaojiguiwei = False
                        else:
                            canXiaojiguiwei = True
                    if qingyiseForWuji:
                        if oldColorState[seatId] > 1:
                            canXiaojiguiwei = False
                    if ziyiseWuji:
                        if oldColorState[seatId] > 0:
                            canXiaojiguiwei = False
                    if sanyuanForWuji:
                        if oldColorState[seatId] > 1:
                            canXiaojiguiwei = False
                    if canXiaojiguiwei:
                        if not isUnique:
                            patterns.append(self.fanXing[self.XIAOJIGUIWEI]['name'])
                            fan += self.fanXing[self.XIAOJIGUIWEI]['index']
                            ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
                else:
                    if not isUnique:
                        patterns.append(self.fanXing[self.WUJI]['name'])
                        fan += self.fanXing[self.WUJI]['index']
                        ftlog.debug("MYunnanOneResult fanxing = ", patterns, "fan = ", fan)
            self.results[self.KEY_FAN_PATTERN][seatId] = patterns
            self.results[self.KEY_WIN_TILE][seatId] = self.winTile
            fanArr[seatId] = fan

        if self.lastSeatId in self.winSeats:
            self.results[self.KEY_STAT][self.lastSeatId].append({MOneResult.STAT_ZIMO: 1})
        else:
            # 点炮,点炮者点炮+1
            self.results[self.KEY_STAT][self.lastSeatId].append({MOneResult.STAT_DIANPAO: 1})
        # 最大番,当前的赢家番数
        self.results[self.KEY_STAT][seatId].append({MOneResult.STAT_ZUIDAFAN: fan})

        # 计算积分
        winScore = baseScore * (self.multiple)
        if self.qiangGang:
            if self.winRuleMgr.itemParams.get('QGHSanbei', 1) == 2:
                winScore = winScore
            else:
                winScore = winScore * 3
            for player in self.tableTileMgr.players:
                if player.curSeatId == self.lastSeatId and self.lastSeatId not in self.winSeats:
                    ftlog.debug("MYunnanOneResultQGH lose seatId:", player.curSeatId, "lastSeatId:", self.lastSeatId)
                    if self.winTile in player.handTiles:
                        ftlog.debug("MYunnanOneResultQGH lose seatId:", player.curSeatId, "lastSeatId:",
                                    self.lastSeatId, "remove tile:", self.winTile)
                        player.handTiles.remove(self.winTile)
                    else:
                        if self.showTile in player.handTiles and self.showTile != 0:
                            ftlog.debug("MYunnanOneResultQGH lose seatId:", player.curSeatId, "lastSeatId:",
                                        self.lastSeatId, "remove tile:", self.showTile)
                            player.handTiles.remove(self.showTile)
            for seatId in self.winSeats:
                if self.winRuleMgr.itemParams.get('QGHJiafan', 1) == 2:
                    fanArr[seatId] += 1
                self.results[self.KEY_WIN_MODE][seatId] = MOneResult.WIN_MODE_QIANGGANGHU

        # 番数上限3
        for win in self.winSeats:
            if fanArr[win] > 3:
                fanArr[win] = 3

        # 计算分数增减
        if self.lastSeatId in self.winSeats:
            for i in range(self.playerCount):
                if self.lastSeatId == i:
                    self.results[self.KEY_SCORE][i] = winScore * (2 ** fanArr[i]) * (self.playerCount - 1)
                else:
                    self.results[self.KEY_SCORE][i] = -winScore * (2 ** fanArr[self.lastSeatId])
        else:
            dianPaoScore = 0
            for i in range(self.playerCount):
                if i in self.winSeats:
                    self.results[self.KEY_SCORE][i] = winScore * (2 ** fanArr[i])
                    dianPaoScore += winScore * (2 ** fanArr[i])
            self.results[self.KEY_SCORE][self.lastSeatId] = -dianPaoScore

        ftlog.debug('MYunnanOneResult calcScore:KEY_SCORE:', self.results[self.KEY_SCORE])
        ftlog.debug('MYunnanOneResult calcScore:KEY_NAME:', self.results[self.KEY_NAME])
        ftlog.debug('MYunnanOneResult calcScore:KEY_TYPE:', self.results[self.KEY_TYPE])
        ftlog.debug('MYunnanOneResult calcScore:KEY_WIN_MODE:', self.results[self.KEY_WIN_MODE])
        ftlog.debug('MYunnanOneResult calcScore:KEY_FAN_PATTERN:', self.results[self.KEY_FAN_PATTERN])
        ftlog.debug('MYunnanOneResult calcScore:KEY_STAT:', self.results[self.KEY_STAT])
示例#30
0
    def checkSpecialHu(cls, tiles, magicTiles, magicTileCount, tile):
        # 判断七对系列
        if cls.isPairs(tiles, magicTiles):
            return True

        # 判定五六七星烂,手牌数必须为14,所有花色最多一张牌,字牌不重复且大于等于5种,其它花色必须都存在且互相不靠
        if cls.isLanPaiHu(tiles, magicTiles):
            return True

        # 判断其它特殊牌型

        allTiles = MHand.copyAllTilesToList(tiles)
        tempTiles = copy.deepcopy(allTiles)
        for magicTile in magicTiles:
            while magicTile in tempTiles:
                tempTiles.remove(magicTile)
        tileArr = MTile.changeTilesToValueArr(tempTiles)
        colorState = MTile.getColorCount(tileArr)
        tempFengTiles = MTile.traverseTile(MTile.TILE_FENG)
        ziState = tileArr[tempFengTiles[0]:tempFengTiles[len(tempFengTiles) -
                                                         1] + 1]
        #         menState = 0
        #         if len(allTiles) == 14:
        #             menState = 1
        playerGangCount = len(tiles[MHand.TYPE_GANG])

        if playerGangCount >= 2 \
                or colorState == 1 or colorState == 0 \
                or len(tiles[MHand.TYPE_HAND]) == 2 or len(tiles[MHand.TYPE_HAND]) == 3:
            return True

        # 三元和混三元
        baibanCount = cls.getZiCountByTypeBySeatId(MTile.TILE_BAI_BAN, ziState)
        hongzhongCount = cls.getZiCountByTypeBySeatId(MTile.TILE_HONG_ZHONG,
                                                      ziState)
        facaiCount = cls.getZiCountByTypeBySeatId(MTile.TILE_FA_CAI, ziState)
        if baibanCount + magicTileCount >= 2 \
                and hongzhongCount + magicTileCount >= 2 \
                and facaiCount + magicTileCount >= 2:
            if baibanCount + hongzhongCount + magicTileCount >= 5 \
                    and baibanCount + facaiCount + magicTileCount >= 5 \
                    and hongzhongCount + facaiCount + magicTileCount >= 5:
                if baibanCount + hongzhongCount + facaiCount + magicTileCount >= 8:
                    return True

        # 大对子,门前不能有吃,手牌多加一个赖子,能保证都是3张
        if len(tiles[MHand.TYPE_CHI]) == 0:
            duiziTiles = copy.deepcopy(tiles[MHand.TYPE_HAND])
            for magicTile in magicTiles:
                while magicTile in duiziTiles:
                    duiziTiles.remove(magicTile)
            # 如果点炮胡,需要给牌堆里加回去一张赖子,并当普通牌处理
            if tile in magicTiles:
                duiziTiles.append(tile)
            duiziArr = MTile.changeTilesToValueArr(duiziTiles)
            ftlog.debug("MYunnanOneResult duiziArr = ", duiziArr)
            cardTypeCount = 0
            # 假设多一张可用赖子
            duiziMagicCount = magicTileCount + 1
            for index in range(len(duiziArr)):
                if duiziArr[index] != 0:
                    cardTypeCount += 1
                    if duiziArr[index] < 3:
                        duiziMagicCount = duiziMagicCount - (3 -
                                                             duiziArr[index])
            if cardTypeCount <= 5 and duiziMagicCount >= 0:
                return True
        return False
示例#31
0
 def getTileLeftCount(self, tile):
     """获取某个花色剩余数量"""
     tileArr = MTile.changeTilesToValueArr(self.__tiles)
     return tileArr[tile]
示例#32
0
 def getTileLeftCount(self, tile):
     """获取某个花色剩余数量"""
     tileArr = MTile.changeTilesToValueArr(self.__tiles)
     return tileArr[tile]
示例#33
0
    def canTing(self, tiles, leftTiles, tile, magicTiles=[]):
        """子类必须实现
        参数:
        1)tiles 该玩家的手牌
        2)leftTiles 剩余手牌
        返回值:
        是否可以听牌,听牌详情
        """
        handCount = len(tiles[MHand.TYPE_HAND])
        if handCount < 5:
            return False, []

        #         ftlog.debug( 'MTingHaerbinRule.canTing 0 tiles:', tiles )
        isTing, tingResults = MTing.canTing(MTile.cloneTiles(tiles), leftTiles, self.winRuleMgr, tile, magicTiles)
        #         ftlog.debug( 'MTingHaerbinRule.canTing 1 tiles:', tiles )
        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])

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

        # 检查刻,刻的来源,碰牌/明杠牌/手牌
        keCount = pengCount + gangCount
        # 必须有顺牌
        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 )

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

                            # 夹起步不能和对倒
                            if len(pattern) == 3 and pattern[0] == pattern[1]:
                                chunJiaContinue = True
                                break

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

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

                zhongCount = tileArr[MTile.TILE_HONG_ZHONG]
                #         ftlog.debug( 'MTingHaerbinRule.canTing hongzhong count: ', zhongCount )

                # 检查牌中的幺/九
                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]
                #         ftlog.debug( 'MTingHaerbinRule.canTing yaoCount:', yaoCount, ' jiuCount:', jiuCount )

                if (yaoCount + jiuCount + zhongCount) == 0:
                    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
示例#34
0
    def calcGenCount(self, tiles, magicTile, mFactor):
        """算单癞子情况下一手牌里的根,墙上牌三张就算一根,三张+一个癞子还能多加一番"""
        genCount = 0
        extraFan = 0
        workTiles = copy.deepcopy(tiles)
        matchedPattern = {'gang': [], 'peng': []}
        if len(tiles[MHand.TYPE_GANG]) > 0:
            for gangInfo in tiles[MHand.TYPE_GANG]:
                if mFactor in gangInfo['pattern']:
                    extraFan = 1
                matchedPattern['gang'].append(gangInfo)
                ftlog.debug("gangAdd0")
                break
            genCount += len(tiles[MHand.TYPE_GANG])
        if len(tiles[MHand.TYPE_PENG]) > 0:
            # 先找一遍因子,优先匹配因子
            for peng in tiles[MHand.TYPE_PENG]:
                if mFactor in peng:
                    genCount += 1
                    #                     extraFan = 1
                    matchedPattern['peng'].append(peng)
                    ftlog.debug("pengAdd0")
                    break
            # 再找其他的 跳过因子
            for peng in tiles[MHand.TYPE_PENG]:
                matchedOk = False
                if mFactor in peng:
                    continue
                for pengTile in peng:
                    if pengTile != magicTile:
                        # 优先匹配非癞子
                        for handTile in workTiles[MHand.TYPE_HAND]:
                            if pengTile == handTile:
                                # 碰的母牌 手里还有  一定算一根
                                genCount += 1
                                matchedOk = True
                                ftlog.debug("pengAdd1")
                                matchedPattern['peng'].append(peng)
                                break
                        if matchedOk:
                            # 匹配成功直接找下一组碰
                            break
                        else:
                            for handTile in workTiles[MHand.TYPE_HAND]:
                                if handTile == magicTile:
                                    # 手里有癞子, 替换成碰的母牌 看是否能胡牌,能胡的话算一根
                                    workTiles[MHand.TYPE_HAND].remove(handTile)
                                    workTiles[MHand.TYPE_HAND].append(pengTile)
                                    result, _ = MWinRuleZhaotong.checkHuByMagicTiles(
                                        workTiles, [magicTile])
                                    if result:
                                        genCount += 1
                                        ftlog.debug("pengAdd2")
                                        matchedPattern['peng'].append(peng)
                                    else:
                                        # 还原手牌
                                        workTiles[MHand.TYPE_HAND].remove(
                                            pengTile)
                                        workTiles[MHand.TYPE_HAND].append(
                                            handTile)
                                    break

                        break
        tempGenArr = copy.deepcopy(workTiles[MHand.TYPE_HAND])
        genMagicCount = 0
        ftlog.debug("MYunnanOneResultCalcScore GENINFO tempGenArr", tempGenArr,
                    "genMagicCount", genMagicCount, "magicTile", magicTile,
                    "mFactor", mFactor, "genCount", genCount)

        while magicTile in tempGenArr:
            tempGenArr.remove(magicTile)
            genMagicCount += 1
        factorCount = 0
        while mFactor in tempGenArr:
            tempGenArr.remove(mFactor)
            factorCount += 1
        if factorCount + genMagicCount >= 4:
            genCount += 1
            extraFan = 1
            ftlog.debug("handAdd0")
            genMagicCount -= 4 - factorCount
        elif factorCount + genMagicCount >= 3:
            genCount += 1
            ftlog.debug("handAdd0.5")
            genMagicCount -= 3 - factorCount
        tileValueArr = MTile.changeTilesToValueArr(tempGenArr)
        tileIndex = 0
        handTileCount = {3: [], 2: [], 1: []}
        # 4个癞子的情况单独考虑
        for count in tileValueArr:
            if tileIndex <= 0 or tileIndex >= 30:
                tileIndex += 1
                continue
            if count == 4:
                genCount += 1
                ftlog.debug("handAdd1")
            elif count == 3:
                handTileCount[3].append(tileIndex)
            elif count == 2:
                handTileCount[2].append(tileIndex)
            elif count == 1:
                handTileCount[1].append(tileIndex)
            tileIndex += 1
        addGenCount = {}
        for i in range(3):
            if genMagicCount > 0 and len(handTileCount[i + 1]) > 0:
                addGenCount[i + 1], genMagicCount = self.dealWithGenCount(
                    workTiles, handTileCount[i + 1], i + 1, genMagicCount,
                    magicTile)
            else:
                break
        for i in range(3):
            if addGenCount.has_key(i + 1):
                genCount += addGenCount.get(i + 1, 0)
        ftlog.debug("MYunnanOneResultCalcScore GENINFO tempGenArr", tempGenArr,
                    "genMagicCount", genMagicCount, "magicTile", magicTile,
                    "mFactor", mFactor, "genCount", genCount, "matchedPattern",
                    matchedPattern)
        return genCount, extraFan
示例#35
0
    def tingQiDui(self, tiles, cur_tile, leftTiles):
        """
        检查是否可以听七小对
        二种牌型可听
        * 别人打牌 五对(包括杠) 一刻 粘一张
        * 自己上牌 六对(包括杠) 两个单张
        :param tiles 手牌
        :param cur_tile 刚刚摸的牌
        :param leftTiles: 全局剩余的牌
        :return
          [
            {
              'isQiDui' : 1
              'dropTile' : 11, # 出牌`一筒`
              'winNodes' : [{ # 听牌细节
                  'winTile' : 1, # 听`一万`
                  'winTileCount' : 3, # 剩`三张一万`
                  'pattern' : [
                    [6, 6], # 听牌的条件
                    ...
                  ]
                }]
            }
          ]
        """
        ftlog.debug('MTingHaerbinJixi.MTing.tingQiDui handTiles:', tiles[MHand.TYPE_HAND], ' tile:', cur_tile)
        handTiles = tiles[MHand.TYPE_HAND]
        newHandTiles = MTile.cloneTiles(handTiles)
        # 不考虑摸牌
        newHandTiles.remove(cur_tile)
        if len(newHandTiles) < 13:
            # 手牌不够
            return False, []

        newHandTilesArr = MTile.changeTilesToValueArr(newHandTiles)
        duiCount = 0
        singleTiles = []
        duiPattern = []
        for tile, number in newHandTilesArr.tile_items():
            if number == 2:
                # 对
                duiCount += 1
                duiPattern.append([tile, tile])
            elif number == 4:
                # 杠算两对
                duiCount += 2
                duiPattern.append([tile, tile])
                duiPattern.append([tile, tile])
            elif number == 3:
                # 碰
                if tile != cur_tile:
                    # 摸牌不能凑杠 有单张了
                    singleTiles.append(tile)
                duiPattern.append([tile, tile])
            elif tile != cur_tile:
                # 摸牌不能凑对 有单张了
                singleTiles.append(tile)
            else:
                duiPattern.append([cur_tile, cur_tile])

        if len(singleTiles) != 2:
            # 单张过多不能听七对
            # 单张过少则已经可以胡牌(不能听了)
            # ftlog.debug('MTingJixiRule.MTing.canTing tingQiDui the singleTiles count error: ', len(singleTiles))
            return False, []

        # 站牌处理 手里有五对 并且有一张或三张上的牌 那么可以听 方案就是剩下的两张
        newLeftTilesArr = MTile.changeTilesToValueArr(leftTiles)
        tingResult = [{  # 听第2张单牌
            'isQiDui': 1,
            'dropTile': singleTiles[0],
            'winNodes': [{
                'winTile': singleTiles[1],
                'winTileCount': newLeftTilesArr[singleTiles[1]],
                'pattern': duiPattern + [[singleTiles[1], singleTiles[1]]]
            }]
        }, {  # 听第1张单牌
            'isQiDui': 1,
            'dropTile': singleTiles[1],
            'winNodes': [{
                'winTile': singleTiles[0],
                'winTileCount': newLeftTilesArr[singleTiles[0]],
                'pattern': duiPattern + [[singleTiles[0], singleTiles[0]]]
            }]
        }]

        return True, tingResult
示例#36
0
    def checkSpecialHu(cls, tiles, magicTiles, magicTileCount, tile):
        # 判断七对系列
        if cls.isPairs(tiles, magicTiles):
            return True

        # 判定五六七星烂,手牌数必须为14,所有花色最多一张牌,字牌不重复且大于等于5种,其它花色必须都存在且互相不靠
        if cls.isLanPaiHu(tiles, magicTiles):
            return True

        # 判断其它特殊牌型

        allTiles = MHand.copyAllTilesToList(tiles)
        tempTiles = copy.deepcopy(allTiles)
        for magicTile in magicTiles:
            while magicTile in tempTiles:
                tempTiles.remove(magicTile)
        tileArr = MTile.changeTilesToValueArr(tempTiles)
        colorState = MTile.getColorCount(tileArr)
        tempFengTiles = MTile.traverseTile(MTile.TILE_FENG)
        ziState = tileArr[tempFengTiles[0]:tempFengTiles[len(tempFengTiles) - 1] + 1]
        #         menState = 0
        #         if len(allTiles) == 14:
        #             menState = 1
        playerGangCount = len(tiles[MHand.TYPE_GANG])

        if playerGangCount >= 2 \
                or colorState == 1 or colorState == 0 \
                or len(tiles[MHand.TYPE_HAND]) == 2 or len(tiles[MHand.TYPE_HAND]) == 3:
            return True

        # 三元和混三元
        baibanCount = cls.getZiCountByTypeBySeatId(MTile.TILE_BAI_BAN, ziState)
        hongzhongCount = cls.getZiCountByTypeBySeatId(MTile.TILE_HONG_ZHONG, ziState)
        facaiCount = cls.getZiCountByTypeBySeatId(MTile.TILE_FA_CAI, ziState)
        if baibanCount + magicTileCount >= 2 \
                and hongzhongCount + magicTileCount >= 2 \
                and facaiCount + magicTileCount >= 2:
            if baibanCount + hongzhongCount + magicTileCount >= 5 \
                    and baibanCount + facaiCount + magicTileCount >= 5 \
                    and hongzhongCount + facaiCount + magicTileCount >= 5:
                if baibanCount + hongzhongCount + facaiCount + magicTileCount >= 8:
                    return True

        # 大对子,门前不能有吃,手牌多加一个赖子,能保证都是3张
        if len(tiles[MHand.TYPE_CHI]) == 0:
            duiziTiles = copy.deepcopy(tiles[MHand.TYPE_HAND])
            for magicTile in magicTiles:
                while magicTile in duiziTiles:
                    duiziTiles.remove(magicTile)
            # 如果点炮胡,需要给牌堆里加回去一张赖子,并当普通牌处理
            if tile in magicTiles:
                duiziTiles.append(tile)
            duiziArr = MTile.changeTilesToValueArr(duiziTiles)
            ftlog.debug("MYunnanOneResult duiziArr = ", duiziArr)
            cardTypeCount = 0
            # 假设多一张可用赖子
            duiziMagicCount = magicTileCount + 1
            for index in range(len(duiziArr)):
                if duiziArr[index] != 0:
                    cardTypeCount += 1
                    if duiziArr[index] < 3:
                        duiziMagicCount = duiziMagicCount - (3 - duiziArr[index])
            if cardTypeCount <= 5 and duiziMagicCount >= 0:
                return True
        return False
示例#37
0
文件: chi_rule.py 项目: zhaozw/hall37
    def hasChi(self, tiles, tile):
        """是否有吃牌解
        
        参数说明;
        tiles - 玩家的所有牌,包括手牌,吃牌,碰牌,杠牌,胡牌
        tile - 待吃的牌
        """
        if tile >= MTile.TILE_DONG_FENG:
            return []

        chiSolutions = MChi.hasChi(tiles[MHand.TYPE_HAND], 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
示例#38
0
        输入参数:
            playMode - 玩法      
        返回值:
            对应玩法手牌管理器
        """
        if playMode == MPlayMode.HAERBIN:
            return MTableTileHaerbin(playerCount, playMode, runMode)
        elif playMode == MPlayMode.YUNNAN:
            return MTableTileYunnan(playerCount, playMode, runMode)
        elif playMode == MPlayMode.ZHAOTONG:
            return MTableTileZhaotong(playerCount, playMode, runMode)
        elif playMode == MPlayMode.JIXI:
            return MTableTileJixi(playerCount, playMode, runMode)
        elif MPlayMode().isSubPlayMode(playMode, MPlayMode.KAWUXING):
            return MTableTileKawuxing(playerCount, playMode, runMode)
        return MTableTile(playerCount, playMode, runMode)


if __name__ == "__main__":
    tableTileMgr = MTableTileFactory.getTableTileMgr(4, MPlayMode.HAERBIN,
                                                     MRunMode.CONSOLE)
    tableTileMgr.tileTestMgr.setHandTiles([[5, 5, 5, 5], [6, 6, 6, 6],
                                           [7, 7, 7, 7], [8, 8, 8, 8]])
    tableTileMgr.tileTestMgr.setTiles([9, 9, 9, 9])
    tableTileMgr.shuffle(0, 13)
    tiles = tableTileMgr.tiles
    print tiles

    tileArr = MTile.changeTilesToValueArr(tiles)
    print tileArr
示例#39
0
文件: chi_rule.py 项目: zhaozw/hall37
    def hasChi(self, tiles, tile):
        """是否有吃牌解
        
        参数说明;
        tiles - 玩家的所有牌,包括手牌,吃牌,碰牌,杠牌,胡牌
        tile - 待吃的牌
        """
        if tile >= MTile.TILE_DONG_FENG:
            return []

        chiSolutions = MChi.hasChi(tiles[MHand.TYPE_HAND], 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
示例#40
0
    def canTing(self, tiles, leftTiles, tile, magicTiles=[]):
        """子类必须实现
        参数:
        1)tiles 该玩家的手牌
        2)leftTiles 剩余手牌
        返回值:
        是否可以听牌,听牌详情
        """
        handCount = len(tiles[MHand.TYPE_HAND])

        if len(tiles[MHand.TYPE_CHI]) == 0 and len(
                tiles[MHand.TYPE_PENG]) == 0 and len(
                    tiles[MHand.TYPE_GANG]) == 0:
            isTing, tingResults = self.tingQiDui(tiles, tile, leftTiles)
            if isTing:
                ftlog.debug(
                    'MTingJixiRule.MTing.canTing tingQiDui tingResults:',
                    tingResults)
                return isTing, tingResults

                #         ftlog.debug( 'MTingJixiRule.canTing 0 tiles:', tiles )
        isTing, tingResults = MTing.canTing(MTile.cloneTiles(tiles), leftTiles,
                                            self.winRuleMgr, tile, magicTiles)
        #         ftlog.debug( 'MTingJixiRule.canTing 1 tiles:', tiles )
        ftlog.debug('MTingJixiRule.MTing.canTing isTing:', isTing,
                    ' tingResults:', tingResults)

        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 = False
                isPiaoHu = self.isPiaoHu(patterns, newTiles)

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

                # 夹起步(顺牌只能和夹和3,7) 不能和两头 可以单吊
                chunJiaConfig = self.getTableConfig(MTDefine.MIN_MULTI, 0)
                if chunJiaConfig:
                    bianMulti = self.tableConfig.get(MTDefine.BIAN_MULTI, 0)
                    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]:
                                hasJia = True
                                break

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

                zhongCount = tileArr[MTile.TILE_HONG_ZHONG]

                # 检查牌中的幺/九
                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]

                # 飘和七小对不需要1,9
                if (yaoCount + jiuCount +
                        zhongCount) == 0 and (not isPiaoHu) and (not isQiDui):
                    continue

                patterns = winNode['pattern']
                checkKeCount = keCount + self.getKeCount(patterns)
                ftlog.debug('MTingHaerbinRule.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)

        return len(newTingResults) > 0, newTingResults
示例#41
0
    def isHu(self,
             tiles,
             tile,
             isTing,
             getTileType,
             magicTiles=[],
             tingNodes=[]):
        """
        tiles:玩家所有的牌,但是手牌是加入了要胡的那张牌的
        """
        # 昭通无听牌
        ftlog.debug('MWinRuleZhaotong.isHu tiles:', tiles, ' tile:', tile,
                    ' magicTils:', magicTiles, ' getTileType:', getTileType)

        if getTileType != MWinRule.WIN_BY_MYSELF and MTableTile.isMagicTile(
                tile, magicTiles):
            # 如果是听用,不能胡
            return False, []

            # 先查花色
        playerAllTiles = []
        playerAllTiles.extend(tiles[MHand.TYPE_HAND])
        for chi in tiles[MHand.TYPE_CHI]:
            playerAllTiles.extend(chi)
        for peng in tiles[MHand.TYPE_PENG]:
            playerAllTiles.extend(peng)
        for gang in tiles[MHand.TYPE_GANG]:
            playerAllTiles.extend(gang['pattern'])
        colorStateWithMagic = MTile.getColorCount(
            MTile.changeTilesToValueArr(playerAllTiles))
        magicCount, tempTiles = MTableTile.getMagicTileCountInTiles(
            playerAllTiles, magicTiles)
        colorState = MTile.getColorCount(
            MTile.changeTilesToValueArr(tempTiles))
        ftlog.debug("MWinRuleZhaotong.isHu colorState = ", colorState,
                    "playerAllTiles = ", playerAllTiles, "tempTiles = ",
                    tempTiles, "colorStateWithMagic = ", colorStateWithMagic,
                    "magicCount = ", magicCount)
        # 必须缺一门才能胡牌
        if colorState >= 3:
            ftlog.debug("MWinRuleZhaotong.isHu men >= 3 can not hu")
            return False, []

        result1, pattern1 = MWinRuleZhaotong.checkHuByMagicTiles(
            tiles, magicTiles)
        #         result2, pattern2 = MWinRuleZhaotong.checkHuByMagicTiles(tiles, [])
        #         if colorStateWithMagic >= 3:
        #             if result1 and not result2:
        #                 return result1, pattern1
        #             else:
        #                 return False, []
        #         else:
        #             if result1:
        #                 return result1, pattern1
        #             else:
        #                 return False, []
        if result1:
            return result1, pattern1
        #             if getTileType != MWinRule.WIN_BY_MYSELF:
        #                 hasMagic = False
        #                 for magicTile in magicTiles:
        #                     if magicTile in tiles[MHand.TYPE_HAND]:
        #                         hasMagic = True
        #                 if hasMagic:
        #                     # 点炮和抢杠胡要检查是不是叫听用,如果叫听用,可以胡任意牌,采用抽3张牌测试的方式,如果通过就认为是叫听用
        #                     testTiles = []
        #                     if tile/10 == 0:
        #                         testTiles.append(2)
        #                         testTiles.append(6)
        #                         testTiles.append(9)
        #                     elif tile/10 == 1:
        #                         testTiles.append(12)
        #                         testTiles.append(14)
        #                         testTiles.append(17)
        #                     elif tile/10 == 2:
        #                         testTiles.append(22)
        #                         testTiles.append(24)
        #                         testTiles.append(28)
        #                     else:
        #                         return False, []
        #                     dandiao = True
        #                     for testTile in testTiles:
        #                         tempDandiao = copy.deepcopy(tiles)
        #                         if tile in tempDandiao[MHand.TYPE_HAND]:
        #                             tempDandiao[MHand.TYPE_HAND].remove(tile)
        #                         tempDandiao[MHand.TYPE_HAND].append(testTile)
        #                         resultDandiao, _ = MWinRuleZhaotong.checkHuByMagicTiles(tempDandiao, magicTiles)
        #                         if not resultDandiao:
        #                             dandiao = False
        #                     if not dandiao:
        #                         return result1, pattern1
        #                 else:
        #                     return result1, pattern1
        #             else:
        #                 return result1, pattern1
        return False, []
示例#42
0
    def calcScore(self):
        """算分"""

        # 序列化
        self.serialize()

        # 牌型数据都在tabletilemgr里面可以取到
        playerAllTiles = [[] for _ in range(self.playerCount)]
        playerAllTilesArr = [[] for _ in range(self.playerCount)]
        playerHandTiles = [[] for _ in range(self.playerCount)]
        for player in self.tableTileMgr.players:
            # 按手牌格式的数组
            playerAllTiles[player.curSeatId] = player.copyTiles()
            # 合到一个数组中
            playerAllTilesArr[player.curSeatId].extend(
                MHand.copyAllTilesToList(playerAllTiles[player.curSeatId]))
            # 只获取手牌
            playerHandTiles[player.curSeatId] = player.copyHandTiles()
        ftlog.debug("playerHandTiles", playerHandTiles)
        ftlog.debug("playerAllTiles", playerAllTiles)
        ftlog.debug("playerAllTilesArr", playerAllTilesArr)
        ftlog.debug("self.winTile", self.winTile)
        self.results[self.KEY_TYPE] = ''
        self.results[self.KEY_NAME] = ''
        self.results[self.KEY_SCORE] = [0 for _ in range(self.playerCount)]
        self.results[self.KEY_WIN_TILE] = [0 for _ in range(self.playerCount)]
        self.results[self.KEY_WIN_MODE] = [
            MOneResult.WIN_MODE_LOSS for _ in range(self.playerCount)
        ]
        # 在和牌时统计自摸,点炮,最大番数
        self.results[self.KEY_STAT] = [[] for _ in range(self.playerCount)]
        self.results[self.KEY_FAN_PATTERN] = [[]
                                              for _ in range(self.playerCount)]
        fanArr = [0 for _ in range(self.playerCount)]
        baseScore = 1

        # 获得癞子数据
        magicTiles = self.tableTileMgr.getMagicTiles()
        colorStateNoMagic = [0 for _ in range(self.playerCount)]
        magicTileCountArr = [0 for _ in range(self.playerCount)]
        # 处理玩家手牌,得到一手不带癞子的花色
        for seatId in range(self.playerCount):
            tempArrColor = copy.deepcopy(playerAllTilesArr[seatId])
            # colorState里面要去掉赖子包含的花色
            for magicTile in magicTiles:
                while magicTile in tempArrColor:
                    tempArrColor.remove(magicTile)
                    magicTileCountArr[seatId] += 1
            # 重新处理一次花色,不算赖子
            colorStateNoMagic[seatId] = MTile.getColorCount(
                MTile.changeTilesToValueArr(tempArrColor))

        if self.resultType == self.RESULT_FLOW:
            # 昭通的流局需要查花猪和大叫
            # 查花猪,赖子不算,赖子可以算作任何已有的花色,要先处理一下赖子s
            pigs = []
            noTings = []
            tings = []
            huSeats = []
            for player in self.tableTileMgr.players:
                if player.hasHu:
                    huSeats.append(player.curSeatId)
            for seatId in range(self.playerCount):
                if colorStateNoMagic[seatId] >= 3:
                    pigs.append(seatId)
            tempScore = [0 for _ in range(self.playerCount)]
            if len(pigs) > 0:
                pigInfo = {
                    'pigs': pigs,
                    'playerCount': self.playerCount,
                    'scoreBase': baseScore,
                    'fanMax': 4,
                    'huSeats': []
                }

                # 会修改传入的score参数
                self.calcPigsScore(pigInfo, tempScore)
                self.setPigs(pigs)
                ftlog.debug(
                    "MYunnanOneResult calcScore Type = RESULT_FLOW calcPigsScore tempScore:",
                    tempScore)

            # 开始查大叫
            # 查大叫,
            # 多给一个赖子能胡牌就算有叫
            for seatId in range(self.playerCount):
                if seatId in pigs or seatId in huSeats:
                    continue
                zhaoTongRule = MWinRuleZhaotong()
                tempNoTingTiles = copy.deepcopy(playerAllTiles[seatId])
                tempNoTingTiles[MHand.TYPE_HAND].append(magicTiles[0])
                result, _ = zhaoTongRule.checkHuByMagicTiles(
                    tempNoTingTiles, magicTiles)
                if result:
                    tings.append(seatId)
                else:
                    noTings.append(seatId)
            fanTings = [0 for _ in range(self.playerCount)]
            # 计算听牌人的番型
            for ting in tings:
                # 番型
                fanData = {'fan': 0, 'patterns': [], 'isUnique': False}
                fan = 1
                patterns = []
                isUnique = fanData.get('isUnique', False)
                tempTingTiles = copy.deepcopy(playerAllTiles[ting])
                tempTingTiles[MHand.TYPE_HAND].append(magicTiles[0])
                # 取出dropTiles和手牌
                dropTiles = self.tableTileMgr.dropTiles[ting]
                # 计算根,修改传入的fanData参数
                self.calcFanGen(fanData, tempTingTiles, magicTiles)
                # 七对必须门清,修改传入的fanData参数
                self.calcFanPairsSeven(fanData, tempTingTiles, magicTiles)
                # 没听用,只要有听用就不算,不管用不用来当赖子
                self.calcFanNoTingYong(fanData, playerAllTilesArr[ting],
                                       magicTiles)
                isDaduizi = False
                magicCount = 0
                # 大对子,门前不能有吃,手牌多加一个赖子,能保证都是3张
                if len(tempTingTiles[MHand.TYPE_CHI]) == 0:
                    duiziTiles = copy.deepcopy(tempTingTiles[MHand.TYPE_HAND])
                    for magicTile in magicTiles:
                        while magicTile in duiziTiles:
                            duiziTiles.remove(magicTile)
                            magicCount += 1
                    duiziArr = MTile.changeTilesToValueArr(duiziTiles)
                    ftlog.debug("MYunnanOneResult duiziArr = ", duiziArr)
                    cardTypeCount = 0
                    # 假设多一张赖子
                    duiziMagicCount = magicCount + 1
                    for index in range(len(duiziArr)):
                        if duiziArr[index] != 0:
                            cardTypeCount += 1
                            if duiziArr[index] < 3:
                                duiziMagicCount = duiziMagicCount - (
                                    3 - duiziArr[index])
                    if cardTypeCount <= 5 and duiziMagicCount >= 0:
                        patterns.append(self.fanXing[self.DUIDUIHU]['name'])
                        fan += self.fanXing[self.DUIDUIHU]['index']
                        ftlog.debug("MYunnanOneResult fanxing = ", patterns,
                                    "fan = ", fan)
                        isDaduizi = True
                        # 清一色
                if colorStateNoMagic[ting] == 1:
                    if isDaduizi:
                        if not isUnique:
                            if self.fanXing[self.DUIDUIHU]['name'] in patterns:
                                patterns.remove(
                                    self.fanXing[self.DUIDUIHU]['name'])
                            patterns.append(
                                self.fanXing[self.QINGYISEDADUIZI]['name'])
                            fan -= self.fanXing[self.DUIDUIHU]['index']
                            fan += self.fanXing[self.QINGYISEDADUIZI]['index']
                            ftlog.debug("MYunnanOneResult fanxing = ",
                                        patterns, "fan = ", fan)
                    else:
                        if not isUnique:
                            patterns.append(
                                self.fanXing[self.QINGYISE]['name'])
                            fan += self.fanXing[self.QINGYISE]['index']
                            ftlog.debug("MYunnanOneResuFlt fanxing = ",
                                        patterns, "fan = ", fan)

                fanData['fan'] = fanData['fan'] + fan
                fanData['patterns'].extend(patterns)
                ftlog.debug("MYunnanOneResult gameFlow fanData = ", fanData)
                fanTings[ting] = fanData.get('fan', 0)
                # 打出过赖子最大只能胡一番
                for magicTile in magicTiles:
                    if magicTile in dropTiles:
                        if fanTings[ting] > 1:
                            fanTings[ting] = 1
                if fanTings[ting] >= 5:
                    fanTings[ting] = 5
            if len(noTings) > 0:
                tingInfo = {
                    'noTings': noTings,
                    'tings': tings,
                    'scoreBase': baseScore,
                    'fanArr': fanTings
                }
                self.calcTingScore(tingInfo, tempScore)
                self.setNoTings(noTings)
                ftlog.debug(
                    "MYunnanOneResult calcScore Type = RESULT_FLOW calcTingScore tempScore:",
                    tempScore)

            self.results[self.KEY_TYPE] = MOneResult.KEY_TYPE_NAME_FLOW
            self.results[self.KEY_SCORE] = tempScore
            # 如果是最终结算,把数据取出来放在results里
            for seatId in huSeats:
                result = self.winRuleMgr.getHasHuDataBySeatId(seatId)
                if result:
                    self.results[self.KEY_WIN_MODE][seatId] = result.get(
                        'winMode', -1)
                    self.results[self.KEY_FAN_PATTERN][seatId] = result.get(
                        'fan', [])
                    self.results[self.KEY_WIN_TILE][seatId] = result.get(
                        'winTile', 0)
            # 清空保存的这些数据
            self.winRuleMgr.clearHasHuData()
            ftlog.debug("MYunnanOneResult calcScore Type = RESULT_FLOW return")
            return

        self.results[self.KEY_TYPE] = MOneResult.KEY_TYPE_NAME_HU

        if len(self.winSeats) <= 0:
            ftlog.debug("MYunnanOneResult self.winSeats error no winner")
            return
        ftlog.debug("MYunnanOneResultCalcScore self.winSeats = ",
                    self.winSeats)

        if self.lastSeatId not in self.winSeats:
            self.results[self.KEY_WIN_MODE][
                self.lastSeatId] = MOneResult.WIN_MODE_DIANPAO

        maxFan = 0
        # 计算胡牌者的番型和分数
        for seatId in self.winSeats:
            # 番型
            fanData = {
                'fan': 0,
                'patterns': [],
                'isUnique': False,
                'isSpecial': False
            }
            ftlog.debug("MYunnanOneResultCalcScorelatestGangState = ",
                        self.latestGangState)
            ftlog.debug(
                'MajiangTableLogic.gameWin.yipaoduoxiang dealwith seatId:',
                seatId, 'lastSeatId:', self.lastSeatId, 'winSeatId:',
                self.winSeatId, 'self.winSeats:', self.winSeats,
                'self.actionID:', self.actionID, 'self.bankerSeatId:',
                self.bankerSeatId)
            if seatId == self.lastSeatId:
                self.results[
                    self.KEY_WIN_MODE][seatId] = MOneResult.WIN_MODE_ZIMO
            else:
                self.results[
                    self.KEY_WIN_MODE][seatId] = MOneResult.WIN_MODE_PINGHU

            # 取出dropTiles和手牌
            dropTiles = self.tableTileMgr.dropTiles[seatId]
            nowTiles = playerAllTiles[seatId]
            nowTiles[MHand.TYPE_HAND].append(self.winTile)
            # 计算根
            self.calcFanGen(fanData, nowTiles, magicTiles)
            # 杠上花和杠上炮
            self.calcFanAfterGang(fanData, self.latestGangState, seatId,
                                  self.lastSeatId)
            # 天胡地胡,没有出过牌,没有吃碰杠
            self.calcFanTianDiHu(fanData, seatId, self.bankerSeatId,
                                 self.lastSeatId, nowTiles, dropTiles)
            # 七对必须门清
            self.calcFanPairsSeven(fanData, nowTiles, magicTiles)
            # 没听用,只要有听用就不算,不管用不用来当赖子
            self.calcFanNoTingYong(fanData, playerAllTilesArr[seatId],
                                   magicTiles)
            # 大对子,门前不能有吃,手牌多加一个赖子,能保证都是3张
            isDaduizi = False
            _, _, _, isDaduizi = self.calcFanDaduizi(fanData, nowTiles,
                                                     magicTiles,
                                                     magicTileCountArr[seatId],
                                                     self.winTile, seatId,
                                                     self.lastSeatId)
            # 清一色
            self.calcFanQingyise(fanData, colorStateNoMagic[seatId], isDaduizi)
            # 自摸是否加番的处理
            if self.winRuleMgr.zimoBonus == 2:
                if self.lastSeatId == seatId:
                    fanData['fan'] += 1
            # 如果对对胡,清一色,七对,龙七对,天胡,地胡,双龙对,清一色大对子,当不存在以上番型时 有平胡的1番
            if not fanData.get('isSpecial', False):
                fanData['fan'] += 1
            ftlog.debug("MYunnanOneResult fanData = ", fanData)
            self.results[self.KEY_WIN_TILE][seatId] = self.winTile
            self.results[self.KEY_FAN_PATTERN][seatId] = copy.deepcopy(
                fanData['patterns'])
            fanArr[seatId] = fanData.get('fan', 0)
            # 打出过赖子最大只能胡一番
            for magicTile in magicTiles:
                if magicTile in dropTiles:
                    if fanArr[seatId] > 1:
                        fanArr[seatId] = 1
            if fanArr[seatId] > maxFan:
                maxFan = fanArr[seatId]
        if self.lastSeatId in self.winSeats:
            self.results[self.KEY_STAT][self.lastSeatId].append(
                {MOneResult.STAT_ZIMO: 1})
        else:
            # 点炮,点炮者点炮+1
            self.results[self.KEY_STAT][self.lastSeatId].append(
                {MOneResult.STAT_DIANPAO: 1})
        # 最大番,当前的赢家番数
        self.results[self.KEY_STAT][seatId].append(
            {MOneResult.STAT_ZUIDAFAN: maxFan})

        # 番数上限5
        for win in self.winSeats:
            if fanArr[win] > 5:
                fanArr[win] = 5

        # 把血战里面已经胡牌的人的位置挑出来
        hasHu = []
        for player in self.tableTileMgr.players:
            if player.hasHu:
                hasHu.append(player.curSeatId)
        if len(hasHu) >= self.playerCount - 1:
            ftlog.error("MZhaotongOneReuslt hasHu Error hasHu:", hasHu)

            # 计算积分
        #         winScore = baseScore*(self.multiple)
        winScore = baseScore
        if self.qiangGang:
            # 如果是最后一个输的人被抢杠胡,需要把被抢的牌从他手中拿掉
            if len(hasHu) + len(self.winSeats) >= self.playerCount - 1:
                for player in self.tableTileMgr.players:
                    if player.curSeatId == self.lastSeatId and self.lastSeatId not in self.winSeats:
                        if self.winTile in player.handTiles:
                            player.handTiles.remove(self.winTile)
                        else:
                            player.handTiles.remove(magicTiles[0])
            for seatId in self.winSeats:
                self.results[self.KEY_WIN_MODE][
                    seatId] = MOneResult.WIN_MODE_QIANGGANGHU

        # 计算分数增减
        if self.lastSeatId in self.winSeats:
            for i in range(self.playerCount):
                if self.lastSeatId == i:
                    looseCount = self.playerCount - 1 - len(hasHu)
                    if looseCount <= 0:
                        looseCount = 1
                    self.results[self.KEY_SCORE][i] = winScore * (2**(
                        fanArr[i] - 1)) * looseCount
                elif i in hasHu:
                    continue
                else:
                    self.results[self.KEY_SCORE][i] = -winScore * (2**(
                        fanArr[self.lastSeatId] - 1))
        else:
            dianPaoScore = 0
            for i in range(self.playerCount):
                if i in self.winSeats:
                    if i not in hasHu:
                        self.results[self.KEY_SCORE][i] = winScore * (2**(
                            fanArr[i] - 1))
                        dianPaoScore += winScore * (2**(fanArr[i] - 1))
            self.results[self.KEY_SCORE][self.lastSeatId] = -dianPaoScore

        if self.playerCount - len(hasHu) - len(self.winSeats) == 1:
            # 如果是最终结算,把数据取出来放在results里
            for seatId in hasHu:
                result = self.winRuleMgr.getHasHuDataBySeatId(seatId)
                if result:
                    self.results[self.KEY_WIN_MODE][seatId] = result.get(
                        'winMode', -1)
                    self.results[self.KEY_FAN_PATTERN][seatId] = result.get(
                        'fan', [])
                    self.results[self.KEY_WIN_TILE][seatId] = result.get(
                        'winTile', 0)
            # 清空保存的这些数据
            self.winRuleMgr.clearHasHuData()
        else:
            # 如果不是最终结算,把胜者的一些信息存起来
            for seatId in self.winSeats:
                result = {
                    'winMode': self.results[self.KEY_WIN_MODE][seatId],
                    'fan': self.results[self.KEY_FAN_PATTERN][seatId],
                    'winTile': self.results[self.KEY_WIN_TILE][seatId]
                }
                self.winRuleMgr.saveHasHuData(result, seatId)

        ftlog.debug('MYunnanOneResult calcScore:KEY_SCORE:',
                    self.results[self.KEY_SCORE])
        ftlog.debug('MYunnanOneResult calcScore:KEY_NAME:',
                    self.results[self.KEY_NAME])
        ftlog.debug('MYunnanOneResult calcScore:KEY_TYPE:',
                    self.results[self.KEY_TYPE])
        ftlog.debug('MYunnanOneResult calcScore:KEY_WIN_MODE:',
                    self.results[self.KEY_WIN_MODE])
        ftlog.debug('MYunnanOneResult calcScore:KEY_FAN_PATTERN:',
                    self.results[self.KEY_FAN_PATTERN])
        ftlog.debug('MYunnanOneResult calcScore:KEY_STAT:',
                    self.results[self.KEY_STAT])
示例#43
0
    def getTableTileMgr(cls, playerCount, playMode, runMode):
        """牌桌手牌管理器获取工厂
        输入参数:
            playMode - 玩法      
        返回值:
            对应玩法手牌管理器
        """
        if playMode == MPlayMode.HAERBIN:
            return MTableTileHaerbin(playerCount, playMode, runMode)
        elif playMode == MPlayMode.YUNNAN:
            return MTableTileYunnan(playerCount, playMode, runMode)
        elif playMode == MPlayMode.ZHAOTONG:
            return MTableTileZhaotong(playerCount, playMode, runMode)
        elif playMode == MPlayMode.JIXI:
            return MTableTileJixi(playerCount, playMode, runMode)
        elif MPlayMode().isSubPlayMode(playMode, MPlayMode.KAWUXING):
            return MTableTileKawuxing(playerCount, playMode, runMode)
        return MTableTile(playerCount, playMode, runMode)


if __name__ == "__main__":
    tableTileMgr = MTableTileFactory.getTableTileMgr(4, MPlayMode.HAERBIN, MRunMode.CONSOLE)
    tableTileMgr.tileTestMgr.setHandTiles([[5, 5, 5, 5], [6, 6, 6, 6], [7, 7, 7, 7], [8, 8, 8, 8]])
    tableTileMgr.tileTestMgr.setTiles([9, 9, 9, 9])
    tableTileMgr.shuffle(0, 13)
    tiles = tableTileMgr.tiles
    print tiles

    tileArr = MTile.changeTilesToValueArr(tiles)
    print tileArr