Example #1
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
Example #2
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 
Example #3
0
    def getHandTilesValue(cls, tiles_player_hand, tiles_left):
        """计算手牌价值
        
        返回值:
        1)每张牌的价值
        2)手牌花色个数的数组
        """
        tiles_player_Arr = MTile.changeTilesToValueArr(
            tiles_player_hand[MHand.TYPE_HAND])
        tiles_left_Arr = MTile.changeTilesToValueArr(tiles_left)

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

        return tiles_value_Arr, tiles_player_Arr
    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
Example #5
0
    def canTing(cls, tiles, leftTiles, winRule, tile, magicTiles = [], curSeatId = 0, winSeatId = 0, actionID = 0,tingForQiangjin = False,flowerRule = None):
        """
        判断是否可以听牌
        参数:
        1)tiles 手牌
        2)leftTiles 剩余未发的牌
        3) tingForQiangjin 是否是抢金,当是判断抢金时,有可听的结果就返回  modify by youjun
        返回值:
        
        """
        handTileArr = MTile.changeTilesToValueArr(tiles[MHand.TYPE_HAND])
        
        leftTileArr = MTile.changeTilesToValueArr(leftTiles)
        leftTileCount = len(leftTileArr)
        '''
	ftlog.debug('MTing.canTing leftTiles:', leftTiles
                     , ' leftTileArr:', leftTileArr
                     , ' leftTileCount:', leftTileCount)
        '''
        result = []
        for tile in range(MTile.TILE_MAX_VALUE):
            if handTileArr[tile] > 0:
                newTiles = MTile.cloneTiles(tiles)
                newTiles[MHand.TYPE_HAND].remove(tile)
                resultNode = cls.canWinAddOneTile(leftTileArr, leftTileCount, newTiles, winRule, magicTiles, curSeatId, winSeatId, actionID,tingForQiangjin,flowerRule)
                if len(resultNode) > 0:
                    winNode = {}
                    winNode['dropTile'] = tile
                    winNode['winNodes'] = resultNode
		    result.append(winNode)
        	    if tingForQiangjin:
                        return len(result) > 0, result 
        return len(result) > 0, result
Example #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)
         
     return self.__tiles
Example #7
0
    def isPiao(self):
        playerChiTiles = self.playerAllTiles[self.winSeatId][MHand.TYPE_CHI]
        if len(playerChiTiles) > 0:
            return False

        playerHandTiles = self.playerAllTiles[self.winSeatId][MHand.TYPE_HAND]
        newPlayerHandTiles = MTile.cloneTiles(playerHandTiles)
        if self.isMagicTile():
            for wn in self.winNodes:
                realWinTile = wn['winTile']
                ftlog.debug('MJixiOneResult.isPiao winTile:', realWinTile)
                newPlayerHandTiles.append(realWinTile)
                break
        else:
            newPlayerHandTiles.append(self.winTile)

        newPlayerHandTilesArr = MTile.changeTilesToValueArr(newPlayerHandTiles)
        twoCount = 0
        for playerHandTileCount in newPlayerHandTilesArr:
            if playerHandTileCount == 1:
                return False
            elif playerHandTileCount == 2:
                twoCount += 1
            elif playerHandTileCount == 4:
                twoCount += 2

        if twoCount > 1:
            return False

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

        if MTile.getValue(self.winTile) == 7 and self.winTile < 30 and (
                self.winTile + 1) in handTile and (self.winTile +
                                                   2) in handTile:
            handTile.remove(self.winTile)
            handTile.remove(self.winTile + 1)
            handTile.remove(self.winTile + 2)
            res, _ = MWin.isHu(handTile)
            ftlog.debug('weihai_one_result.isSanQi result: ', res)
            return res
        elif MTile.getValue(self.winTile) == 3 and self.winTile < 30 and (
                self.winTile - 1) in handTile and self.winTile - 2 in handTile:
            handTile.remove(self.winTile)
            handTile.remove(self.winTile - 1)
            handTile.remove(self.winTile - 2)
            res, _ = MWin.isHu(handTile)
            ftlog.debug('weihai_one_result.isSanQi result: ', res)
            return res
        else:
            ftlog.debug('weihai_one_result.isSanQi result: False')
            return False
Example #9
0
 def getHandTilesValue(cls, tiles_player_hand, tiles_left):
     """计算手牌价值
     
     返回值:
     1)每张牌的价值
     2)手牌花色个数的数组
     """
     tiles_player_Arr = MTile.changeTilesToValueArr(tiles_player_hand[MHand.TYPE_HAND])
     tiles_left_Arr = MTile.changeTilesToValueArr(tiles_left)
             
     # 权值初始化    
     tiles_value_Arr = [0 for _ in range(40)]
     for index in range(MTile.TILE_MAX_VALUE):
         if tiles_player_Arr[index] == 0:
             continue
         tiles_value_Arr[index] = tiles_player_Arr[index] * 4 + tiles_left_Arr[index]
         if index < 30:
             if index % 10 < 9:
                 tiles_value_Arr[index] += tiles_player_Arr[index + 1] * 3
             if index % 10 < 8:
                 tiles_value_Arr[index] += tiles_player_Arr[index + 2] * 2
             if index % 10 > 1:
                 tiles_value_Arr[index] += tiles_player_Arr[index - 1] * 3
             if index % 10 > 2:
                 tiles_value_Arr[index] += tiles_player_Arr[index - 2] * 2
                 
     return tiles_value_Arr, tiles_player_Arr
Example #10
0
    def isHu(self,
             tiles,
             tile,
             isTing,
             getTileType,
             magicTiles=[],
             tingNodes=[],
             winSeatId=0):
        # 检查是否过胡状态 自摸情况下不判断过胡
        if getTileType != MWinRule.WIN_BY_MYSELF and self.tableTileMgr.isPassHuTileBySeatId(
                winSeatId, tile):
            ftlog.debug('MWinRuleXueZhan.isHu passHu...')
            return False, []
        tileArr = MTile.changeTilesToValueArr(MHand.copyAllTilesToList(tiles))
        # 获取当前座位号定缺的花色
        colorAbsence = self.tableTileMgr.absenceColors[winSeatId]
        # 获取手牌中定缺花色牌的数量,大于0,不用判断胡
        colorAbsenceNum = MTile.getTileCountByColor(tileArr, colorAbsence)
        # ftlog.debug('MWinRuleXueZhan colorAbsenceNum:', colorAbsenceNum, 'tiles:', tiles, 'tile:', tile, 'colorAbsence:', colorAbsence)
        if colorAbsenceNum > 0:
            return False, []

        resultQidui, qiduiPattern = MWin.isQiDui(tiles[MHand.TYPE_HAND], [])
        if resultQidui:
            return True, qiduiPattern

        result, rePattern = MWin.isHu(tiles[MHand.TYPE_HAND])
        if result:
            return True, rePattern
        return False, []
Example #11
0
    def isJipinghu(self, pattern, tiles, tileArr, magicTiles):

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

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

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

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

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

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

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

        return False
Example #12
0
    def isQingyise(self, tiles):
        """
        清一色:由同一门花色(筒子或条子)组成的和牌牌型
        """
        tileArr = MTile.changeTilesToValueArr(MHand.copyAllTilesToListButHu(tiles))
        colors = MTile.getColorCount(tileArr)
        #ftlog.debug('MWinRuleQueshou.isQingyise tileArr=',tileArr,colors)
	return colors == 1
