def doQingYiSe(self, allTiles, leftTiles, seatId, abColors):
        '''
            是否做清一色
        '''
        isSanSha, bestColor = self.isSanShaQingYiSe(seatId, abColors)
        if isSanSha:
            ftlog.debug('SanSha, best situation!!! doSanShaQingYiSe')
            return True, bestColor

        length = 9
        if len(leftTiles) >= 50:
            length = 8
        elif len(leftTiles) >= 40:
            length = 9
        elif len(leftTiles) >= 30:
            length = 10
        elif len(leftTiles) >= 20:
            length = 11

        allTilesArr = MHand.copyAllTilesToList(allTiles)
        cpgTiles = MHand.copyTiles(
            allTiles, [MHand.TYPE_CHI, MHand.TYPE_PENG, MHand.TYPE_GANG])
        wans = MTile.filterTiles(allTilesArr, MTile.TILE_WAN)
        wanLength = len(wans)
        if wanLength >= length:
            for tile in cpgTiles:
                if MTile.getColor(tile) != MTile.TILE_WAN:
                    return False, MTile.TILE_FENG
            return True, MTile.TILE_WAN

        tongs = MTile.filterTiles(allTilesArr, MTile.TILE_TONG)
        tongLength = len(tongs)
        if tongLength >= length:
            for tile in cpgTiles:
                if MTile.getColor(tile) != MTile.TILE_TONG:
                    return False, MTile.TILE_FENG
            return True, MTile.TILE_TONG

        tiaos = MTile.filterTiles(allTilesArr, MTile.TILE_TIAO)
        tiaoLength = len(tiaos)
        if tiaoLength >= length:
            for tile in cpgTiles:
                if MTile.getColor(tile) != MTile.TILE_TIAO:
                    return False, MTile.TILE_FENG
            return True, MTile.TILE_TIAO

        if wanLength >= tongLength and wanLength >= tiaoLength:
            return False, MTile.TILE_WAN
        elif tongLength >= wanLength and tongLength >= tiaoLength:
            return False, MTile.TILE_TONG
        else:
            return False, MTile.TILE_TIAO
Exemple #2
0
    def hasChi(self, tiles, tile, extendInfo={}):
        """是否有吃牌解
        
        参数说明;
        tiles - 玩家的所有牌,包括手牌,吃牌,碰牌,杠牌,胡牌
        tile - 待吃的牌
        """
        newTiles = copy.deepcopy(tiles)
        absenseColor = extendInfo.get('absenseColor', -1)
        if MTile.getColor(tile) == absenseColor:
            return []

        newTiles[MHand.TYPE_HAND] = filter(
            lambda x: MTile.getColor(x) != absenseColor,
            newTiles[MHand.TYPE_HAND])
        return super(MChiRuleXuezhan, self).hasChi(newTiles, tile)
    def isWin(self,
              allTiles,
              winTile,
              winStyle,
              leftTiles,
              seatResponse,
              extend={}):
        '''
            默认能胡就胡
            allTiles - 当前玩家的所有手牌
            winTile - 胡牌
            winStyle - 是吃炮胡,抢杠胡,还是自摸胡。
                被人点炮则胡
                自摸胡时,考虑下是否更换听口,以博取更好的机会
            seatResponse - 玩家是否选择,已选择,则返回True
            
            extend - 扩展信息,本接口不要再添加更多参数,更多参数通过extend传递
        '''
        ftlog.debug('isWin allTiles:', allTiles, ' winTile:', winTile,
                    ' winStyle:', winStyle, ' leftTiles:', leftTiles,
                    ' seatResponse:', seatResponse)

        if seatResponse:
            return True

        seatId = extend.get('seatId', None)
        abColors = extend.get('absenceColor', None)
        doQing, qingColor = self.doQingYiSe(allTiles, leftTiles, seatId,
                                            abColors)
        if doQing:
            return self.isQingYiSe(
                allTiles, qingColor) and (MTile.getColor(winTile) == qingColor)
        return True
    def isChi(self,
              allTiles,
              chiTile,
              chiPatterns,
              leftTiles,
              tingResults,
              seatResponse,
              extend={}):
        '''
            默认能吃就吃
            allTiles - 当前玩家的所有手牌
            chiTile - 吃牌
            chiPatterns - 吃牌方案
            seatResponse - 玩家是否做出选择
            
            extend - 扩展信息,本接口不要再添加更多参数,更多参数通过extend传递
        '''
        if seatResponse:
            return True

        seatId = extend.get('seatId', None)
        abColors = extend.get('absenceColor', None)
        doQing, qingColor = self.doQingYiSe(allTiles, leftTiles, seatId,
                                            abColors)
        if doQing:
            return (MTile.getColor(chiTile) == qingColor)

        return True
    def isPeng(self,
               allTiles,
               pengTile,
               pengPatterns,
               leftTiles,
               tingResults,
               seatResponse,
               extend={}):
        '''
            默认能碰就碰
            allTiles - 当前玩家的所有手牌
            pengTile - 碰牌
            pengPatterns - 碰牌方案
            seatResponse - 玩家是否选择
            
            extend - 扩展信息,本接口不要再添加更多参数,更多参数通过extend传递
        '''
        if seatResponse:
            return True

        seatId = extend.get('seatId', None)
        abColors = extend.get('absenceColor', None)
        doQing, qingColor = self.doQingYiSe(allTiles, leftTiles, seatId,
                                            abColors)
        if doQing:
            return (MTile.getColor(pengTile) == qingColor)

        return True
