コード例 #1
0
ファイル: ting_rule_luosihu.py プロジェクト: zhaozw/mjserver
    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, []
コード例 #2
0
ファイル: ting.py プロジェクト: zhaozw/mjserver
    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
コード例 #3
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
コード例 #4
0
ファイル: ting.py プロジェクト: zhaozw/mjserver
    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
コード例 #5
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
コード例 #6
0
ファイル: ting_rule_queshou.py プロジェクト: zhaozw/mjserver
 def canTingForQiangjin(self,
                        tiles,
                        leftTiles,
                        tile,
                        magicTiles=[],
                        curSeatId=0,
                        winSeatId=0,
                        actionID=0,
                        tingForQiangjin=True):
     isTing, tingResults = MTing.canTing(MTile.cloneTiles(tiles), leftTiles,
                                         self.winRuleMgr, tile, magicTiles,
                                         curSeatId, winSeatId, actionID,
                                         tingForQiangjin, self.flowerRule)
     ftlog.debug('MTingQueshouRule.canTingForQiangjin using MTing isTing:',
                 isTing, ' tingResults:', tingResults)
     return isTing, tingResults
コード例 #7
0
    def canWinAddOneTile(cls,
                         tilePatternChecker,
                         tableTileMgr,
                         leftTileArr,
                         leftTileCount,
                         tiles,
                         winRule,
                         magicTiles=[],
                         winSeatId=0):
        result = []
        #for tile in range(leftTileCount):
        ishuAll = True
        for tile in tableTileMgr.getAllTilesForTing():
            newTile = MTile.cloneTiles(tiles)
            newTile[MHand.TYPE_HAND].append(tile)
            '''
            # 添加tile牌,如果tile牌总数大于4,则不用判断
            if newTile[MHand.TYPE_HAND].count(tile) > 4:
                continue
            '''
            # 测试听牌时,默认听牌状态
            winResult, winPattern = winRule.isHu(newTile, tile, True,
                                                 MWinRule.WIN_BY_MYSELF,
                                                 magicTiles, [], winSeatId)
            if winResult:
                winNode = {}
                winNode['winTile'] = tile
                winNode['winTileCount'] = leftTileArr[tile]
                # getVisibleTileCount 返回值是已经有几张了 最多为4张,一炮多响胡牌会算多
                visibleTileCount = tableTileMgr.getVisibleTilesCount(
                    tile, True, winSeatId)
                winNode['winTileCountUserCanSee'] = 4 - visibleTileCount
                tilePatternChecker.initChecker(newTile, tableTileMgr)
                winNode['winFan'] = tilePatternChecker.calcFanPatternTing()
                winNode['pattern'] = winPattern
                ftlog.debug('MTing.canWinAddOneTile winTile:', tile,
                            ' winTileCount:', winNode['winTileCount'],
                            ' winPattern:', winPattern, ' winNode:', winNode)
                result.append(winNode)
            else:
                ishuAll = False

        return result, ishuAll
コード例 #8
0
    def canTing(cls,
                tilePatternChecker,
                tableTileMgr,
                tiles,
                leftTiles,
                winRule,
                tile,
                magicTiles=[],
                winSeatId=0):
        """
        判断是否可以听牌
        参数:
        1)tiles 手牌
        2)leftTiles 剩余未发的牌
        
        返回值:
        
        """
        ftlog.debug('MTile.changeTilesToValueArr', tiles[MHand.TYPE_HAND])
        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 tableTileMgr.getAllTilesForTing():
            if handTileArr[tile] > 0:
                newTiles = MTile.cloneTiles(tiles)
                newTiles[MHand.TYPE_HAND].remove(tile)
                resultNode, istingAll = cls.canWinAddOneTile(
                    tilePatternChecker, tableTileMgr, leftTileArr,
                    leftTileCount, newTiles, winRule, magicTiles, winSeatId)
                if len(resultNode) > 0:
                    winNode = {}
                    winNode['dropTile'] = tile
                    winNode['winNodes'] = resultNode
                    winNode['isHuAll'] = istingAll
                    result.append(winNode)

        return len(result) > 0, result
コード例 #9
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)
        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