Example #13
0
    def isHu(self, tiles, tile, isTing, getTileType, magicTiles = [], tingNodes = [], curSeatId = 0, winSeatId = 0, actionID = 0, isGangKai = False,isForHu = True):

	if self.tableTileMgr.playMode == "luosihu-luosihu" and isForHu:
	    if not isTing:
	        if not self.tableTileMgr.players[winSeatId].isWon():
		    return False,[],0

        allTiles = MHand.copyAllTilesToListButHu(tiles)
        tilesArr = MTile.changeTilesToValueArr(allTiles)	
        # 需要缺一门: 定缺的时候约定的那门
        if self.absenceColor:
            if MTile.getTileCountByColor(tilesArr, self.absenceColor[winSeatId]) > 0:
                return False, [],0
        result, pattern = self.isQidui(tiles)
        if result:
            if self.tableTileMgr.playMode == "luosihu-luosihu":
                self.fanXing[self.QIDUI]["index"] = 1 
            return True, pattern,self.fanXing[self.QIDUI]["index"]

        result, pattern = MWin.isHu(tiles[MHand.TYPE_HAND], magicTiles)

        if result:
            ftlog.debug('MWinRuleLuosihu.isHu result=',result,' getTileType=',getTileType,' pattern=',pattern)
            player = self.tableTileMgr.players[winSeatId]
            self.winSeatId = winSeatId
            self.__tile_pattern_checker = MTilePatternCheckerFactory.getTilePatternChecker(MPlayMode.LUOSIHU)
            playersAllTiles = [[] for _ in range(self.tableTileMgr.playCount)]
            self.__win_patterns = [[] for _ in range(self.tableTileMgr.playCount)]
            self.__win_patterns[winSeatId] = [pattern]
            for seatId in range(self.tableTileMgr.playCount):
                if seatId == winSeatId:
                    playersAllTiles[seatId] = copy.deepcopy(tiles)
                else:
                    playersAllTiles[seatId] = self.tableTileMgr.players[seatId].copyTiles()
            self.setAllPlayerTiles(playersAllTiles)
            # 判断和牌的时候
            self.__tile_pattern_checker.initChecker(playersAllTiles, tile, self.tableTileMgr, True, curSeatId, winSeatId, actionID)
            winnerResult = []
            if self.tableTileMgr.playMode == "luosihu-ctxuezhan":
                winnerResult = self.getWinnerResultsForXueZhanDaoDi(winSeatId)
            elif self.tableTileMgr.playMode == "luosihu-xuezhan":
                winnerResult = self.getWinnerResultsForLuoSiHuXueZhan(winSeatId)
            elif self.tableTileMgr.playMode == "luosihu-luosihu":
                winnerResult = self.getWinnerResultsForLuoSiHu(winSeatId)
            finalResult = []
            finalResult.extend(winnerResult)
            maxFan = self.tableConfig.get(MTDefine.MAX_FAN, 0)
            winScore,indexFan = self.getScoreByResults(finalResult, maxFan)
            ftlog.debug('MWinRuleLuosihu.isHu player.guoHuPoint :',winScore,' finalResult=',finalResult,' indexFan')
            # 过胡判断
            if getTileType == MWinRule.WIN_BY_MYSELF:
                return True,pattern,indexFan
            if player.guoHuPoint >= winScore and self.tableTileMgr.playMode == "luosihu-ctxuezhan":
                return False, [],0
            player.totalWinPoint = winScore
            return True,pattern,indexFan

	return False, [],0
Example #14
0
    def is13BuKaoWithOutLimit(cls, handTiles, hanMagics=[]):
        '''
        判断是否十三不靠 只要手牌没有靠着的就行 没有其他限制
        hanMagics是手牌中的赖子数组,如手牌中有2个7是赖子 baoTiles=[7,7]
        '''
        newHandTiles = copy.deepcopy(handTiles)
        # 有五张不同的风牌或箭牌
        fengTiles = []
        for index in range(0, len(newHandTiles)):
            if (MTile.isFeng(newHandTiles[index])
                    or MTile.isArrow(newHandTiles[index])):
                if (newHandTiles[index] not in fengTiles):
                    fengTiles.append(newHandTiles[index])
                else:
                    return False, []

        if len(fengTiles) > 0:
            for tile in fengTiles:
                newHandTiles.remove(tile)

        # 排序
        newHandTiles.sort()
        for magic in hanMagics:
            if magic in newHandTiles:
                newHandTiles.remove(magic)

        # 根据花色分组
        groups = [[] for _ in xrange(3)]
        for tile in newHandTiles:
            if ((tile % 10) == 0) or (tile >= 30):
                continue

            index = tile / 10
            groups[index].append(tile)

        # 每组3张牌
        buKaoCount = 0
        for grp in groups:
            if len(grp) == 0:
                continue

            v = grp[0] % 10
            if len(grp) == 2 and ((grp[1] % 10 == (v + 3)
                                   or grp[1] % 10 == (v + 6))):
                buKaoCount += len(grp)
            elif len(grp) == 3 and ((grp[1] % 10 == (v + 3)
                                     and grp[2] % 10 == (v + 6))):
                buKaoCount += len(grp)
            elif len(grp) == 1:
                buKaoCount += len(grp)

        ftlog.debug("buKaoCount ===", buKaoCount)
        ftlog.debug("handMagics ===", len(hanMagics))
        ftlog.debug("fengTiles ===", len(fengTiles))
        if buKaoCount + len(hanMagics) + len(fengTiles) != 14:
            return False, []

        return True, [handTiles]
Example #15
0
 def isQingyise(self, tiles):
     """
     清一色:由同一门花色(筒子或条子)组成的和牌牌型
     """
     tileArr = MTile.changeTilesToValueArr(
         MHand.copyAllTilesToListButHu(tiles))
     colors = MTile.getColorCount(tileArr)
     #ftlog.debug('MWinRuleQueshou.isQingyise tileArr=',tileArr,colors)
     return colors == 1
Example #16
0
    def is13BuKao(cls, handTiles):
        '''
        判断是否十三不靠
        '''

        #有五张不同的风牌或箭牌
        fengTiles = []
        for index in range(0, len(handTiles)):
            if (MTile.isFeng(handTiles[index])
                    or MTile.isArrow(handTiles[index])):
                if (handTiles[index] not in fengTiles):
                    fengTiles.append(handTiles[index])
                else:
                    return False, []

        if len(fengTiles) > 0:
            for tile in fengTiles:
                handTiles.remove(tile)
        #剩余9张牌
        if not (len(fengTiles) == 5 and len(handTiles) == 9):
            return False, []
        #排序
        handTiles.sort()

        ftlog.debug("handTiles ===", handTiles)

        #根据花色分组
        groups = [[] for _ in xrange(3)]
        for tile in handTiles:
            if ((tile % 10) == 0) or (tile >= 30):
                continue

            index = tile / 10
            groups[index].append(tile)

        ftlog.debug("groups ===", groups)

        # 每组3张牌
        types = [1, 2, 3]
        for grp in groups:
            if len(grp) != 3:
                return False, []

            v = grp[0] % 10
            if not (grp[1] % 10 == (v + 3) and grp[2] % 10 == (v + 6)):
                return False, []

            if v in types:
                types.remove(v)
            else:
                return False, []

        ftlog.debug("handTile ===", handTiles)

        handTiles.extend(fengTiles)

        return True, [handTiles]