Exemple #6
0
    def shuffle(self, goodPointCount, handTileCount):
        """
        洗牌器 
        子类里可添加特殊逻辑,比如确定宝牌
        """
        if self.tileTestMgr.initTiles():
            # 检查手牌
            handTiles = self.tileTestMgr.handTiles
            poolTiles = self.tileTestMgr.tiles
            ftlog.debug("self.tiles len1 = ", len(self.__tiles),
                        "poolTiles = ", poolTiles, "handTiles = ", handTiles)
            if self.__dealer.initTiles(handTiles, poolTiles):
                ftlog.debug("self.tiles len2 = ", len(self.__tiles),
                            "poolTiles = ", poolTiles, "handTiles = ",
                            handTiles)
                self.__tiles = copy.deepcopy(self.__dealer.tiles)
            ftlog.debug("self.tiles len3 = ", len(self.__tiles),
                        "poolTiles = ", poolTiles, "handTiles = ", handTiles)
        else:
            ftlog.debug("self.tiles len4 = ", len(self.__tiles))
            self.__tiles = self.__dealer.shuffle(goodPointCount, handTileCount)
            ftlog.debug("self.tiles len5 = ", len(self.__tiles))
        ftlog.info('MTableTile.shuffle tiles:', self.__tiles)

        if self.removeFeng:
            self.__tiles = filter(lambda x: not MTile.isFeng(x), self.__tiles)
        if self.removeArrow:
            self.__tiles = filter(lambda x: not MTile.isArrow(x), self.__tiles)

        if self.isRemoveWanTile:
            self.__tiles = filter(
                lambda x: MTile.getColor(x) == MTile.TILE_WAN, self.__tiles)

        return self.__tiles