コード例 #10
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)
        newPlayerHandTiles.append(self.winTile)

        ishu, pattern = MWin.isHu(newPlayerHandTiles,
                                  self.tableTileMgr.getMagicTiles(True), True)
        ftlog.debug('MPanjinOneResult.calcWin isPiao newPlayerHandTiles:',
                    newPlayerHandTiles, 'ishu', ishu, 'pattern', pattern)
        if ishu:
            for p in pattern:
                if len(p) == 3:
                    if (p[0] == p[2] or p[1] == p[2] or p[0] == p[1]):
                        continue
                    else:
                        ftlog.debug('MPanjinOneResult.calcWin isPiao False')
                        return False
        ftlog.debug('MPanjinOneResult.calcWin isPiao True')
        return True
コード例 #11
0
ファイル: ting_rule_jixi.py プロジェクト: zhaozw/freetime5
    def canTing(self, tiles, leftTiles, tile, magicTiles=[], winSeatId=0):
        """子类必须实现
        参数:
        1)tiles 该玩家的手牌
        2)leftTiles 剩余手牌
        返回值:
        是否可以听牌,听牌详情
        """
        handCount = len(tiles[MHand.TYPE_HAND])

        isTing, tingResults = MTing.canTing(self.tilePatternChecker,
                                            self.tableTileMgr,
                                            MTile.cloneTiles(tiles), leftTiles,
                                            self.winRuleMgr, tile, magicTiles,
                                            winSeatId)
        ftlog.debug('MTingJixiRule.canTing tiles:', tiles, 'tile:', tile)
        ftlog.debug('MTingJixiRule.MTing.canTing isTing:', isTing,
                    ' tingResults:', tingResults)
        #         [{'dropTile': 11, 'winNodes': [{'winTile': 1, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [1, 2, 3]]}, {'winTile': 2, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [3, 4, 5], [2, 2]]}, {'winTile': 4, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [2, 3, 4]]}, {'winTile': 5, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [5, 5], [2, 3, 4]]}, {'winTile': 7, 'winTileCount': 1, 'pattern': [[6, 6], [5, 6, 7], [5, 6, 7], [2, 3, 4]]}, {'winTile': 8, 'winTileCount': 1, 'pattern': [[6, 7, 8], [6, 6, 6], [5, 5], [2, 3, 4]]}]}]
        #tingResults: [{'dropTile': 23, 'winNodes': [{'winTile': 12, 'winTileCount': 0, 'pattern': [[13, 14, 15], [12, 12, 12], [29, 29], [25, 25, 25]]}, {'winTile': 29, 'winTileCount': 1, 'pattern': [[13, 14, 15], [12, 12], [29, 29, 29], [25, 25, 25]]}]}]

        if not isTing:
            return False, []

        # 检查刻,刻的来源,碰牌/明杠牌/手牌
        pengCount = len(tiles[MHand.TYPE_PENG])
        gangCount = len(tiles[MHand.TYPE_GANG])
        keCount = pengCount + gangCount

        newTingResults = []
        for tingResult in tingResults:
            newWinNodes = []
            winNodes = tingResult['winNodes']
            for winNode in winNodes:
                newTiles = MTile.cloneTiles(tiles)
                newTiles[MHand.TYPE_HAND].remove(tingResult['dropTile'])
                newTiles[MHand.TYPE_HAND].append(winNode['winTile'])
                tileArr = MTile.changeTilesToValueArr(
                    MHand.copyAllTilesToList(newTiles))
                patterns = winNode['pattern']
                isQiDui = self.isQiDui(patterns, newTiles)
                isPiaoHu = self.isPiaoHu(patterns, newTiles)

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

                # 飘和七小对不需要1,9,如果不是飘也不是七小对:
                # 检查牌中的幺/九
                # 1软 听牌可以没有19,只要胡牌带19就可以
                # 2硬 听牌时就要有19
                if not (isPiaoHu or isQiDui):
                    RuanYaoJiuConfig = self.getTableConfig(
                        MTDefine.RUAN_YAO_JIU, 1)
                    if RuanYaoJiuConfig == 0:
                        #硬幺九 :听牌必须有19
                        #tileArr 减去 winNode['winTile'] 后判断
                        tileArr[winNode['winTile']] -= 1
                        yaoCount = tileArr[MTile.TILE_ONE_WAN] + tileArr[
                            MTile.TILE_ONE_TONG] + tileArr[MTile.TILE_ONE_TIAO]
                        jiuCount = tileArr[MTile.TILE_NINE_WAN] + tileArr[
                            MTile.TILE_NINE_TONG] + tileArr[
                                MTile.TILE_NINE_TIAO]
                        zhongCount = tileArr[MTile.TILE_HONG_ZHONG]
                        ftlog.debug('MTingJixiRule.canTing : YING yaoCount:',
                                    yaoCount, 'jiuCount', jiuCount,
                                    'zhongCount', zhongCount)
                        if (yaoCount + jiuCount + zhongCount) <= 0:
                            continue
                    else:
                        #软幺九 :只要胡牌有19就行
                        yaoCount = tileArr[MTile.TILE_ONE_WAN] + tileArr[
                            MTile.TILE_ONE_TONG] + tileArr[MTile.TILE_ONE_TIAO]
                        jiuCount = tileArr[MTile.TILE_NINE_WAN] + tileArr[
                            MTile.TILE_NINE_TONG] + tileArr[
                                MTile.TILE_NINE_TIAO]
                        zhongCount = tileArr[MTile.TILE_HONG_ZHONG]
                        ftlog.debug('MTingJixiRule.canTing : RUAN yaoCount:',
                                    yaoCount, 'jiuCount', jiuCount,
                                    'zhongCount', zhongCount)
                        if (yaoCount + jiuCount + zhongCount) == 0:
                            continue

                #夹起步(顺牌只能和夹和3,7) 不能和两头 可以单吊
                chunJiaConfig = self.getTableConfig(MTDefine.MIN_MULTI, 0)
                if chunJiaConfig:
                    bianMulti = self.tableConfig.get(MTDefine.BIAN_MULTI, 0)
                    danDiaoJia = self.tableConfig.get(MTDefine.DAN_DIAO_JIA, 1)
                    hasJia = False
                    for pattern in patterns:
                        if winNode['winTile'] in pattern:
                            if len(pattern) == 3 and pattern[0] != pattern[1]:
                                if pattern.index(winNode['winTile']) == 2:
                                    if bianMulti:
                                        if MTile.getValue(
                                                winNode['winTile']) == 3:
                                            hasJia = True
                                            break
                                if pattern.index(winNode['winTile']) == 0:
                                    if bianMulti:
                                        if MTile.getValue(
                                                winNode['winTile']) == 7:
                                            hasJia = True
                                            break

                                if pattern.index(winNode['winTile']) == 1:
                                    hasJia = True
                                    break

                            #单吊
                            if len(pattern) == 2 and pattern[0] == pattern[
                                    1] and danDiaoJia:
                                hasJia = True
                                break

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

                patterns = winNode['pattern']
                checkKeCount = keCount + self.getKeCount(patterns)
                ftlog.debug('MTingJixiRule.canTing keCount:', keCount)

                #胡牌必须有刻牌 七小对除外
                if checkKeCount or isQiDui:
                    newWinNodes.append(winNode)

            if len(newWinNodes) > 0:
                newTingResult = {}
                newTingResult['dropTile'] = tingResult['dropTile']
                newTingResult['winNodes'] = newWinNodes
                newTingResults.append(newTingResult)

        ftlog.debug('MTingJixiRule.canTing :len(newTingResults) ',
                    len(newTingResults), 'newTingResults', newTingResults)
        return len(newTingResults) > 0, newTingResults