Example #17
0
 def isFengyise(self):
     """
     风一色:由东南西北中发白组成的胡牌
     """
     handTile = MHand.copyAllTilesToList(
         self.playerAllTiles[self.winSeatId])  # 手牌区+吃+碰+杠+锚+胡区
     handArr = MTile.changeTilesToValueArr(handTile)
     colorCount = MTile.getColorCount(handArr)
     result, _ = MWin.isLuanFengyise(handTile, colorCount)
     return result
Example #18
0
    def canTing(self, tiles, leftTiles, tile, magicTiles = [], curSeatId = 0, winSeatId = 0, actionID = 0):
        #if self.tableTileMgr.playMode == 'luosihu-suizhou' or self.tableTileMgr.playMode == 'luosihu-luosihu':
            #小于12张可以显示听牌
            #if len(leftTiles) < 12:
                # 随州和孝感小于12张不能亮牌/听牌
            #    return False, []
        isTing, tingResults = MTing.canTing(MTile.cloneTiles(tiles), leftTiles, self.winRuleMgr, tile, magicTiles, curSeatId, winSeatId, actionID)
        ftlog.debug( 'MTingLuosihuRule.canTing using MTing isTing:', isTing, ' tingResults:', tingResults )
        
        #if not self.tableTileMgr:
        #    # 用于单元测试,正常情况下都有tableTileMgr
        return isTing, tingResults

        finalTingResults = []
        if isTing:
            # 听牌时,要丢弃的牌必须要过滤掉别人要胡的牌,如果都被滤掉了,就不能听牌
            for tingResult in tingResults:
                resultOk = True
                for player in self.tableTileMgr.players:
                    if player.curSeatId != winSeatId:
                        if player.tingLiangWinTiles:
                            if tingResult['dropTile'] and player.tingLiangWinTiles \
                                    and tingResult['dropTile'] in player.tingLiangWinTiles:
                                ftlog.debug( 'MTingLuosihuRule.canTing drop tile: ', tingResult['dropTile'], ' is forbidden by player: ', player.curSeatId)
                                resultOk = False
                                break
                if resultOk:
                    for wn in tingResult['winNodes']:
                        allWinTiles = []
                        for p in wn['pattern']:
                            allWinTiles.extend(p)
                        tileCountArr = MTile.changeTilesToValueArr(MTile.cloneTiles(allWinTiles))
                        #canKouTiles = []
                        #for p in wn['pattern']:
                        #    if len(p) == 2:
                        #        continue
                        #    if p[0] == p[1] and p[1] == p[2]:
                        #        if tileCountArr[p[0]] == 4 and p[0] != wn['winTile']:
                        #            # 手上已经有四张了(去掉winTile),不能扣牌
                        #            continue
                        #        if (p[0] != wn['winTile'] or (p[0] == wn['winTile'] and tileCountArr[p[0]] == 4)) and p[0] not in canKouTiles:
                        #            # 手上只有3张一样的牌,或者手上有4张一样的牌(包含winTile)
                        #            canKouTiles.append(p[0])
                        # 此处为引用,原有tingResults在每个winNode增加canKouTiles
                        #wn['canKouTiles'] = canKouTiles
                        #ftlog.debug( 'MTingLuosihuRule.canTing winNode: ', wn, ' ,current allWinTiles: ', allWinTiles)
                    finalTingResults.append(tingResult)

        ftlog.debug( 'MTingLuosihuRule.canTing using after liang filter tingResults:', finalTingResults )
        if len(finalTingResults) > 0:
            return True, finalTingResults
        else:
            return False, []
Example #19
0
    def isHu(self,
             tiles,
             tile,
             isTing,
             getTileType,
             magicTiles=[],
             tingNodes=[],
             winSeatId=0):
        ftlog.debug(self.TAG, '.isHu tiles:', tiles, ' tile:', tile,
                    ' isTing:', isTing, ' getTileType:', getTileType,
                    ' magicTiles:', magicTiles, ' tingNodes:', tingNodes,
                    ' winSeatId:', winSeatId)
        # 平度麻将即可以听也可以不听,听牌后,校验tingNodes即可,无其他限制条件
        if isTing:
            #[{'winTile': 16, 'winTileCount': 0, 'pattern': [[16, 17, 18], [12, 12]]}, {'winTile': 19, 'winTileCount': 0, 'pattern': [[17, 18, 19], [12, 12]]}]
            for tingNode in tingNodes:
                if tingNode['winTile'] == tile:
                    pattern = tingNode['pattern']
                    return True, pattern

        # 检查8张的规则
        allTiles = MHand.copyAllTilesToListButHu(tiles)
        tilesArr = MTile.changeTilesToValueArr(allTiles)
        wanCount = MTile.getTileCountByColor(tilesArr, MTile.TILE_WAN)
        tiaoCount = MTile.getTileCountByColor(tilesArr, MTile.TILE_TIAO)
        tongCount = MTile.getTileCountByColor(tilesArr, MTile.TILE_TONG)
        fengCount = MTile.getTileCountByColor(tilesArr, MTile.TILE_FENG)
        ftlog.debug('win_rule_pingdu.isHu allTiles:', allTiles,
                    ' tilesLength:', len(allTiles), ' tilesArr:', tilesArr,
                    ' wanCount:', wanCount, ' tiaoCount:', tiaoCount,
                    ' tongCount:', tongCount, ' fengCount:', fengCount)

        if (wanCount >= 8) or (tiaoCount >= 8) or (tongCount >=
                                                   8) or (fengCount >= 8):
            pass
        else:
            #             ftlog.info('win_rule_pingdu.isHu ok but do not have >=8 tiles in one color, allTiles:', allTiles
            #                     , ' tilesLength:', len(allTiles)
            #                     , ' tilesArr:', tilesArr
            #                     , ' wanCount:', wanCount
            #                     , ' tiaoCount:', tiaoCount
            #                     , ' tongCount:', tongCount
            #                     , ' fengCount:', fengCount)
            return False, []

        # 平度麻将允许胡七对
        resultQiDui, patternQiDui = MWin.isQiDui(tiles[MHand.TYPE_HAND])
        if resultQiDui:
            return True, patternQiDui

        result, pattern = MWin.isHu(tiles[MHand.TYPE_HAND])
        return result, pattern
Example #20
0
    def isDadiaoche(self, tiles):
        """
        大吊车:胡牌时自己手上只有一张牌,且胡的是二五八
        """
        handTile = tiles[MHand.TYPE_HAND]
        huTile = tiles[MHand.TYPE_HU][0]
        handTile.extend(tiles[MHand.TYPE_HU])
        if len(handTile) == 2 and huTile < MTile.TILE_DONG_FENG and (
                MTile.getValue(huTile) == 2 or MTile.getValue(huTile) == 5
                or MTile.getValue(huTile) == 8):
            return True, [handTile]

        return False, []
Example #21
0
    def isQingYiSe(self):
        if self.colorState[self.winSeatId] == 1:
            return True

        if self.isMagicTile():
            tileArr = MTile.changeTilesToValueArr(
                MHand.copyAllTilesToListButHu(
                    self.playerAllTiles[self.winSeatId]))
            tempCountColor = MTile.getColorCount(tileArr)
            if tempCountColor == 1:
                return True

        return False
Example #22
0
 def SatisyYaoJiu(self,tiles):
     #有幺九
     allTiles = MHand.copyAllTilesToList(tiles)
     tilesArr = MTile.changeTilesToValueArr(allTiles)
     
     yaojiucount = MTile.getYaoJiuCount(tilesArr)
     if yaojiucount>0:
         return True
     else:
         for feng in range(MTile.TILE_DONG_FENG,MTile.TILE_BAI_BAN+1):
             if tilesArr[feng]>=1:
                 return True
                 
     return False
