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

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

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

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

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

        if wanLength >= tongLength and wanLength >= tiaoLength:
            return False, MTile.TILE_WAN
        elif tongLength >= wanLength and tongLength >= tiaoLength:
            return False, MTile.TILE_TONG
        else:
            return False, MTile.TILE_TIAO
    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
Ejemplo n.º 3
0
 def sortHandTileColor(self, players, isAbsence=True):
     '''
     玩家手牌花色排序计算,保存到__hand_tile_sort,相应玩法各自实现
     定缺的颜色不用判断,在最右边,只需要判断没有定缺的
     定缺结束后,额外处理定缺的花色排序 初始化手牌 则不用
     '''
     TILE_COLORS = [MTile.TILE_WAN, MTile.TILE_TONG, MTile.TILE_TIAO]
     colorList = [[] for _ in range(self.playCount)]
     for cp in players:
         if not cp:
             continue
         handTiles = cp.copyHandTiles()
         colorLenList = []
         for color in TILE_COLORS:
             if isAbsence and color == self.absenceColors[cp.curSeatId]:
                 pass
             else:
                 colorTiles = MTile.filterTiles(handTiles, color)
                 colorLenList.append({
                     'color': color,
                     'len': len(colorTiles)
                 })
         # 根据len来进行排序
         colorLenList.sort(key=lambda colorLen: colorLen['len'],
                           reverse=True)
         for cpColor in colorLenList:
             colorList[cp.curSeatId].append(cpColor['color'])
         # 加上定缺的花色
         if isAbsence:
             colorList[cp.curSeatId].append(
                 self.absenceColors[cp.curSeatId])
     ftlog.debug('MTableTileSiChuan.sortHandTileColor cpColorList:',
                 colorList)
     self.setHandTileColorSort(colorList)
Ejemplo n.º 4
0
    def doQingYiSe(self, allTiles, leftTiles):
        '''
            是否做清一色
        '''
        length = 9
        if len(leftTiles) >= 50:
            length = 8
        elif len(leftTiles) >= 40:
            length = 9
        elif len(leftTiles) >= 30:
            length = 10
        elif len(leftTiles) >= 20:
            length = 11

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

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

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

        if wanLength >= tongLength and wanLength >= tiaoLength:
            return False, MTile.TILE_WAN
        elif tongLength >= wanLength and tongLength >= tiaoLength:
            return False, MTile.TILE_TONG
        else:
            return False, MTile.TILE_TIAO
Ejemplo n.º 5
0
    def getBestDropTile(cls,
                        tiles_player_hand,
                        tiles_left,
                        playMode,
                        tile,
                        isTing,
                        magicTiles,
                        absenceColor,
                        tingRule=None,
                        seatId=0):
        """
        手牌的价值,根据玩家自己的手牌和已经出的牌,计算手牌价值
        参数:
            tiles_player_hand - 用户的手牌
            tiles_droped - 牌桌上已经打出的牌和玩家手里已经成型的牌,这部分牌不再参与计算牌的可能性
        计算方法:
        1)没有的手牌,权值为0
        2)有的手牌,初始权值为4 * count + 1 * left
        3)左右相邻的手牌,增加权重 3 * count
        4)左右隔一张的手牌,增加权重 2 * count
        """
        ftlog.debug('MTileValue.getBestDropTile tiles_player_hand:',
                    tiles_player_hand, ' tiles_left:', tiles_left,
                    ' playMode:', playMode, ' tile:', tile, ' isTing:', isTing,
                    ' magicTiles:', magicTiles, ' tingRule:', tingRule,
                    ' seatId:', seatId)

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

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

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

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

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

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

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

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

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

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

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

        ftlog.debug('MTileValue.getBestDropTile minTile:', minTile,
                    ' tileValue:', tiles_value_Arr[minTile])
        return minTile, tiles_value_Arr[minTile]
