package gamelogic import ( "fmt" "bet24.com/log" ladder "bet24.com/servers/micros/ladderservice/proto" ) type PlayerInfo struct { IsValid bool // 是否有效玩家 HandCards []int // 手牌 EndScore int // 游戏结算所得 TotalScore int // 游戏总得分 AutoOut bool // 托管标志 LastAction int // 上一个动作 LastActionData int // 上个动作数据 CurrentCard int // 当前轮次的出牌 WinCardScore int // 每一小局赢牌得分 WinCardChangeScore int // 每一小局每轮赢牌获得分数,用于赢牌飘分 TotalChangeScore int // 每一小局获得的分数 FinalCalcScore int // 每一小局最后计算得分 Projects []SingleProject // 项目数据 CallProject int // 玩家需要发声的最高项目名 CanAction []int // 玩家叫牌的动作 CanGawah bool // 玩家能否全部打出 HaveBaloot bool // 是否有baloot项目 IsCallBiggest bool // 在hokum模式下,非第一轮,玩家如果第一个出牌,此牌在该花色下是否为最大且非主牌不为A,主牌不为J WinCardNumber int // 赢牌数量 LeftSendCards []int // 剩余三张发牌数据 CanDoReshuffle bool // 是否有重新洗牌操作 ReshuffleAction int // 洗牌动作 IsReshuffleTime bool // 是否刷新倒计时 BigCards []int // 在Hokum模式下,玩家必须压的大牌,如果为空则走原来的逻辑 Doublings []DoublingDetail // 翻倍详情 MatchScore int // 比赛分 LevelValue int // 经验值 IsSurrender bool // 是否投降 ProjectTips []int // 项目提示 LadderInfo ladder.UserLadderInfo // 玩家段位信息 LadderChangeValue int // 段位变化值 LastWinCount int // 结算前连胜次数,用于连胜中断时,展示玩家中断时的连胜次数 userID int // 玩家ID bet int // 进房押注金额 isRobot bool // 是否机器人 enterGold int // 玩家携带金币 consecutiveWinCardCount int // 连续赢牌次数 isEndToStart bool // 金币场继续游戏情况为true,用于记录是否发送匹配界面的 bakHandCards []int // 备用手牌数据,用于导入数据到Excel表中,后期不用可以删除 winCardScore int // 玩家吃牌分数,用于统计玩家每小局吃牌分并导入数据到Excel表中,后期不用可以删除 isControl bool // 是否走个个人奖池控牌 controlType int // 控制类型 roundScores []int // 玩家每小局得分 controlDoubling int // 加倍场触发倍数,非加倍场为-1 averageDoubling int // 平均执行倍数 bakProjects []SingleProject robotType int robotActionType int robotActionProb int selfConsecutiveWinCardCount int outTimeCount int } func (p *PlayerInfo) initData(userId, enterGold, initScore int) { p.gameInit() p.IsValid = false p.TotalScore = initScore p.enterGold = enterGold p.userID = userId p.EndScore = 0 p.Doublings = []DoublingDetail{} p.isControl = false p.controlType = 0 p.roundScores = []int{} p.controlDoubling = -1 p.averageDoubling = 0 p.IsSurrender = false p.LadderChangeValue = 0 } func (p *PlayerInfo) gameInit() { p.HandCards = []int{} p.AutoOut = false p.LastAction = Action_Invalid p.LastActionData = -1 p.CurrentCard = CARD_COUNT p.WinCardScore = 0 p.WinCardChangeScore = 0 p.CanAction = []int{} p.Projects = []SingleProject{} p.bakProjects = []SingleProject{} p.CallProject = PROJECT_INVALID p.CanGawah = false p.HaveBaloot = false p.IsCallBiggest = false p.TotalChangeScore = 0 p.FinalCalcScore = 0 p.WinCardNumber = 0 p.LeftSendCards = []int{} p.CanDoReshuffle = false p.ReshuffleAction = Reshuffle_None p.IsReshuffleTime = false p.BigCards = []int{} p.consecutiveWinCardCount = 0 p.selfConsecutiveWinCardCount = 0 p.bakHandCards = []int{} p.winCardScore = 0 p.LevelValue = 0 p.ProjectTips = []int{0, 0, 0, 0} p.robotActionType = RobotType_Cautious p.robotActionProb = 100 p.outTimeCount = 0 } func (p *PlayerInfo) canReshuffle() bool { return p.CanDoReshuffle && p.ReshuffleAction == Reshuffle_None } func (p *PlayerInfo) intLastAction() { p.LastAction = Action_Invalid p.LastActionData = -1 } func (p *PlayerInfo) addDoublingData(gameIndex, times int) { p.Doublings = append(p.Doublings, DoublingDetail{ RoundIndex: gameIndex, DoublingTotalTimes: times, }) } func (p *PlayerInfo) initBigCards(bigCards []int) { p.BigCards = []int{} if len(bigCards) > 0 { p.BigCards = append(p.BigCards, bigCards...) } } func (p *PlayerInfo) getPlayerCurrentTotalDoublings() int { baseTimes := 0 for n := 0; n < len(p.Doublings); n++ { baseTimes += p.Doublings[n].DoublingTotalTimes } return baseTimes } func (p *PlayerInfo) checkBaloot(trumpType int) { haveTrumpQ := false haveTrumpK := false for i := 0; i < len(p.HandCards); i++ { if p.HandCards[i] == trumpType*8+CardValueQ { haveTrumpQ = true } if p.HandCards[i] == trumpType*8+CardValueK { haveTrumpK = true } } if haveTrumpQ && haveTrumpK { p.HaveBaloot = true } } func (p *PlayerInfo) isAllZeroScoreCard() bool { for i := 0; i < len(p.HandCards); i++ { if value_regular[getCardValue(p.HandCards[i])] > 0 { return false } } p.CanDoReshuffle = true return true } func (p *PlayerInfo) needReshuffle() bool { for i := 0; i < len(p.HandCards); i++ { if value_regular[getCardValue(p.HandCards[i])] > 0 { return false } } return true } func (p *PlayerInfo) isIncludeBaloot() bool { if !p.HaveBaloot { return false } if len(p.Projects) == 0 { return false } for i := 0; i < len(p.Projects); i++ { if p.Projects[i].Type == PROJECT_BALOOT { return true } } return false } func (p *PlayerInfo) outAllBalootCard(trumpType int) bool { if !p.HaveBaloot || trumpType == CardType_Invalid { return false } haveTrumpQ := haveCard(p.HandCards, trumpType*8+CardValueQ) haveTrumpK := haveCard(p.HandCards, trumpType*8+CardValueK) return !haveTrumpQ && !haveTrumpK } func (p *PlayerInfo) ininTime() { p.IsReshuffleTime = false } func (p *PlayerInfo) setPlayerOperators(buyList []int) { if len(buyList) > 0 { p.IsReshuffleTime = true } p.CanAction = []int{} p.CanAction = buyList } func (p *PlayerInfo) isBuyPass() bool { if len(p.CanAction) == 0 { return true } return p.LastActionData == Action_Buy_Pass } func (p *PlayerInfo) canAction() bool { return len(p.CanAction) > 0 } func (p *PlayerInfo) getAutoBuyAction() int { if len(p.CanAction) > 0 { return p.CanAction[0] } return Action_Buy_Invaild } func (p *PlayerInfo) canDoBuyAction(buyAction int) bool { if buyAction < 0 || buyAction >= Action_Buy_Invaild { return false } for i := 0; i < len(p.CanAction); i++ { if p.CanAction[i] == buyAction { return true } } return false } func (p *PlayerInfo) hideSecretData() { if len(p.HandCards) == 0 { return } for i := 0; i < len(p.HandCards); i++ { p.HandCards[i] = CARD_COUNT } if len(p.LeftSendCards) == 0 { return } for i := 0; i < len(p.LeftSendCards); i++ { p.LeftSendCards[i] = CARD_COUNT } } func (p *PlayerInfo) analysisProject(projects []int, suit int) { cardList := make([]int, len(p.HandCards)) copy(cardList, p.HandCards) cardList = append(cardList, p.CurrentCard) projectList := []SingleProject{} bestType := -1 for i := PROJECT_FOURHUNDRED; i >= PROJECT_SIRA; i-- { for n := 0; n < projects[i]; n++ { if suit == Suit_Hokum && i == PROJECT_FOURHUNDRED { return } cards, bInclude := isIncludeTheProject(cardList, i, suit) if !bInclude { return } cardList = removeCards(cardList, cards) projectList = append(projectList, SingleProject{ Type: i, Score: value_project[i], Cards: cards, taskScore: value_project_task[i], }) if bestType < i { bestType = i } } } p.CallProject = bestType p.Projects = projectList p.bakProjects = projectList } func (p *PlayerInfo) removeCard(card int) bool { for i := 0; i < len(p.HandCards); i++ { if p.HandCards[i] == card { p.HandCards = append(p.HandCards[:i], p.HandCards[i+1:]...) p.CurrentCard = card return true } } log.Release("PlayerInfo.removeCard %d not exist %v", card, p.HandCards) return false } func (p *PlayerInfo) clearHandCard() { p.HandCards = []int{} } func (p *PlayerInfo) addScore(mineScore int) { p.WinCardScore += mineScore p.WinCardChangeScore = mineScore } func (p *PlayerInfo) getProjectScore() int { score := 0 for i := 0; i < len(p.Projects); i++ { score += p.Projects[i].Score } return score } func (p *PlayerInfo) IsAllTrumpCard(trumpType int) bool { for i := 0; i < len(p.HandCards); i++ { if getCardType(p.HandCards[i]) != trumpType { return false } } return true } func (p *PlayerInfo) addEndScore(weScore int, endScore int, isBO1Win bool, bo1WinScore int) { if isBO1Win { p.TotalScore = bo1WinScore p.roundScores = append(p.roundScores, bo1WinScore) } else { p.TotalScore += weScore p.roundScores = append(p.roundScores, weScore) } p.FinalCalcScore = weScore p.TotalChangeScore = endScore } func (p *PlayerInfo) getTotalScore() int { return p.TotalScore } func (p *PlayerInfo) pointsToEndScore() { p.EndScore = p.getTotalScore() } func (p *PlayerInfo) dump(chairId int) { robot := "" if p.isRobot { robot = "ROBOT" } log.Debug(" ----Player [%d] chair [%d] enterGold:%d bet:%d %s", p.userID, chairId, p.enterGold, p.bet, robot) log.Debug(" HandCards%s ", getCardsHex(p.HandCards)) log.Debug(" LeftSendCards%s", getCardsHex(p.LeftSendCards)) log.Debug(" AutoOut[%v] LastAction[%d] Data[%d] CurrentCard[%d]", p.AutoOut, p.LastAction, p.LastActionData, p.CurrentCard) log.Debug(" CanGawah[%v] HaveBaloot[%v] IsCallBiggest[%v]", p.CanGawah, p.HaveBaloot, p.IsCallBiggest) log.Debug(" EndScore[%d] TotalScore[%d] WinCardScore[%d], WinCardChangeScore[%d], TotalChangeScore[%d], FinalCalcScore[%d]", p.EndScore, p.TotalScore, p.WinCardScore, p.WinCardChangeScore, p.TotalChangeScore, p.FinalCalcScore) log.Debug(" CanDoReshuffle[%v] ReshuffleAction[%d] IsReshuffleTime[%v]", p.CanDoReshuffle, p.ReshuffleAction, p.IsReshuffleTime) log.Debug(" CallProject:%d", p.CallProject) for i := 0; i < len(p.Projects); i++ { log.Debug(" %s", p.Projects[i].getProjectHex()) } ret := "PlayerAction:[ " for n := 0; n < len(p.CanAction); n++ { ret += fmt.Sprintf("%d", p.CanAction[n]) ret += " " } ret += "]" log.Debug(" %s", ret) log.Debug(" BigCards%s", getCardsHex(p.BigCards)) log.Debug(" winDoulingData:") for n := 0; n < len(p.Doublings); n++ { p.Doublings[n].dump() } if p.isControl { log.Debug(" ContorlType:%d", p.controlType) log.Debug(" controlDoubling:%d", p.controlDoubling) log.Debug(" averageDoubling:%d", p.averageDoubling) } log.Debug(" IsSurrender:%v", p.IsSurrender) log.Debug(" +++++++++++++++++") }