コード例 #12
0
ファイル: ting_rule_haerbin.py プロジェクト: zhaozw/freetime5
    def canTing(self, tiles, leftTiles, tile, magicTiles=[], winSeatId=0):
        """子类必须实现
        参数:
        1)tiles 该玩家的手牌
        2)leftTiles 剩余手牌
        返回值:
        是否可以听牌,听牌详情
        """
        handCount = len(tiles[MHand.TYPE_HAND])
        if handCount < 5:
            return False, []

        isTing, tingResults = MTing.canTing(self.tilePatternChecker,
                                            self.tableTileMgr,
                                            MTile.cloneTiles(tiles), leftTiles,
                                            self.winRuleMgr, tile, magicTiles,
                                            winSeatId)
        ftlog.debug('MTingHaerbinRule.MTing.canTing isTing:', isTing,
                    ' tingResults:', tingResults)
        #         [{'dropTile': 11, 'winNodes': [{'winTile': 1, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [1, 2, 3]]}, {'winTile': 2, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [3, 4, 5], [2, 2]]}, {'winTile': 4, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [2, 3, 4]]}, {'winTile': 5, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [5, 5], [2, 3, 4]]}, {'winTile': 7, 'winTileCount': 1, 'pattern': [[6, 6], [5, 6, 7], [5, 6, 7], [2, 3, 4]]}, {'winTile': 8, 'winTileCount': 1, 'pattern': [[6, 7, 8], [6, 6, 6], [5, 5], [2, 3, 4]]}]}]

        if not isTing:
            return False, []

        chiCount = len(tiles[MHand.TYPE_CHI])
        pengCount = len(tiles[MHand.TYPE_PENG])
        gangCount = len(tiles[MHand.TYPE_GANG])

        mingGangCount = 0
        anGangCount = 0
        #计算明杠个数,因为暗杠不算开门
        if gangCount != 0:
            mingGangCount, anGangCount = MTile.calcGangCount(
                tiles[MHand.TYPE_GANG])
        ftlog.debug('MTingHaerbinRule.gang tiles:', tiles[MHand.TYPE_GANG],
                    ' mingGangCount=', mingGangCount, ' anGangCount=',
                    anGangCount)

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

        # 检查刻,刻的来源,碰牌/明杠牌/手牌
        keCount = pengCount + mingGangCount + anGangCount
        # 必须有顺牌
        shunCount = chiCount

        newTingResults = []
        for tingResult in tingResults:
            newWinNodes = []
            winNodes = tingResult['winNodes']
            for winNode in winNodes:
                newTiles = MTile.cloneTiles(tiles)
                newTiles[MHand.TYPE_HAND].remove(tingResult['dropTile'])
                newTiles[MHand.TYPE_HAND].append(winNode['winTile'])
                tileArr = MTile.changeTilesToValueArr(
                    MHand.copyAllTilesToList(newTiles))
                #       ftlog.debug( 'MTingHaerbinRule.canTing tileArr:', tileArr )

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

                # 检查牌中的幺/九
                # 1软 听牌可以没有19,只要胡牌带19就可以
                # 2硬 听牌时就要有19
                RuanYaoJiuConfig = self.getTableConfig(MTDefine.RUAN_YAO_JIU,
                                                       1)
                if RuanYaoJiuConfig == 0:
                    #硬幺九 :听牌必须有19
                    #tileArr 减去 winNode['winTile'] 后判断
                    tileArr[winNode['winTile']] -= 1
                    yaoCount = tileArr[MTile.TILE_ONE_WAN] + tileArr[
                        MTile.TILE_ONE_TONG] + tileArr[MTile.TILE_ONE_TIAO]
                    jiuCount = tileArr[MTile.TILE_NINE_WAN] + tileArr[
                        MTile.TILE_NINE_TONG] + tileArr[MTile.TILE_NINE_TIAO]
                    zhongCount = tileArr[MTile.TILE_HONG_ZHONG]
                    ftlog.debug('MTingJixiRule.canTing : YING yaoCount:',
                                yaoCount, 'jiuCount', jiuCount, 'zhongCount',
                                zhongCount)
                    if (yaoCount + jiuCount + zhongCount) <= 0:
                        continue
                else:
                    #软幺九 :只要胡牌有19就行
                    yaoCount = tileArr[MTile.TILE_ONE_WAN] + tileArr[
                        MTile.TILE_ONE_TONG] + tileArr[MTile.TILE_ONE_TIAO]
                    jiuCount = tileArr[MTile.TILE_NINE_WAN] + tileArr[
                        MTile.TILE_NINE_TONG] + tileArr[MTile.TILE_NINE_TIAO]
                    zhongCount = tileArr[MTile.TILE_HONG_ZHONG]
                    ftlog.debug('MTingJixiRule.canTing : RUAN yaoCount:',
                                yaoCount, 'jiuCount', jiuCount, 'zhongCount',
                                zhongCount)
                    if (yaoCount + jiuCount + zhongCount) == 0:
                        continue

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

                                if pattern.index(winNode['winTile']) == 1:
                                    hasJia = True
                                    break

                            #单吊
                            if len(pattern) == 2 and pattern[0] == pattern[
                                    1] and danDiaoJia:
                                hasJia = True
                                break

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

                patterns = winNode['pattern']
                checkKeCount = keCount + self.getKeCount(patterns)
                checkShunCount = shunCount + self.getShunCount(patterns)
                ftlog.debug('MTingHaerbinRule.canTing keCount:', keCount,
                            ' shunCount:', shunCount)

                if checkKeCount and checkShunCount:
                    newWinNodes.append(winNode)

            if len(newWinNodes) > 0:
                newTingResult = {}
                newTingResult['dropTile'] = tingResult['dropTile']
                newTingResult['winNodes'] = newWinNodes
                newTingResults.append(newTingResult)

        return len(newTingResults) > 0, newTingResults