Example #23
0
    def SatisyKe(self,tiles):
        #有刻
        if len(tiles[MHand.TYPE_PENG])==0:
            ming,an = MTile.calcGangCount(tiles[MHand.TYPE_GANG])
            if (ming + an) ==0:
                allTiles = MHand.copyAllTilesToList(tiles)
                tilesArr = MTile.changeTilesToValueArr(allTiles)
                #中发白做将
                if tilesArr[MTile.TILE_HONG_ZHONG] < 2 and tilesArr[MTile.TILE_FA_CAI] < 2 and tilesArr[MTile.TILE_BAI_BAN] < 2:
                    #中发白
                    if not self.hasKe(tiles[MHand.TYPE_HAND]):
                        return False

        return True
Example #24
0
    def isHunyise(self):
        """
        混一色:只有一色牌(如全是万),有金牌,但金牌不同色
        """
	'''
        colorArr = [0, 0, 0, 0]
        handTile = MHand.copyAllTilesToList(self.playerAllTiles[self.winSeatId])  # 手牌区+吃+碰+杠+锚+胡区
        for tile in handTile:
            color = MTile.getColor(tile)
            colorArr[color] = 1
        
        magicTile = self.tableTileMgr.getMagicTile()
        magicTileColor = MTile.getColor(magicTile)
	
	handTile = MHand.copyAllTilesToList(self.playerAllTiles[self.winSeatId])
        tilesArr = MTile.changeTilesToValueArr(handTile)
        count = MTile.getTileCountByColor(tilesArr, magicTileColor)

        magicCount = MTile.getTileCount(magicTile,handTile[MHand.TYPE_HAND])
	
        if count!=magicCount:
            return False
	
        colorCount = 0
        for eachColor in colorArr:
            if eachColor:
                colorCount += 1
        if colorCount == 2 and colorArr[magicTileColor] == 1:
            return True
        return False
	'''
	magicTile = self.tableTileMgr.getMagicTile()
	magicCount = 0
	allTiles = MHand.copyAllTilesToList(self.playerAllTiles[self.winSeatId])
        #allTiles = MHand.copyAllTilesToListButHu(handTile)
        allTileArr = MTile.changeTilesToValueArr(allTiles)
        allColors = MTile.getColorCount(allTileArr)
        for tile in allTiles:
            if magicTile and tile == magicTile:
		magicCount = magicCount + 1

        for i in range(magicCount):
            allTiles.remove(magicTile)

        tileArr = MTile.changeTilesToValueArr(allTiles)
        colors = MTile.getColorCount(tileArr)

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

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

        minTile = 0
        minValue = 0

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

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

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

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

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

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

        return minTile
Example #26
0
    def SatisyYaoJiu(self,tiles):
        #有幺九
        if len(tiles[MHand.TYPE_MAO])==0:
            allTiles = MHand.copyAllTilesToList(tiles)
            tilesArr = MTile.changeTilesToValueArr(allTiles)
            #中发白做将
            if tilesArr[MTile.TILE_HONG_ZHONG] < 2 and tilesArr[MTile.TILE_FA_CAI] < 2 and tilesArr[MTile.TILE_BAI_BAN] < 2:
                #中发白
                if not (tilesArr[MTile.TILE_HONG_ZHONG]>0 and tilesArr[MTile.TILE_FA_CAI]>0 and tilesArr[MTile.TILE_BAI_BAN]>0):
                    yaojiucount = MTile.getYaoJiuCount(tilesArr)
                    if yaojiucount==0:
                        return False

        return True
Example #27
0
    def isLuanFengyise(cls, tiles, colorCount):
        """
         风一色
        """
        ftlog.debug('MWin.isLuanFengyise tiles:', tiles, ' colorCount:',
                    colorCount)
        if colorCount > 1:
            return False, []

        for tile in tiles:
            if (not MTile.isFeng(tile)) and (not MTile.isArrow(tile)):
                return False, []

        ftlog.debug('MWin.isLuanFengyise ok, pattern:', tiles)
        return True, [tiles]
Example #28
0
    def isPiao(self):
        # 如果有吃牌,且不是123条,返回false
        playerChiTiles = self.playerAllTiles[self.winSeatId][MHand.TYPE_CHI]
        ftlog.debug('MJixiOneResult.isPiao playerChiTiles:', playerChiTiles)
        for chipattern in playerChiTiles:
            if (21 not in chipattern) or (22 not in chipattern) or (
                    23 not in chipattern):
                return False

        playerHandTiles = self.playerAllTiles[self.winSeatId][MHand.TYPE_HAND]
        newPlayerHandTiles = MTile.cloneTiles(playerHandTiles)
        if self.isMagicTile():
            for wn in self.winNodes:
                realWinTile = wn['winTile']
                ftlog.debug('MJixiOneResult.isPiao winTile:', realWinTile)
                newPlayerHandTiles.append(realWinTile)
                break
        else:
            newPlayerHandTiles.append(self.winTile)

        # 排除21,22,23
        while ((21 in newPlayerHandTiles) and (22 in newPlayerHandTiles)
               and (23 in newPlayerHandTiles)):
            newPlayerHandTiles.remove(21)
            newPlayerHandTiles.remove(22)
            newPlayerHandTiles.remove(23)

        # 排除中发白
        while ((35 in newPlayerHandTiles) and (36 in newPlayerHandTiles)
               and (37 in newPlayerHandTiles)):
            newPlayerHandTiles.remove(35)
            newPlayerHandTiles.remove(36)
            newPlayerHandTiles.remove(37)

        newPlayerHandTilesArr = MTile.changeTilesToValueArr(newPlayerHandTiles)
        twoCount = 0
        for playerHandTileCount in newPlayerHandTilesArr:
            if playerHandTileCount == 1:
                return False
            elif playerHandTileCount == 2:
                twoCount += 1
            elif playerHandTileCount == 4:
                twoCount += 2

        if twoCount > 1:
            return False

        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
Example #30
0
    def isJiHu(self):
        # 只要牌里有幺鸡,就是鸡胡
        # tileArr = MTile.changeTilesToValueArr(MHand.copyAllTilesToList(self.playerAllTiles[self.winSeatId]))
        iszimo = self.lastSeatId == self.winSeatId

        tempCount = MTile.getTileCount(
            MTile.TILE_ONE_TIAO,
            MHand.copyAllTilesToList(self.playerAllTiles[self.winSeatId]))
        ftlog.debug('MBaichengOneResult.calcWin isJiHu tempCount:', tempCount)

        magics = self.tableTileMgr.getMagicTiles(True)
        if iszimo and (self.winTile == magics[0] == MTile.TILE_ONE_TIAO):
            isHuYaoji = False
            for wn in self.winNodes:
                if wn['winTile'] == MTile.TILE_ONE_TIAO:
                    isHuYaoji = True
            if isHuYaoji:
                return True
            else:
                if tempCount <= 1:
                    return False
                else:
                    return True

        else:
            # 胡牌
            if tempCount >= 1:
                return True
            else:
                return False