Exemple #7
0
 def canTing(self, tiles, leftTiles, tile, magicTiles=[], winSeatId=0):
     """子类必须实现
     参数:
     1)tiles 该玩家的手牌
     返回值:
     是否可以听牌,听牌详情
     """
     # 血流 血战听牌 需要没有缺牌
     tileArr = MTile.changeTilesToValueArr(MHand.copyAllTilesToList(tiles))
     # 获取当前座位号定缺的花色
     colorAbsence = self.tableTileMgr.absenceColors[winSeatId]
     # 获取手牌中定缺花色牌的数量,大于1,不用判断听 缺牌为1张的时候,打出去缺牌,有可能会听牌
     colorAbsenceNum = MTile.getTileCountByColor(tileArr, colorAbsence)
     # ftlog.debug('MTingRuleSiChuan.canTing colorAbsenceNum:', colorAbsenceNum, 'tiles:', tiles, 'tile:', tile, 'colorAbsence:', colorAbsence)
     if colorAbsenceNum > 1:
         return False, []
     resultFlag, result = MTing.canTing(self.tilePatternChecker, self.tableTileMgr, tiles, leftTiles, self.winRuleMgr, tile, magicTiles, winSeatId)
     # 如果听牌中有定的缺色,需要把其余的听口去掉
     ftlog.debug('MTingRuleSiChuan.canTing result:', result)
     if resultFlag and colorAbsenceNum == 1:
         filterResult = []
         for tingNodes in result:
             if MTile.getColor(tingNodes['dropTile']) == colorAbsence:
                 filterResult.append(tingNodes)
         ftlog.debug('MTingRuleSiChuan.canTing filterResult:', filterResult)
         return len(filterResult) > 0, filterResult   
     else:
         return resultFlag, result 
    def isTing(self,
               allTiles,
               dropTile,
               leftTiles,
               seatResponse=False,
               extend={}):
        '''
        是否听牌
        '''
        ftlog.debug('isTing allTiles:', allTiles, ' dropTile:', dropTile,
                    ' leftTiles:', leftTiles, ' seatResponse:', seatResponse)
        if seatResponse:
            return True

        seatId = extend.get('seatId', None)
        abColors = extend.get('absenceColor', None)
        doQing, qingColor = self.doQingYiSe(allTiles, leftTiles, seatId,
                                            abColors)
        if doQing:
            handTiles = copy.deepcopy(allTiles[MHand.TYPE_HAND])
            handColors = MTile.filterTiles(handTiles, qingColor)
            if (MTile.getColor(dropTile)
                    == qingColor) and (len(handTiles) != len(handColors)):
                ftlog.debug('handTiles:', handTiles, ' handColors:',
                            handColors, ' dropTile:', dropTile,
                            ' doQingYiSe, do not drop...')
                return False
        return True
    def doQingYiSe(self, allTiles, leftTiles):
        '''
            是否做清一色
        '''
        length = 9
        if len(leftTiles) >= 50:
            length = 8
        elif len(leftTiles) >= 40:
            length = 9
        elif len(leftTiles) >= 30:
            length = 10
        elif len(leftTiles) >= 20:
            length = 11

        allTilesArr = MHand.copyAllTilesToList(allTiles)
        cpgTiles = MHand.copyTiles(
            allTiles, [MHand.TYPE_CHI, MHand.TYPE_PENG, MHand.TYPE_GANG])
        wans = MTile.filterTiles(allTilesArr, MTile.TILE_WAN)
        wanLength = len(wans)
        if wanLength >= length:
            for tile in cpgTiles:
                if MTile.getColor(tile) != MTile.TILE_WAN:
                    return False, MTile.TILE_FENG
            return True, MTile.TILE_WAN

        tongs = MTile.filterTiles(allTilesArr, MTile.TILE_TONG)
        tongLength = len(tongs)
        if tongLength >= length:
            for tile in cpgTiles:
                if MTile.getColor(tile) != MTile.TILE_TONG:
                    return False, MTile.TILE_FENG
            return True, MTile.TILE_TONG

        tiaos = MTile.filterTiles(allTilesArr, MTile.TILE_TIAO)
        tiaoLength = len(tiaos)
        if tiaoLength >= length:
            for tile in cpgTiles:
                if MTile.getColor(tile) != MTile.TILE_TIAO:
                    return False, MTile.TILE_FENG
            return True, MTile.TILE_TIAO

        if wanLength >= tongLength and wanLength >= tiaoLength:
            return False, MTile.TILE_WAN
        elif tongLength >= wanLength and tongLength >= tiaoLength:
            return False, MTile.TILE_TONG
        else:
            return False, MTile.TILE_TIAO
    def isQingYiSe(self, allTiles, qingColor):
        '''
        判断当前是否是清一色
        '''
        allTilesArr = MHand.copyAllTilesToList(allTiles)
        for tile in allTilesArr:
            if MTile.getColor(tile) != qingColor:
                return False

        return True
Exemple #11
0
    def hasGang(self, tiles, curTile, state, extendInfo={}):
        """判断杠牌"""

        # 缺门的牌不能杠
        absenceColor = extendInfo.get('absenceColor', -1)
        if MTile.getColor(curTile) == absenceColor:
            return []

        return super(MGangRuleHeXian, self).hasGang(tiles, curTile, state,
                                                    extendInfo)
Exemple #12
0
    def getFengKe(self):
        """
        获得风刻的分数:手牌区和碰牌区
        """
        score = 0
        pengTile = self.playerAllTiles[self.winSeatId][MHand.TYPE_PENG]  # 碰牌区
        handTile = copy.deepcopy(self.playerAllTiles[self.winSeatId][MHand.TYPE_HAND])
        for pengPatten in pengTile:
                if MTile.getColor(pengPatten[0]) == 3:
                    score = score + 1

        tileCountArr = MTile.changeTilesToValueArr(handTile)  # 手牌区
        for tileIndex in range(0, len(tileCountArr)):
            # 刻子
            if tileCountArr[tileIndex] == 3 and MTile.getColor(tileIndex) == 3:
                score = score + 1

        ftlog.debug('jinan_one_result.getFengKe  ', score)
        return score
Exemple #13
0
 def isWin(self, allTiles, winTile, winStyle, leftTiles):
     '''
         默认能胡就胡
         allTiles - 当前玩家的所有手牌
         winTile - 胡牌
         winStyle - 是吃炮胡,抢杠胡,还是自摸胡。
             被人点炮则胡
             自摸胡时,考虑下是否更换听口,以博取更好的机会
     '''
     doQing, qingColor = self.doQingYiSe(allTiles, leftTiles)
     if doQing:
         return (MTile.getColor(winTile) == qingColor)
     return True
    def chooseBestDropTile(self, tiles, leftTiles, mostColor):
        '''
        从若干最小分值的牌中选择一个最合适的
        附加权重:
        1)自身权重
        1、9的本身附加权重为0
        2,8的附件权重为1
        3,4,5,6,7的附件权重为2
        2)剩余牌数权重
        剩余牌数的附件权重每张为1
        3)花色权重
        花色之间的比较,花色较多的一方去加权重为1,花色较少的一方附件权重为0
        '''
        if len(tiles) == 1:
            return tiles[0]

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

        minTile = 0
        minValue = 0

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

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

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

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

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

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

        return minTile