コード例 #13
0
ファイル: ting_rule_queshou.py プロジェクト: zhaozw/mjserver
    def canTingForQiangjin(self, tiles, leftTiles, tile, magicTiles = [], curSeatId = 0, winSeatId = 0, actionID = 0,tingForQiangjin = True):
        isTing, tingResults = MTing.canTing(MTile.cloneTiles(tiles), leftTiles, self.winRuleMgr, tile, magicTiles, curSeatId, winSeatId, actionID,tingForQiangjin,self.flowerRule)
        ftlog.debug( 'MTingQueshouRule.canTingForQiangjin using MTing isTing:', isTing, ' tingResults:', tingResults) 
	return isTing, tingResults
コード例 #14
0
    def canTing(self, tiles, leftTiles, tile, magicTiles=[], winSeatId=0):
        """子类必须实现
        参数:
        1)tiles 该玩家的手牌
        2)leftTiles 剩余手牌
        返回值:
        是否可以听牌,听牌详情
        """
        handCount = len(tiles[MHand.TYPE_HAND])
        if handCount < 5:
            return False, []

        isTing, tingResults = MTing.canTing(self.tilePatternChecker,
                                            self.tableTileMgr,
                                            MTile.cloneTiles(tiles), leftTiles,
                                            self.winRuleMgr, tile, magicTiles,
                                            winSeatId)
        ftlog.debug('MTingMudanjiangRule.MTing.canTing isTing:', isTing,
                    ' tingResults:', tingResults)
        #         [{'dropTile': 11, 'winNodes': [{'winTile': 1, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [1, 2, 3]]}, {'winTile': 2, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [3, 4, 5], [2, 2]]}, {'winTile': 4, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [2, 3, 4]]}, {'winTile': 5, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [5, 5], [2, 3, 4]]}, {'winTile': 7, 'winTileCount': 1, 'pattern': [[6, 6], [5, 6, 7], [5, 6, 7], [2, 3, 4]]}, {'winTile': 8, 'winTileCount': 1, 'pattern': [[6, 7, 8], [6, 6, 6], [5, 5], [2, 3, 4]]}]}]

        if not isTing:
            return False, []

        chiCount = len(tiles[MHand.TYPE_CHI])
        pengCount = len(tiles[MHand.TYPE_PENG])
        gangCount = len(tiles[MHand.TYPE_GANG])

        mingGangCount = 0
        anGangCount = 0
        #计算明杠个数,因为暗杠不算开门
        if gangCount != 0:
            mingGangCount, anGangCount = MTile.calcGangCount(
                tiles[MHand.TYPE_GANG])
        ftlog.debug('MTingMudanjiangRule.gang tiles:', tiles[MHand.TYPE_GANG],
                    ' mingGangCount=', mingGangCount, ' anGangCount=',
                    anGangCount)

        #daKouConfig = self.getTableConfig(MTDefine.DA_KOU, 0)
        daKouConfig = 1
        ftlog.debug('.canTing daKouConfig:', daKouConfig)
        if daKouConfig != 1:
            if (chiCount + pengCount + mingGangCount) == 0:
                return False, []

        # 检查刻,刻的来源,碰牌/明杠牌/手牌
        keCount = pengCount + mingGangCount + anGangCount
        # 必须有顺牌
        shunCount = chiCount

        newTingResults = []
        for tingResult in tingResults:
            newWinNodes = []
            winNodes = tingResult['winNodes']
            for winNode in winNodes:
                newTiles = MTile.cloneTiles(tiles)
                newTiles[MHand.TYPE_HAND].remove(tingResult['dropTile'])
                newTiles[MHand.TYPE_HAND].append(winNode['winTile'])
                tileArr = MTile.changeTilesToValueArr(
                    MHand.copyAllTilesToList(newTiles))
                #       ftlog.debug( 'MTingMudanjiangRule.canTing tileArr:', tileArr )

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

                # 检查牌中的幺/九
                # 1软 听牌可以没有19,只要胡牌带19就可以
                # 2硬 听牌时就要有19
                RuanYaoJiuConfig = self.getTableConfig(MTDefine.RUAN_YAO_JIU,
                                                       1)
                if RuanYaoJiuConfig == 0:
                    #硬幺九 :听牌必须有19
                    #tileArr 减去 winNode['winTile'] 后判断
                    tileArr[winNode['winTile']] -= 1
                    yaoCount = tileArr[MTile.TILE_ONE_WAN] + tileArr[
                        MTile.TILE_ONE_TONG] + tileArr[MTile.TILE_ONE_TIAO]
                    jiuCount = tileArr[MTile.TILE_NINE_WAN] + tileArr[
                        MTile.TILE_NINE_TONG] + tileArr[MTile.TILE_NINE_TIAO]
                    zhongCount = tileArr[MTile.TILE_HONG_ZHONG]
                    ftlog.debug('MTingMudanjiangRule.canTing : YING yaoCount:',
                                yaoCount, 'jiuCount', jiuCount, 'zhongCount',
                                zhongCount)
                    if (yaoCount + jiuCount + zhongCount) <= 0:
                        continue
                else:
                    #软幺九 :只要胡牌有19就行
                    yaoCount = tileArr[MTile.TILE_ONE_WAN] + tileArr[
                        MTile.TILE_ONE_TONG] + tileArr[MTile.TILE_ONE_TIAO]
                    jiuCount = tileArr[MTile.TILE_NINE_WAN] + tileArr[
                        MTile.TILE_NINE_TONG] + tileArr[MTile.TILE_NINE_TIAO]
                    zhongCount = tileArr[MTile.TILE_HONG_ZHONG]
                    ftlog.debug('MTingMudanjiangRule.canTing : RUAN yaoCount:',
                                yaoCount, 'jiuCount', jiuCount, 'zhongCount',
                                zhongCount)
                    if (yaoCount + jiuCount + zhongCount) == 0:
                        continue

                patterns = winNode['pattern']
                winTile = winNode['winTile']

                #夹起步(顺牌只能和夹和3,7) 除单吊
                chunJiaConfig = self.getTableConfig(MTDefine.MIN_MULTI, 0)
                if chunJiaConfig:
                    hasJia = False

                    bianMulti = self.tableConfig.get(MTDefine.BIAN_MULTI, 0)
                    if bianMulti:
                        if MTile.getValue(
                                winTile
                        ) == 3 and winTile < MTile.TILE_DONG_FENG:
                            newTilesBian = copy.deepcopy(newTiles)
                            # 1,2,3
                            if ((winTile - 2)
                                    in newTilesBian[MHand.TYPE_HAND]) and (
                                        (winTile - 1)
                                        in newTilesBian[MHand.TYPE_HAND]):
                                newTilesBian[MHand.TYPE_HAND].remove(winTile -
                                                                     2)
                                newTilesBian[MHand.TYPE_HAND].remove(winTile -
                                                                     1)
                                newTilesBian[MHand.TYPE_HAND].remove(winTile)
                                newTilesBian[MHand.TYPE_CHI].append(
                                    [winTile - 2, winTile - 1, winTile])
                                rBian, rPattern = self.winRuleMgr.isHu(
                                    newTilesBian, winTile, True,
                                    MWinRule.WIN_BY_MYSELF, magicTiles)
                                if rBian:
                                    ftlog.debug(
                                        'MTingMudanjiangRule isJia 3 Bian : ',
                                        newTilesBian, ' patterns:', rPattern)
                                    hasJia = True

                        if not hasJia and MTile.getValue(
                                winTile
                        ) == 7 and winTile < MTile.TILE_DONG_FENG:
                            newTiles37 = copy.deepcopy(newTiles)
                            # 7,8,9
                            if ((winTile + 1)
                                    in newTiles37[MHand.TYPE_HAND]) and (
                                        (winTile + 2)
                                        in newTiles37[MHand.TYPE_HAND]):
                                newTiles37[MHand.TYPE_HAND].remove(winTile + 1)
                                newTiles37[MHand.TYPE_HAND].remove(winTile + 2)
                                newTiles37[MHand.TYPE_HAND].remove(winTile)
                                newTiles37[MHand.TYPE_CHI].append(
                                    [winTile, winTile + 1, winTile + 2])
                                rQi, qiPattern = self.winRuleMgr.isHu(
                                    newTiles37, winTile, True,
                                    MWinRule.WIN_BY_MYSELF, magicTiles)
                                if rQi:
                                    ftlog.debug(
                                        'MTingMudanjiangRule isJia 7 Bian : ',
                                        newTiles37, ' pattern:', qiPattern)
                                    hasJia = True

                    danDiaoJia = self.tableConfig.get(MTDefine.DAN_DIAO_JIA, 1)
                    if not hasJia and danDiaoJia:
                        newTilesDan = copy.deepcopy(newTiles)
                        ftlog.debug(
                            'MTingMudanjiangRule isJia in >> danDiao : ',
                            newTilesDan)
                        # 5,5
                        if winTile in newTilesDan[MHand.TYPE_HAND]:
                            rDan, danPattern = MWin.isHuWishSpecialJiang(
                                newTilesDan[MHand.TYPE_HAND],
                                [winTile, winTile], magicTiles)
                            if rDan:
                                ftlog.debug(
                                    'MTingMudanjiangRule isJia danDiao : ',
                                    newTilesDan, ' winTile:', winTile,
                                    ' pattern:', danPattern)
                                hasJia = True

                    if not hasJia:
                        newTilesJia = copy.deepcopy(newTiles)
                        # 2,3,4
                        if ((winTile - 1)
                                in newTilesJia[MHand.TYPE_HAND]) and (
                                    (winTile + 1)
                                    in newTilesJia[MHand.TYPE_HAND]):
                            newTilesJia[MHand.TYPE_HAND].remove(winTile + 1)
                            newTilesJia[MHand.TYPE_HAND].remove(winTile - 1)
                            newTilesJia[MHand.TYPE_HAND].remove(winTile)
                            newTilesJia[MHand.TYPE_CHI].append(
                                [winTile - 1, winTile, winTile + 1])
                            rJia, jiaPattern = self.winRuleMgr.isHu(
                                newTilesJia, winTile, True,
                                MWinRule.WIN_BY_MYSELF, magicTiles)
                            if rJia:
                                ftlog.debug('MTingMudanjiangRule isJia : ',
                                            newTilesJia, ' pattern:',
                                            jiaPattern)
                                hasJia = True

                    # winNodes中的patterns只是胡牌的一种方式,不是全部的胡牌解,判断夹牌,只使用patterns的组合会有遗漏的情况
                    # 合理的做法是先把夹拿出来,在判断剩下的牌是否能胡。
                    if not hasJia:
                        ftlog.debug(
                            'MTingMudanjiangRule.canTing :, can not win tile:',
                            winNode['winTile'], ', not has jia continue....')
                        continue

                patterns = winNode['pattern']
                checkKeCount = keCount + self.getKeCount(patterns)
                checkShunCount = shunCount + self.getShunCount(patterns)
                ftlog.debug('MTingMudanjiangRule.canTing checkKeCount:',
                            checkKeCount, ' checkShunCount:', checkShunCount)

                if checkKeCount and checkShunCount:
                    newWinNodes.append(winNode)

            if len(newWinNodes) > 0:
                newTingResult = {}
                newTingResult['dropTile'] = tingResult['dropTile']
                newTingResult['winNodes'] = newWinNodes
                newTingResults.append(newTingResult)

        return len(newTingResults) > 0, newTingResults