Example #31
0
    def getHandTilesValue(cls, tiles_player_hand, tiles_left):
        """计算手牌价值
        
        返回值:
        1)每张牌的价值
        2)手牌花色个数的数组
        """
        tiles_player_Arr = MTile.changeTilesToValueArr(
            tiles_player_hand[MHand.TYPE_HAND])
        #         tiles_left_Arr = MTile.changeTilesToValueArr(tiles_left)

        # 权值初始化
        tiles_value_Arr = [0 for _ in range(40)]
        for index in range(MTile.TILE_MAX_VALUE):
            if tiles_player_Arr[index] == 0:
                continue
            # 风牌只考虑自己的价值
            tiles_value_Arr[index] = tiles_player_Arr[index] * 4
            #              + tiles_left_Arr[index]
            # 万筒条还考虑同周围牌的关系
            if index < 30:
                if index % 10 < 9:
                    tiles_value_Arr[index] += tiles_player_Arr[index + 1] * 3
                if index % 10 < 8:
                    tiles_value_Arr[index] += tiles_player_Arr[index + 2] * 2
                if index % 10 > 1:
                    tiles_value_Arr[index] += tiles_player_Arr[index - 1] * 3
                if index % 10 > 2:
                    tiles_value_Arr[index] += tiles_player_Arr[index - 2] * 2

        ftlog.debug('getHandTilesValue valueArr:', tiles_value_Arr,
                    'playerArr:', tiles_player_Arr)
        return tiles_value_Arr, tiles_player_Arr
Example #32
0
    def isHuWishSpecialJiang(cls, tiles, jiangPattern, magics=[]):
        """
        指定将牌类型判断是否胡牌
            暂时不考虑将牌
        """
        # 先移除将牌。无指定将牌,判和失败
        tileArr = MTile.changeTilesToValueArr(tiles)
        jiangTile = jiangPattern[0]
        if tileArr[jiangTile] < 2:
            return False, []
        # 移除将牌
        tileArr[jiangTile] -= 2

        # 计算剩下的结果
        resultArr = []
        resultArr.append(jiangPattern)
        tileTypes = [
            MTile.TILE_WAN, MTile.TILE_TONG, MTile.TILE_TIAO, MTile.TILE_FENG
        ]
        winResult = False
        for tileType in tileTypes:
            winResult, _, _tArr, _rArr, _mArr = cls.isHuWithMagic(
                tileArr, resultArr, magics, True, tileType, False)
            if not winResult:
                return False, []
            else:
                tileArr = copy.deepcopy(_tArr)
                resultArr = copy.deepcopy(_rArr)

        return winResult, resultArr
    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
Example #34
0
    def isQiDui(cls, tiles, baoTiles=[]):
        '''
        判断是否是七对
        现在加入宝牌处理判断
        
        特别注意,baoTiles不是癞子牌,是宝牌,穷和玩法特有的宝牌,上听后生效。
        上听后摸到一张就和牌
        baoTiles可以是癞子牌,但传进来的必须是手牌中的赖子数组,如手牌中有2个7是赖子 baoTiles=[7,7]
        '''

        #ftlog.debug('MWin.isQiDui tiles:', tiles, ' baoTiles:', baoTiles)
        tileArr = MTile.changeTilesToValueArr(tiles)
        #ftlog.debug('MWin.isQiDui tileArr:', tileArr)

        for magicTile in baoTiles:
            tileArr[magicTile] -= 1

        allMagicTiles = copy.deepcopy(baoTiles)
        resultArr = []
        duiCount = 0
        for tileIndex in range(0, len(tileArr)):
            if tileArr[tileIndex] == 0:
                continue

            #单张情况
            elif tileArr[tileIndex] == 1:
                if len(allMagicTiles) >= 1:
                    duiCount += 1
                    resultArr.append([tileIndex, allMagicTiles.pop(0)])
            #三张情况
            elif tileArr[tileIndex] == 3:
                if len(allMagicTiles) >= 1:
                    duiCount += 2
                    resultArr.append([tileIndex, tileIndex])
                    resultArr.append([tileIndex, allMagicTiles.pop(0)])
            #一对
            elif tileArr[tileIndex] == 2:
                resultArr.append([tileIndex, tileIndex])
                duiCount += 1
            #两对
            elif tileArr[tileIndex] == 4:
                resultArr.append([tileIndex, tileIndex])
                resultArr.append([tileIndex, tileIndex])
                duiCount += 2

        for index in range(len(allMagicTiles)):
            if ((index + 1) % 2) == 0:
                resultArr.append(
                    [allMagicTiles[index - 1], allMagicTiles[index]])
                duiCount += 1

        ftlog.info('MWin.isQiDui, tiles:', tiles, ' baoTiles:', baoTiles,
                   ' duiCount:', duiCount, ' resultArr', resultArr)

        if (duiCount == 7) and (len(tiles) == 14):
            return True, resultArr
        elif (duiCount == 6) and (len(tiles) == 12):
            return True, resultArr
        else:
            return False, []
Example #35
0
    def checkPengMao(cls,tile,maoDanSetting,maoTiles):

        ftlog.debug('MMao.checkChiMao tile:', tile, 'maoDanSetting: ', maoDanSetting,'maoTiles: ',maoTiles)
        if maoDanSetting & MTDefine.MAO_DAN_DNXBZFB: #乱锚情况下
            if len(maoTiles) > 0:#已经放过锚
                if MTile.isArrow(tile) or MTile.isFeng(tile):#
                    return False
        else:
            if len(maoTiles) > 0:#已经放过锚
                for mao in maoTiles:
                    ftlog.debug('MMao.checkChiMao type:', mao['type'])
                    if MTile.isArrow(tile) and mao['type'] == 1:#已放箭牌
                        return False
                    if MTile.isFeng(tile) and mao['type'] == 2:#已放风牌
                        return False

        return True
Example #36
0
 def hasPeng(cls, tiles, tile):
     """是否可以碰
     判断之前tile已经加到tiles中
     tiles - 手牌
     tile - 待碰的牌
     """
     tileArr = MTile.changeTilesToValueArr(tiles)
     if tileArr[tile] >= 3:
         return True
     return False
Example #37
0
 def hasAnGang(cls, tiles, tile):
     """自摸是否可以暗杠
     判断杠牌时,tile已经加入tiles中
     tiles - 手牌
     tile - 待杠的牌
     """
     tileArr = MTile.changeTilesToValueArr(tiles)
     if tileArr[tile] == 4:
         return True
     return False
Example #38
0
 def __init__(self):
     """初始化
         子类在自己的初始化方法里,初始化麻将牌池范围,准备发牌
         包含所有的牌
     """
     super(AllFlowerDealer, self).__init__()
     # 本玩法包含的花色
     self.__card_colors = [MTile.TILE_WAN, MTile.TILE_TONG, MTile.TILE_TIAO, MTile.TILE_FENG,MTile.TILE_FLOWER]
     # 花色数量
     self.__card_count = len(self.__card_colors)
     # 初始化本玩法包含的牌
     self.setCardTiles(MTile.getTiles(self.__card_colors))
Example #39
0
    def isHunyise(self, tiles, magicTiles):
	if not len(magicTiles):
	    return False
	magicTile = magicTiles[0]
	magicCount = 0
        allTiles = MHand.copyAllTilesToListButHu(tiles)
        allTileArr = MTile.changeTilesToValueArr(allTiles)
        allColors = MTile.getColorCount(allTileArr)
        for tile in allTiles:
	    if tile == magicTile:
		magicCount = magicCount + 1

        for i in range(magicCount):
            allTiles.remove(magicTile)

        tileArr = MTile.changeTilesToValueArr(allTiles)
        colors = MTile.getColorCount(tileArr)
	#ftlog.debug('MWinRuleQueshou.isHunyise allColors colors=',allColors,colors,magicCount,allTiles)
        if allColors == 2 and colors == 1:
            return True
        return False 
