| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218 |
- package gamelogic
- import (
- "encoding/json"
- "math/rand"
- "sort"
- "bet24.com/log"
- "bet24.com/servers/games/baloot/config"
- ladder "bet24.com/servers/micros/ladderservice/proto"
- )
- type GameScene struct {
- Banker int // 庄家
- FirstActionChair int // 第一个操作的玩家,用作标识
- Phase int // 场景阶段
- PhaseIndex int // 场景阶段索引
- BuyChair int // 当前买牌玩家
- BuyAction int // 当前买公共牌动作
- FinalClub int // 最终模式
- WhoseTurn int // 当前轮到谁操作
- LastTurn int // 上个操作的玩家
- Players []PlayerInfo // 玩家信息
- userActions []userAction // 玩家动作用作回放数据
- tableId int // 桌子ID
- Index int // 场景索引
- GameIndex int // 第几局
- ScoreToWin int // 达到多少分就赢,负数表示打多少局
- PublicCard int // 本局公共牌
- RoundType int // 当前圈牌色
- RoundWinner int // 本圈赢家
- RoundIndex int // 第几轮出牌
- LeftSec int // 剩余时间
- BaseTimes int // 本轮倍数
- TrumpType int // 主牌花色,Sun或Ashkal模式下为CardType_Invalid
- IsBO1 bool // 本轮是否一局定胜负
- IsClose bool // 为true表示本局在每一轮第一个出牌时不能出主牌(除了手上全是主牌的情况)
- ShowAllCards bool // 是否要展示所有人的牌,用于玩家选择全部打出剩余牌的时候
- LastWinChair int // 最后一轮赢牌玩家
- DoublingDetails []DoublingData // 加倍详情
- GameOutCardHistory []int // 已出的牌
- CorrectMode int // 纠错模式
- SawaChair int // 做了Sawa的玩家
- CorrectResult int // 胜利结果
- CorrectCards []int // 纠错牌
- CorrectType int // 纠错类型
- CanCorrect bool // 能否质疑
- LeftSurrenderCount int // 剩余投降次数
- isCorrectEnd bool // 是否是纠错结束
- isEnterAshkal bool // 是否有人选过Ashkal
- reshuffleResult int // 进入重洗前的买牌结果
- reshufflePhase int // 进入重新前的场景阶段
- buyPhase int // 确定买牌阶段
- scoreHistory []perRoundScores
- currentRoundDoubling int
- maxDoublingTime int
- robotSendChatCount int
- robotSendChatMaxCount int
- robotChatList []robotChatAction
- statics []robotChatActionList
- isSendChat bool
- }
- func (gs *GameScene) addAction(chairId int, action int, data int) {
- gs.userActions = append(gs.userActions, userAction{ChairId: chairId, Action: action, Data: data})
- gs.Index++
- }
- func (gs *GameScene) addOutCardAction(chairId int, action int, data int, projects []int) {
- gs.userActions = append(gs.userActions, userAction{ChairId: chairId, Action: action, Data: data, ExtData: projects})
- gs.Index++
- gs.PhaseIndex++
- }
- func (gs *GameScene) addCorrectAction(chairId int, action int, correctType int, correctCards []int) {
- gs.userActions = append(gs.userActions, userAction{ChairId: chairId, Action: action, Data: correctType, ExtData: correctCards})
- gs.Index++
- }
- func newGameScene(tableId int, winpoint int, leftSurrenderCount int) *GameScene {
- gs := new(GameScene)
- gs.ctor()
- gs.Banker = rand.Intn(CHAIR_COUNT)
- gs.initData(tableId, winpoint, leftSurrenderCount)
- gs.GameIndex = 0
- gs.robotSendChatMaxCount = 12
- if winpoint == -1 {
- gs.robotSendChatMaxCount = 6
- }
- return gs
- }
- func (gs *GameScene) ctor() {
- gs.Players = make([]PlayerInfo, CHAIR_COUNT)
- for i := 0; i < CHAIR_COUNT; i++ {
- gs.Players[i].isEndToStart = false
- }
- }
- func (gs *GameScene) initData(tableId int, winpoint int, leftSurrenderCount int) {
- gs.userActions = []userAction{}
- gs.scoreHistory = []perRoundScores{}
- gs.LeftSurrenderCount = leftSurrenderCount
- gs.robotSendChatCount = 0
- gs.robotChatList = []robotChatAction{}
- gs.statics = []robotChatActionList{}
- // 比赛场海选赛打的一场,ScoreToWin为1,淘汰赛打三场,ScoreToWin为-3,
- // 做统一处理:当ScoreToWin<0时表示打多少场
- initScore := 0
- if winpoint <= 2 {
- if winpoint > 0 {
- winpoint = -winpoint
- }
- gs.ScoreToWin = winpoint
- } else {
- // gs.ScoreToWin = SCORE_TO_WIN
- // initScore = SCORE_TO_WIN - winpoint
- gs.ScoreToWin = winpoint
- }
- gs.Index = 0
- for i := 0; i < CHAIR_COUNT; i++ {
- gs.Players[i].initData(0, 0, initScore)
- }
- gs.tableId = tableId
- gs.maxDoublingTime = -1
- gs.gameInit(-1)
- }
- func (gs *GameScene) gameInit(whoseTurn int) {
- gs.BuyChair = -1
- gs.BuyAction = -1
- gs.Phase = Phase_Free
- gs.PhaseIndex = 0
- gs.WhoseTurn = whoseTurn
- gs.FirstActionChair = whoseTurn
- gs.LastTurn = -1
- gs.PublicCard = CARD_COUNT
- gs.RoundType = CardType_Invalid
- gs.RoundWinner = CHAIR_COUNT
- gs.GameOutCardHistory = []int{}
- gs.RoundIndex = 0
- gs.BaseTimes = 1
- gs.TrumpType = CardType_Invalid
- gs.IsBO1 = false
- gs.FinalClub = Suit_Invalid
- gs.IsClose = false
- gs.ShowAllCards = false
- gs.LastWinChair = -1
- gs.reshuffleResult = -1
- gs.reshufflePhase = Phase_Free
- gs.isCorrectEnd = false
- gs.isEnterAshkal = false
- gs.DoublingDetails = []DoublingData{}
- gs.CorrectMode = Correct_Invaild
- gs.SawaChair = CHAIR_COUNT
- gs.CorrectResult = -1
- gs.CorrectCards = []int{}
- gs.CanCorrect = false
- gs.buyPhase = Phase_FirstBuy
- gs.currentRoundDoubling = 0
- gs.isSendChat = false
- for i := 0; i < CHAIR_COUNT; i++ {
- gs.Players[i].gameInit()
- }
- }
- func (gs *GameScene) initAllPlayerLastAction() {
- for i := 0; i < CHAIR_COUNT; i++ {
- gs.Players[i].intLastAction()
- }
- }
- func (gs *GameScene) canDouble(chairId int) bool {
- return gs.Players[chairId].TotalScore > 100 && gs.Players[getNextChair(chairId)].TotalScore < 100
- }
- func (gs *GameScene) canDoubleInSun() bool {
- if gs.FinalClub == Suit_Hokum {
- return false
- }
- return gs.Players[gs.BuyChair].TotalScore > 100 && gs.Players[getNextChair(gs.BuyChair)].TotalScore < 100
- }
- func (gs *GameScene) checkProject(chairId int, projects []int) {
- gs.Players[chairId].analysisProject(projects, gs.FinalClub)
- }
- func (gs *GameScene) initAllPlayerTime() {
- for i := 0; i < CHAIR_COUNT; i++ {
- gs.Players[i].ininTime()
- }
- }
- func (gs *GameScene) isBuySunEnterDouble(buyAction, buyChairId int) bool {
- if buyAction != Action_Buy_Sun {
- return false
- }
- if gs.BuyAction == Action_Buy_Hokum {
- return false
- }
- if gs.isEnterAshkal && buyChairId != gs.FirstActionChair {
- return false
- }
- return gs.canDouble(buyChairId)
- }
- // 0 表示继续买牌或者直接进入double阶段,1表示结束买牌阶段,进入发剩余牌阶段
- func (gs *GameScene) resetBuyActionOfChangeBuyChair(buyAction, buyChairId int) int {
- // 先把做完买牌玩家可做动作清空
- gs.Players[buyChairId].setPlayerOperators([]int{})
- // 如果玩家选择pass且当前都没有人买牌
- if buyAction == Action_Buy_Pass {
- // 如果当前买牌的人为庄家,则进入第二次买牌阶段
- if buyChairId == gs.Banker && gs.Phase == Phase_FirstBuy {
- gs.Phase = Phase_SecondBuy
- gs.PhaseIndex = 0
- }
- gs.WhoseTurn = getPreviousChair(gs.WhoseTurn)
- for i := 0; i < CHAIR_COUNT; i++ {
- buyList := []int{}
- if i == gs.WhoseTurn {
- buyList = append(buyList, Action_Buy_Pass, Action_Buy_Hokum, Action_Buy_Sun)
- if i == gs.Banker || isPreviousChair(i, gs.Banker) {
- buyList = append(buyList, Action_Buy_Ashkal)
- }
- gs.Players[i].setPlayerOperators(buyList)
- } else {
- gs.Players[i].setPlayerOperators(buyList)
- }
- }
- return 0
- }
- // 如果玩家选择hokum
- if buyAction == Action_Buy_Hokum {
- gs.BuyAction = buyAction
- gs.BuyChair = buyChairId
- for i := 0; i < CHAIR_COUNT; i++ {
- buyList := []int{}
- if i == gs.BuyChair {
- continue
- }
- buyList = append(buyList, Action_Buy_Pass, Action_Buy_Sun)
- if i == gs.Banker || isPreviousChair(i, gs.Banker) {
- buyList = append(buyList, Action_Buy_Ashkal)
- }
- gs.Players[i].setPlayerOperators(buyList)
- gs.Players[i].intLastAction()
- }
- gs.WhoseTurn = -1
- return 0
- }
- // 如果玩家选择Action_Buy_Sun或者Action_Buy_Ashkal
- result := 1
- if buyAction == Action_Buy_Sun || buyAction == Action_Buy_Ashkal {
- if buyAction == Action_Buy_Ashkal {
- gs.isEnterAshkal = true
- }
- bOnlyOnePlayer := false
- isBeforeBuyHokum := (gs.BuyAction == Action_Buy_Hokum)
- if !isBeforeBuyHokum {
- bOnlyOnePlayer = true
- gs.BuyAction = buyAction
- gs.BuyChair = buyChairId
- for i := 0; i < CHAIR_COUNT; i++ {
- gs.Players[i].setPlayerOperators([]int{})
- }
- } else {
- result = 0
- if isFriendChair(gs.BuyChair, buyChairId) && buyAction == Action_Buy_Ashkal {
- result = 1
- gs.BuyAction = buyAction
- gs.BuyChair = buyChairId
- for i := 0; i < CHAIR_COUNT; i++ {
- gs.Players[i].setPlayerOperators([]int{})
- }
- bOnlyOnePlayer = true
- } else {
- for i := 0; i < CHAIR_COUNT; i++ {
- buyList := []int{}
- if i == gs.BuyChair {
- buyList = append(buyList, Action_Buy_Pass, Action_Buy_Sun)
- if (i == gs.Banker || isPreviousChair(i, gs.Banker)) && !gs.isEnterAshkal {
- buyList = append(buyList, Action_Buy_Ashkal)
- }
- if gs.BuyChair == getNextChair(buyChairId) {
- bOnlyOnePlayer = true
- }
- }
- gs.Players[i].setPlayerOperators(buyList)
- }
- gs.WhoseTurn = gs.BuyChair
- gs.BuyAction = buyAction
- gs.BuyChair = buyChairId
- }
- }
- buyList := []int{}
- buyList = append(buyList, Action_Buy_Pass, Action_Buy_Sun)
- if buyAction == Action_Buy_Ashkal {
- result = 0
- if bOnlyOnePlayer {
- gs.WhoseTurn = getNextChair(buyChairId)
- } else {
- gs.WhoseTurn = -1
- }
- gs.Players[getNextChair(buyChairId)].setPlayerOperators(buyList)
- }
- if gs.isEnterAshkal && buyAction == Action_Buy_Sun && buyChairId != gs.FirstActionChair {
- result = 0
- if bOnlyOnePlayer {
- gs.WhoseTurn = getNextChair(buyChairId)
- } else {
- gs.WhoseTurn = -1
- }
- gs.Players[getNextChair(buyChairId)].setPlayerOperators(buyList)
- }
- }
- if result == 1 {
- gs.setFinalSuit()
- gs.TrumpType = CardType_Invalid
- // sun模式下,判断玩家能不能买double
- if gs.canDoubleInSun() {
- for i := 0; i < CHAIR_COUNT; i++ {
- buyList := []int{}
- if isSameTeam(i, gs.BuyChair) {
- gs.Players[i].setPlayerOperators(buyList)
- continue
- }
- buyList = append(buyList, Action_Buy_Pass, Action_Buy_Double)
- gs.Players[i].setPlayerOperators(buyList)
- }
- gs.WhoseTurn = -1
- gs.Phase = Phase_Double
- gs.PhaseIndex = 0
- result = 0
- }
- }
- return result
- }
- func (gs *GameScene) isBuyChairWin() bool {
- if !isValidChair(gs.BuyChair) {
- return false
- }
- return gs.Players[gs.BuyChair].FinalCalcScore >= gs.Players[getNextChair(gs.BuyChair)].FinalCalcScore
- }
- func (gs *GameScene) isAllPlayerPass() bool {
- for i := 0; i < CHAIR_COUNT; i++ {
- if i == gs.BuyChair {
- continue
- }
- if !gs.Players[i].isBuyPass() {
- return false
- }
- }
- return true
- }
- func (gs *GameScene) isAllCanDoReshufflePlayerPass() bool {
- for i := 0; i < CHAIR_COUNT; i++ {
- if !gs.Players[i].CanDoReshuffle {
- continue
- }
- if gs.Players[i].ReshuffleAction != Reshuffle_Pass {
- return false
- }
- }
- return true
- }
- func (gs *GameScene) setFinalSuit() {
- switch gs.BuyAction {
- case Action_Buy_Hokum:
- gs.FinalClub = Suit_Hokum
- case Action_Buy_Sun:
- gs.FinalClub = Suit_Sun
- case Action_Buy_Ashkal:
- gs.FinalClub = Suit_Ashkal
- }
- }
- func (gs *GameScene) setBaseTimes(buyAction int) {
- if buyAction < Action_Buy_Double || buyAction > Action_Buy_Four {
- return
- }
- time := buyAction - Action_Buy_Double + 2
- if time < 2 {
- time = 2
- }
- gs.BaseTimes = time
- if gs.BaseTimes > 4 {
- gs.BaseTimes = 4
- }
- }
- func (gs *GameScene) havePlayerConfirmReshuffle(chairId int) bool {
- for i := 0; i < CHAIR_COUNT; i++ {
- if chairId == i {
- continue
- }
- if gs.Players[i].CanDoReshuffle && gs.Players[i].ReshuffleAction == Reshuffle_Confirm {
- return true
- }
- }
- return false
- }
- func (gs *GameScene) canReshuffle(buyAction, chairId int) bool {
- if buyAction <= Action_Buy_Pass {
- return false
- }
- for i := 0; i < CHAIR_COUNT; i++ {
- if gs.Players[i].CanDoReshuffle && gs.Players[i].ReshuffleAction > Reshuffle_None {
- return false
- }
- }
- canReshuffle := false
- for i := 0; i < CHAIR_COUNT; i++ {
- if i == chairId {
- continue
- }
- if gs.Players[i].needReshuffle() {
- canReshuffle = true
- }
- }
- return canReshuffle
- }
- func (gs *GameScene) isEnterReshuffle(buyAction int) bool {
- if buyAction <= Action_Buy_Pass {
- return false
- }
- for i := 0; i < CHAIR_COUNT; i++ {
- if gs.Players[i].CanDoReshuffle && gs.Players[i].ReshuffleAction > Reshuffle_None {
- return false
- }
- }
- canReshuffle := false
- for i := 0; i < CHAIR_COUNT; i++ {
- if i == gs.BuyChair {
- continue
- }
- if gs.Players[i].isAllZeroScoreCard() {
- canReshuffle = true
- }
- }
- if canReshuffle {
- gs.reshufflePhase = gs.Phase
- gs.Phase = Phase_Reshuffle
- gs.PhaseIndex = 0
- }
- return canReshuffle
- }
- func (gs *GameScene) isPlayerCanAction() bool {
- for i := 0; i < CHAIR_COUNT; i++ {
- if len(gs.Players[i].CanAction) > 0 {
- return true
- }
- }
- return false
- }
- // 0表示继续等待其他人操作,1表示进入选花色或者加倍阶段或者继续买牌二次确认阶段,2表示进入发剩余牌阶段
- func (gs *GameScene) resetBuyActionOfNotChangeBuyChair(buyChair, buyAction int) int {
- result := 0
- // 先把做完买牌玩家可做动作清空
- gs.Players[buyChair].setPlayerOperators([]int{})
- // 已经有人买牌,当前玩家没有抢牌
- if buyAction == Action_Buy_Pass {
- if !gs.isEnterAshkal {
- if gs.isAllPlayerPass() {
- for i := 0; i < CHAIR_COUNT; i++ {
- if i == buyChair {
- continue
- }
- gs.Players[i].setPlayerOperators([]int{})
- }
- if gs.BuyAction == Action_Buy_Hokum {
- buyList := []int{}
- buyList = append(buyList, Action_Buy_ConfirmHokum, Action_Buy_SwitchSun)
- gs.Players[gs.BuyChair].setPlayerOperators(buyList)
- gs.WhoseTurn = gs.BuyChair
- result = 1
- } else {
- gs.setFinalSuit()
- gs.TrumpType = CardType_Invalid
- result = 2
- }
- }
- } else {
- if !gs.isPlayerCanAction() {
- gs.setFinalSuit()
- gs.TrumpType = CardType_Invalid
- result = 2
- }
- }
- }
- if buyAction == Action_Buy_ConfirmHokum {
- result = 1
- gs.WhoseTurn = -1
- gs.setFinalSuit()
- if gs.Phase == Phase_SecondBuy {
- gs.Phase = Phase_ChooseTrump
- gs.PhaseIndex = 0
- gs.WhoseTurn = gs.BuyChair
- gs.Players[gs.BuyChair].setPlayerOperators([]int{})
- return result
- }
- gs.TrumpType = getCardType(gs.PublicCard)
- for i := 0; i < CHAIR_COUNT; i++ {
- sort.Slice(gs.Players[i].HandCards, func(m, n int) bool {
- return getCardSortValue(gs.Players[i].HandCards[m], gs.TrumpType) <
- getCardSortValue(gs.Players[i].HandCards[n], gs.TrumpType)
- })
- buyList := []int{}
- if isSameTeam(i, gs.BuyChair) {
- gs.Players[i].setPlayerOperators(buyList)
- continue
- }
- buyList = append(buyList, Action_Buy_Pass, Action_Buy_Double)
- gs.Players[i].setPlayerOperators(buyList)
- }
- gs.initAllPlayerLastAction()
- gs.Phase = Phase_Double
- gs.PhaseIndex = 0
- }
- if buyAction == Action_Buy_SwitchSun {
- for i := 0; i < CHAIR_COUNT; i++ {
- gs.Players[i].setPlayerOperators([]int{})
- }
- gs.BuyAction = Action_Buy_Sun
- gs.TrumpType = CardType_Invalid
- gs.setFinalSuit()
- result = 2
- }
- if result == 2 && gs.FinalClub != Suit_Hokum {
- if gs.canDoubleInSun() {
- for i := 0; i < CHAIR_COUNT; i++ {
- buyList := []int{}
- if isSameTeam(i, gs.BuyChair) {
- gs.Players[i].setPlayerOperators(buyList)
- continue
- }
- buyList = append(buyList, Action_Buy_Pass, Action_Buy_Double)
- gs.Players[i].setPlayerOperators(buyList)
- }
- gs.WhoseTurn = -1
- gs.Phase = Phase_Double
- gs.PhaseIndex = 0
- result = 1
- }
- }
- return result
- }
- func (gs *GameScene) setNextBanker() {
- for i := 1; i < CHAIR_COUNT; i++ {
- next := (gs.Banker + CHAIR_COUNT - i) % CHAIR_COUNT
- if gs.Players[next].IsValid {
- gs.Banker = next
- break
- }
- }
- }
- // 本圈已出牌人数
- func (gs *GameScene) getRoundOutedPlayerCount() int {
- outedCount := 0
- for _, v := range gs.Players {
- if v.CurrentCard != CARD_COUNT {
- outedCount++
- }
- }
- return outedCount
- }
- func (gs *GameScene) isRoundEnd() bool {
- return gs.getRoundOutedPlayerCount() == CHAIR_COUNT
- }
- func (gs *GameScene) nextChair() {
- gs.LastTurn = gs.WhoseTurn
- gs.WhoseTurn = getPreviousChair(gs.LastTurn)
- }
- // 获取本圈玩家出牌
- func (gs *GameScene) getRoundCards() []int {
- ret := make([]int, CHAIR_COUNT)
- for i := 0; i < CHAIR_COUNT; i++ {
- ret[i] = gs.Players[i].CurrentCard
- }
- return ret
- }
- func (gs *GameScene) endAOutCardRound(winner int) int {
- winScore := 0
- for i := 0; i < CHAIR_COUNT; i++ {
- score := getCardPoint(gs.Players[i].CurrentCard, gs.TrumpType)
- winScore += score
- gs.Players[i].CurrentCard = CARD_COUNT
- gs.Players[i].BigCards = []int{}
- }
- gs.Players[winner].winCardScore += winScore
- for i := 0; i < CHAIR_COUNT; i++ {
- if isSameTeam(i, winner) {
- gs.Players[i].addScore(winScore)
- } else {
- gs.Players[i].addScore(0)
- }
- }
- gs.Players[winner].WinCardNumber += 4
- gs.RoundWinner = winner
- gs.WhoseTurn = -1
- gs.addAction(-1, Action_RoundEnd, gs.RoundType)
- return winScore
- }
- // 本局是否已结束
- func (gs *GameScene) isGameEnd() bool {
- for _, v := range gs.Players {
- if len(v.HandCards) > 0 {
- return false
- }
- }
- return true
- }
- func (gs *GameScene) newOutCardRound() {
- gs.RoundIndex++
- gs.RoundType = CardType_Invalid
- if !isValidChair(gs.RoundWinner) {
- log.Debug("Wrong RoundWinner:%d", gs.RoundWinner)
- return
- }
- if !gs.ShowAllCards {
- for i := 0; i < CHAIR_COUNT; i++ {
- gs.Players[i].CurrentCard = CARD_COUNT
- }
- } else {
- gs.ShowAllCards = false
- }
- if gs.isGameEnd() {
- gs.LastWinChair = gs.RoundWinner
- }
- if gs.RoundIndex == 2 {
- gs.compareProject()
- }
- for i := 0; i < CHAIR_COUNT; i++ {
- gs.Players[i].CallProject = PROJECT_INVALID
- gs.Players[i].IsCallBiggest = false
- }
- gs.LastTurn = -1
- gs.WhoseTurn = gs.RoundWinner
- gs.RoundWinner = CHAIR_COUNT
- }
- func (gs *GameScene) checkCanGawah() {
- handLen := len(gs.Players[gs.WhoseTurn].HandCards)
- if handLen <= 1 || handLen == 8 {
- gs.Players[gs.WhoseTurn].CanGawah = false
- return
- }
- gs.Players[gs.WhoseTurn].CanGawah = checkCanGawah(gs.getAllPlayerCards(), gs.WhoseTurn, gs.TrumpType)
- }
- func (gs *GameScene) compareProject() {
- buyProject := []SingleProject{}
- playerProject := []SingleProject{}
- for i := 0; i < CHAIR_COUNT; i++ {
- if gs.Players[i].CallProject == PROJECT_INVALID || len(gs.Players[i].Projects) == 0 {
- continue
- }
- if isSameTeam(i, gs.BuyChair) {
- buyProject = append(buyProject, gs.Players[i].Projects[0])
- } else {
- playerProject = append(playerProject, gs.Players[i].Projects[0])
- }
- }
- if len(buyProject) == 0 || len(playerProject) == 0 {
- return
- }
- // 从大到小排序
- sort.Slice(buyProject, func(i, j int) bool {
- return buyProject[i].isBiggerThan(buyProject[j])
- })
- sort.Slice(playerProject, func(i, j int) bool {
- return playerProject[i].isBiggerThan(playerProject[j])
- })
- isBuyBig := buyProject[0].isBiggerThan(playerProject[0])
- for i := 0; i < CHAIR_COUNT; i++ {
- if gs.Players[i].CallProject == PROJECT_INVALID {
- continue
- }
- if isSameTeam(i, gs.BuyChair) {
- if !isBuyBig {
- gs.Players[i].Projects = []SingleProject{}
- }
- } else {
- if isBuyBig {
- gs.Players[i].Projects = []SingleProject{}
- }
- }
- }
- }
- func (gs *GameScene) gameEnd() {
- gs.Phase = Phase_GameEnd
- gs.PhaseIndex = 0
- scores := make([]int, CHAIR_COUNT)
- // 这里计算Buy方和player方得分
- buyPoint := 0
- playerPoint := 0
- for i := 0; i < CHAIR_COUNT; i++ {
- if isSameTeam(i, gs.BuyChair) {
- buyPoint += gs.Players[i].getProjectScore()
- } else {
- playerPoint += gs.Players[i].getProjectScore()
- }
- }
- if !isValidCard(gs.BuyChair) {
- log.Debug("Serious Error Buy Chair:%d", gs.BuyChair)
- return
- }
- buyWinCardScore := gs.Players[gs.BuyChair].WinCardScore
- playerWinCardScore := gs.Players[getNextChair(gs.BuyChair)].WinCardScore
- buyPoint += gs.Players[gs.BuyChair].WinCardScore
- playerPoint += gs.Players[getNextChair(gs.BuyChair)].WinCardScore
- gs.Players[gs.LastWinChair].winCardScore += LAST_WIN_SCORE
- if isSameTeam(gs.BuyChair, gs.LastWinChair) {
- buyPoint += LAST_WIN_SCORE
- buyWinCardScore += LAST_WIN_SCORE
- } else {
- playerPoint += LAST_WIN_SCORE
- playerWinCardScore += LAST_WIN_SCORE
- }
- buyAbnat := buyPoint
- playerAbnat := playerPoint
- // 如果买的一方输的情况
- if (buyPoint == playerPoint && (gs.BaseTimes > 1 || gs.IsBO1)) || buyPoint < playerPoint {
- playerPoint += buyPoint
- if gs.Players[gs.BuyChair].WinCardScore == 0 && !gs.isCorrectEnd {
- playerPoint += ALL_WIN_EXTRA_SCORE
- }
- buyPoint = 0
- } else {
- if gs.Players[getNextChair(gs.BuyChair)].WinCardScore == 0 && !gs.isCorrectEnd {
- buyPoint += ALL_WIN_EXTRA_SCORE
- playerPoint = 0
- }
- if gs.IsBO1 || gs.BaseTimes > 1 {
- buyPoint += playerAbnat
- playerPoint = 0
- }
- }
- finalBuyPoint := calcFinalPonit(buyPoint)
- finalPlayerPoint := calcFinalPonit(playerPoint)
- if gs.FinalClub != Suit_Hokum {
- finalBuyPoint *= 2
- finalPlayerPoint *= 2
- if buyWinCardScore%10 == 5 && playerWinCardScore%10 == 5 && buyPoint > 0 && playerPoint > 0 {
- finalBuyPoint++
- finalPlayerPoint++
- }
- } else {
- if buyWinCardScore%10 == 6 && playerWinCardScore%10 == 6 && buyPoint > 0 && playerPoint > 0 {
- finalPlayerPoint--
- }
- }
- finalBuyPoint *= gs.BaseTimes
- finalPlayerPoint *= gs.BaseTimes
- for i := 0; i < CHAIR_COUNT; i++ {
- if isSameTeam(i, gs.BuyChair) {
- scores[i] = finalBuyPoint
- } else {
- scores[i] = finalPlayerPoint
- }
- }
- var scoreData = 0
- for i := 0; i < CHAIR_COUNT; i++ {
- scoreData += int(scores[i])
- if i != CHAIR_COUNT-1 {
- scoreData *= 1000
- }
- }
- isBuyChairBO1Win := false
- isPlayerBO1Win := false
- if gs.IsBO1 {
- isBuyChairBO1Win = (finalBuyPoint > finalPlayerPoint)
- if isBuyChairBO1Win {
- finalPlayerPoint = 0
- } else {
- finalBuyPoint = 0
- isPlayerBO1Win = true
- }
- }
- totalTimes := gs.getDoublingTotalTimes()
- if totalTimes > 1 {
- gs.currentRoundDoubling = totalTimes
- }
- gs.userActions = append(gs.userActions, userAction{ChairId: -1, Action: Action_GameEnd, Data: scoreData})
- for i := 0; i < CHAIR_COUNT; i++ {
- if isSameTeam(i, gs.BuyChair) {
- gs.Players[i].addEndScore(finalBuyPoint, buyAbnat, isBuyChairBO1Win, SCORE_TO_WIN)
- if finalBuyPoint >= finalPlayerPoint && totalTimes > 1 {
- gs.Players[i].addDoublingData(gs.GameIndex, totalTimes)
- }
- } else {
- gs.Players[i].addEndScore(finalPlayerPoint, playerAbnat, isPlayerBO1Win, SCORE_TO_WIN)
- if finalBuyPoint < finalPlayerPoint && totalTimes > 1 {
- gs.Players[i].addDoublingData(gs.GameIndex, totalTimes)
- }
- }
- }
- gs.WhoseTurn = -1
- }
- func (gs *GameScene) getDoublingTotalTimes() int {
- totalTimes := 1
- for n := 0; n < len(gs.DoublingDetails); n++ {
- totalTimes *= gs.DoublingDetails[n].DoublingTimes
- }
- return totalTimes
- }
- func (gs *GameScene) isPlayerWinInQuickGame(chairId int) bool {
- if gs.Players[chairId].FinalCalcScore < gs.Players[getNextChair(chairId)].FinalCalcScore {
- return false
- }
- if gs.Players[chairId].FinalCalcScore == gs.Players[getNextChair(chairId)].FinalCalcScore &&
- !isSameTeam(chairId, gs.BuyChair) {
- return false
- }
- return true
- }
- func (gs *GameScene) isFirstOutCardInCloseMode() bool {
- return gs.FinalClub == Suit_Hokum && gs.RoundType == CardType_Invalid && gs.IsClose
- }
- func (gs *GameScene) isGameFinish() bool {
- if gs.IsBO1 && gs.ScoreToWin > 0 {
- return true
- }
- // ScoreToWin小于0表示大多少局结束
- if gs.ScoreToWin < 0 {
- if (gs.ScoreToWin + gs.GameIndex) >= -1 {
- return true
- }
- } else {
- for i := 0; i < CHAIR_COUNT; i++ {
- if gs.Players[i].getTotalScore() >= gs.ScoreToWin &&
- gs.Players[i].getTotalScore() != gs.Players[getNextChair(i)].getTotalScore() {
- return true
- }
- }
- }
- return false
- }
- // 如果已经要结算了,在返回FALSE
- func (gs *GameScene) nextGame(isSurrenderFinish bool) bool {
- if isSurrenderFinish {
- return false
- }
- gs.GameIndex++
- if gs.IsBO1 && gs.ScoreToWin > 0 {
- return false
- }
- // ScoreToWin小于0表示大多少局结束
- if gs.ScoreToWin < 0 {
- if (gs.ScoreToWin + gs.GameIndex) >= 0 {
- return false
- }
- } else {
- for i := 0; i < CHAIR_COUNT; i++ {
- if gs.Players[i].getTotalScore() >= gs.ScoreToWin &&
- gs.Players[i].getTotalScore() != gs.Players[getNextChair(i)].getTotalScore() {
- return false
- }
- }
- }
- gs.setNextBanker()
- gs.gameInit(getPreviousChair(gs.Banker))
- return true
- }
- func (gs *GameScene) getWinner() []int {
- var ret []int
- var biggestScore int = -10000
- biggestChair := CHAIR_COUNT
- for i := 0; i < CHAIR_COUNT; i++ {
- if !gs.Players[i].IsValid {
- continue
- }
- chairScore := gs.Players[i].getTotalScore()
- if biggestChair == CHAIR_COUNT || chairScore > biggestScore {
- biggestChair = i
- biggestScore = chairScore
- }
- }
- for i := 0; i < CHAIR_COUNT; i++ {
- if !gs.Players[i].IsValid {
- continue
- }
- if gs.Players[i].getTotalScore() == biggestScore {
- ret = append(ret, i)
- }
- }
- if len(ret) == CHAIR_COUNT {
- ret = []int{}
- for i := 0; i < CHAIR_COUNT; i++ {
- if !gs.Players[i].IsValid {
- continue
- }
- if isSameTeam(i, gs.BuyChair) {
- ret = append(ret, i)
- }
- }
- }
- return ret
- }
- func (gs *GameScene) pointsToEndScore() {
- for i := 0; i < CHAIR_COUNT; i++ {
- if !gs.Players[i].IsValid {
- continue
- }
- gs.Players[i].pointsToEndScore()
- }
- }
- func (gs *GameScene) initMaxDoubling(isDoublingMode bool) {
- if !isDoublingMode || gs.Players[0].enterGold == 0 || gs.Players[0].bet == 0 {
- return
- }
- maxTimes := gs.Players[0].enterGold / gs.Players[0].bet
- for i := 1; i < CHAIR_COUNT; i++ {
- times := gs.Players[i].enterGold / gs.Players[i].bet
- if maxTimes > times {
- maxTimes = times
- }
- }
- gs.maxDoublingTime = maxTimes
- }
- func (gs *GameScene) getTotalBet(winner int) int {
- ret := 0
- baseTimes := 0
- for n := 0; n < len(gs.Players[winner].Doublings); n++ {
- baseTimes += gs.Players[winner].Doublings[n].DoublingTotalTimes
- }
- if baseTimes > gs.maxDoublingTime && gs.maxDoublingTime != -1 {
- baseTimes = gs.maxDoublingTime
- }
- for i := 0; i < CHAIR_COUNT; i++ {
- if !gs.Players[i].IsValid {
- continue
- }
- playerBet := gs.Players[i].bet
- if baseTimes > 0 && !isSameTeam(winner, i) {
- playerBet *= baseTimes
- gs.Players[i].EndScore = gs.Players[i].bet - playerBet
- }
- ret += playerBet
- }
- return ret
- }
- func (gs *GameScene) getValidUserCount() int {
- ret := 0
- for i := 0; i < CHAIR_COUNT; i++ {
- if gs.Players[i].IsValid {
- ret++
- }
- }
- return ret
- }
- func (gs *GameScene) getUserCount() int {
- ret := 0
- for i := 0; i < CHAIR_COUNT; i++ {
- if !gs.Players[i].isRobot {
- ret++
- }
- }
- return ret
- }
- func (gs *GameScene) getControlRobot() int {
- team1RobotCount := 0
- team2RobotCount := 0
- for i := 0; i < CHAIR_COUNT; i++ {
- if gs.Players[i].isRobot && isSameTeam(i, 0) {
- team1RobotCount++
- }
- if gs.Players[i].isRobot && isSameTeam(i, 1) {
- team2RobotCount++
- }
- }
- if team1RobotCount == team2RobotCount {
- return -1
- }
- controlRobot := -1
- if team1RobotCount > team2RobotCount {
- for i := 0; i < CHAIR_COUNT; i++ {
- if gs.Players[i].isRobot && isSameTeam(i, 0) {
- controlRobot = i
- break
- }
- }
- } else {
- for i := 0; i < CHAIR_COUNT; i++ {
- if gs.Players[i].isRobot && isSameTeam(i, 1) {
- controlRobot = i
- break
- }
- }
- }
- return controlRobot
- }
- func (gs *GameScene) dump(includeAction bool) {
- log.Debug("====GameScene Table[%d] Index[%d] GameIndex[%d] ScoreToWin[%d]====",
- gs.tableId, gs.Index, gs.GameIndex, gs.ScoreToWin)
- log.Debug(" Phase[%s],PhaseIndex[%d],BuyChair[%d], WhoseTurn[%d],LastTurn[%d],Banker[%d],FirstActionChair[%d]",
- getPhaseDesc(gs.Phase), gs.PhaseIndex, gs.BuyChair, gs.WhoseTurn, gs.LastTurn, gs.Banker, gs.FirstActionChair)
- log.Debug(" BuyAction[%d],FinalClub[%s],RoundType[%d],RoundIndex[%d], RoundWinner[%d]",
- gs.BuyAction, getSuitDesc(gs.FinalClub), gs.RoundType, gs.RoundIndex, gs.RoundWinner)
- log.Debug(" PublicCard[%s],BaseTimes[%d],TrumpType[%d],IsBO1[%v],IsClose[%v], ShowAllCards[%v], LastWinChair[%d]",
- getCardHex(gs.PublicCard), gs.BaseTimes, gs.TrumpType, gs.IsBO1, gs.IsClose, gs.ShowAllCards, gs.LastWinChair)
- log.Debug(" reshuffleResult[%d], reshufflePhase[%d]", gs.reshuffleResult, gs.reshufflePhase)
- log.Debug(" isCorrectEnd[%v], isEnterAshkal[%v]", gs.isCorrectEnd, gs.isEnterAshkal)
- log.Debug(" GameOutCardHistory%s", getCardsHex(gs.GameOutCardHistory))
- log.Debug(" CorrectMode[%s], SawaChair[%d], CorrectResult[%d], CorrectCards%s, CorrectType[%s], CanCorrect[%v]",
- getCorrectModeDesc(gs.CorrectMode), gs.SawaChair, gs.CorrectResult, getCardsHex(gs.CorrectCards),
- getCorrectTypeDesc(gs.CorrectType), gs.CanCorrect)
- log.Debug(" doublingDetails:")
- for n := 0; n < len(gs.DoublingDetails); n++ {
- gs.DoublingDetails[n].dump()
- }
- log.Debug(" Users:%d", gs.getValidUserCount())
- for i := 0; i < CHAIR_COUNT; i++ {
- gs.Players[i].dump(i)
- }
- if includeAction && len(gs.userActions) > 0 {
- log.Debug(" Actions:%d", len(gs.userActions))
- for _, v := range gs.userActions {
- v.dump()
- }
- }
- log.Debug("---------------------------")
- }
- func (gs *GameScene) getPlayerLadderInfo() string {
- type GameUserLadderInfo struct {
- UserID int
- LadderInfo ladder.UserLadderInfo
- }
- var ret []GameUserLadderInfo
- for i := 0; i < CHAIR_COUNT; i++ {
- if gs.Players[i].userID == 0 {
- continue
- }
- ret = append(ret, GameUserLadderInfo{
- UserID: gs.Players[i].userID,
- LadderInfo: gs.Players[i].LadderInfo,
- })
- }
- d, _ := json.Marshal(ret)
- return string(d)
- }
- func (gs *GameScene) getCopy() GameScene {
- var ret GameScene
- d, _ := json.Marshal(gs)
- json.Unmarshal(d, &ret)
- return ret
- }
- func (gs *GameScene) getScene(chairId int, isPlayer bool, isOwnerWatCh bool) string {
- tmp := gs.getCopy()
- if gs.Phase == Phase_GameEnd && gs.ScoreToWin < -1 && (gs.ScoreToWin+gs.GameIndex) < -1 && config.Server.IsLadderRoom == 1 {
- tmp.Phase = Phase_End
- }
- if isOwnerWatCh {
- /*for i := 0; i < CHAIR_COUNT; i++ {
- tmp.Players[i].hideSecretData()
- }*/
- d, _ := json.Marshal(tmp)
- return string(d)
- }
- for i := 0; i < CHAIR_COUNT; i++ {
- if gs.Phase == Phase_End || gs.Phase == Phase_GameEnd {
- continue
- }
- if gs.ShowAllCards {
- continue
- }
- if gs.Players[i].CanDoReshuffle && gs.Players[i].ReshuffleAction == Reshuffle_Confirm && gs.Phase == Phase_Reshuffle {
- continue
- }
- if chairId == i {
- continue
- }
- tmp.Players[i].hideSecretData()
- tmp.Players[i].ProjectTips = []int{0, 0, 0, 0}
- }
- d, _ := json.Marshal(tmp)
- return string(d)
- }
- func (gs *GameScene) getAllPlayerCards() [][]int {
- var ret [][]int
- for i := 0; i < CHAIR_COUNT; i++ {
- ret = append(ret, gs.Players[i].HandCards)
- }
- return ret
- }
- func (gs *GameScene) onAllCardsSent() {
- // 插入所有玩家的牌
- for i := 0; i < CHAIR_COUNT; i++ {
- cardList := make([]int, len(gs.Players[i].HandCards))
- copy(cardList, gs.Players[i].HandCards)
- gs.userActions = append(gs.userActions, userAction{
- ChairId: i,
- Action: Action_RoundStart,
- Data: 0,
- ExtData: cardList,
- })
- }
- }
- func (gs *GameScene) getLeftScore() int {
- leftScore := 0
- if gs.FinalClub == Suit_Hokum {
- leftScore = HOKUM_TOTAL_SCORE - gs.Players[0].WinCardScore - gs.Players[1].WinCardScore
- } else {
- leftScore = SUN_TOTAL_SCORE - gs.Players[0].WinCardScore - gs.Players[1].WinCardScore
- }
- return leftScore
- }
- func (gs *GameScene) getLeftCardNumber() int {
- leftCard := CARD_COUNT
- for i := 0; i < CHAIR_COUNT; i++ {
- leftCard -= gs.Players[i].WinCardNumber
- }
- return leftCard
- }
|