Ejemplo n.º 6
0
    def autoProcessAddCard(self, nPause):
        '''
        自动处理摸牌
        '''
        player = self.table.addCardProcessor.getPlayer()
        nowTile = self.table.addCardProcessor.getTile()
        extendStrategyInfo = self.getExtendStrategyInfo(player)

        # 海底且不出牌时,gameNext
        if self.table.tableTileMgr.isHaidilao() \
            and (not self.table.tableTileMgr.canDropWhenHaidiLao()) \
            and (not self.table.addCardProcessor.getState() & MTableState.TABLE_STATE_HU):
            self.table.addCardProcessor.reset()
            self.table.gameNext()
            return

        if (player.isRobot() and self.isRobotFoolish()) or \
            ((not player.isRobot()) and player.autoDecide and self.isHumanAutoDecideFoolish(player)):
            '''
            AI是傻瓜级别,抓什么打什么
            如果有缺牌,则自动打出缺牌
                如果nowTile是缺牌,则优先打出nowTile
                
            如果没有缺牌并且nowTile也不是缺牌,则打出nowTile
            
            '''
            if self.table.checkTableState(MTableState.TABLE_STATE_ABSENCE):
                abColor = self.table.getAbsenceColor(player.curSeatId)
                hands = player.copyHandTiles()
                abTiles = MTile.filterTiles(hands, abColor)
                if (len(abTiles) > 0) and (nowTile not in abTiles):
                    nowTile = abTiles[0]

            # 剔除赖子
            hands = player.copyHandTiles()
            mts = self.table.tableTileMgr.getMagicTiles()
            afterTiles = MTile.filterMagicTiles(hands, mts)
            ftlog.debug('autoProcessAddCard:', nowTile,hands,afterTiles)
            if nowTile not in afterTiles:
                if (len(afterTiles) > 0):
                    nowTile = afterTiles[-1]

            self.table.dropTile(player.curSeatId, nowTile)
            return
        
        self.consumeSmartOperateCount(player)
        
        exInfo = self.table.addCardProcessor.extendInfo
        winScore = 0
        if self.table.addCardProcessor.getState() & MTableState.TABLE_STATE_HU:
            winScore = player.getTingResultScore(MWinRule.WIN_BY_MYSELF)
            
        tingScore = 0
        tingInfo = None
        # 添加判断条件玩家是否胡牌,胡牌后,不走听
        if (self.table.addCardProcessor.getState() & MTableState.TABLE_STATE_TING) and not player.isWon():
            tingInfo = exInfo.getChoosedInfo(MTableState.TABLE_STATE_TING)
            ftlog.debug('ActionHandler.autoProcessAddCard tingInfo:', tingInfo)
            tingScore = tingInfo.get('value', 0)
        
        if (self.table.addCardProcessor.getState() & MTableState.TABLE_STATE_HU) and (winScore >= tingScore):
            self.table.gameWin(player.curSeatId, nowTile)
            return
        
        if (self.table.addCardProcessor.getState() & MTableState.TABLE_STATE_TING) and (not player.isWon()):
            if self.table.addCardProcessor.getState() & MTableState.TABLE_STATE_GANG:
                gangs = exInfo.getChiPengGangResult(MTableState.TABLE_STATE_GANG)
                allDropTilesInTing = exInfo.getAllDropTilesInTing()
                for gangInfo in gangs:
                    if gangInfo['pattern'][0] in allDropTilesInTing:
                        style = gangInfo['style']
                        pattern = gangInfo['pattern']
                        special_tile = self.getPiguTile()
                        self.table.gangTile(player.curSeatId, gangInfo['pattern'][0], pattern, style, MTableState.TABLE_STATE_GANG, special_tile)
                        return
            
            # 选择打掉的牌,用剩下的牌听,自动选择可胡牌数最多的解,默认不扣任何牌
            if tingInfo and self.table.dropCardStrategy.isTing(player.copyTiles()
                                    , tingInfo['dropTile']
                                    , self.table.tableTileMgr.getTiles()
                                    , False
                                    , extendStrategyInfo
                                    ):
                self.table.tingAfterDropCard(player.curSeatId, tingInfo['dropTile'], True, [], self.table.addCardProcessor.extendInfo)
                return
        
        ftlog.debug('ActionHandler.autoProcessAddCard player.copyTiles:', player.copyTiles(), 'isStateFixeder:', player.isStateFixeder())
        minTile, minValue = self.table.dropCardStrategy.getBestDropTile(player.copyTiles()
            , self.table.tableTileMgr.getTiles()
            , nowTile
            , player.isStateFixeder()
            , self.table.tableTileMgr.getMagicTiles(player.isTing())
            , extendStrategyInfo)
        ftlog.debug('ActionHandler.getBestDropTile minTile:', minTile, ' minValue:', minValue)

        if self.table.addCardProcessor.getState() & MTableState.TABLE_STATE_GANG:
            gangInfo = exInfo.getChoosedInfo(MTableState.TABLE_STATE_GANG)
            # 第一种情况,当前策略允许杠
            if self.table.dropCardStrategy.isGang(player.copyTiles()
                        , nowTile
                        , gangInfo
                        , self.table.tableTileMgr.getTiles()
                        , player.tingResult
                        , False
                        , extendStrategyInfo):
                exInfo.updateState(MTableState.TABLE_STATE_GANG, gangInfo)
                ftlog.debug('ActionHandler.autoProcessAddCard gangInfo:', gangInfo
                            , ' strategy decide gang')
                style = gangInfo['style']
                pattern = gangInfo['pattern']
                special_tile = self.getPiguTile()
                self.table.gangTile(player.curSeatId, nowTile, pattern, style, MTableState.TABLE_STATE_GANG, special_tile)
                return
            
            # 第二种情况,当前的最佳出牌是杠牌
            gangs = exInfo.getChiPengGangResult(MTableState.TABLE_STATE_GANG)
            for gangInfo in gangs:
                gangTile = gangInfo['pattern'][0]
                if gangTile != minTile:
                    continue
                
                exInfo.updateState(MTableState.TABLE_STATE_GANG, gangInfo)
                ftlog.debug('ActionHandler.autoProcessAddCard gangInfo:', gangInfo
                            , ' gangTile:', gangTile
                            , ' minTile:', minTile
                            , ' gangTile same with minTile, gang!!!')
                style = gangInfo['style']
                pattern = gangInfo['pattern']
                special_tile = self.getPiguTile()
                self.table.gangTile(player.curSeatId, nowTile, pattern, style, MTableState.TABLE_STATE_GANG, special_tile)
                return
        
        # 最后,出价值最小的牌
        self.table.tingAfterDropCard(player.curSeatId, minTile, player.isTing(), [], exInfo)