Example #40
0
 def __init__(self):
     """初始化
         子类在自己的初始化方法里,初始化麻将牌池范围,准备发牌
         四川玩法,只有三门,没有风
     """
     super(SanMenNoFengDealer, self).__init__()
     # 本玩法包含的花色
     self.__card_colors = [MTile.TILE_WAN, MTile.TILE_TONG, MTile.TILE_TIAO]
     # 花色数量
     self.__card_count = len(self.__card_colors)
     # 初始化本玩法包含的牌
     self.setCardTiles(MTile.getTiles(self.__card_colors))
     ftlog.debug( self.cardTiles )
Example #41
0
 def __init__(self):
     """初始化
         子类在自己的初始化方法里,初始化麻将牌池范围,准备发牌
         包括万/筒/条三门+中发白
     """
     super(SanMenWithZFBDealer, self).__init__()
     # 本玩法包含的花色
     self.__card_colors = [MTile.TILE_WAN, MTile.TILE_TONG, MTile.TILE_TIAO, MTile.TILE_FENG]
     # 风牌的描述
     self.__feng_details = MTile.FENG_ZHONG | MTile.FENG_FA | MTile.FENG_BAI
     # 花色数量
     self.__card_count = len(self.__card_colors)
     # 初始化本玩法包含的牌
     self.setCardTiles(MTile.getTiles(self.__card_colors, self.__feng_details))
Example #42
0
    def isJinQue(self,magicTile,pattern,handTiles):
        """
        金雀:金做将对
        """ 
	magicCount = MTile.getTileCount(magicTile,handTiles) 
	if magicCount != 2:
	    return False
        for p in pattern:
            for oneTile in p:
                if oneTile in handTiles:
                    handTiles.remove(oneTile)
        if len(handTiles) == 2 and handTiles[0] == handTiles[1] and handTiles[0] == magicTile:
            return True
        return False
Example #43
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
Example #44
0
    def canWinAddOneTile(cls, leftTileArr, leftTileCount, tiles, winRule, magicTiles = [], curSeatId = 0, winSeatId = 0, actionID = 0,tingForQiangjin = False,flowerRule = None):
        """
        tingForQiangjin 是否是抢金,当是判断抢金时,有可听的结果就返回  modify by youjun
        """ 
        result = []
        if len(magicTiles):
            testTile = MTile.cloneTiles(tiles)
            testTile[MHand.TYPE_HAND].append(magicTiles[0])
            testResult,testPattern,_ = winRule.isHu(testTile, magicTiles[0], True, MWinRule.WIN_BY_MYSELF, magicTiles, [], curSeatId, winSeatId, actionID,False,False)
            if not testResult:
                return result	

        for tile in range(leftTileCount):
	    if flowerRule and flowerRule.isFlower(tile):
                break
	    if tile % 10 == 0:
		continue
            newTile = MTile.cloneTiles(tiles)
            newTile[MHand.TYPE_HAND].append(tile)
            # 测试停牌时,默认听牌状态	modify youjun 06.23 默认未听牌状态
            winResult, winPattern,indexFan = winRule.isHu(newTile, tile, True, MWinRule.WIN_BY_MYSELF, magicTiles, [], curSeatId, winSeatId, actionID,False,False)
            if winResult:
                winNode = {}
                winNode['winTile'] = tile
                winNode['winTileCount'] = leftTileArr[tile]
		'''	
                ftlog.debug('MTing.canWinAddOneTile winTile:', tile
                            , ' winTileCount:', winNode['winTileCount']
                            , ' winPattern:', winPattern
			    , ' result:',indexFan)
		'''
                winNode['pattern'] = winPattern
		winNode['result'] = indexFan
		result.append(winNode)
       		if tingForQiangjin:
                    return result  
        return result
Example #45
0
 def __init__(self):
     """初始化
         子类在自己的初始化方法里,初始化麻将牌池范围,准备发牌
         鸡西麻将三人玩法
         包括筒/条三门+红中
     """
     super(TongTiaoWithZhonggDealer, self).__init__()
     # 本玩法包含的花色
     self.__card_colors = [MTile.TILE_TONG, MTile.TILE_TIAO, MTile.TILE_FENG]
     # 风牌的描述
     self.__feng_details = MTile.FENG_ZHONG
     # 花色数量
     self.__card_count = len(self.__card_colors)
     # 初始化本玩法包含的牌
     self.setCardTiles(MTile.getTiles(self.__card_colors, self.__feng_details))
Example #46
0
    def isSanJinDao(self):
        """
        三金倒
        """
        magicTile = self.tableTileMgr.getMagicTile()
        handTiles = self.playerAllTiles[self.winSeatId][MHand.TYPE_HAND]
        magicCount = MTile.getTileCount(magicTile,handTiles)
	huTiles = self.tableTileMgr.players[self.winSeatId].huTiles
	ftlog.debug('isSanJinDao. self.winSeatId,huTiles=',self.winSeatId,huTiles)
	if len(huTiles) and huTiles[0] == magicTile:
	    magicCount = magicCount + 1
	ftlog.debug('isSanJinDao.magicCount=',magicCount,handTiles,magicTile)
        if magicCount == 3:
            return True
        return False
Example #47
0
    def getWinnerGen(self):
        #只要你手上有4个一样的,哪怕是碰了之后自己摸的加杠,或者手上有4张一样的牌,没有杠等等都算一番,你有2根就是2番,*4
        #杠牌个数+手中可暗杠个数
        winnerGen = 0
        handTiles = self.tableTileMgr.players[self.winSeatId].copyHandTiles()
        tileArr = MTile.changeTilesToValueArr(handTiles)
        for tile in range(MTile.TILE_MAX_VALUE):
            if tileArr[tile] == 4:
                winnerGen += 1
        gangTiles = self.tableTileMgr.players[self.winSeatId].copyGangArray()
        winnerGen += len(gangTiles)
	if winnerGen > 0:
            return True,winnerGen
	else:
	    return False,winnerGen
Example #48
0
    def shuffle(self, goodPointCount, cardCountPerHand):
        """参数说明
            goodPointCount : 好牌点的人数
            cardCountPerHand : 每手牌的麻将牌张数
        """
        # 初始化一下cardTiles,因为每设置一次好牌点都会从里面弹出13张牌
        self.setCardTiles(MTile.getTiles(self.__card_colors))
        
        left_tiles = []    
        for color in self.__card_colors:
            left_tiles.extend(self.cardTiles[color])
        # 对剩余的牌洗牌
        random.shuffle(left_tiles)
        self.addTiles(left_tiles)

        return self.tiles
Example #49
0
 def hasPeng(self, tiles, tile, seatId=-1):
     """是否有碰牌解
     
     参数说明;
     tiles - 玩家的所有牌,包括手牌,吃牌,碰牌,杠牌,胡牌
     tile - 待碰的牌
     """
     
     #是否允许会牌参与,如果不允许,删除会牌
     tilesForPeng = copy.deepcopy(tiles[MHand.TYPE_HAND])
     if not self.tableTileMgr.allowMagicChiPengGang():
         magicTile = self.tableTileMgr.getMagicTile()
         while magicTile in tilesForPeng:
             tilesForPeng.remove(magicTile)
             
             
     pengSolutions = []
     normalPeng = MPeng.hasPeng(tilesForPeng, tile)
     if normalPeng:
         pengSolutions.append([tile, tile, tile])
         
     magics = self.tableTileMgr.getMagicTiles(False)
     tileArr = MTile.changeTilesToValueArr(tiles[MHand.TYPE_HAND])
     tileArr, magicTiles = self.tableTileMgr.exculeMagicTiles(tileArr, magics)
     magicCount = len(magicTiles)
     if magicCount == 0:
         return pengSolutions
     
     if not self.tableTileMgr.canUseMagicTile(MTableState.TABLE_STATE_PENG):
         return pengSolutions
     
     ftlog.debug('MPengRule.hasPeng tile:', tile
                 , ' tileCount:', tileArr[tile]
                 , ' magicCount:', magicCount)
     
     if (magicCount == 0) or (tileArr[tile] == 0):
         return pengSolutions
     
     if magicCount >= 1 and tileArr[tile] >= 2:
         # 使用一个癞子
         pengSolutions.append([tile, tile, magicTiles[0]])
         
     if magicCount >= 2 and tileArr[tile] >= 1:
         # 使用两个癞子
         pengSolutions.append([tile, magicTiles[0], magicTiles[1]])
         
     return pengSolutions