Exemple #15
0
    def isDuanYaoJiu(self):
        """
        断幺九:每副顺子,刻字,将牌都不包含1或9
        """
        if self.tableConfig.get(MTDefine.DUANYAOJIU, 0) != 1:
            return False
        
        allPlayerTiles = MHand.copyAllTilesToList(self.tableTileMgr.players[self.winSeatId].copyTiles())
        yaoJiuCount = 0
        for tile in allPlayerTiles:
            if MTile.getColor(tile) == MTile.TILE_FENG or tile%10 == 1 or tile%10 == 9:
                yaoJiuCount += 1

        return yaoJiuCount == 0
Exemple #16
0
    def isDuanYaoJiu(self):
        """
        断幺九:每副顺子,刻字,将牌都不包含1或9
        """
        if self.tableConfig.get(MTDefine.DUANYAOJIU, 0) != 1:
            return False

        allPlayerTiles = MHand.copyAllTilesToList(
            self.tableTileMgr.players[self.winSeatId].copyTiles())
        yaoJiuCount = 0
        for tile in allPlayerTiles:
            if MTile.getColor(
                    tile
            ) == MTile.TILE_FENG or tile % 10 == 1 or tile % 10 == 9:
                yaoJiuCount += 1

        return yaoJiuCount == 0
Exemple #17
0
    def isQingyise(self):
        """
        清一色:只有一色牌(如全是万),有无金牌皆可,但金牌必须与其他牌同色
        """
        colorArr = [0, 0, 0, 0]
        handTile = MHand.copyAllTilesToList(self.playerAllTiles[self.winSeatId])  # 手牌区+吃+碰+杠+锚+胡区

        for tile in handTile:
            color = MTile.getColor(tile)
            colorArr[color] = 1

        colorCount = 0
        for eachColor in colorArr:
            if eachColor:
                colorCount += 1
        if colorCount == 1:
            return True
        return False
    def isQingyise(self):
        """
        清一色:由同一门花色(筒子或条子)组成的和牌牌型
        """
        colorArr = [0, 0, 0, 0]
        for tile in self.playerAllTilesArr[self.winSeatId]:
            color = MTile.getColor(tile)
            colorArr[color] = 1

        colorCount = 0
        for eachColor in colorArr:
            if eachColor:
                colorCount += 1
        if colorCount > 1:
            ftlog.debug('MTilePatternChecker.isQingyise result: False')
            return False
        ftlog.debug('MTilePatternChecker.isQingyise result: True')
        return True
 def isQingyise(self):
     """
     清一色:由同一门花色(筒子或条子)组成的和牌牌型
     """
     colorArr = [0,0,0,0]
     for tile in self.playerAllTilesArr[self.winSeatId]:
         color = MTile.getColor(tile)
         colorArr[color] = 1
      
     colorCount = 0
     for eachColor in colorArr:
         if eachColor:
             colorCount += 1
     if colorCount > 1:
         ftlog.debug('MTilePatternChecker.isQingyise result: False')
         return False
     ftlog.debug('MTilePatternChecker.isQingyise result: True')
     return True
Exemple #20
0
    def hasPeng(self, tiles, tile, extendInfo={}):
        """是否有碰牌解
        
        参数说明;
        tiles - 玩家的所有牌,包括手牌,吃牌,碰牌,杠牌,胡牌
        tile - 待碰的牌
        """
        absenceColor = extendInfo.get('absenceColor', -1)
        if MTile.getColor(tile) == absenceColor:
            return []

        tilesForPeng = copy.deepcopy(tiles[MHand.TYPE_HAND])
        tilesForPeng = MTile.filterTilesWithOutColor(tilesForPeng,
                                                     absenceColor)

        pengSolutions = []
        if MPeng.hasPeng(tilesForPeng, tile):
            pengSolutions.append([tile, tile, tile])

        return pengSolutions
    def isWin(self, allTiles, winTile, winStyle, leftTiles, seatResponse):
        '''
            默认能胡就胡
            allTiles - 当前玩家的所有手牌
            winTile - 胡牌
            winStyle - 是吃炮胡,抢杠胡,还是自摸胡。
                被人点炮则胡
                自摸胡时,考虑下是否更换听口,以博取更好的机会
            seatResponse - 玩家是否选择,已选择,则返回True
        '''
        ftlog.debug('isWin allTiles:', allTiles, ' winTile:', winTile,
                    ' winStyle:', winStyle, ' leftTiles:', leftTiles,
                    ' seatResponse:', seatResponse)

        if seatResponse:
            return True

        doQing, qingColor = self.doQingYiSe(allTiles, leftTiles)
        if doQing:
            return (MTile.getColor(winTile) == qingColor)
        return True
