Beispiel #1
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, []
Beispiel #2
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, []
Beispiel #3
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])
Beispiel #4
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, []
Beispiel #5
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, []
Beispiel #6
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
Beispiel #7
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])
Beispiel #8
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
Beispiel #9
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