Example #50
0
    def hasChi(cls, tiles, tile):
        """是否可以吃
        吃牌的判断中,tile已经在tiles中
        参数:
            tiles - 手牌
            tile - 待吃的牌
        返回值:吃牌选择
            最多三种解
            
        例子:
            [[2, 3, 4], [3, 4, 5], [4, 5, 6
        """
        tileArr = MTile.changeTilesToValueArr(tiles)
        result = []
	
        # 第一种情况 001
        if (tile % 10) >= 3:
            if tileArr[tile - 2] > 0 and tileArr[tile - 1] > 0 and tileArr[tile] > 0:
                solution = [tile - 2, tile - 1, tile]
                result.append(solution)
        '''
        # 第三种情况 100
        if (tile % 10) < 8:
            if tileArr[tile] > 0 and tileArr[tile + 1] > 0 and tileArr[tile + 2] > 0:
                solution = [tile, tile + 1, tile + 2]
                result.append(solution)
	'''
        # 第二种情况 010
        if (tile % 10) >= 2 and (tile % 10) < 9:
            if tileArr[tile - 1] > 0 and tileArr[tile] > 0 and tileArr[tile + 1] > 0:
                solution = [tile - 1, tile, tile + 1]
                result.append(solution)
	        
        # 第三种情况 100
        if (tile % 10) < 8:
            if tileArr[tile] > 0 and tileArr[tile + 1] > 0 and tileArr[tile + 2] > 0:
                solution = [tile, tile + 1, tile + 2]
                result.append(solution)
   	'''     
        # 第一种情况 001
        if (tile % 10) >= 3:
            if tileArr[tile - 2] > 0 and tileArr[tile - 1] > 0 and tileArr[tile] > 0:
                solution = [tile - 2, tile - 1, tile]
                result.append(solution) 
        '''
        return result
Example #51
0
    def isQidui(self, tiles):
        handTiles = copy.deepcopy(tiles[MHand.TYPE_HAND])
        handTilesArr = MTile.changeTilesToValueArr(handTiles)

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

        pattern = []
        for tile in range(MTile.TILE_MAX_VALUE):
            if handTilesArr[tile] == 1 or handTilesArr[tile] == 3:
                # 只要出现单数,必然不是七对
                return False, []
            if handTilesArr[tile] == 2:
                pattern.append([tile, tile])
            if handTilesArr[tile] == 4:
            	# 和LuosihuOneResult配合
                pattern.extend([[tile, tile],[tile, tile]])
        return True, pattern
Example #52
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
Example #53
0
 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
Example #54
0
    def canTingBeforeAddTile(cls, tiles, leftTiles, winRule, magicTiles = [], curSeatId = 0, winSeatId = 0, actionID = 0,tingForQiangjin = False,flowerRule = None):
        """判断在摸牌之前是否可以听
        """
        #ftlog.debug('MTile.changeTilesToValueArr', tiles[MHand.TYPE_HAND])
        leftTileArr = MTile.changeTilesToValueArr(leftTiles)
        leftTileCount = len(leftTileArr)
        '''
	ftlog.debug('MTing.canTingBeforeAddTile leftTiles:', leftTiles
                     , ' leftTileArr:', leftTileArr
                     , ' leftTileCount:', leftTileCount)
        '''
        result = []
        resultNode = cls.canWinAddOneTile(leftTileArr, leftTileCount, tiles, winRule, magicTiles, curSeatId, winSeatId, actionID,tingForQiangjin,flowerRule)
        if len(resultNode) > 0:
            winNode = {}
            winNode['winNodes'] = resultNode
            result.append(winNode)
            if tingForQiangjin:
                return len(result) > 0, result    
        return len(result) > 0, result
Example #55
0
    def isJinQue(self,isZiMo = False):
        """
        金雀:金做将对
        
	if not isZiMo:
	    return False
	"""
	magicTile = self.tableTileMgr.getMagicTile()
	handTiles = self.playerAllTiles[self.winSeatId][MHand.TYPE_HAND]
	magicCount = MTile.getTileCount(magicTile,handTiles)
        huTiles = self.tableTileMgr.players[self.winSeatId].huTiles
        if len(huTiles) and huTiles[0] == magicTile:
            magicCount = magicCount + 1 
	if magicCount != 2:
	    return False
        for p in self.__win_pattern:
            if len(p) == 2:
                if p[0] == p[1] and p[0] == magicTile:
                    return True
        return False
Example #56
0
    def canJinQue(self,magicTile,pattern,handTiles,tile):
	'''
        magicCount = MTile.getTileCount(magicTile,handTiles)
        if magicCount == 2:
            result, pattern= MWin.isHu(handTiles, [])
	    ftlog.debug('MWinRuleQueshou.canJinQue result, pattern=',result, pattern)
            if result:
                return True
        return False
	'''
        magicCount = MTile.getTileCount(magicTile,handTiles)
        if magicCount == 2:
            if tile in handTiles:
                handTiles.remove(tile)
                handTiles.append(31)
            result, pattern= MWin.isHu(handTiles, [31])
	    ftlog.debug('MWinRuleQueshou.canJinQue result, pattern=',result, pattern,handTiles)
            if result:
                return True

        return False
Example #57
0
    def isYouJin(self,magicTile,pattern,handTiles,tile):
        '''
        游金:金做将对
        游金不胡点炮
	
	ftlog.debug('MWinRuleQueshou.isYouJin pattern,handTiles,tile',pattern,handTiles,tile)
        for p in pattern:
            if len(p) == 2:
                if magicTile in p:
                    p.remove(magicTile)
                    if p[0] == tile:
                        return True
	'''
	magicCount = MTile.getTileCount(magicTile,handTiles)
        if magicCount == 1:
            if tile in handTiles:
                handTiles.remove(tile)
                handTiles.append(31)
            result, pattern= MWin.isHu(handTiles, [magicTile])
            #ftlog.debug('MWinRuleQueshou.canJinQue result, pattern=',result, pattern,handTiles)
            if result:
                return True
	return False
