From fb52115883b2fc0de78ac331b9b86e6e8e541b2b Mon Sep 17 00:00:00 2001 From: tangmingyou <234767776@qq.com> Date: Tue, 14 Feb 2023 18:00:40 +0800 Subject: [PATCH] betting logic --- api/poker.proto | 6 +- internal/game/player.go | 35 +++++++- internal/game/table.go | 165 ++++++++++++++++++++++++++---------- internal/service/table.go | 171 ++++++++++++++++++-------------------- 4 files changed, 236 insertions(+), 141 deletions(-) diff --git a/api/poker.proto b/api/poker.proto index 9662074..1d59f66 100644 --- a/api/poker.proto +++ b/api/poker.proto @@ -130,7 +130,6 @@ message ResGameFullStatus { // 玩家当前游戏状态: 断线,重新登录.... int32 tableNo = 2; // 所在桌面编号 int32 gameStage = 3; // 游戏阶段? int32 chip = 4; // 牌桌筹码 - int32 roundTimes = 5; // 回合次数 int64 playerId = 6; // 当前玩家id int32 bigBlindPos = 7; // 大盲注位 int32 smallBlindPos = 8; // 小盲注位 @@ -204,3 +203,8 @@ message ResGameEndSettle { message ResCalcWinnerChip { map playersWinChip = 9; } + +// 回合数变化时响应消息,前端等发牌动画结束后放开操作 +message ResGameNextRound { + int32 round = 1; +} diff --git a/internal/game/player.go b/internal/game/player.go index ef764f5..17bd172 100644 --- a/internal/game/player.go +++ b/internal/game/player.go @@ -5,6 +5,10 @@ import ( "texas-poker-bk/internal/letter" ) +var ( + emptyOpts = make([]int32, 0) +) + // Player 游戏玩家 type Player struct { PosIndex int // 座位索引 @@ -15,7 +19,7 @@ type Player struct { Cards [2]*Card // 手牌 Chip int32 // 玩家筹码 TotalBetChip int32 // 本次游戏已下注筹码 - Status int32 // 状态: 1待准备开始,2已准备开始,3等待其他玩家动作,4第一回合小盲注跟注, [5待大盲注,5待小盲注,] 6待跟注,7已弃牌 + Status int32 // 状态: 1待准备开始,2已准备开始,3等待其他玩家动作,[4第一回合小盲注跟注,5待大盲注,5待小盲注,] 6待跟注,7已弃牌 LastStatus int32 // 变化前一个状态 BetOpts []int32 // status=[4,6]时下注可操作按钮: 1跟注,2加注(-[0]+),3All-In,4弃牌,5过牌 BetMin int32 // 最低下注额 @@ -39,18 +43,43 @@ func (p *Player) RoundInit() { p.SetStatus(1) p.BetMin = 0 p.BetMax = 0 - p.BetOpts = make([]int32, 0) + p.BetOpts = emptyOpts p.TotalBetChip = 0 p.Hand = nil p.Cards[0] = nil p.Cards[1] = nil - p.RoundInit() +} + +// WaitBet 将状态置为:3等待下注 +func (p *Player) WaitBet() { + if p.Status == 7 { + return + } + p.SetStatus(3) + p.BetOpts = emptyOpts + p.BetMin = 0 + p.BetMax = 0 } func (p *Player) SetStatus(status int32) { p.StatusLock.Lock() defer p.StatusLock.Unlock() + switch status { + case 1: + fallthrough + case 2: + fallthrough + case 3: // 等待其他玩家 + fallthrough + case 7: // 弃牌 + p.BetMin = 0 + p.BetMax = 0 + if len(p.BetOpts) > 0 { + p.BetOpts = emptyOpts + } + } + p.LastStatus = p.Status p.Status = status } diff --git a/internal/game/table.go b/internal/game/table.go index edcbba1..555cd27 100644 --- a/internal/game/table.go +++ b/internal/game/table.go @@ -9,10 +9,10 @@ import ( ) type Table struct { - TableNo int32 // 牌桌编号 - MasterId int64 // 房主Id - RoundTimes int32 // 回合次数 - Stage int32 // 游戏阶段: 1等待玩家准备;2游戏开始(自动扣大小盲注,发牌,轮流下注) [2(开始发牌)下大盲注;3下小盲注;4发公共牌;] 5发第四张公共牌,轮流下注;6发第五张公共牌,轮流下注,7比牌结算,9已解散 + TableNo int32 // 牌桌编号 + MasterId int64 // 房主Id + GameTimes int32 // 游戏次数 + Stage int32 // 游戏阶段: 1等待玩家准备;2游戏开始(自动扣大小盲注,发手牌,轮流下注); 3:发3张公共牌 4:发第四张公共牌,轮流下注;5:发第五张公共牌,轮流下注,7比牌结算,9已解散 Chip int32 // 牌桌当前筹码 robotChip int32 // 牌桌当前机器人下注筹码 @@ -33,8 +33,8 @@ type Table struct { LastPosBetChip int32 // 上家下注金额 RoundRaiseTimes int32 // 该轮押注圈加注次数 + Lock *sync.Mutex // 牌桌锁 PlayersLock *sync.Mutex - ChipLock *sync.Mutex // 桌面筹码更新锁 // TODO game logs7 } @@ -43,8 +43,8 @@ func (t *Table) InitGameAndPlayerStatus() { if t.PlayersLock == nil { t.PlayersLock = &sync.Mutex{} } - if t.ChipLock == nil { - t.ChipLock = &sync.Mutex{} + if t.Lock == nil { + t.Lock = &sync.Mutex{} } t.PublicCards = [5]*Card{nil, nil, nil, nil, nil} if t.Dealer == nil { @@ -92,8 +92,9 @@ func (t *Table) NextPlayerPos(current int) int { // NextHoldingCardPlayerPos 下一个未弃牌玩家 func (t *Table) NextHoldingCardPlayerPos(current int) int { + nextPos := current for i := 0; i < 999; i++ { - nextPos := t.NextPlayerPos(current) + nextPos = t.NextPlayerPos(nextPos) if nextPos == current { return current } @@ -133,7 +134,6 @@ func (t *Table) BuildResGameFullStatus() *api.ResGameFullStatus { TableNo: t.TableNo, GameStage: t.Stage, Chip: t.Chip, - RoundTimes: t.RoundTimes, BigBlindPos: int32(t.BigBlindPos), SmallBlindPos: int32(t.SmallBlindPos), } @@ -172,13 +172,15 @@ func (t *Table) BuildResGameFullStatus() *api.ResGameFullStatus { BetOpts: p.BetOpts, }, } - // 玩家手牌 - for j, card := range p.Cards { - if card == nil { - player.HandCard[j] = nil - continue + // 未到结算时不展示其他玩家手牌 + if !collect.In(t.Stage, 7, 9) { + for j, card := range p.Cards { + if card == nil { + player.HandCard[j] = nil + continue + } + player.HandCard[j] = &api.Card{Dot: int32(card.Dot), Suit: CardColors[card.Suit]} } - player.HandCard[j] = &api.Card{Dot: int32(card.Dot), Suit: CardColors[card.Suit]} } resGame.Players[i] = player } @@ -215,37 +217,16 @@ func (t *Table) NoticeAllPlayer(message proto.Message) { // RoundOver 当前回合结束 func (t *Table) RoundOver() error { // 游戏结束,开牌结算 - if t.RoundTimes >= 4 || 1 == len(collect.Filter(t.Players, func(i int, p *Player) bool { + if t.Stage == 5 || 1 == len(collect.Filter(t.Players, func(i int, p *Player) bool { return p != nil && p.Status != 7 })) { return t.cardFightAndSettle() } - // 开启下一回合, 重置一些状态 - t.RoundRaiseTimes = 0 - t.RoundTimes++ - for _, p := range t.Players { - if p != nil { - p.RoundBetTimes = 0 - p.TotalBetChip = 0 - p.BetMin = 0 - p.BetMax = 0 - p.BetOpts = []int32{} - p.SetStatus(3) - } - } - // 由小盲注或小盲注后第一个未弃牌玩家开始 - nextBegin := t.SmallBlindPos - if t.Players[t.SmallBlindPos].Status == 7 { - nextBegin = t.NextHoldingCardPlayerPos(nextBegin) - } - begin := t.Players[nextBegin] - begin.SetStatus(6) - begin.BetOpts = []int32{1, 2, 4, 5} - - // 根据回合发公共牌 - switch t.RoundTimes { + // 开启下一回合, 根据回合发公共牌 + switch t.Stage { case 2: // 发3张公共牌(翻牌) + t.Stage = 3 for i := 0; i < 5; i++ { if i < 3 { t.PublicCards[i] = t.Dealer.Deal() @@ -255,23 +236,115 @@ func (t *Table) RoundOver() error { t.PublicCards[i] = nil } case 3: // 发第4张公共牌(转牌turn) + t.Stage = 4 t.PublicCards[3] = t.Dealer.Deal() - t.Stage = 5 case 4: // 发第5张公共牌(河牌river) + t.Stage = 5 t.PublicCards[4] = t.Dealer.Deal() - t.Stage = 6 } + + // 重置一些状态 + t.RoundRaiseTimes = 0 + for _, p := range t.Players { + if p != nil { + p.RoundBetTimes = 0 + p.WaitBet() + } + } + // 由小盲注或小盲注后第一个未弃牌玩家开始 + nextPos := t.SmallBlindPos + if t.Players[t.SmallBlindPos].Status == 7 { + nextPos = t.NextHoldingCardPlayerPos(nextPos) + } + nextPlayer := t.Players[nextPos] + nextPlayer.SetStatus(6) + nextPlayer.BetOpts = []int32{1, 2, 4, 5} + return nil } +// SetNextPlayerWithRoundStart 回合开始, 设置下一个下注玩家 +func (t *Table) SetNextPlayerWithRoundStart() { + nextPos := t.SmallBlindPos + if t.Stage == 2 { // TODO 第一回合第一轮由大盲注后一个玩家下注 + nextPos = t.NextPlayerPos(t.BigBlindPos) + } + if t.Players[nextPos].Status == 7 { + nextPos = t.NextHoldingCardPlayerPos(nextPos) + } + // 重置其他玩家状态为等待 + for _, p := range t.Players { + if p == nil || p.Status == 7 { + continue + } + if p.PosIndex != nextPos { + p.WaitBet() + } + } + + nextP := t.Players[nextPos] + nextP.SetStatus(6) + nextP.BetOpts = []int32{2, 4} + nextP.BetMin = t.BigBlindChip + + switch t.TexasType { + case 2: // 底池限注 + nextP.BetMax = t.Chip + t.LastPosBetChip*2 + case 3: // 无限注 + nextP.BetOpts = append(nextP.BetOpts, 3) // 可 all in + nextP.BetMax = -1 + case 1: // 限注 + fallthrough + default: + // 第1,2回合跟注加注需和大盲注相同, 3,4回合两倍 + nextP.BetMax = t.BigBlindChip * (t.Stage/2 + 1) + } + + // 如果下一玩家是大小盲注第一次下注 + if t.Stage == 2 && nextP.RoundBetTimes == 0 { + switch nextP.PosIndex { + case t.SmallBlindPos: + nextP.BetMin -= t.SmallBlindChip + if t.TexasType != 3 { + nextP.BetMax -= t.SmallBlindChip + } + case t.BigBlindPos: + nextP.BetMin -= t.BigBlindChip + nextP.BetOpts = append(nextP.BetOpts, 5) + if t.TexasType != 3 { + nextP.BetMax -= t.BigBlindChip + } + } + } +} + +// SetNextPlayer 查找下一个下注玩家, TODO 并计算最大最小下注额 +func (t *Table) SetNextPlayer(current int) { + // 找下一个拿牌玩家 + var nextPos = t.NextHoldingCardPlayerPos(current) + // 其他玩家状态等待 + for _, p := range t.Players { + if p == nil || p.Status == 7 { + continue + } + if p.PosIndex != nextPos { + p.WaitBet() + } + } + nextP := t.Players[nextPos] + nextP.SetStatus(6) + + // 最大最小下注额 + nextP.BetMin = t.LastPosBetChip +} + // cardFightAndSettle 斗牌并结算 func (t *Table) cardFightAndSettle() error { var winners []*Player = nil leftPlayers := collect.Filter(t.Players, func(i int, p *Player) bool { return p != nil && p.Status != 7 }) - - if t.RoundTimes < 4 && 1 < len(leftPlayers) { + if t.Stage != 5 && 1 < len(leftPlayers) { return errors.New("未到最后一轮下注且由1一个以上玩家持有牌") } t.Stage = 7 @@ -282,7 +355,7 @@ func (t *Table) cardFightAndSettle() error { } else { // 剩余玩家大于1: 比牌 for _, p := range t.Players { - if p != nil { + if p == nil { continue } hand, err := AnalyzeMaxHand(p.Cards, t.PublicCards) @@ -337,7 +410,7 @@ func (t *Table) cardFightAndSettle() error { // TODO 通知输赢金额 // TODO 初始化牌桌及状态 - t.InitGameAndPlayerStatus(); + t.InitGameAndPlayerStatus() go func() { // TODO 等前端展示3秒钟后,牌桌回到初始状态,剔除掉线玩家 diff --git a/internal/service/table.go b/internal/service/table.go index 2b45959..ee1fc8a 100644 --- a/internal/service/table.go +++ b/internal/service/table.go @@ -135,8 +135,8 @@ func HandleReqJoinTable(account *session.NetAccount, msg *api.ReqJoinTable) (pro } table := store.LobbyTables[msg.TableNo] - table.ChipLock.Lock() - defer table.ChipLock.Unlock() + table.Lock.Lock() + defer table.Lock.Unlock() if table == nil { return &api.ResFail{Msg: "牌桌不存在"}, nil } @@ -297,8 +297,8 @@ func HandleReqCancelReady(player *game.Player, msg *api.ReqCancelReady) (proto.M // HandleReqDismissGameTable 解散牌桌 func HandleReqDismissGameTable(player *game.Player, msg *api.ReqDismissGameTable) (proto.Message, error) { - player.GameTable.ChipLock.Lock() - defer player.GameTable.ChipLock.Unlock() + player.GameTable.Lock.Lock() + defer player.GameTable.Lock.Unlock() if player.GameTable.Stage != 1 { return &api.ResFail{Msg: fmt.Sprintf("#%d,牌局进行中", player.GameTable.Stage)}, nil } @@ -322,8 +322,8 @@ func HandleReqDismissGameTable(player *game.Player, msg *api.ReqDismissGameTable // HandleReqGameStart 游戏开始,初始化,扣除大小盲注,每个玩家发2张牌 func HandleReqGameStart(player *game.Player, msg *api.ReqGameStart) (proto.Message, error) { - player.GameTable.ChipLock.Lock() - defer player.GameTable.ChipLock.Unlock() + player.GameTable.Lock.Lock() + defer player.GameTable.Lock.Unlock() // 锁定牌桌所有玩家 for _, p := range player.GameTable.Players { if p != nil { @@ -349,7 +349,7 @@ func HandleReqGameStart(player *game.Player, msg *api.ReqGameStart) (proto.Messa // 游戏状态开始 table.Stage = 2 // 小盲注位 - if table.RoundTimes == 0 { + if table.GameTimes == 0 { // 第一轮由庄家左手边第一个作为小盲注 table.SmallBlindPos = table.NextPlayerPos(0) } else { @@ -358,17 +358,18 @@ func HandleReqGameStart(player *game.Player, msg *api.ReqGameStart) (proto.Messa // 大盲注位 table.BigBlindPos = table.NextPlayerPos(table.SmallBlindPos) // 回合数+1 - table.RoundTimes++ + table.GameTimes++ // 扣除大小盲注金额 table.Players[table.SmallBlindPos].Chip -= table.SmallBlindChip table.Players[table.SmallBlindPos].TotalBetChip += table.SmallBlindChip table.Players[table.BigBlindPos].Chip -= table.BigBlindChip table.Players[table.BigBlindPos].TotalBetChip += table.BigBlindChip - table.Chip += table.BigBlindChip + table.SmallBlindChip + // 桌面筹码 + table.Chip = table.BigBlindChip + table.SmallBlindChip // 回合下注次数 - table.Players[table.BigBlindPos].RoundBetTimes++ + // table.Players[table.BigBlindPos].RoundBetTimes++ // table.Players[table.SmallBlindPos].RoundBetTimes++ // 初始上次下注金额为大盲注 @@ -386,8 +387,6 @@ func HandleReqGameStart(player *game.Player, msg *api.ReqGameStart) (proto.Messa } table.NoticeAllPlayer(msgSmallBlind) table.NoticeAllPlayer(msgBigBlind) - //table.Players[table.BigBlindPos].ProtoWriter.Write(&api.ResBigBlindChip{Chip: game.BigBlindChip}) - //table.Players[table.SmallBlindPos].ProtoWriter.Write(&api.ResSmallBlindChip{Chip: game.SmallBlinds}) // 开始发牌(手牌,公共牌) table.Dealer.Init() // 初始化发牌员 @@ -405,47 +404,8 @@ func HandleReqGameStart(player *game.Player, msg *api.ReqGameStart) (proto.Messa // 待大盲注位下一位玩家下注 optPos := table.NextPlayerPos(table.BigBlindPos) optPlayer := table.Players[optPos] - optPlayer.SetStatus(4) + optPlayer.SetStatus(3) optPlayer.BetOpts = []int32{2, 4} - optPlayer.BetMax = table.BigBlindChip - // 游戏类型处理最大下注额 - switch table.TexasType { - case 2: // 底池限注 - optPlayer.BetMax = table.Chip + table.LastPosBetChip*2 - case 3: // 无限注 - optPlayer.BetOpts = append(optPlayer.BetOpts, 3) // 可 all in - optPlayer.BetMax = -1 - case 1: // 限注 - fallthrough - default: - // 第1,2回合跟注加注需和大盲注相同, 3,4回合两倍 - optPlayer.BetMax = table.BigBlindChip * 2 - } - // 根据玩家类型计算最小下注额,最大下注额 - switch optPos { - case table.SmallBlindPos: - optPlayer.BetMin = table.BigBlindChip - table.SmallBlindChip - if table.TexasType != 3 { - optPlayer.BetMax = optPlayer.BetMax - optPlayer.BetMin - } - case table.BigBlindPos: - optPlayer.BetMin = 0 - optPlayer.BetOpts = append(optPlayer.BetOpts, 5) - if table.TexasType != 3 { - optPlayer.BetMax = optPlayer.BetMax - table.BigBlindChip - } - default: - optPlayer.BetMin = table.BigBlindChip - } - // 其他玩家暂不可操作 - for pos, p := range table.Players { - if p != nil && pos != optPos { - p.Status = 3 - p.BetOpts = make([]int32, 0) - p.BetMin = 0 - p.BetMax = 0 - } - } // 广播牌桌状态 table.NoticeGameFullStatus() @@ -467,10 +427,10 @@ func HandleReqGameStart(player *game.Player, msg *api.ReqGameStart) (proto.Messa func HandleReqBetting(player *game.Player, msg *api.ReqBetting) (proto.Message, error) { player.Lock.Lock() defer player.Lock.Unlock() - player.GameTable.ChipLock.Lock() - defer player.GameTable.ChipLock.Unlock() + player.GameTable.Lock.Lock() + defer player.GameTable.Lock.Unlock() - if !collect.In(player.Status, 4, 6) { + if player.Status != 6 { return &api.ResFail{Msg: "当前未轮到您下注"}, nil } if !collect.In(msg.BetType, player.BetOpts...) { @@ -482,18 +442,20 @@ func HandleReqBetting(player *game.Player, msg *api.ReqBetting) (proto.Message, table := player.GameTable - var raise bool // 是否加注 + var raise bool // 是否加注 + playerBettingChip := msg.BetChip // 当前玩家加注/跟注金额 betNotice := &api.ResNoticePlayerLine{PlayerId: player.Id} + switch msg.BetType { case 1: // 跟注 - if msg.BetChip != player.BetMin { + if msg.BetChip > player.BetMin { return &api.ResFail{Msg: fmt.Sprintf("投注大于应跟注金额#%d", player.BetMin)}, nil } fallthrough case 2: // 加注 - if table.LastPosBetChip < 0 { - return &api.ResFail{Msg: "您当前只能All-In或弃牌"}, nil - } + //if table.LastPosBetChip < 0 { + // return &api.ResFail{Msg: "您当前只能All-In或弃牌"}, nil + //} if msg.BetChip < player.BetMin { return &api.ResFail{Msg: fmt.Sprintf("小于当前最低投注额#%d", player.BetMin)}, nil } @@ -504,15 +466,35 @@ func HandleReqBetting(player *game.Player, msg *api.ReqBetting) (proto.Message, if table.TexasType == 1 && msg.BetChip > player.BetMin && table.RoundRaiseTimes >= 3 { return &api.ResFail{Msg: "该轮不可再加注"}, nil } - // TODO 加注判断 - if msg.BetChip > table.LastPosBetChip { + if table.Stage == 2 && player.RoundBetTimes == 0 { + // 如果是第一圈第一次大小盲注玩家下注,下注额算加上盲注 + switch player.PosIndex { + case table.SmallBlindPos: + playerBettingChip += table.SmallBlindChip + case table.BigBlindPos: + playerBettingChip += table.BigBlindChip + } + } + // 加注判断 + raise = msg.BetChip > player.BetMin + if raise { table.RoundRaiseTimes++ } player.RoundBetTimes++ - raise = msg.BetChip > player.BetMin table.LastPosBetChip = msg.BetChip table.Chip += msg.BetChip player.Chip -= msg.BetChip + player.TotalBetChip += msg.BetChip + + betNotice.Line1 = fmt.Sprintf("+%d", msg.BetChip) + if playerBettingChip == player.BetMin { + betNotice.Line2 = "跟注" + } else { + betNotice.Line2 = fmt.Sprintf("加注:%d", msg.BetChip-player.BetMin) + if player.BetMin > 0 { + betNotice.Line2 = fmt.Sprintf("跟注:%d", player.BetMin) + } + } case 3: // All-In TODO 边池 player.RoundBetTimes++ @@ -520,12 +502,12 @@ func HandleReqBetting(player *game.Player, msg *api.ReqBetting) (proto.Message, table.Chip += player.Chip player.Chip = 0 - table.LastPosBetChip = msg.BetChip + table.LastPosBetChip = playerBettingChip case 4: // 弃牌 player.SetStatus(7) - betNotice.Line1 = "弃牌" - // 剩余牌手数为1则结束 + betNotice.Line2 = "弃牌" + // 剩余玩家数为1则结束 leftPlayers := collect.Filter(player.GameTable.Players, func(i int, p *game.Player) bool { return p != nil && p.Status != 7 }) @@ -534,61 +516,57 @@ func HandleReqBetting(player *game.Player, msg *api.ReqBetting) (proto.Message, if err != nil { return &api.ResFail{Code: 500, Msg: err.Error()}, nil } + player.GameTable.NoticeAllPlayer(betNotice) return &api.ResSuccess{}, nil } case 5: // 过牌 player.RoundBetTimes++ - betNotice.Line1 = "过牌" + betNotice.Line2 = "过牌" default: return &api.ResFail{Msg: fmt.Sprintf("未知操作#%d", msg.BetType)}, nil } - player.TotalBetChip += msg.BetChip // 通知下注结果 - if betNotice.Line1 != "" { + if betNotice.Line1 != "" || betNotice.Line2 != "" { player.GameTable.NoticeAllPlayer(betNotice) } - player.SetStatus(3) + if player.Status != 7 { + player.SetStatus(3) + } // 下注完成:若还有玩家未下注、加注,下一玩家继续下注;若该轮下注完成,发牌开启下一轮下注 // 下一位玩家:跟注 nextPlayerPos := table.NextHoldingCardPlayerPos(player.PosIndex) nextPlayer := table.Players[nextPlayerPos] - if nextPlayer.Id == player.Id { - // 开启下一轮 - err := table.RoundOver() - if err != nil { - return &api.ResFail{Code: 500, Msg: err.Error()}, nil - } - return &api.ResSuccess{}, nil - } + //if nextPlayer.Id == player.Id { + // // 开启下一轮 + // err := table.RoundOver() + // if err != nil { + // return &api.ResFail{Code: 500, Msg: err.Error()}, nil + // } + // return &api.ResSuccess{}, nil + //} if !raise { // 当前玩家未加注, 判断是否结束本轮下注 - if nextPlayer.RoundBetTimes > 0 { + if nextPlayer.RoundBetTimes == player.RoundBetTimes { // 开启下一轮 err := table.RoundOver() if err != nil { return &api.ResFail{Code: 500, Msg: err.Error()}, nil } + return &api.ResSuccess{}, nil } } - // 判断下一玩家是否需要再下注: 下一玩家是否已下注,当前玩家是否跟注, + + // 判断该轮下一玩家可下注情况 : 下一玩家是否已下注,当前玩家是否跟注, nextPlayer.SetStatus(6) - nextPlayer.BetMin = msg.BetChip + nextPlayer.BetMin = playerBettingChip nextPlayer.BetOpts = []int32{1, 4} // 下一玩家需跟注 - // 如果当前玩家是小盲注第一次下注 - if player.RoundBetTimes == 1 && table.SmallBlindPos == player.PosIndex { - nextPlayer.BetMin += table.SmallBlindChip - } - // 如果下一玩家是大盲注第一次下注 - if nextPlayer.RoundBetTimes == 0 && table.BigBlindPos == nextPlayerPos { - nextPlayer.BetMin -= table.BigBlindChip - } // 游戏类型处理最大下注额 switch table.TexasType { case 2: // 底池限注 @@ -604,13 +582,24 @@ func HandleReqBetting(player *game.Player, msg *api.ReqBetting) (proto.Message, if table.RoundRaiseTimes < 3 { nextPlayer.BetOpts = append(nextPlayer.BetOpts, 3) // 第1,2回合跟注加注需和大盲注相同, 3,4回合两倍 - nextPlayer.BetMax = table.BigBlindChip * ((table.RoundTimes+1)/2 + 1) + nextPlayer.BetMax = table.BigBlindChip * (table.Stage/2 + 1) } else { // 只能跟注 - nextPlayer.BetMax = msg.BetChip + nextPlayer.BetMax = playerBettingChip } } + // 如果下一玩家是大小盲注第一次下注 + if table.Stage == 2 && nextPlayer.RoundBetTimes == 0 { + switch nextPlayer.PosIndex { + case table.SmallBlindPos: + nextPlayer.BetMin -= table.SmallBlindChip + nextPlayer.BetMax -= table.SmallBlindChip + case table.BigBlindPos: + nextPlayer.BetMin -= table.BigBlindChip + nextPlayer.BetMax -= table.BigBlindChip + } + } // 依赌场规则而异, // 若所余筹码All-in后仍低于最低加注金额,则此注仅视为跟注(call)而不能被当成加注(raise),亦及该圈若未有其他人再加注,则原加注者(此例中的第一位牌手)仅可跟注补齐或盖牌,于此圈不可再行加注 // 亦有少部分赌场规定All-in后大于最低加注额的一半以上,原加注者即可重新加注。