Exemple #22
0
    def isQingyise(self):
        """
        清一色:由同一门花色(筒子或条子)组成的和牌牌型
        """
        colorArr = [0, 0, 0, 0]
        handTile = MHand.copyAllTilesToList(self.playerAllTiles[self.winSeatId])  # 手牌区+吃+碰+杠+锚+胡区

        ftlog.debug('jinan_one_result.isQingyise handTile=', handTile)

        for tile in handTile:
            color = MTile.getColor(tile)
            colorArr[color] = 1

        colorCount = 0
        for eachColor in colorArr:
            if eachColor:
                colorCount += 1
        if colorCount == 1 and colorArr[3] == 0:
            ftlog.debug('jinan_one_result.isQingyise result: True')
            return True
        ftlog.debug('jinan_one_result.isQingyise result: False')
        return False
Exemple #23
0
    def hasPeng(self, tiles, tile, extendInfo={}):
        """是否有碰牌解

        参数说明;
        tiles - 玩家的所有牌,包括手牌,吃牌,碰牌,杠牌,胡牌
        tile - 待碰的牌
        """
        pengSolutions = []
        seatId = extendInfo.get('seatId', -1)
        if seatId == -1:
            return pengSolutions

        # 缺门不能碰
        absenceColor = self.tableTileMgr.absenceColors[seatId]
        if MTile.getColor(tile) == absenceColor:
            return pengSolutions

        # 手牌里加上这张牌>=3张,可以碰
        normalPeng = MPeng.hasPeng(tiles[MHand.TYPE_HAND], tile)
        if normalPeng:
            pengSolutions.append([tile, tile, tile])
        return pengSolutions
    def isChi(self,
              allTiles,
              chiTile,
              chiPatterns,
              leftTiles,
              tingResults,
              seatResponse,
              tingRule=None):
        '''
            默认能吃就吃
            allTiles - 当前玩家的所有手牌
            chiTile - 吃牌
            chiPatterns - 吃牌方案
            seatResponse - 玩家是否做出选择
        '''
        if seatResponse:
            return True
        doQing, qingColor = self.doQingYiSe(allTiles, leftTiles)
        if doQing:
            return (MTile.getColor(chiTile) == qingColor)

        return True
    def isPeng(self,
               allTiles,
               pengTile,
               pengPatterns,
               leftTiles,
               tingResults,
               seatResponse,
               tingRule=None):
        '''
            默认能碰就碰
            allTiles - 当前玩家的所有手牌
            pengTile - 碰牌
            pengPatterns - 碰牌方案
            seatResponse - 玩家是否选择
        '''
        if seatResponse:
            return True
        doQing, qingColor = self.doQingYiSe(allTiles, leftTiles)
        if doQing:
            return (MTile.getColor(pengTile) == qingColor)

        return True
Exemple #26
0
    def isHunyise(self):
        """
        混一色:由东南西北中发白 + 万、条、筒中的任意一种组成的胡牌
        """
        colorArr = [0, 0, 0, 0]
        handTile = MHand.copyAllTilesToList(self.playerAllTiles[self.winSeatId])  # 手牌区+吃+碰+杠+锚+胡区

        ftlog.debug('jinan_one_result.isHunyise handTile=', handTile)

        for tile in handTile:
            color = MTile.getColor(tile)
            colorArr[color] = 1

        colorCount = 0
        for eachColor in colorArr:
            if eachColor:
                colorCount += 1
        if colorCount == 2 and colorArr[3] == 1:
            ftlog.debug('jinan_one_result.isHunyise result: True')
            return True
        ftlog.debug('jinan_one_result.isHunyise result: False')
        return False
