9 changed files with 658 additions and 173 deletions
@ -0,0 +1,274 @@ |
|||||||
|
package game |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
"fmt" |
||||||
|
"github.com/golang/protobuf/proto" |
||||||
|
"texas-poker-bk/api" |
||||||
|
"texas-poker-bk/tool/collect" |
||||||
|
) |
||||||
|
|
||||||
|
type PlayerBetting struct { |
||||||
|
betHandlers map[int32]func(player *Player, betChip int32) proto.Message |
||||||
|
|
||||||
|
SetNextPlayer func(roundStart bool, t *Table, current *Player) |
||||||
|
|
||||||
|
IsRoundOver func(current *Player, currentBetOp int32) bool |
||||||
|
} |
||||||
|
|
||||||
|
// GetBetHandler 获取下注类型对应 handler
|
||||||
|
// betOp: 1跟注,2加注,3All-In,4弃牌,5过牌
|
||||||
|
func (betting *PlayerBetting) GetBetHandler(betOp int32) (func(player *Player, betChip int32) proto.Message, error) { |
||||||
|
handler := betting.betHandlers[betOp] |
||||||
|
if handler == nil { |
||||||
|
return nil, errors.New(fmt.Sprintf("未知操作#%d", betOp)) |
||||||
|
} |
||||||
|
return handler, nil |
||||||
|
} |
||||||
|
|
||||||
|
var ( |
||||||
|
LimitedBetting *PlayerBetting |
||||||
|
) |
||||||
|
|
||||||
|
// var LimitedActions map[int32]func(player *Player, betChip int32) proto.Message
|
||||||
|
|
||||||
|
func init() { |
||||||
|
// 1跟注,2加注,3All-In,4弃牌,5过牌
|
||||||
|
LimitedActions := make(map[int32]func(player *Player, betChip int32) proto.Message, 7) |
||||||
|
LimitedActions[1] = Call4Limited |
||||||
|
LimitedActions[2] = Raise4Limited |
||||||
|
LimitedActions[3] = AllIn4Limited |
||||||
|
LimitedActions[4] = Discard4Limited |
||||||
|
LimitedActions[5] = Check4Limited |
||||||
|
LimitedBetting = &PlayerBetting{ |
||||||
|
betHandlers: LimitedActions, |
||||||
|
SetNextPlayer: SetNextPlayer4Limited, |
||||||
|
IsRoundOver: IsRoundOver4Limited, |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
func Call4Limited(player *Player, betChip int32) proto.Message { |
||||||
|
if betChip > player.BetMin { |
||||||
|
return &api.ResFail{Msg: fmt.Sprintf("投注金额大于跟注金额:%d", player.BetMin)} |
||||||
|
} |
||||||
|
return Raise4Limited(player, betChip) |
||||||
|
} |
||||||
|
|
||||||
|
// Raise4Limited 限注加注处理
|
||||||
|
func Raise4Limited(player *Player, betChip int32) proto.Message { |
||||||
|
table := player.GameTable |
||||||
|
if betChip < player.BetMin { |
||||||
|
return &api.ResFail{Msg: fmt.Sprintf("小于当前最低投注额:%d", player.BetMin)} |
||||||
|
} |
||||||
|
if player.BetMax > 0 && betChip > player.BetMax { |
||||||
|
return &api.ResFail{Msg: fmt.Sprintf("大于当前最大投注额:%d", player.BetMax)} |
||||||
|
} |
||||||
|
// 限注式加注3次判断
|
||||||
|
if table.TexasType == 1 && betChip > player.BetMin && table.RoundRaiseTimes >= 3 { |
||||||
|
return &api.ResFail{Msg: "限加注3次,当前只能跟注"} |
||||||
|
} |
||||||
|
var raise bool // 是否加注
|
||||||
|
betNotice := &api.ResNoticePlayerLine{PlayerId: player.Id} |
||||||
|
|
||||||
|
//if table.Stage == 2 && player.RoundBetTimes == 0 {
|
||||||
|
// // 如果是第一圈第一次大小盲注玩家下注,下注额算加上盲注
|
||||||
|
// switch player.PosIndex {
|
||||||
|
// case table.SmallBlindPos:
|
||||||
|
// playerBettingChip += table.SmallBlindChip
|
||||||
|
// case table.BigBlindPos:
|
||||||
|
// playerBettingChip += table.BigBlindChip
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
// 加注判断
|
||||||
|
raise = betChip > player.BetMin |
||||||
|
if raise { |
||||||
|
table.RoundRaiseTimes++ |
||||||
|
table.LastPosBetOp = 2 |
||||||
|
} else { |
||||||
|
table.LastPosBetOp = 1 |
||||||
|
} |
||||||
|
player.RoundBetTimes++ |
||||||
|
table.LastPosBetChip = betChip |
||||||
|
table.Chip += betChip |
||||||
|
player.Chip -= betChip |
||||||
|
player.TotalBetChip += betChip |
||||||
|
|
||||||
|
betNotice.Line1 = fmt.Sprintf("+%d", betChip) |
||||||
|
if betChip == player.BetMin { |
||||||
|
betNotice.Line2 = fmt.Sprintf("跟注%d", player.BetMin) |
||||||
|
} else { |
||||||
|
betNotice.Line2 = fmt.Sprintf("加注:%d", betChip-player.BetMin) |
||||||
|
if player.BetMin > 0 { |
||||||
|
betNotice.Line3 = fmt.Sprintf("跟注:%d", player.BetMin) |
||||||
|
} |
||||||
|
} |
||||||
|
// 通知下注结果
|
||||||
|
table.NoticeAllPlayer(betNotice) |
||||||
|
|
||||||
|
return &api.ResSuccess{} |
||||||
|
} |
||||||
|
|
||||||
|
func AllIn4Limited(player *Player, betChip int32) proto.Message { |
||||||
|
return &api.ResFail{Msg: "限注牌桌不可AllIn"} |
||||||
|
} |
||||||
|
|
||||||
|
func Discard4Limited(player *Player, betChip int32) proto.Message { |
||||||
|
table := player.GameTable |
||||||
|
table.LastPosBetOp = 4 |
||||||
|
table.LastPosBetChip = 0 |
||||||
|
|
||||||
|
betNotice := &api.ResNoticePlayerLine{PlayerId: player.Id} |
||||||
|
|
||||||
|
player.SetStatus(7) |
||||||
|
betNotice.Line2 = "弃牌" |
||||||
|
// 剩余玩家数为1则结束
|
||||||
|
leftPlayers := collect.Filter(player.GameTable.Players, func(i int, p *Player) bool { |
||||||
|
return p != nil && p.Status != 7 |
||||||
|
}) |
||||||
|
if len(leftPlayers) == 1 { |
||||||
|
err := table.RoundOver() |
||||||
|
if err != nil { |
||||||
|
return &api.ResFail{Code: 500, Msg: err.Error()} |
||||||
|
} |
||||||
|
player.GameTable.NoticeAllPlayer(betNotice) |
||||||
|
return &api.ResSuccess{} |
||||||
|
} |
||||||
|
player.GameTable.NoticeAllPlayer(betNotice) |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func Check4Limited(player *Player, betChip int32) proto.Message { |
||||||
|
table := player.GameTable |
||||||
|
table.LastPosBetOp = 5 |
||||||
|
table.LastPosBetChip = 0 |
||||||
|
betNotice := &api.ResNoticePlayerLine{PlayerId: player.Id} |
||||||
|
|
||||||
|
player.RoundBetTimes++ |
||||||
|
betNotice.Line2 = "过牌" |
||||||
|
|
||||||
|
// 第一轮只有未加注时大盲注可过牌,大盲注了不算只过牌
|
||||||
|
player.RoundCheckRaiseOnly = table.Stage != 2 |
||||||
|
|
||||||
|
player.GameTable.NoticeAllPlayer(betNotice) |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// IsRoundOver4Limited 判断回合是否结束
|
||||||
|
func IsRoundOver4Limited(current *Player, currentBetOp int32) bool { |
||||||
|
table := current.GameTable |
||||||
|
// 当前玩家弃牌, 判断剩余玩家数1结束
|
||||||
|
if currentBetOp == 4 { |
||||||
|
if 1 == len(table.HoldingCardPlayers()) { |
||||||
|
return true |
||||||
|
} |
||||||
|
} |
||||||
|
// 判断下注轮 和 下注金额
|
||||||
|
if collect.IsEmptyMap(table.RoundBetOps) || |
||||||
|
collect.IsEmptyMap(table.RoundBetChips) { |
||||||
|
return false |
||||||
|
} |
||||||
|
// 当前玩家加注, 继续
|
||||||
|
if currentBetOp == 2 { |
||||||
|
return false |
||||||
|
} |
||||||
|
var totalTemp int32 = -1 // 所有玩家投入相同筹码回合结束
|
||||||
|
for _, p := range table.Players { |
||||||
|
if p == nil || p.Status == 7 { |
||||||
|
continue |
||||||
|
} |
||||||
|
// 还有玩家未下注
|
||||||
|
if collect.IsEmptySlice(table.RoundBetOps[p.Id]) { |
||||||
|
return false |
||||||
|
} |
||||||
|
// 计算玩家下注额
|
||||||
|
if totalTemp == -1 { |
||||||
|
totalTemp = table.RoundBetTotal[p.Id] |
||||||
|
continue |
||||||
|
} |
||||||
|
if totalTemp != table.RoundBetTotal[p.Id] { |
||||||
|
return false |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 判断当前玩家和下一玩家 回合是否结束
|
||||||
|
nextPlayerPos := table.NextHoldingCardPlayerPos(current.PosIndex) |
||||||
|
nextPlayer := table.Players[nextPlayerPos] |
||||||
|
if table.Stage == 2 && nextPlayerPos == table.BigBlindPos && |
||||||
|
len(table.RoundBetOps[nextPlayer.Id]) == 1 { // 大盲注玩家还下注一次
|
||||||
|
return false |
||||||
|
} |
||||||
|
//// 投注金额相同
|
||||||
|
//currentBetTotal := table.RoundBetTotal[current.Id]
|
||||||
|
//if currentBetTotal == 0 {
|
||||||
|
// if currentBetOp == 5 && // 当前玩家过牌且下一位玩家已过牌
|
||||||
|
// collect.Tail(table.RoundBetOps[nextPlayer.Id], 0) == 5 {
|
||||||
|
// return true
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//} else if table.RoundBetTotal[nextPlayer.Id] == currentBetTotal {
|
||||||
|
// // 下一玩家已投入等量筹码
|
||||||
|
// return true
|
||||||
|
//}
|
||||||
|
|
||||||
|
//var total int32 = -1
|
||||||
|
//for uid, betTotal := range table.RoundBetTotal {
|
||||||
|
// player := table.GetPlayerById(uid)
|
||||||
|
// if player == nil || player.Status == 7 {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
// if total == -1 {
|
||||||
|
// total = betTotal
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
// if total != betTotal {
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
// TODO 判断剩余牌手All-In情况
|
||||||
|
return true |
||||||
|
} |
||||||
|
|
||||||
|
func SetNextPlayer4Limited(roundStart bool, t *Table, current *Player) { |
||||||
|
var nextPos int = t.SmallBlindPos |
||||||
|
if !roundStart { |
||||||
|
// 非回合开始
|
||||||
|
nextPos = t.NextHoldingCardPlayerPos(current.PosIndex) |
||||||
|
} else { |
||||||
|
// 回合开始
|
||||||
|
if t.Stage == 2 { // 第一轮由大盲注后一个玩家下注
|
||||||
|
nextPos = t.NextPlayerPos(t.BigBlindPos) |
||||||
|
|
||||||
|
} else 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{4} |
||||||
|
|
||||||
|
// 回合最大下注额 减 下一玩家总下注额
|
||||||
|
roundMaxBet := collect.Max(collect.MapValues(t.RoundBetTotal), 0) |
||||||
|
nextP.BetMin = roundMaxBet - t.RoundBetTotal[nextP.Id] |
||||||
|
// 第1,2回合跟注加注需和大盲注相同, 3,4回合两倍
|
||||||
|
nextP.BetMax = t.BigBlindChip * (t.Stage/2 + 1) |
||||||
|
if nextP.BetMin == 0 { // 过牌
|
||||||
|
nextP.BetOpts = append(nextP.BetOpts, 5) |
||||||
|
} else if nextP.BetMin > 0 { // 跟注
|
||||||
|
nextP.BetOpts = append(nextP.BetOpts, 1) |
||||||
|
} |
||||||
|
if nextP.BetMax > nextP.BetMin { // 加注
|
||||||
|
nextP.BetOpts = append(nextP.BetOpts, 2) |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue