def hasMao(cls, tiles, maoDanSetting, alreadyHave = 0): ftlog.debug('MMao.hasMao tiles:', tiles , ' maoDanSetting:', maoDanSetting , ' alreadyHave:', alreadyHave) maos = [] if (maoDanSetting & MTDefine.MAO_DAN_DNXBZFB) and (not (alreadyHave & MTDefine.MAO_DAN_DNXBZFB)): pattern = [] values = [] for tile in tiles: if MTile.isFeng(tile) or MTile.isArrow(tile): pattern.append(tile) if tile not in values: values.append(tile) if len(values) >= 3: luanMao = {} luanMao['type'] = MTDefine.MAO_DAN_DNXBZFB luanMao['pattern'] = values luanMao['name'] = MTDefine.MAO_DAN_DNXBZFB_NAME maos.append(luanMao) if (maoDanSetting & MTDefine.MAO_DAN_DNXB) and \ (not (alreadyHave & MTDefine.MAO_DAN_DNXB) and \ (not (maoDanSetting & MTDefine.MAO_DAN_DNXBZFB))): pattern = [] values = [] for tile in tiles: if MTile.isFeng(tile): pattern.append(tile) if tile not in values: values.append(tile) if len(values) >= 3: fengMao = {} fengMao['type'] = MTDefine.MAO_DAN_DNXB fengMao['pattern'] = values fengMao['name'] = MTDefine.MAO_DAN_DNXB_NAME maos.append(fengMao) if (maoDanSetting & MTDefine.MAO_DAN_ZFB) and \ (not (alreadyHave & MTDefine.MAO_DAN_ZFB)) and \ (not (maoDanSetting & MTDefine.MAO_DAN_DNXBZFB)): pattern = [] values = [] for tile in tiles: if MTile.isArrow(tile): pattern.append(tile) if tile not in values: values.append(tile) if len(values) >= 3: arrowMao = {} arrowMao['type'] = MTDefine.MAO_DAN_ZFB arrowMao['pattern'] = values arrowMao['name'] = MTDefine.MAO_DAN_ZFB_NAME maos.append(arrowMao) if (maoDanSetting & MTDefine.MAO_DAN_YAO) and (not (alreadyHave & MTDefine.MAO_DAN_YAO)): pattern = [] values = [] for tile in tiles: if MTile.getValue(tile) == 1: pattern.append(tile) if tile not in values: values.append(tile) if len(values) >= 3: yaoMao = {} yaoMao['type'] = MTDefine.MAO_DAN_YAO yaoMao['pattern'] = values yaoMao['name'] = MTDefine.MAO_DAN_YAO_NAME maos.append(yaoMao) if (maoDanSetting & MTDefine.MAO_DAN_JIU) and (not (alreadyHave & MTDefine.MAO_DAN_JIU)): pattern = [] values = [] for tile in tiles: if MTile.getValue(tile) == 9: pattern.append(tile) if tile not in values: values.append(tile) if len(values) >= 3: jiuMao = {} jiuMao['type'] = MTDefine.MAO_DAN_JIU jiuMao['pattern'] = values jiuMao['name'] = MTDefine.MAO_DAN_JIU_NAME maos.append(jiuMao) ftlog.debug('MMao.hasMao tiles:', tiles , ' maoDanSetting:', maoDanSetting , ' maos:', maos) return maos
def isDaKouLoose(self, seatId): ftlog.debug('MMudanjiangOneResult.isDaKouLoose seatId:', seatId, ' menState:', self.menState, ' tingState:', self.tingState) return self.tingState[seatId] and self.menState[seatId]
def calcWin(self): """ 牡丹江算番规则: 1)合并一番 自摸,特殊情况下的自摸可以有杠开/红中宝两种叫法 1.1杠开 1.2红中宝 自己摸到红中 1.4刮大风 上听后摸到自己的碰牌或刻牌且不是宝牌,宝牌算宝中宝 1.5宝中宝1 3番 宝牌 夹牌 1.6宝中宝2 3番 刮大风+宝牌 2)自摸点炮都算 2.1夹胡 2.2三七边 2.3摸宝 1.3宝边,2番,自摸的要胡的牌刚好是宝牌 2.4边夹双 2倍数 大扣 """ self.results['type'] = MOneResult.KEY_TYPE_NAME_HU # 在和牌时统计自摸,点炮,最大番数 resultStat = [[] for _ in range(self.playerCount)] isZiMo = (self.lastSeatId == self.winSeatId) if isZiMo: resultStat[self.lastSeatId].append({MOneResult.STAT_ZIMO: 1}) isLikeZiMo = False if (self.lastSeatId != self.winSeatId) and (self.tingState[self.lastSeatId] == 0): isLikeZiMo = True resultStat[self.winSeatId].append({MOneResult.STAT_WIN: 1}) isJia = self.isJia() isBian = self.isBian() isDanDiao = self.isDanDiao() isMagic = self.isMagicTile() isDaKou = self.isDaKou() ftlog.debug('MMudanjiangOneResult.calcWin isJia:', isJia, ' isBian:', isBian, ' isDanDiao', isDanDiao, ' isDafeng', self.daFeng, ' isDaKou', isDaKou, ' isMagic:', isMagic, ' isZiMo:', isZiMo, ' isLikeZiMo:', isLikeZiMo, ' menState:', self.menState, ' tingState:', self.tingState) self.clearWinFanPattern() # 计算基本番型(只有单吊 夹胡 三七边) name, index = self.calcDianPaoFan(isJia, isBian, isDanDiao) ftlog.info('MMudanjiangOneResult.calcWin after calcDianPaoFan name:', name, ' index:', index) # 计算自摸高级番型 都和自摸有关(不包含自摸 杠开 抢杠胡 摸宝 红中宝) if isZiMo or isLikeZiMo: name2 = '' index2 = 1 if isLikeZiMo and (self.tableConfig.get(MTDefine.DUI_BAO, 0) == 0): # 点黑炮的时候,如果不选择对宝,只算自摸 ftlog.info( 'MMudanjiangOneResult.calcWin isLikeZimo, justCalcZiMO name2:', name2, ' index2:', index2) name2 = self.fanXing[self.ZIMO]['name'] index2 = self.fanXing[self.ZIMO]['index'] else: name2, index2 = self.calcZiMoAdvFan( (isZiMo or isLikeZiMo), isDanDiao, self.daFeng, self.baoZhongBao, isMagic, isJia, isBian) ftlog.info( 'MMudanjiangOneResult.calcWin after calcZiMoAdvFan name2:', name2, ' index2:', index2) # 只是自摸 没有高级番型 if name2 == self.fanXing[self.ZIMO]['name']: # 在基础番型上增加自摸倍数 ftlog.info( 'MMudanjiangOneResult.calcWin after calcZiMoAdvFan zimo name2:', name2, ' index2:', index2) hongZongBaoConfig = self.tableConfig.get( MTDefine.HONG_ZHONG_BAO, 0) if isMagic and isZiMo: index += self.fanXing[self.MOBAO]['index'] resultStat[self.lastSeatId].append( {MOneResult.STAT_MOBAO: 1}) elif self.isHongZhong() and hongZongBaoConfig and isZiMo: index += self.fanXing[self.HONGZHONGBAO]['index'] else: index += index2 # 自摸相关的特殊番型 直接覆盖基本番型 else: ftlog.info( 'MMudanjiangOneResult.calcWin after calcZiMoAdvFan not zimo name2:', name2, ' index2:', index2) name = name2 index = index2 self.clearWinFanPattern() self.addWinFanPattern(name, index) ftlog.info('MMudanjiangOneResult.calcWin after calcZimo name:', name, ' index:', index) if name == self.fanXing[self.GUADAFENG]['name']: # 刮大风的情况下判断是不是夹 if isJia or (isBian and self.tableConfig.get(MTDefine.BIAN_MULTI, 0)): jianame = self.fanXing[self.JIAHU]['name'] jiaindex = self.fanXing[self.JIAHU]['index'] self.addWinFanPattern(jianame, jiaindex) index += 1 ftlog.info('MMudanjiangOneResult.calcWin after calcDafeng name:', name, ' index:', index) # daKouConfig = self.tableConfig.get(MTDefine.DA_KOU, 0) daKouConfig = 1 if self.isDaKou() and daKouConfig: dakouname = self.fanXing[self.DAKOU]['name'] dakouindex = self.fanXing[self.DAKOU]['index'] self.addWinFanPattern(dakouname, dakouindex) index += 1 ftlog.info('MMudanjiangOneResult.calcWin after calcDaKou name:', name, ' index:', index) scoreBase = self.tableConfig.get(MTDefine.WIN_BASE, 1) ftlog.debug('MMudanjiangOneResult.calcWin scoreBase:', scoreBase) scoreIndex = [] if scoreBase == 5: scoreIndex = [2, 5, 10, 20, 40, 80, 160, 320, 640, 1280, 2560] else: scoreIndex = self.tableConfig.get( MTDefine.FAN_LIST, [1, 2, 4, 8, 16, 32, 64, 128, 256]) ftlog.info('MMudanjiangOneResult.calcWin scoreIndex:', scoreIndex) # 当前局番型处理 fanPattern = [[] for _ in range(self.playerCount)] winMode = [MOneResult.WIN_MODE_LOSS for _ in range(self.playerCount)] # 输赢模式 输家番型统计 for seatId in range(self.playerCount): if seatId == self.winSeatId: winModeValue = MOneResult.WIN_MODE_PINGHU # 自摸 if self.lastSeatId == self.winSeatId: winModeValue = MOneResult.WIN_MODE_ZIMO if self.baoZhongBao: winModeValue = MOneResult.WIN_MODE_baozhongbao if self.magicAfertTing: if self.tableConfig.get(MTDefine.DUI_BAO, 0) == 1: winModeValue = MOneResult.WIN_MODE_LOUHU # 红中宝 hongZongBaoConfig = self.tableConfig.get( MTDefine.HONG_ZHONG_BAO, 0) if self.isHongZhong() and hongZongBaoConfig and ( MTile.TILE_HONG_ZHONG not in self.tableTileMgr.getMagicTiles(True)): winModeValue = MOneResult.WIN_MODE_hongzhongbao self.addWinFanPattern( self.fanXing[self.HONGZHONGBAO]['name'], self.fanXing[self.HONGZHONGBAO]['index']) if isMagic and (not self.magicAfertTing): winModeValue = MOneResult.WIN_MODE_mobao self.addWinFanPattern( self.fanXing[self.MOBAO]['name'], self.fanXing[self.MOBAO]['index']) if self.gangKai: winModeValue = MOneResult.WIN_MODE_GANGKAI self.addWinFanPattern(self.fanXing[self.GANGKAI]['name'], self.fanXing[self.GANGKAI]['index']) if self.qiangGang: winModeValue = MOneResult.WIN_MODE_QIANGGANGHU self.addWinFanPattern( self.fanXing[self.QIANGGANG]['name'], self.fanXing[self.QIANGGANG]['index']) if self.daFeng: winModeValue = MOneResult.WIN_MODE_guadafeng winMode[seatId] = winModeValue fanPattern[self.winSeatId] = self.winFanPattern elif seatId == self.lastSeatId: winModeValue = MOneResult.WIN_MODE_DIANPAO winMode[seatId] = winModeValue resultStat[seatId].append({MOneResult.STAT_DIANPAO: 1}) fanPattern[seatId] = [] # 点炮包庄 if self.tingState[seatId] == 0: winModeValue = MOneResult.WIN_MODE_DIANPAO_BAOZHUANG winMode[seatId] = winModeValue # 闭门 if self.menState[seatId] == 1: looseFanName = self.fanXing[self.BIMEN]['name'] looseFanIndex = self.fanXing[self.BIMEN]['index'] fanPattern[seatId].append( [looseFanName.strip(), str(looseFanIndex) + "番"]) else: fanPattern[seatId] = [] # 闭门 if self.menState[seatId] == 1: looseFanName = self.fanXing[self.BIMEN]['name'] looseFanIndex = self.fanXing[self.BIMEN]['index'] fanPattern[seatId].append( [looseFanName.strip(), str(looseFanIndex) + "番"]) score = [index for _ in range(self.playerCount)] ''' #不听点炮*2 if self.lastSeatId != self.winSeatId: if self.tingState[self.lastSeatId]: ftlog.debug('MHaerbinOneResult.calcWin dianpao index is zero becore tingState') else: score[self.lastSeatId] += 1 ftlog.info('MMudanjiangOneResult.calcWin dianpao score:', score) ''' if (self.bankerSeatId == self.winSeatId) and self.tableConfig.get( MTDefine.BANKER_DOUBLE, 1): for seatId in range(self.playerCount): if seatId == self.winSeatId: continue score[seatId] += 1 ftlog.info('MMudanjiangOneResult.calcWin zhuang double score:', score, ' bankerSeatId:', self.bankerSeatId, ' winSeatId:', self.winSeatId) if (self.bankerSeatId != self.winSeatId) and self.tableConfig.get( MTDefine.BANKER_DOUBLE, 1): score[self.bankerSeatId] += 1 ftlog.info('MMudanjiangOneResult.calcWin zhuang loose double score:', score, ' bankerSeatId:', self.bankerSeatId, ' winSeatId:', self.winSeatId, ' looseSeatId:', self.lastSeatId) for seatId in range(len(self.menState)): if (self.menState[seatId] == 1) and ( seatId != self.winSeatId) and self.tableConfig.get( MTDefine.MEN_CLEAR_DOUBLE, 1): score[seatId] += 1 ftlog.info( 'MMudanjiangOneResult.calcWin menqing double score:', score, ' menState:', self.menState) # 输家只算闭门,不算大扣 winScore = 0 for seatId in range(self.playerCount): if seatId != self.winSeatId: newIndex = score[seatId] looseScore = scoreIndex[newIndex] # if self.isDaKouLoose(seatId): # ftlog.info('MMudanjiangOneResult.calcWin dakouLoose double score:', looseScore # , ' seatId:', seatId # , ' menState:', self.menState # , ' tingState:', self.tingState) # looseScore = looseScore * 2 # # 大扣 # looseFanName = self.fanXing[self.DAKOU]['name'] # looseFanIndex = self.fanXing[self.DAKOU]['index'] # fanPattern[seatId].append([looseFanName.strip(), str(looseFanIndex) + "番"]) score[seatId] = -looseScore winScore += looseScore score[self.winSeatId] = winScore # 加入底分的概念*2或者*5 ''' for seatId in range(len(score)): score[seatId] *= scoreBase ''' ftlog.info('MMudanjiangOneResult.calcWin score before baopei:', score) if self.lastSeatId != self.winSeatId: if self.tingState[self.lastSeatId] == 0: # 包赔 for seatId in range(len(score)): if seatId != self.winSeatId and seatId != self.lastSeatId: s = score[seatId] score[seatId] = 0 score[self.lastSeatId] += s ftlog.info( 'MMudanjiangOneResult.calcWin dianpaobaozhuang score:', score, ' lastSeatId:', self.lastSeatId, ' winSeatId:', self.winSeatId, ' tingState:', self.tingState) # 最大番统计(改成单局最佳) resultStat[self.winSeatId].append( {MOneResult.STAT_ZUIDAFAN: score[self.winSeatId]}) self.results[self.KEY_TYPE] = '和牌' self.results[self.KEY_NAME] = name ftlog.debug('MMudanjiangOneResult.calcWin result score:', score) self.results[self.KEY_SCORE] = score ftlog.debug('MMudanjiangOneResult.calcWin result winMode:', winMode) self.results[self.KEY_WIN_MODE] = winMode self.results[self.KEY_STAT] = resultStat ftlog.debug('MMudanjiangOneResult.calcWin result fanPattern:', fanPattern) self.results[self.KEY_FAN_PATTERN] = fanPattern
def debug(*argl, **argd): ftlog.debug(*argl, **argd)
def serialize(self): """序列化""" obj = {} if self.playMode: obj['playMode'] = self.playMode if self.bankerSeatId: obj['bankerSeatId'] = self.bankerSeatId if self.winSeatId: obj['winSeatId'] = self.winSeatId if self.winSeats: obj['winSeats'] = self.winSeats if self.lastSeatId: obj['lastSeatId'] = self.lastSeatId if self.winTile: obj['winTile'] = self.winTile if self.actionID: obj['actionID'] = self.actionID if self.zhaNiaoCount: obj['zhaNiaoCount'] = self.zhaNiaoCount if self.winPattern: obj['winPattern'] = self.winPattern if self.winPatternType: obj['winPatternType'] = self.winPatternType if self.playerCount: obj['playCount'] = self.playerCount if self.style: obj['style'] = self.style if self.winNodes: obj['winNodes'] = self.winNodes if self.huaCi: obj['huaCi'] = self.huaCi if self.gangKai: obj['gangKai'] = self.gangKai if self.baoZhongBao: obj['baoZhongBao'] = self.baoZhongBao if self.qiangGang: obj['qiangGang'] = self.qiangGang if self.tableConfig: obj['tableConfig'] = self.tableConfig if self.menState: obj['menState'] = self.menState if self.tingState: obj['tingState'] = self.tingState if self.colorState: obj['colorState'] = self.colorState if self.daFeng: obj['daFeng'] = self.daFeng if self.daKou: obj['daKou'] = self.daKou if self.magics: obj['magics'] = self.magics if self.alarmNodes: obj['alarmNodes'] = self.alarmNodes if self.jiaoPaiConf: obj['jiaoPaiConf'] = self.jiaoPaiConf if self.fanRuleConf: obj['fanRuleConf'] = self.fanRuleConf if self.playerCurScore: obj['playerCurScore'] = self.playerCurScore if self.playerAllTiles: obj['playerAllTiles'] = self.playerAllTiles if self.tableTileMgr: obj['tableTileMgr_absenceColors'] = self.tableTileMgr.absenceColors if self.gangKai: obj['gangKai'] = self.gangKai if self.qiangGang: obj['qiangGang'] = self.qiangGang ftlog.debug('MOneResult.serialize: ', obj)
def setState(self, state): ftlog.debug('MShuffleHuProcessor setState:', state) self.__state = state
def isBian(self): """是否夹牌""" if not self.isWinTile(): return False for wn in self.winNodes: if wn['winTile'] == self.winTile: patterns = wn['pattern'] ftlog.debug('MHaerbinOneResult.isBian winTile:', self.winTile, ' winPatterns:', patterns) for p in patterns: if len(p) == 2: continue if p[0] == p[1]: continue # 三七边 if (self.winTile in p) \ and (p.index(self.winTile) == 0) \ and (MTile.getValue(p[1]) == 8) \ and (MTile.getValue(p[2]) == 9): ftlog.debug('MHaerbinOneResult.isBian winTile:', self.winTile, ' winPatterns:', patterns, ' 7 bian') return True if (self.winTile in p) \ and (p.index(self.winTile) == 2) \ and (MTile.getValue(p[0]) == 1) \ and (MTile.getValue(p[1]) == 2): ftlog.debug('MHaerbinOneResult.isBian winTile:', self.winTile, ' winPatterns:', patterns, ' 3 bian') return True # 宝牌情况处理 if self.isMagicTile(): for wn in self.winNodes: winTile = wn['winTile'] patterns = wn['pattern'] for p in patterns: if len(p) == 2: continue if p[0] == p[1]: continue # 三七边 if (winTile in p) \ and (p.index(winTile) == 0) \ and (MTile.getValue(p[1]) == 8) \ and (MTile.getValue(p[2]) == 9): ftlog.debug('MHaerbinOneResult.isBian winTile:', self.winTile, ' winPatterns:', patterns, ' 7 bian') return True if (winTile in p) \ and (p.index(winTile) == 2) \ and (MTile.getValue(p[0]) == 1) \ and (MTile.getValue(p[1]) == 2): ftlog.debug('MHaerbinOneResult.isBian winTile:', self.winTile, ' winPatterns:', patterns, ' 3 bian') return True return False
def getBestDropTile(self, tiles_player_hand, tiles_left, tile, isTing, magicTiles, absenceColor, tingRule=None): """ 手牌的价值,根据玩家自己的手牌和已经出的牌,计算手牌价值 参数: tiles_player_hand - 用户的手牌 tiles_droped - 牌桌上已经打出的牌和玩家手里已经成型的牌,这部分牌不再参与计算牌的可能性 计算方法: 1)没有的手牌,权值为0 2)有的手牌,初始权值为4 * count + 1 * left 3)左右相邻的手牌,增加权重 3 * count 4)左右隔一张的手牌,增加权重 2 * count """ ftlog.debug( 'MDropCardStrategyJipinghu.getBestDropTile tiles_player_hand:', tiles_player_hand, ' tiles_left:', tiles_left, ' tile:', tile, ' isTing:', isTing, ' magicTiles:', magicTiles, ' absenceColor:', absenceColor, ' tingRule:', tingRule) if isTing: # 听牌后,直接打出摸到的牌 return tile, 0 doQing, qingColor = self.doQingYiSe(tiles_player_hand, tiles_left) tiles_value_Arr, tiles_player_Arr = MTileValue.getHandTilesValue( tiles_player_hand, tiles_left) # 放大癞子牌的作用 for mTile in magicTiles: tiles_value_Arr[mTile] = tiles_value_Arr[mTile] * 100 # 如果有一门花色大于9张牌,放大该门花色牌的价值,便于去做清一色番型 if doQing: for tile in MTile.traverseTile(qingColor): tiles_value_Arr[tile] += 10 # 减小缺牌的作用 for tile in range(len(tiles_value_Arr)): if MTile.getColor(tile) == absenceColor: tiles_value_Arr[tile] -= 100 continue if doQing and MTile.getColor(tile) != qingColor: tiles_value_Arr[tile] -= 10 continue # [{'dropTile': 11, 'winNodes': [{'winTile': 1, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [1, 2, 3]]}, {'winTile': 2, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [3, 4, 5], [2, 2]]}, {'winTile': 4, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [2, 3, 4]]}, {'winTile': 5, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [5, 5], [2, 3, 4]]}, {'winTile': 7, 'winTileCount': 1, 'pattern': [[6, 6], [5, 6, 7], [5, 6, 7], [2, 3, 4]]}, {'winTile': 8, 'winTileCount': 1, 'pattern': [[6, 7, 8], [6, 6, 6], [5, 5], [2, 3, 4]]}]}] if tingRule: canTing, tingResults = tingRule.canTing(tiles_player_hand, tiles_left, tile, magicTiles) ftlog.debug(canTing) ftlog.debug(tingResults) if canTing: totalValue = 0 for tingResult in tingResults: dropTile = tingResult['dropTile'] winNodes = tingResult['winNodes'] for winNode in winNodes: totalValue += winNode['winTileCount'] * winNode[ 'winFan'] for tingResult in tingResults: dropTile = tingResult['dropTile'] winNodes = tingResult['winNodes'] dropValue = 0 for winNode in winNodes: dropValue += winNode['winTileCount'] * winNode['winFan'] tiles_value_Arr[dropTile] = (totalValue - dropValue) if doQing and (MTile.getColor(dropTile) == qingColor) and ( tiles_value_Arr[dropTile] != -4): # 优先打出非清一色颜色的上听牌 tiles_value_Arr[dropTile] += (totalValue / len(tingResults)) ftlog.debug( 'MDropCardStrategyJipinghu.getBestDropTile adjust tileValue by ting:', tiles_value_Arr, ' tingResults:', tingResults, ' totalValue:', totalValue) minTile = 0 minValue = 0 for index in range(MTile.TILE_MAX_VALUE): if tiles_player_Arr[index] > 0: if minTile == 0: minTile = index minValue = tiles_value_Arr[index] continue if minValue > tiles_value_Arr[index]: minValue = tiles_value_Arr[index] minTile = index ftlog.debug('MDropCardStrategyJipinghu.getBestDropTile minTile:', minTile, ' tileValue:', tiles_value_Arr[minTile]) return minTile, tiles_value_Arr[minTile]
def setPlayers(self, players): """设置玩家""" ftlog.debug('msg.setPlayers:', self.players) self.__players = players
def getCreateExtendBudgets(self, tableResults, playerCount, playMode, score): ''' 自建桌大结算 自摸 点炮 刮风 下雨 单场最佳 ''' ftlog.debug( 'MTableResultsStatXuezhan.getCreateExtendBudgets playMode:', playMode) createExtendBudgets = [{} for _ in range(playerCount)] allResults = [] ftlog.debug( 'MTableResultsStatXuezhan.getCreateExtendBudgets roundResult count', len(tableResults)) for roundResult in tableResults: for oneResult in roundResult.roundResults: allResults.append(oneResult) ziMoMaxValue = 0 ziMoMaxSeatId = -1 dianPaoMaxValue = 0 dianPaoMaxSeatId = -1 for seatId in range(playerCount): extendBudget = {} extendBudget["sid"] = seatId winValue = 0 ziMoValue = 0 dianPaoValue = 0 danJuZuiJiaValue = 0 qingnaValue = 0 # 清拿分 guaFengValue = 0 # 刮风分 xiaYuValue = 0 # 下雨分s # statistics statisticInfo = [] # one result for oneResult in allResults: ftlog.debug( 'MTableResultsStatXuezhan.getCreateExtendBudgets seatId:', seatId) stats = [[] for _ in range(playerCount)] playerStats = [] if MOneResult.KEY_STAT in oneResult.results: stats = oneResult.results[MOneResult.KEY_STAT] playerStats = stats[seatId] for stat in playerStats: if MOneResult.STAT_WIN in stat: winValue += stat[MOneResult.STAT_WIN] if MOneResult.STAT_ZIMO in stat: ziMoValue += stat[MOneResult.STAT_ZIMO] if MOneResult.STAT_DIANPAO in stat: dianPaoValue += stat[MOneResult.STAT_DIANPAO] if MOneResult.STAT_QINGNA in stat: qingnaValue += stat[MOneResult.STAT_QINGNA] if MOneResult.STAT_MINGGANG in stat: guaFengValue += stat[MOneResult.STAT_MINGGANG] if MOneResult.STAT_ANGANG in stat: xiaYuValue += stat[MOneResult.STAT_ANGANG] if MOneResult.STAT_GANG in stat: xiaYuValue += stat[MOneResult.STAT_XUGAANG] # 单局最佳表示每局的分数变化,应该从RoundResult中获取,先获取第一个值 danJuZuiJiaValue = tableResults[-1].scoreChange[ seatId] if tableResults else 0 for roundResult in tableResults: if danJuZuiJiaValue < roundResult.scoreChange[seatId]: danJuZuiJiaValue = roundResult.scoreChange[seatId] ftlog.debug('MTableResultsStatXuezhan.createExtendBudgets seatId:', seatId, 'danJuZuiJiaValue:', danJuZuiJiaValue) statisticInfo.append({"desc": "自摸", "value": ziMoValue}) statisticInfo.append({"desc": "点炮", "value": dianPaoValue}) statisticInfo.append({"desc": "刮风", "value": guaFengValue}) statisticInfo.append({"desc": "下雨", "value": xiaYuValue}) statisticInfo.append({"desc": "单局最佳", "value": danJuZuiJiaValue}) ftlog.debug('MTableResultsStatXuezhan.createExtendBudgets seatId', seatId, ' ziMoValue:', ziMoValue, ' dianPaoValue:', dianPaoValue, 'guaFengValue:', guaFengValue, 'xiaYuValue:', xiaYuValue) # extendBudget["total_delta_score"] = totalDeltaScore if score and (len(score) > seatId): extendBudget["total_delta_score"] = score[seatId] else: extendBudget["total_delta_score"] = 0 extendBudget["statistics"] = statisticInfo # dianpao_most zimo_most extendBudget["head_mark"] = "" createExtendBudgets[seatId] = extendBudget if ziMoValue > ziMoMaxValue: ziMoMaxValue = ziMoValue ziMoMaxSeatId = seatId if dianPaoValue > dianPaoMaxValue: dianPaoMaxValue = dianPaoValue dianPaoMaxSeatId = seatId if ziMoMaxSeatId >= 0: createExtendBudgets[ziMoMaxSeatId]["head_mark"] = "zimo_most" ftlog.debug( 'MTableResultsStatXuezhan.createExtendBudgets zimo_most seat:', ziMoMaxSeatId) if dianPaoMaxSeatId >= 0: createExtendBudgets[dianPaoMaxSeatId]["head_mark"] = "dianpao_most" ftlog.debug( 'MTableResultsStatXuezhan.createExtendBudgets dianpao_most seat:', dianPaoMaxSeatId) return createExtendBudgets
def getBestDropTile(self, tiles_player_hand, tiles_left, tile, isTing, magicTiles, extend={}): """ 手牌的价值,根据玩家自己的手牌和已经出的牌,计算手牌价值 参数: tiles_player_hand - 用户的手牌 tiles_droped - 牌桌上已经打出的牌和玩家手里已经成型的牌,这部分牌不再参与计算牌的可能性 计算方法: 1)没有的手牌,权值为0 2)有的手牌,初始权值为4 * count + 1 * left 3)左右相邻的手牌,增加权重 3 * count 4)左右隔一张的手牌,增加权重 2 * count """ ftlog.debug( 'MDropCardStrategyXuezhan.getBestDropTile tiles_player_hand:', tiles_player_hand, ' tiles_left:', tiles_left, ' tile:', tile, ' isTing:', isTing, ' magicTiles:', magicTiles, ' extend:', extend) if isTing: # 听牌后,直接打出摸到的牌 return tile, 0 tiles_value_Arr, tiles_player_Arr = MTileValue.getHandTilesValue( tiles_player_hand, tiles_left) # 如果有缺牌,打出缺牌 seatId = extend.get('seatId', 0) abColors = extend.get('absenceColor', []) absenceColor = MTile.TILE_FENG if len(abColors) > 0: absenceColor = abColors[seatId] abMinTile = 0 abMinValue = 0 for tile in MTile.traverseTile(absenceColor): if tiles_player_Arr[tile] > 0: if abMinTile == 0: abMinTile = tile abMinValue = tiles_value_Arr[tile] continue if abMinValue > tiles_value_Arr[tile]: abMinValue = tiles_value_Arr[tile] abMinTile = tile if abMinTile: ftlog.debug('has Absence, drop the min absence tile:', abMinTile, ' abMinValue:', abMinValue) return abMinTile, abMinValue seatId = extend.get('seatId', None) abColors = extend.get('absenceColor', None) doQing, qingColor = self.doQingYiSe(tiles_player_hand, tiles_left, seatId, abColors) # 放大癞子牌的作用 for mTile in magicTiles: tiles_value_Arr[mTile] = tiles_value_Arr[mTile] * 100 # 如果有一门花色大于9张牌,放大该门花色牌的价值,便于去做清一色番型 if doQing: colors = [MTile.TILE_WAN, MTile.TILE_TONG, MTile.TILE_TIAO] colors.remove(absenceColor) colors.remove(qingColor) dMinTiles = [] dMinValue = 0 for tile in MTile.traverseTile(colors[0]): if tiles_player_Arr[tile] > 0: if len(dMinTiles) == 0: dMinValue = tiles_value_Arr[tile] dMinTiles.append(tile) continue if dMinValue > tiles_value_Arr[tile]: dMinValue = tiles_value_Arr[tile] dMinTiles = [tile] elif dMinValue == tiles_value_Arr[tile]: dMinTiles.append(tile) if len(dMinTiles) > 0: ftlog.debug('doQingYiSe, qingColor:', qingColor, ' dMinTiles:', dMinTiles, ' dMinValue:', dMinValue) return self.chooseBestDropTile(dMinTiles, tiles_left, qingColor), dMinValue tingRule = extend.get('tingRule', None) # [{'dropTile': 11, 'winNodes': [{'winTile': 1, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [1, 2, 3]]}, {'winTile': 2, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [3, 4, 5], [2, 2]]}, {'winTile': 4, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [2, 3, 4]]}, {'winTile': 5, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [5, 5], [2, 3, 4]]}, {'winTile': 7, 'winTileCount': 1, 'pattern': [[6, 6], [5, 6, 7], [5, 6, 7], [2, 3, 4]]}, {'winTile': 8, 'winTileCount': 1, 'pattern': [[6, 7, 8], [6, 6, 6], [5, 5], [2, 3, 4]]}]}] if tingRule: canTing, tingResults = tingRule.canTing(tiles_player_hand, tiles_left, tile, magicTiles) ftlog.debug(canTing) ftlog.debug(tingResults) if canTing: totalValue = 0 for tingResult in tingResults: # 对dropTile的价值重新考虑 dropTile = tingResult['dropTile'] tiles_value_Arr[dropTile] = 0 winNodes = tingResult['winNodes'] for winNode in winNodes: totalValue += winNode['winTileCount'] * winNode[ 'winFan'] for tingResult in tingResults: dropTile = tingResult['dropTile'] winNodes = tingResult['winNodes'] dropValue = 0 for winNode in winNodes: dropValue += winNode['winTileCount'] * winNode['winFan'] tiles_value_Arr[dropTile] += (-dropValue) if doQing and (MTile.getColor(dropTile) == qingColor): # 优先打出非清一色颜色的上听牌 tiles_value_Arr[dropTile] += (totalValue / len(tingResults)) ftlog.debug( 'MDropCardStrategyXuezhan.getBestDropTile dropTile:', dropTile, ' dropTileValue:', tiles_value_Arr[dropTile]) ftlog.debug( 'MDropCardStrategyXuezhan.getBestDropTile adjust tileValue by ting:', tiles_value_Arr, ' tingResults:', tingResults, ' totalValue:', totalValue) minTiles = [] minValue = 0 for index in range(MTile.TILE_MAX_VALUE): if tiles_player_Arr[index] > 0: if (len(minTiles) == 0) or (minValue > tiles_value_Arr[index]): minValue = tiles_value_Arr[index] minTiles = [index] elif minValue == tiles_value_Arr[index]: minTiles.append(index) ftlog.debug('MDropCardStrategyJipinghu.getBestDropTile minTiles:', minTiles, ' tileValue:', minValue) return self.chooseBestDropTile(minTiles, tiles_left, qingColor), minValue
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 # 烟台麻将允许胡七对 resultQiDui, patternQiDui = MWin.isQiDui(tiles[MHand.TYPE_HAND]) if resultQiDui: if self.tableConfig[MTDefine.ONLY_JIANG_258]: ftlog.debug('MWinRuleYantai.isHu checkQiDui with 258') for pattern in patternQiDui: tile = pattern[0] if tile > MTile.TILE_NINE_TIAO: continue if MTile.getValue(pattern[0]) % 3 == 2: return True, patternQiDui return False, [] return True, patternQiDui # 烟台麻将允许胡十三幺 self.tilePatternChecker.setPlayerAllTiles(tiles) if self.tilePatternChecker.isShisanyao(): if self.tableConfig[MTDefine.ONLY_JIANG_258]: ftlog.debug( 'MWinRuleYantai.isHu isShisanyao with 258, return False') return False, [] return True, tiles[MHand.TYPE_HAND] # 烟台麻将允许胡风一色 allTiles = MHand.copyAllTilesToList(tiles) allArr = MTile.changeTilesToValueArr(allTiles) colorCount = MTile.getColorCount(allArr) resultFeng, patternFeng = MWin.isLuanFengyise(tiles[MHand.TYPE_HAND], colorCount) if resultFeng: if self.tableConfig[MTDefine.ONLY_JIANG_258]: ftlog.debug( 'MWinRuleYantai.isHu isLuanFengyise with 258, return False' ) return False, [] return True, patternFeng # 挑出2,5,8将,看剩下的牌是否能胡牌 if self.tableConfig[MTDefine.ONLY_JIANG_258]: jiangPatterns = [[MTile.TILE_TWO_WAN, MTile.TILE_TWO_WAN], [MTile.TILE_FIVE_WAN, MTile.TILE_FIVE_WAN], [MTile.TILE_EIGHT_WAN, MTile.TILE_EIGHT_WAN], [MTile.TILE_TWO_TONG, MTile.TILE_TWO_TONG], [MTile.TILE_FIVE_TONG, MTile.TILE_FIVE_TONG], [MTile.TILE_EIGHT_TONG, MTile.TILE_EIGHT_TONG], [MTile.TILE_TWO_TIAO, MTile.TILE_TWO_TIAO], [MTile.TILE_FIVE_TIAO, MTile.TILE_FIVE_TIAO], [MTile.TILE_EIGHT_TIAO, MTile.TILE_EIGHT_TIAO]] ftlog.debug('MWinRuleYantai.isHu with 258') for jiangPat in jiangPatterns: result, pattern = MWin.isHuWishSpecialJiang( tiles[MHand.TYPE_HAND], jiangPat) if result: return result, pattern return False, [] else: result, pattern = MWin.isHu(tiles[MHand.TYPE_HAND]) return result, pattern
def isHu(self, tiles, tile, isTing, getTileType, magicTiles=[], tingNodes=[], winSeatId=0): #tile已经加入到tiles ftlog.debug('MWinRulePanjin.isHu tiles:', tiles, ' magicTiles:', magicTiles, ' tile:', tile) if self.tableTileMgr.isPassHuTileBySeatId(winSeatId, tile): return False, [] #是否允许闭门胡 if not self.tableConfig.get(MTDefine.BI_MEN_FAN, 0): if len(tiles[MHand.TYPE_HAND]) == 14: return False, [] # 三色全 allTiles = MHand.copyAllTilesToList(tiles) #避免摸宝时候检查三色全问题,所以剔除最后一张 allTiles.remove(tile) #会牌剔除 if self.tableConfig.get(MTDefine.HUI_PAI, 0): magics = self.tableTileMgr.getMagicTiles(True) while magics[0] in allTiles: allTiles.remove(magics[0]) tilesArr = MTile.changeTilesToValueArr(allTiles) wanCount = MTile.getTileCountByColor(tilesArr, MTile.TILE_WAN) tongCount = MTile.getTileCountByColor(tilesArr, MTile.TILE_TONG) tiaoCount = MTile.getTileCountByColor(tilesArr, MTile.TILE_TIAO) if wanCount == 0 or tongCount == 0 or tiaoCount == 0: return False, [] #有幺九 if not self.SatisyYaoJiu(tiles): return False, [] result, pattern = MWin.isHu(tiles[MHand.TYPE_HAND], magicTiles, True) ftlog.debug('MWinRulePanjin.isHu tiles:', result, ' pattern:', pattern) if not result: return False, [] else: keAlreadyhas = self.SatisyKe2(tiles) if keAlreadyhas: return True, pattern else: #检查胡牌番型pattern,要有刻 for p in pattern: if len(p) == 3 and (p[0] == p[2] or p[1] == p[2] or p[0] == p[1]): return True, pattern elif len(p) == 2: if (p[0] in range(MTile.TILE_DONG_FENG,MTile.TILE_BAI_BAN+1)) \ or (p[1] in range(MTile.TILE_DONG_FENG,MTile.TILE_BAI_BAN+1)): return True, pattern if self.tableConfig.get(MTDefine.HUI_PAI, 0): if (p[0] == p[1] == magicTiles[0]): return True, pattern return False, []
def getBestDropTile(self, tiles_player_hand, tiles_left, tile, isTing, magicTiles, extend={}): """ 手牌的价值,根据玩家自己的手牌和已经出的牌,计算手牌价值 参数: tiles_player_hand - 用户的手牌 tiles_droped - 牌桌上已经打出的牌和玩家手里已经成型的牌,这部分牌不再参与计算牌的可能性 计算方法: 1)没有的手牌,权值为0 2)有的手牌,初始权值为4 * count + 1 * left 3)左右相邻的手牌,增加权重 3 * count 4)左右隔一张的手牌,增加权重 2 * count 该套策略可用于推倒胡 """ if isTing: # 听牌后,直接打出摸到的牌 ftlog.debug('alReady ting, drop tile directly:', tile) return tile, 0 tiles_value_Arr, tiles_player_Arr = MTileValue.getHandTilesValue( tiles_player_hand, tiles_left) # 放大癞子牌的作用 for mTile in magicTiles: tiles_value_Arr[mTile] = tiles_value_Arr[mTile] * 100 tingRule = extend.get('tingRule', None) # [{'dropTile': 11, 'winNodes': [{'winTile': 1, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [1, 2, 3]]}, {'winTile': 2, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [3, 4, 5], [2, 2]]}, {'winTile': 4, 'winTileCount': 3, 'pattern': [[6, 6], [5, 6, 7], [4, 5, 6], [2, 3, 4]]}, {'winTile': 5, 'winTileCount': 2, 'pattern': [[6, 6, 6], [5, 6, 7], [5, 5], [2, 3, 4]]}, {'winTile': 7, 'winTileCount': 1, 'pattern': [[6, 6], [5, 6, 7], [5, 6, 7], [2, 3, 4]]}, {'winTile': 8, 'winTileCount': 1, 'pattern': [[6, 7, 8], [6, 6, 6], [5, 5], [2, 3, 4]]}]}] if tingRule: canTing, tingResults = tingRule.canTing(tiles_player_hand, tiles_left, tile, magicTiles) ftlog.debug(canTing) ftlog.debug(tingResults) if canTing: totalValue = 0 for tingResult in tingResults: dropTile = tingResult['dropTile'] tiles_value_Arr[dropTile] = 0 winNodes = tingResult['winNodes'] for winNode in winNodes: totalValue += winNode['winTileCount'] * winNode[ 'winFan'] for tingResult in tingResults: dropTile = tingResult['dropTile'] winNodes = tingResult['winNodes'] dropValue = 0 for winNode in winNodes: dropValue += winNode['winTileCount'] * winNode['winFan'] tiles_value_Arr[dropTile] += (-dropValue) 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('MDropCardStrategy.getBestDropTile ', ' tile:', tile, ' magicTiles:', magicTiles, ' isTing:', isTing, ' tiles_player_hand:', tiles_player_hand, ' tileValues:', tiles_value_Arr, ' tiles_left:', tiles_left, ' minTile:', minTile, ' minTileValue:', minValue) return minTile, tiles_value_Arr[minTile]
def initialize(cls, serverId): """初始化,加载lua脚本,清除serverId对应的数据 """ ftlog.debug('CreateTableData.initialize serverId:', serverId) pluginCross.mj2dao.clearCreateTableData(serverId)
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 if __name__ == "__main__": tiles = [[3, 4, 15, 5, 5, 6, 9, 9], [[26, 27, 28]], [[8, 8, 8]], [], [], []] rule = MTingHaerbinRule() rule.setWinRuleMgr(MWinRuleHaerbin()) ftlog.debug(rule.canTing(tiles, [], 4, []))
[MTile.TILE_FIVE_WAN, MTile.TILE_FIVE_WAN], [MTile.TILE_EIGHT_WAN, MTile.TILE_EIGHT_WAN], [MTile.TILE_TWO_TONG, MTile.TILE_TWO_TONG], [MTile.TILE_FIVE_TONG, MTile.TILE_FIVE_TONG], [MTile.TILE_EIGHT_TONG, MTile.TILE_EIGHT_TONG], [MTile.TILE_TWO_TIAO, MTile.TILE_TWO_TIAO], [MTile.TILE_FIVE_TIAO, MTile.TILE_FIVE_TIAO], [MTile.TILE_EIGHT_TIAO, MTile.TILE_EIGHT_TIAO]] for jiangPat in jiangPatterns: result, pattern = MWin.isHuWishSpecialJiang( tiles[MHand.TYPE_HAND], jiangPat) if result: return result, pattern return False, [] def canWinAfterChiPengGang(self, tiles): """ 吃完之后是否能和牌 平度麻将无此限制 """ return True if __name__ == "__main__": tiles = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 12], [[12, 13, 14]], [], [], [], []] rule = MWinRulePingDu258() ftlog.debug(rule.isHu(tiles, 2, True, [3]))
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
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]
def appendInfo(self, state, info): ftlog.debug('MTableStateExtendInfo appendInfo state:', state, ' info:', info) if (state & MTableState.TABLE_STATE_CHI) and (state & MTableState.TABLE_STATE_GRABTING): if self.GRAB_CHI_TING not in self.__extend: self.__extend[self.GRAB_CHI_TING] = [] self.__extend[self.GRAB_CHI_TING].append(info) return if (state & MTableState.TABLE_STATE_PENG) and (state & MTableState.TABLE_STATE_GRABTING): if self.GRAB_PENG_TING not in self.__extend: self.__extend[self.GRAB_PENG_TING] = [] self.__extend[self.GRAB_PENG_TING].append(info) return if (state & MTableState.TABLE_STATE_GANG) and (state & MTableState.TABLE_STATE_GRABTING): if self.GRAB_GANG_TING not in self.__extend: self.__extend[self.GRAB_GANG_TING] = [] self.__extend[self.GRAB_GANG_TING].append(info) return if (state & MTableState.TABLE_STATE_ZHAN) and (state & MTableState.TABLE_STATE_GRABTING): if self.GRAB_ZHAN_TING not in self.__extend: self.__extend[self.GRAB_ZHAN_TING] = [] self.__extend[self.GRAB_ZHAN_TING].append(info) return if state & MTableState.TABLE_STATE_HU: if self.WIN not in self.__extend: self.__extend[self.WIN] = [] self.__extend[self.WIN].append(info) return if state & MTableState.TABLE_STATE_QIANGGANG: if self.QIANG_GANG_HU not in self.__extend: self.__extend[self.QIANG_GANG_HU] = [] self.__extend[self.QIANG_GANG_HU].append(info) return if state & MTableState.TABLE_STATE_QIANG_EXMAO: if self.PENG not in self.__extend: self.__extend[self.QIANG_EXMAO] = [] self.__extend[self.QIANG_EXMAO].append(info) return if state & MTableState.TABLE_STATE_QIANG_EXMAO_HU: if self.QIANG_EXMAO_HU not in self.__extend: self.__extend[self.QIANG_EXMAO_HU] = [] self.__extend[self.QIANG_EXMAO_HU].append(info) return if state & MTableState.TABLE_STATE_TING: if self.TING not in self.__extend: self.__extend[self.TING] = [] self.__extend[self.TING].extend(info) return if state & MTableState.TABLE_STATE_GANG: if self.GANG not in self.__extend: self.__extend[self.GANG] = [] self.__extend[self.GANG].append(info) ftlog.debug('MTableStateExtendInfo.appendInfo append gang node:', info, ' after add:', self.__extend[self.GANG]) return if state & MTableState.TABLE_STATE_PENG: if self.PENG not in self.__extend: self.__extend[self.PENG] = [] self.__extend[self.PENG].append(info) return if state & MTableState.TABLE_STATE_CHI: if self.CHI not in self.__extend: self.__extend[self.CHI] = [] self.__extend[self.CHI].append(info) return if state & MTableState.TABLE_STATE_FANPIGU: if 'pigus' not in self.__extend: self.__extend['pigus'] = [] self.__extend['pigus'] = info return if state & MTableState.TABLE_STATE_FANGMAO: if self.MAO not in self.extend: self.extend[self.MAO] = [] self.extend[self.MAO].append(info) if state & MTableState.TABLE_STATE_BUFLOWER: if self.BUFLOWER not in self.extend: self.extend[self.BUFLOWER] = [] self.extend[self.BUFLOWER].append(info) if state & MTableState.TABLE_STATE_ABSENCE: if self.ABSENCE not in self.extend: self.extend[self.ABSENCE] = [] self.extend[self.ABSENCE].append(info)
def calcWin(self): """ 哈麻算番规则: 1)合并一番 自摸,特殊情况下的自摸可以有杠开/红中宝两种叫法 1.1杠开 1.2红中宝 自己摸到红中 1.4刮大风 上听后摸到自己的碰牌或刻牌且不是宝牌,宝牌算宝中宝 1.5宝中宝1 3番 宝牌 夹牌 1.6宝中宝2 3番 刮大风+宝牌 2)自摸点炮都算 2.1夹胡 2.2三七边 2.3摸宝 1.3宝边,2番,自摸的要胡的牌刚好是宝牌 2.4边夹双 2倍数 """ scoreBase = self.tableConfig.get(MTDefine.WIN_BASE, 1) ftlog.debug('MHaerbinOneResult.calcWin scoreBase:', scoreBase) self.results['type'] = MOneResult.KEY_TYPE_NAME_HU # 在和牌时统计自摸,点炮,最大番数 resultStat = [[] for _ in range(self.playerCount)] isZiMo = (self.lastSeatId == self.winSeatId) if isZiMo: resultStat[self.lastSeatId].append({MOneResult.STAT_ZIMO: 1}) resultStat[self.winSeatId].append({MOneResult.STAT_WIN: 1}) isJia = self.isJia() isBian = self.isBian() isDanDiao = self.isDanDiao() isMagic = self.isMagicTile() ftlog.debug('MHaerbinOneResult.calcWin isJia:', isJia, ' isBian:', isBian, ' isDanDiao', isDanDiao, ' isMagic:', isMagic) self.clearWinFanPattern() # 计算基本番型(只有单吊 夹胡 三七边) name, index = self.calcDianPaoFan(isJia, isBian, isDanDiao) ftlog.debug('MHaerbinOneResult.calcWin name:', name, ' index:', index, ' type:', type) # 计算自摸高级番型 都和自摸有关(不包含自摸 杠开 抢杠胡 摸宝 红中宝) if isZiMo: name2, index2 = self.calcZiMoAdvFan(isZiMo, isDanDiao, self.daFeng, self.baoZhongBao, isMagic, isJia, isBian) ftlog.debug('MHaerbinOneResult.calcWin name2:', name2, ' index2:', index2, ' type:', type) # 只是自摸 没有高级番型 if name2 == self.fanXing[self.ZIMO]['name']: # 在基础番型上增加自摸倍数 hongZongBaoConfig = self.tableConfig.get( MTDefine.HONG_ZHONG_BAO, 0) if isMagic: index = index + self.fanXing[self.MOBAO]['index'] resultStat[self.lastSeatId].append( {MOneResult.STAT_MOBAO: 1}) elif self.isHongZhong() and hongZongBaoConfig: index = index + self.fanXing[self.HONGZHONGBAO]['index'] else: index = index + 1 # 自摸相关的特殊番型 直接覆盖基本番型 else: name = name2 index = index2 self.clearWinFanPattern() self.addWinFanPattern(name, index) ftlog.debug('MHaerbinOneResult.calcWin name:', name, ' index:', index, ' type:', type) if name == self.fanXing[self.GUADAFENG]['name']: # 刮大风的情况下判断是不是夹 if isJia or (isBian and self.isSanQi() and self.tableConfig.get(MTDefine.BIAN_MULTI, 0)): jianame = self.fanXing[self.JIAHU]['name'] jiaindex = self.fanXing[self.JIAHU]['index'] self.addWinFanPattern(jianame, jiaindex) index += 1 if self.bankerSeatId == self.winSeatId: ftlog.debug('MHaerbinOneResult.calcWin name:', name, ' index:', index, ' type:', type, ' bankerSeatId:', self.bankerSeatId, ' winSeatId:', self.winSeatId) index += 1 scoreIndex = self.tableConfig.get(MTDefine.FAN_LIST, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) ftlog.debug('MHaerbinOneResult.calcWin scoreIndex:', scoreIndex) # 当前局番型处理 fanPattern = [[] for _ in range(self.playerCount)] winMode = [MOneResult.WIN_MODE_LOSS for _ in range(self.playerCount)] # 输赢模式 输家番型统计 for seatId in range(self.playerCount): if seatId == self.winSeatId: winModeValue = MOneResult.WIN_MODE_PINGHU # 自摸 if self.lastSeatId == self.winSeatId: winModeValue = MOneResult.WIN_MODE_ZIMO if self.baoZhongBao: winModeValue = MOneResult.WIN_MODE_baozhongbao if self.magicAfertTing: if self.tableConfig.get(MTDefine.DUI_BAO, 0) == 1: winModeValue = MOneResult.WIN_MODE_LOUHU # 红中宝 hongZongBaoConfig = self.tableConfig.get( MTDefine.HONG_ZHONG_BAO, 0) if self.isHongZhong() and hongZongBaoConfig and ( MTile.TILE_HONG_ZHONG not in self.tableTileMgr.getMagicTiles(True)): winModeValue = MOneResult.WIN_MODE_hongzhongbao self.addWinFanPattern( self.fanXing[self.HONGZHONGBAO]['name'], self.fanXing[self.HONGZHONGBAO]['index']) if isMagic and (not self.magicAfertTing): winModeValue = MOneResult.WIN_MODE_mobao self.addWinFanPattern( self.fanXing[self.MOBAO]['name'], self.fanXing[self.MOBAO]['index']) if self.gangKai: winModeValue = MOneResult.WIN_MODE_GANGKAI self.addWinFanPattern(self.fanXing[self.GANGKAI]['name'], self.fanXing[self.GANGKAI]['index']) if self.qiangGang: winModeValue = MOneResult.WIN_MODE_QIANGGANGHU self.addWinFanPattern( self.fanXing[self.QIANGGANG]['name'], self.fanXing[self.QIANGGANG]['index']) if self.daFeng: winModeValue = MOneResult.WIN_MODE_guadafeng winMode[seatId] = winModeValue fanPattern[self.winSeatId] = self.winFanPattern elif seatId == self.lastSeatId: winModeValue = MOneResult.WIN_MODE_DIANPAO winMode[seatId] = winModeValue resultStat[seatId].append({MOneResult.STAT_DIANPAO: 1}) fanPattern[seatId] = [] # 点炮包庄 if self.tingState[seatId] == 0: winModeValue = MOneResult.WIN_MODE_DIANPAO_BAOZHUANG winMode[seatId] = winModeValue # 闭门 if self.menState[seatId] == 1: looseFanName = self.fanXing[self.BIMEN]['name'] looseFanIndex = self.fanXing[self.BIMEN]['index'] fanPattern[seatId].append( [looseFanName.strip(), str(looseFanIndex) + "番"]) else: fanPattern[seatId] = [] # 闭门 if self.menState[seatId] == 1: looseFanName = self.fanXing[self.BIMEN]['name'] looseFanIndex = self.fanXing[self.BIMEN]['index'] fanPattern[seatId].append( [looseFanName.strip(), str(looseFanIndex) + "番"]) score = [index for _ in range(self.playerCount)] if self.lastSeatId != self.winSeatId: if self.tingState[self.lastSeatId]: ftlog.debug( 'MHaerbinOneResult.calcWin dianpao index is zero becore tingState' ) else: score[self.lastSeatId] += 1 ftlog.debug('MHaerbinOneResult.calcWin dianpao score:', score) if self.bankerSeatId != self.winSeatId: score[self.bankerSeatId] += 1 ftlog.debug('MHaerbinOneResult.calcWin zhuangjia double score:', score, ' bankerSeatId:', self.bankerSeatId, ' winSeatId:', self.winSeatId) for seatId in range(len(self.menState)): if self.menState[seatId] == 1 and seatId != self.winSeatId: score[seatId] += 1 ftlog.debug('MHaerbinOneResult.calcWin menqing double score:', score, ' menState:', self.menState) winScore = 0 for seatId in range(len(score)): if seatId != self.winSeatId: newIndex = score[seatId] score[seatId] = -scoreIndex[newIndex] winScore += scoreIndex[newIndex] score[self.winSeatId] = winScore ftlog.debug('MHaerbinOneResult.calcWin score before baopei:', score) if self.lastSeatId != self.winSeatId: if self.tingState[self.lastSeatId] == 0: # 包赔 for seatId in range(len(score)): if seatId != self.winSeatId and seatId != self.lastSeatId: s = score[seatId] score[seatId] = 0 score[self.lastSeatId] += s ftlog.debug( 'MHaerbinOneResult.calcWin dianpaobaozhuang score:', score, ' lastSeatId:', self.lastSeatId, ' winSeatId:', self.winSeatId, ' tingState:', self.tingState) # 最大番统计(改成单局最佳) resultStat[self.winSeatId].append( {MOneResult.STAT_ZUIDAFAN: score[self.winSeatId]}) self.results[self.KEY_TYPE] = '和牌' self.results[self.KEY_NAME] = name ftlog.debug('MHaerbinOneResult.calcWin result score:', score) self.results[self.KEY_SCORE] = score ftlog.debug('MHaerbinOneResult.calcWin result winMode:', winMode) self.results[self.KEY_WIN_MODE] = winMode self.results[self.KEY_STAT] = resultStat ftlog.debug('MHaerbinOneResult.calcWin result fanPattern:', fanPattern) self.results[self.KEY_FAN_PATTERN] = fanPattern
def updateState(self, state, pattern): """用户做出了选择,更新""" if state & MTableState.TABLE_STATE_CHI: if state & MTableState.TABLE_STATE_GRABTING: chiTing = self.getChoiceByPattern(pattern, self.__extend[self.GRAB_CHI_TING]) if not chiTing: ftlog.error('MTableStateExtendInfo.updateState error, pattern:', pattern , ' extend:', self.__extend) return False self.__extend[self.GRAB_CHI_TING] = [chiTing] else: patternSorted = copy.deepcopy(pattern) patternSorted = sorted(patternSorted) inChiPattern = False for chiPattern in self.__extend[self.CHI]: chiPatternSorted = copy.deepcopy(chiPattern) chiPatternSorted = sorted(chiPatternSorted) if patternSorted == chiPatternSorted: inChiPattern = True break if not inChiPattern: ftlog.error('MTableStateExtendInfo.updateState error, pattern:', pattern , ' extend:', self.__extend) return False self.__extend[self.CHI] = [pattern] self.updateInfo(state) return True if state & MTableState.TABLE_STATE_PENG: if state & MTableState.TABLE_STATE_GRABTING: pengTing = self.getChoiceByPattern(pattern, self.__extend[self.GRAB_PENG_TING]) if not pengTing: ftlog.error('MTableStateExtendInfo.updateState error, pattern:', pattern , ' extend:', self.__extend) return False self.__extend[self.GRAB_PENG_TING] = [pengTing] else: if pattern not in self.__extend[self.PENG]: ftlog.error('MTableStateExtendInfo.updateState error, pattern:', pattern , ' extend:', self.__extend) return False self.__extend[self.PENG] = [pattern] self.updateInfo(state) return True if state & MTableState.TABLE_STATE_GANG: if state & MTableState.TABLE_STATE_GRABTING: ftlog.debug('MTableStateExtendInfo.updateState try gangTing, pattern:', pattern, ' extend:', self.__extend) gangTing = self.getChoiceByPattern(pattern, self.__extend[self.GRAB_GANG_TING]) if not gangTing: ftlog.error('MTableStateExtendInfo.updateState error, pattern:', pattern , ' extend:', self.__extend) return False self.__extend[self.GRAB_GANG_TING] = [gangTing] else: ftlog.debug('MTableStateExtendInfo.updateState pattern:', pattern, ' extend:', self.__extend) gang = self.getChoiceByPattern(pattern['pattern'], self.__extend[self.GANG]) if not gang: ftlog.error('MTableStateExtendInfo.updateState error, pattern:', pattern , ' extend:', self.__extend) return False self.__extend[self.GANG] = [pattern] self.updateInfo(state) return True if state & MTableState.TABLE_STATE_ZHAN: if state & MTableState.TABLE_STATE_GRABTING: ftlog.debug('MTableStateExtendInfo.updateState try zhanTing, pattern:', pattern, ' extend:', self.__extend) zhanTing = self.getChoiceByPattern(pattern, self.__extend[self.GRAB_ZHAN_TING]) if not zhanTing: ftlog.error('MTableStateExtendInfo.updateState error, pattern:', pattern , ' extend:', self.__extend) return False self.__extend[self.GRAB_ZHAN_TING] = [zhanTing] self.updateInfo(state) return True if state & MTableState.TABLE_STATE_PASS_HU: return True if state & MTableState.TABLE_STATE_HU: return True ftlog.error('MTableStateExtendInfo.updateState error state:', state, ' pattern:', pattern) return False
def setTableType(self, tableType): ftlog.debug('MOneResult.setTableType:', tableType) self.__table_type = tableType
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) # 不能和牌的情况: 放过锚手中有风牌或箭牌 if len(tiles[MHand.TYPE_MAO]) > 0: if self.tableConfig[ MTDefine. MAO_DAN_SETTING] & MTDefine.MAO_DAN_DNXBZFB: #乱锚时手中有风牌或箭牌 for T in tiles[MHand.TYPE_HAND]: if T >= 31: return False, [] else: has_jmao = 0 #有箭牌 has_fmao = 0 #有风牌 for mao in tiles[MHand.TYPE_MAO]: if mao['type'] == 1: has_jmao = 1 if mao['type'] == 2: has_fmao = 1 if has_jmao: for T in tiles[MHand.TYPE_HAND]: if T >= 35: return False, [] if has_fmao: for T in tiles[MHand.TYPE_HAND]: if T >= 31 and T <= 34: return False, [] # 威海麻将允许胡七对 resultQiDui, patternQiDui = MWin.isQiDui(tiles[MHand.TYPE_HAND]) if resultQiDui: return True, patternQiDui ftlog.debug('MWinRuleWeihai 258jiang_config======:', self.tableConfig[MTDefine.ONLY_JIANG_258]) # 挑出2,5,8将,看剩下的牌是否能胡牌 if self.tableConfig[MTDefine.ONLY_JIANG_258]: jiangPatterns = [[MTile.TILE_TWO_WAN, MTile.TILE_TWO_WAN], [MTile.TILE_FIVE_WAN, MTile.TILE_FIVE_WAN], [MTile.TILE_EIGHT_WAN, MTile.TILE_EIGHT_WAN], [MTile.TILE_TWO_TONG, MTile.TILE_TWO_TONG], [MTile.TILE_FIVE_TONG, MTile.TILE_FIVE_TONG], [MTile.TILE_EIGHT_TONG, MTile.TILE_EIGHT_TONG], [MTile.TILE_TWO_TIAO, MTile.TILE_TWO_TIAO], [MTile.TILE_FIVE_TIAO, MTile.TILE_FIVE_TIAO], [MTile.TILE_EIGHT_TIAO, MTile.TILE_EIGHT_TIAO]] for jiangPat in jiangPatterns: result, pattern = MWin.isHuWishSpecialJiang( tiles[MHand.TYPE_HAND], jiangPat) ftlog.debug( 'MWinRuleWeihai isHuWishSpecialJiang.result======:', result, 'pattern=====', pattern) if result: return result, pattern return False, [] else: result, pattern = MWin.isHu(tiles[MHand.TYPE_HAND]) return result, pattern
def calcWin(self): ftlog.debug( 'MDandongOneResult.calcWin self.playerAllTiles[self.winSeatId]', self.playerAllTiles[self.winSeatId]) resultwin = [] if not self.tingState[self.winSeatId]: for tileTry in range(MTile.TILE_MAX_VALUE): if self.SatisyYaoJiu(self.playerAllTiles[self.winSeatId], tileTry): handTile = copy.deepcopy( self.playerAllTiles[self.winSeatId][MHand.TYPE_HAND]) handTile.append(tileTry) ishu, pattern = MWin.isHu(handTile, [], True) if ishu: winNode = {} winNode['winTile'] = tileTry winNode['winTileCount'] = 2 for p in pattern: p.sort() winNode['pattern'] = pattern resultwin.append(winNode) ftlog.debug( 'MPanjinOneResult.calcWin MWin.isHu(handTile) resultwin', resultwin) self.setWinNodes(resultwin) self.results['type'] = MOneResult.KEY_TYPE_NAME_HU name = '' index = 0 fanPattern = [[] for _ in range(self.playerCount)] winMode = [MOneResult.WIN_MODE_LOSS for _ in range(self.playerCount)] # 在和牌时统计自摸,点炮,最大番数 resultStat = [[] for _ in range(self.playerCount)] resultStat[self.winSeatId].append({MOneResult.STAT_WIN: 1}) # 正常和牌 isZiMo = (self.lastSeatId == self.winSeatId) if isZiMo: resultStat[self.winSeatId].append({MOneResult.STAT_ZIMO: 1}) isTianhu = False if self.tableConfig.get(MTDefine.TIAN_HU, 0): isTianhu = self.isTianHu() isPiao = self.isPiao() isDandiao = self.isDandiao() ftlog.debug('MDandongOneResult.calcWin:', ' isTianhu:', isTianhu, ' isPiao:', isPiao, ' isDandiao:', isDandiao) self.clearWinFanPattern() if isZiMo: index += self.fanXing[self.ZIMO]['index'] if self.tableConfig.get(MTDefine.DAN_DIAO_JIA, 0): if isDandiao: namejia = self.fanXing[self.JIAHU]['name'] indexjia = self.fanXing[self.JIAHU]['index'] self.addWinFanPattern(namejia, indexjia) index += self.fanXing[self.JIAHU]['index'] if isPiao: namepiaohu = self.fanXing[self.PIAO]['name'] indexpiaohu = self.fanXing[self.PIAO]['index'] self.addWinFanPattern(namepiaohu, indexpiaohu) index += self.fanXing[self.PIAO]['index'] # 赢家门清永远x2 if self.menState[self.winSeatId] == 1: namemenqing = self.fanXing[self.MENQING]['name'] indexmenqing = self.fanXing[self.MENQING]['index'] self.addWinFanPattern(namemenqing, indexmenqing) index += self.fanXing[self.MENQING]['index'] if self.tingState[self.winSeatId]: nameting = self.fanXing[self.TING]['name'] indexting = self.fanXing[self.TING]['index'] self.addWinFanPattern(nameting, indexting) index += self.fanXing[self.TING]['index'] # 庄家赢x2 if self.bankerSeatId == self.winSeatId: index += 1 # 当前局番型处理 # 输赢模式 输家番型统计 biMenFanConfig = self.tableConfig.get(MTDefine.BI_MEN_FAN, 0) for seatId in range(self.playerCount): if seatId == self.winSeatId: winModeValue = MOneResult.WIN_MODE_PINGHU # 自摸 if self.lastSeatId == self.winSeatId: winModeValue = MOneResult.WIN_MODE_ZIMO winMode[seatId] = winModeValue fanPattern[self.winSeatId] = self.winFanPattern elif seatId == self.lastSeatId: winModeValue = MOneResult.WIN_MODE_DIANPAO winMode[seatId] = winModeValue resultStat[seatId].append({MOneResult.STAT_DIANPAO: 1}) fanPattern[seatId] = [] # 点炮包庄 if self.tableConfig.get(MTDefine.BAOZHUANG_BAOGANG, 0): winModeValue = MOneResult.WIN_MODE_DIANPAO_BAOZHUANG winMode[seatId] = winModeValue # 闭门 if self.menState[seatId] == 1 and biMenFanConfig: looseFanName = self.fanXing[self.BIMEN]['name'] looseFanIndex = self.fanXing[self.BIMEN]['index'] fanPattern[seatId].append( [looseFanName.strip(), str(looseFanIndex) + "番"]) else: fanPattern[seatId] = [] # 闭门 if self.menState[seatId] == 1 and biMenFanConfig: looseFanName = self.fanXing[self.BIMEN]['name'] looseFanIndex = self.fanXing[self.BIMEN]['index'] fanPattern[seatId].append( [looseFanName.strip(), str(looseFanIndex) + "番"]) score = [index for _ in range(self.playerCount)] # 庄家输x2 if self.bankerSeatId != self.winSeatId: score[self.bankerSeatId] += 1 # 点炮x2 if self.lastSeatId != self.winSeatId: score[self.lastSeatId] += 1 # 如果选择背靠背 输家闭门x2 for seatId in range(len(self.menState)): if biMenFanConfig and self.menState[ seatId] == 1 and seatId != self.winSeatId: score[seatId] += 1 scoreIndex = self.tableConfig.get(MTDefine.FAN_LIST, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) ftlog.debug('MDandongOneResult.calcWin scoreIndex:', scoreIndex) winScore = 0 for seatId in range(len(score)): if seatId != self.winSeatId: newIndex = score[seatId] score[seatId] = -scoreIndex[newIndex] winScore += abs(score[seatId]) score[self.winSeatId] = winScore ftlog.debug('MDandongOneResult.calcWin score before baopei:', score) # 加入底分的概念*2或者*5 scoreBase = self.tableConfig.get(MTDefine.WIN_BASE, 1) ftlog.debug('MMudanjiangOneResult.calcWin scoreBase:', scoreBase) for seatId in range(len(score)): score[seatId] *= scoreBase # 包庄 if self.lastSeatId != self.winSeatId: if self.tableConfig.get(MTDefine.BAOZHUANG_BAOGANG, 0): # 包赔 for seatId in range(len(score)): if seatId != self.winSeatId and seatId != self.lastSeatId: s = score[seatId] score[seatId] = 0 score[self.lastSeatId] += s ftlog.debug( 'MDandongOneResult.calcWin dianpaobaozhuang score:', score, ' lastSeatId:', self.lastSeatId, ' winSeatId:', self.winSeatId) # 单局最佳统计(分数) resultStat[self.winSeatId].append( {MOneResult.STAT_ZUIDAFAN: score[self.winSeatId]}) self.results[self.KEY_TYPE] = '和牌' self.results[self.KEY_NAME] = name ftlog.debug('MDandongOneResult.calcWin result score:', score) self.results[self.KEY_SCORE] = score ftlog.debug('MDandongOneResult.calcWin result winMode:', winMode) self.results[self.KEY_WIN_MODE] = winMode self.results[self.KEY_STAT] = resultStat ftlog.debug('MDandongOneResult.calcWin result fanPattern:', fanPattern) self.results[self.KEY_FAN_PATTERN] = fanPattern
def updateTimeOut(self, deta): if self.schedule == self.SCHEDULE_ABSENCE_DING: self.__absence_timeout += deta ftlog.debug('MAbsenceProcessor schedule:', self.schedule, ' absenceTimeOut:', self.absenceTimeOut)
def isBian(self): """是否夹牌""" for wn in self.winNodes: if wn['winTile'] == self.winTile: patterns = wn['pattern'] ftlog.debug('MMudanjiangOneResult.isBian winTile:', self.winTile, ' winPatterns:', patterns) for p in patterns: if len(p) == 2: continue if p[0] == p[1]: continue # 三七边 if (self.winTile in p) \ and (p.index(self.winTile) == 0) \ and (MTile.getValue(p[1]) == 8) \ and (MTile.getValue(p[2]) == 9): ftlog.debug('MMudanjiangOneResult.isBian winTile:', self.winTile, ' winPatterns:', patterns, ' 7 bian') return True if (self.winTile in p) \ and (p.index(self.winTile) == 2) \ and (MTile.getValue(p[0]) == 1) \ and (MTile.getValue(p[1]) == 2): ftlog.debug('MMudanjiangOneResult.isBian winTile:', self.winTile, ' winPatterns:', patterns, ' 3 bian') return True # 宝牌情况处理 hongZongBaoConfig = self.tableConfig.get(MTDefine.HONG_ZHONG_BAO, 0) ftlog.debug('MMudanjiangOneResult.isBian checkMagic, isMagicTile:', self.isMagicTile(), ' isHongZhong:', self.isHongZhong(), ' hongZongBaoConfig:', hongZongBaoConfig, ' daFeng:', self.daFeng, ' magicAfertTing:', self.magicAfertTing) if self.isMagicTile() or (self.isHongZhong() and hongZongBaoConfig ) or self.daFeng or self.magicAfertTing: for wn in self.winNodes: winTile = wn['winTile'] patterns = wn['pattern'] for p in patterns: if len(p) == 2: continue if p[0] == p[1]: continue # 三七边 if (winTile in p) \ and (p.index(winTile) == 0) \ and (MTile.getValue(p[1]) == 8) \ and (MTile.getValue(p[2]) == 9): ftlog.debug('MMudanjiangOneResult.isBian winTile:', self.winTile, ' winPatterns:', patterns, ' 7 bian') return True if (winTile in p) \ and (p.index(winTile) == 2) \ and (MTile.getValue(p[0]) == 1) \ and (MTile.getValue(p[1]) == 2): ftlog.debug('MMudanjiangOneResult.isBian winTile:', self.winTile, ' winPatterns:', patterns, ' 3 bian') return True return False
def beginAbsence(self): """ 开始定缺,前端收到这个消息之后提示让玩家选择缺哪门 """ ftlog.debug('MAbsenceProcessor.beginAbsence...') self.setSchedule(self.SCHEDULE_ABSENCE_BEGIN)
def _isfilterConditions_group3(userId, clientId): # conf = configure.getGameJson(HALL_GAMEID, 'gamelistipfilter', {}, configure.DEFAULT_CLIENT_ID) conf = hallshare2_config.getZeroConfig() ipstr = sessiondata.getClientIp(userId) if not iploc.isBjSzIp(ipstr): if _DEBUG: ftlog.debug('_isfilterConditions_group3', userId, ipstr, 'enableIpCheck !') adjustVIP = 0 adjustPlayTime = 0 group3_passVipLevel = conf.get('group3_passVipLevel', 0) if group3_passVipLevel > 0: vipLevel = _getVIpLevel(userId) if vipLevel >= group3_passVipLevel: if _DEBUG: ftlog.debug('_isfilterConditions_group3', userId, vipLevel, group3_passVipLevel, '_isfilterConditions_group3 !') adjustVIP = 1 group3_passTotalPlayTime = conf.get('group3_passTotalPlayTime', 0) if group3_passTotalPlayTime > 0: totalTime = _getPlayTimes(userId) if totalTime >= group3_passTotalPlayTime: if _DEBUG: ftlog.debug('gamelistipfilter', userId, totalTime, group3_passTotalPlayTime, '_isfilterConditions_group3 !') adjustPlayTime = 1 return adjustVIP == 1 and adjustPlayTime == 1 else: if _DEBUG: ftlog.debug('_isfilterConditions_group3 is in beijing or shenzhe!! userId = ', userId , 'enableIpCheck !') adjustVIP = 0 adjustPlayTime = 0 group3_passVipLevel = conf.get('group3_key_area_passVipLevel', 0) if group3_passVipLevel > 0: vipLevel = _getVIpLevel(userId) if vipLevel >= group3_passVipLevel: if _DEBUG: ftlog.debug('_isfilterConditions_group3', userId, vipLevel, group3_passVipLevel, 'group3_passVipLevel !') adjustVIP = 1 group3_passTotalPlayTime = conf.get('group3_key_area_passTotalPlayTime', 0) if group3_passTotalPlayTime > 0: totalTime = _getPlayTimes(userId) if totalTime >= group3_passTotalPlayTime: if _DEBUG: ftlog.debug('gamelistipfilter', userId, totalTime, group3_passTotalPlayTime, 'group3_key_area_passTotalPlayTime !') adjustPlayTime = 1 return adjustVIP == 1 and adjustPlayTime == 1
def hasMaoDemo(): tiles = [2,2,2,3,3,3,4,4,4,22,31,32,33,34] result = MMao.hasMao(tiles, 6, 0) ftlog.debug( result )