Exemple #27
0
    def getBestDropTile(cls,
                        tiles_player_hand,
                        tiles_left,
                        playMode,
                        tile,
                        isTing,
                        magicTiles,
                        absenceColor,
                        tingRule=None,
                        seatId=0):
        """
        手牌的价值,根据玩家自己的手牌和已经出的牌,计算手牌价值
        参数:
            tiles_player_hand - 用户的手牌
            tiles_droped - 牌桌上已经打出的牌和玩家手里已经成型的牌,这部分牌不再参与计算牌的可能性
        计算方法:
        1)没有的手牌,权值为0
        2)有的手牌,初始权值为4 * count + 1 * left
        3)左右相邻的手牌,增加权重 3 * count
        4)左右隔一张的手牌,增加权重 2 * count
        """
        ftlog.debug('MTileValue.getBestDropTile tiles_player_hand:',
                    tiles_player_hand, ' tiles_left:', tiles_left,
                    ' playMode:', playMode, ' tile:', tile, ' isTing:', isTing,
                    ' magicTiles:', magicTiles, ' tingRule:', tingRule,
                    ' seatId:', seatId)

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

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

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

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

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

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

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

        # [{'dropTile': 11, 'winNodes': [{'winTile': 1, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [1, 2, 3]]}, {'winTile': 2, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [3, 4, 5], [2, 2]]}, {'winTile': 4, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [2, 3, 4]]}, {'winTile': 5, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [5, 5], [2, 3, 4]]}, {'winTile': 7, 'winTileCount': 1, 'pattern': [[6, 6], [5, 6, 7], [5, 6, 7], [2, 3, 4]]}, {'winTile': 8, 'winTileCount': 1, 'pattern': [[6, 7, 8], [6, 6, 6], [5, 5], [2, 3, 4]]}]}]
        if tingRule:
            canTing, tingResults = tingRule.canTing(tiles_player_hand,
                                                    tiles_left, tile,
                                                    magicTiles)
            ftlog.debug(canTing)
            ftlog.debug(tingResults)

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

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

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

        ftlog.debug('MTileValue.getBestDropTile minTile:', minTile,
                    ' tileValue:', tiles_value_Arr[minTile])
        return minTile, tiles_value_Arr[minTile]