Example #58
0
    def calcWin(self,winState = 0):
        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:
	    if not winState:
                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 = 1
	winScore = 0
	# 连庄
	bankerRemainCount = 0
	if self.winSeatId == self.bankerSeatId:
            bankerRemainCount = self.tableTileMgr.tableConfig.get(MTDefine.WIN_BASE,1) - 1

	winScore = winScore + bankerRemainCount
        ### 算杠分
        minggangScore = 0
        angangScore = 0        
	gangscore = 0  # 杠牌得分
        gangList = self.playerGangTiles[self.winSeatId]
        for gang in gangList:
            #if MTile.getColor(gang['pattern'][0]) == 3:
            #    gangscore += 1
	    #	minggangScore += 1
            if gang['style'] == 0:  # 暗杠
                gangscore += 2
		angangScore += 2
            else:
                gangscore += 1
		minggangScore += 1

        #winScore = winScore + angangScore + minggangScore

        ##算花分
        huaScore = len(self.tableTileMgr.flowerTiles(self.winSeatId))
        #winScore = winScore + huaScore

        ###算金分
        magicTile = self.tableTileMgr.getMagicTile()
        handTiles = self.playerAllTiles[self.winSeatId][MHand.TYPE_HAND]
        magicScore = MTile.getTileCount(magicTile,handTiles)
	huTiles = self.tableTileMgr.players[self.winSeatId].huTiles
	if len(huTiles) > 0 and huTiles[0] == magicTile and not winState == MTableState.TABLE_STATE_SANJINDAO:
            magicScore = magicScore + 1
	ftlog.debug('calcWin handTiles=',handTiles,huTiles,magicScore)
        winScore = winScore + magicScore

        winnerResults = []
        if winState:
            if winState == MTableState.TABLE_STATE_TIANHU:
                winnerResults.append(self.processFanXingResult(self.TIANHU))
            elif winState == MTableState.TABLE_STATE_QIANGJIN:
                winnerResults.append(self.processFanXingResult(self.QIANGJIN))
	    elif winState == MTableState.TABLE_STATE_QIANGJIN_B: 
		winnerResults.append(self.processFanXingResult(self.QIANGJIN))
            elif winState == MTableState.TABLE_STATE_SANJINDAO: 
	        winnerResults.append(self.processFanXingResult(self.SANJINDAO))

        #if not isZiMo:
        if not huaScore and not len(gangList):
            winnerResults.append(self.processFanXingResult(self.PINGHU))
        if huaScore + gangscore == 1:
            winnerResults.append(self.processFanXingResult(self.PINGHUYIHUA))
 
        if winState and winState == MTableState.TABLE_STATE_TIANHU:
            if self.isSanJinDao():
                winnerResults.append(self.processFanXingResult(self.SANJINDAO))
	    if self.tableConfig.get(MTDefine.QINGHUNYISE, 0):
                if self.isQingyise():   #清一色
                    winnerResults.append(self.processFanXingResult(self.QINGYISE))
                elif self.isHunyise():  # 混一色
                    winnerResults.append(self.processFanXingResult(self.HUNYISE))
            if self.tableTileMgr.players[self.winSeatId].jinkanState:
                winnerResults.append(self.processFanXingResult(self.JINKAN))
            if self.isJinQue(isZiMo):
                winnerResults.append(self.processFanXingResult(self.JINQUE))
        if not winState:
            if self.isSanJinDao():
                winnerResults.append(self.processFanXingResult(self.SANJINDAO))
	    if self.tableConfig.get(MTDefine.QINGHUNYISE, 0):
                if self.isQingyise():   #清一色
                    winnerResults.append(self.processFanXingResult(self.QINGYISE))
                elif self.isHunyise():  # 混一色
                    winnerResults.append(self.processFanXingResult(self.HUNYISE))
            if self.tableTileMgr.players[self.winSeatId].jinkanState:
                winnerResults.append(self.processFanXingResult(self.JINKAN))
            if self.isJinQue(isZiMo):
                winnerResults.append(self.processFanXingResult(self.JINQUE))

        if not len(winnerResults):
            winScore = winScore + baseScore

        ###自摸 或者特殊番型*2
        #if isZiMo or len(winnerResults) > 0:
        #    winScore = winScore * 2 

        bestWinnerResult = None
        maxScore = 0
        for result in winnerResults:
            tempScore = self.getScoreByResults(result)
            if tempScore > maxScore:
                maxScore = tempScore
                bestWinnerResult = result

        if bestWinnerResult and bestWinnerResult['index'] == 19:
            huaScore = 0 
	else:
	    winScore = winScore + angangScore + minggangScore
	    winScore = winScore + huaScore
        ###自摸 或者特殊番型*2
        if isZiMo or len(winnerResults) > 0:
            winScore = winScore * 2 

	winScore = winScore + maxScore

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

            if winState: #抢金
                score = [-winScore for _ in range(self.playerCount)]
                score[self.winSeatId] = (self.playerCount-1) * winScore
            else:
                if self.getFangHuConfig() == 1:
                    score = [-winScore for _ in range(self.playerCount)]
                    score[self.winSeatId] = (self.playerCount-1) * winScore
                elif self.getFangHuConfig() == 2:
                    score[self.lastSeatId] = -winScore
                    score[self.winSeatId] = winScore

        if bestWinnerResult:
            winMode[self.winSeatId] = bestWinnerResult['index']

        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] = bestWinnerResult
        #self.results[self.KEY_FAN_PATTERN] = fanPattern
	'''	
	winInfo = []
        jinResult = []
        huaResult = []
        baseResult = []
	winPatt = []
        if len(winnerResults) > 0 or isZiMo:
            #self.results['double'] = 2
            jinResult.append("金牌:" + str(magicScore) + "花" + "*2")
            huaResult.append("花牌:" + str(huaScore) + "花" + "*2")
            baseResult.append("底分:" + str(baseScore) + "花" + "*2")
	    if bestWinnerResult:
		winPatt.append(bestWinnerResult['name'] + ":" + str(bestWinnerResult['value'])+ "花")
        else:
            jinResult.append("金牌:" + str(magicScore) + "花")
            huaResult.append("花牌:" + str(huaScore) + "花")
	    baseResult.append("底分:" + str(baseScore) + "花")
	winInfo.append(baseResult)
	if magicScore:
            winInfo.append(jinResult)
	if huaScore:
            winInfo.append(huaResult)
	if len(winPatt) > 0:
            winInfo.append(winPatt)
	'''

        winInfo = []
        jinResult = "金牌" + str(magicScore)
        huaResult = "花牌" + str(huaScore)
        baseResult = "底分" + str(baseScore)
        remainResult = "连庄" + str(bankerRemainCount)
        winPatt = None
        if bestWinnerResult:
            winPatt = bestWinnerResult['name'] + str(bestWinnerResult['value'])
        minggangResult = "明杠" + str(minggangScore)
        angangResult = "暗杠" + str(angangScore)


        winResult = "("
        if not len(winnerResults):
            winResult = winResult + " " + baseResult
        if huaScore:
            winResult = winResult + " " + huaResult
        if magicScore:
            winResult = winResult + " " + jinResult
        if minggangScore:
            winResult = winResult + " " + minggangResult
        if angangScore:
            winResult = winResult + " " + angangResult
        if bankerRemainCount:
            winResult = winResult + " " + remainResult

	if len(winnerResults) > 0 or isZiMo:
	    if bestWinnerResult:
                winPatt = bestWinnerResult['name'] + str(bestWinnerResult['value'])
		if huaScore or magicScore or minggangScore or angangScore or bankerRemainCount:
	            winResult = winResult + " )" + " *2 + " + winPatt + " = " + str(winScore)
		else:
		    winResult = winPatt + " = " + str(winScore)
            else:
                winResult = winResult + " )" + " *2" + " = " + str(winScore)
        else:
            winResult = winResult + " )" + " *1" + " = " + str(winScore)
	winInfo.append([winResult])
	
        fanPattern[self.winSeatId] = winInfo
        self.results[self.KEY_FAN_PATTERN] = fanPattern
        self.results[self.KEY_FLOWER_SCORES] = flowerScores
	self.results[self.KEY_LIANZHUANG] = bankerRemainCount