Exemple #28
0
    def calcWin(self):
        """
        济南赢牌算分
        """
        # ## 清理
        self.clearWinFanPattern()

        # 在和牌时统计自摸,点炮状态
        resultStat = [[] for _ in range(self.playerCount)]
        winMode = [MOneResult.WIN_MODE_LOSS for _ in range(self.playerCount)]
        fanPattern = [[] for _ in range(self.playerCount)]
        fanXing = self.fanXing[self.PINGHU]
        resultStat[self.winSeatId].append({MOneResult.STAT_WIN:1})
        isZiMo = (self.lastSeatId == self.winSeatId)
        if isZiMo:
            resultStat[self.lastSeatId].append({MOneResult.STAT_ZIMO:1})
            winMode[self.lastSeatId] = MOneResult.WIN_MODE_ZIMO
        else:
            resultStat[self.lastSeatId].append({MOneResult.STAT_DIANPAO: 1})
            winMode[self.lastSeatId] = MOneResult.WIN_MODE_DIANPAO
            winMode[self.winSeatId] = MOneResult.WIN_MODE_PINGHU
            if self.qiangGang:
                winMode[self.winSeatId] = MOneResult.WIN_MODE_QIANGGANGHU

        score = [0 for _ in range(self.playerCount)]
        # 底分 配置项的底分
        baseScore = self.tableTileMgr.tableConfig.get(MTDefine.WIN_BASE, 1)

        ftlog.debug('jinan_one_result.calcWin baseScore=====', baseScore)

        # ## 算杠分
        gangscore = 0  # 杠牌得分
        gangList = self.playerGangTiles[self.winSeatId]
        for ga in gangList:
            if MTile.getColor(ga['pattern'][0]) == 3:
                gangscore += 1

            if ga['style'] == 0:  # 暗杠
                gangscore += 2
            else:
                gangscore += 1

        baseScore = baseScore + gangscore
        ftlog.debug('jinan_one_result.calcWin baseScore=====', baseScore, ' gangscore:', gangscore)

        # ## 算风刻分
        baseScore = baseScore + self.getFengKe()
        ftlog.debug('jinan_one_result.calcWin baseScore=====', baseScore, ' getFengKe:', self.getFengKe())

        # #算花分
        huaScore = len(self.tableTileMgr.flowerTiles(self.winSeatId))
        baseScore = baseScore + huaScore
        ftlog.debug('jinan_one_result.calcWin baseScore=====', baseScore, ' huaScore:', huaScore)


        # 胡型判断
        if self.isDadiaoche():  # 大吊车
            ftlog.debug('jinan_one_result.calcWin isDadiaoche=====', self.isDadiaoche())
            fx = self.fanXing[self.DADIAOCHE]
            self.addWinFanPattern(fx['name'], fx['index'])
            baseScore = baseScore * 2
        if self.tableTileMgr.isHaidilao():  # 海底捞月
            ftlog.debug('jinan_one_result.calcWin isHaidilao=====', self.tableTileMgr.isHaidilao())
            fx = self.fanXing[self.HAIDILAO]
            self.addWinFanPattern(fx['name'], fx['index'])
            baseScore = baseScore * 2
        if self.gangKai:  # 杠呲
            ftlog.debug('jinan_one_result.calcWin isGangKai=====', self.gangKai)
            fx = self.fanXing[self.GANGCI]
            self.addWinFanPattern(fx['name'], fx['index'])
            baseScore = baseScore * 2
        if self.huaCi:  # 花呲
            ftlog.debug('jinan_one_result.calcWin isHuaCi=====', self.huaCi)
            fx = self.fanXing[self.HUACI]
            self.addWinFanPattern(fx['name'], fx['index'])
            baseScore = baseScore * 2
        if self.tingState[self.winSeatId]:  # 明搂
            ftlog.debug('jinan_one_result.calcWin isMingLou=====', self.tingState[self.winSeatId])
            fx = self.fanXing[self.MINGLOU]
            self.addWinFanPattern(fx['name'], fx['index'])
            baseScore = baseScore * 2


        ####牌型判断
        if self.isFlowerHu():  # 花胡
            fx = self.fanXing[self.FLOWERHU]
            self.addWinFanPattern(fx['name'], fx['index'])
            baseScore = baseScore * 1

        if self.isQingyise():  # 清一色
            ftlog.debug('jinan_one_result.calcWin isQingyise=====', self.isQingyise())
            fx = self.fanXing[self.QINGYISE]
            self.addWinFanPattern(fx['name'], fx['index'])
            baseScore = baseScore * 4
        elif self.isHunyise():  # 混一色
            fx = self.fanXing[self.HUNYISE]
            self.addWinFanPattern(fx['name'], fx['index'])
            baseScore = baseScore * 2

        if self.isQidui():
            if self.isQiduiHao():  # 豪华七小对
                ftlog.debug('jinan_one_result.calcWin isQiduiHao=====', self.isQiduiHao())
                fx = self.fanXing[self.HHQIXIAODUI]
                self.addWinFanPattern(fx['name'], fx['index'])
                baseScore = baseScore * 4
            else:  # 七小对
                ftlog.debug('jinan_one_result.calcWin isQidui=====', self.isQidui())
                fx = self.fanXing[self.QIXIAODUI]
                self.addWinFanPattern(fx['name'], fx['index'])
                baseScore = baseScore * 2

        elif self.isPengpenghu():  # 碰碰胡
            ftlog.debug('jinan_one_result.calcWin isPengpenghu=====', self.isPengpenghu())
            fx = self.fanXing[self.PENGPENGHU]
            self.addWinFanPattern(fx['name'], fx['index'])
            baseScore = baseScore * 2

        elif self.isQuanjiang():  # 全将
            ftlog.debug('jinan_one_result.calcWin isQuanjiang=====', self.isQuanjiang())
            fx = self.fanXing[self.QUANJIANG]
            self.addWinFanPattern(fx['name'], fx['index'])
            baseScore = baseScore * 2

        elif self.is13BuKao():  # 十三不靠
            ftlog.debug('jinan_one_result.calcWin is13BuKao=====', self.is13BuKao())
            fx = self.fanXing[self.BUKAO13]
            self.addWinFanPattern(fx['name'], fx['index'])
            baseScore = baseScore * 2


        ftlog.debug('jinan_one_result.calcWin baseScore=====', baseScore)


        #### 胡法判断
        if isZiMo:  # 自摸
            score = [-baseScore for _ in range(self.playerCount)]
            score[self.winSeatId] = (self.playerCount - 1) * baseScore
        else:  # 点炮
            if self.qiangGang:  # 抢杠包三家
                score = [0 for _ in range(self.playerCount)]
                score[self.winSeatId] = (self.playerCount - 1) * baseScore
                score[self.lastSeatId] = -(self.playerCount - 1) * baseScore
            else:
                score[self.lastSeatId] = -baseScore
                score[self.winSeatId] = baseScore

        #### 跑分计算
        if isZiMo:  # 自摸 自己的飘 + 别人的飘 + 必票*n
            for loose in range(self.playerCount):
                if loose != self.winSeatId:
                    piao = self.piaoProcessor.getPiaoPointsBySeats(self.winSeatId, loose)  # 算飘的分
                    ftlog.debug('jinan_one_result.calcWin isZiMo.piao=====', piao)
                    score[loose] -= piao
                    score[self.winSeatId] += piao

        else:  # 点炮
            if self.qiangGang:  # 抢杠包三家
                for loose in range(self.playerCount):
                    if loose != self.winSeatId:
                        piao = self.piaoProcessor.getPiaoPointsBySeats(self.winSeatId, loose)  # 算飘的分
                        score[self.lastSeatId] -= piao
                        score[self.winSeatId] += piao
            else:
                piao = self.piaoProcessor.getPiaoPointsBySeats(self.winSeatId, self.lastSeatId)  # 算飘的分
                ftlog.debug('jinan_one_result.calcWin dianpao.piao=====', piao)
                score[self.lastSeatId] -= piao
                score[self.winSeatId] += piao

        piaoPoints = {}
        piaoPoints['points'] = [self.piaoProcessor.piaoPoints[seat] for seat in range(self.playerCount)]  # 给前端显示票分
        flowerScores = {}
        flowerScores['scores'] = [self.tableTileMgr.flowerScores(seat) for seat in range(self.playerCount)]  # 给前端显示花分

        # 最大番统计(改成单局最佳)
        resultStat[self.winSeatId].append({MOneResult.STAT_ZUIDAFAN: score[self.winSeatId]})

        self.results[self.KEY_TYPE] = '和牌'
        self.results[self.KEY_NAME] = fanXing['name']
        self.results[self.KEY_SCORE] = score
        self.results[self.KEY_WIN_MODE] = winMode
        self.results[self.KEY_STAT] = resultStat
        fanPattern[self.winSeatId] = self.winFanPattern
        ftlog.debug('jinan_one_result.calcWin result fanPattern:', fanPattern)
        self.results[self.KEY_FAN_PATTERN] = fanPattern
        self.results[self.KEY_PIAO_POINTS] = piaoPoints
        self.results[self.KEY_FLOWER_SCORES] = flowerScores
Exemple #29
0
    def getBestDropTile(self,
                        tiles_player_hand,
                        tiles_left,
                        tile,
                        isTing,
                        magicTiles,
                        absenceColor,
                        tingRule=None):
        """
        手牌的价值,根据玩家自己的手牌和已经出的牌,计算手牌价值
        参数:
            tiles_player_hand - 用户的手牌
            tiles_droped - 牌桌上已经打出的牌和玩家手里已经成型的牌,这部分牌不再参与计算牌的可能性
        计算方法:
        1)没有的手牌,权值为0
        2)有的手牌,初始权值为4 * count + 1 * left
        3)左右相邻的手牌,增加权重 3 * count
        4)左右隔一张的手牌,增加权重 2 * count
        """
        ftlog.debug(
            'MDropCardStrategyJipinghu.getBestDropTile tiles_player_hand:',
            tiles_player_hand, ' tiles_left:', tiles_left, ' tile:', tile,
            ' isTing:', isTing, ' magicTiles:', magicTiles, ' absenceColor:',
            absenceColor, ' tingRule:', tingRule)

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

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

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

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

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

        # [{'dropTile': 11, 'winNodes': [{'winTile': 1, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [1, 2, 3]]}, {'winTile': 2, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [3, 4, 5], [2, 2]]}, {'winTile': 4, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [2, 3, 4]]}, {'winTile': 5, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [5, 5], [2, 3, 4]]}, {'winTile': 7, 'winTileCount': 1, 'pattern': [[6, 6], [5, 6, 7], [5, 6, 7], [2, 3, 4]]}, {'winTile': 8, 'winTileCount': 1, 'pattern': [[6, 7, 8], [6, 6, 6], [5, 5], [2, 3, 4]]}]}]
        if tingRule:
            canTing, tingResults = tingRule.canTing(tiles_player_hand,
                                                    tiles_left, tile,
                                                    magicTiles)
            ftlog.debug(canTing)
            ftlog.debug(tingResults)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        tingRule = extend.get('tingRule', None)
        # [{'dropTile': 11, 'winNodes': [{'winTile': 1, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [1, 2, 3]]}, {'winTile': 2, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [3, 4, 5], [2, 2]]}, {'winTile': 4, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [2, 3, 4]]}, {'winTile': 5, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [5, 5], [2, 3, 4]]}, {'winTile': 7, 'winTileCount': 1, 'pattern': [[6, 6], [5, 6, 7], [5, 6, 7], [2, 3, 4]]}, {'winTile': 8, 'winTileCount': 1, 'pattern': [[6, 7, 8], [6, 6, 6], [5, 5], [2, 3, 4]]}]}]
        if tingRule:
            canTing, tingResults = tingRule.canTing(tiles_player_hand,
                                                    tiles_left, tile,
                                                    magicTiles)
            ftlog.debug(canTing)
            ftlog.debug(tingResults)

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

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

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

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

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

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

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

        ftlog.debug('MDropCardStrategyJipinghu.getBestDropTile minTiles:',
                    minTiles, ' tileValue:', minValue)
        return self.chooseBestDropTile(minTiles, tiles_left,
                                       qingColor), minValue