Browse Source

betting round

master
tangmingyou 4 years ago
parent
commit
46e34fb12f
  1. 5
      api/operation.go
  2. 278
      api/poker.pb.go
  3. 18
      api/poker.proto
  4. 723
      api/proto.js
  5. 12
      internal/game/player.go
  6. 185
      internal/game/table.go
  7. 2
      internal/server/wsroute.go
  8. 63
      internal/service/table.go
  9. 2
      tool/collect/collect.go

5
api/operation.go

@ -47,9 +47,12 @@ var protoInstances = []proto.Message{
&ResDismissGameTable{},
&ReqGameStart{},
&ReqPlaceBet{},
&ReqBetting{},
&ResNoticePlayerLine{},
&ResCalcWinnerChip{},
&ResGameEndSettle{},
}
var (

278
api/poker.pb.go

@ -1272,7 +1272,9 @@ type TablePlayer struct {
Chip int32 `protobuf:"varint,5,opt,name=chip,proto3" json:"chip,omitempty"` // 筹码
Status int32 `protobuf:"varint,6,opt,name=status,proto3" json:"status,omitempty"` // 玩家状态: 1待准备开始,2已准备开始,已开始(3等待其他玩家动作,4待大盲注,5待小盲注,6待跟注,7已弃)
LastStatus int32 `protobuf:"varint,7,opt,name=lastStatus,proto3" json:"lastStatus,omitempty"` // TODO 删, 前端通过消息监听获取下注金额信息
Master bool `protobuf:"varint,8,opt,name=master,proto3" json:"master,omitempty"` // 是否房主`
Master bool `protobuf:"varint,8,opt,name=master,proto3" json:"master,omitempty"` // 是否房主
RoundBetTimes int32 `protobuf:"varint,11,opt,name=roundBetTimes,proto3" json:"roundBetTimes,omitempty"` // 该局下注次数
TotalBetChip int32 `protobuf:"varint,13,opt,name=totalBetChip,proto3" json:"totalBetChip,omitempty"` // 该局牌已下注筹码
BetRole *BetRole `protobuf:"bytes,14,opt,name=betRole,proto3" json:"betRole,omitempty"` // 下注时规则限制
HandCard []*Card `protobuf:"bytes,15,rep,name=handCard,proto3" json:"handCard,omitempty"` // 手牌
}
@ -1365,6 +1367,20 @@ func (x *TablePlayer) GetMaster() bool {
return false
}
func (x *TablePlayer) GetRoundBetTimes() int32 {
if x != nil {
return x.RoundBetTimes
}
return 0
}
func (x *TablePlayer) GetTotalBetChip() int32 {
if x != nil {
return x.TotalBetChip
}
return 0
}
func (x *TablePlayer) GetBetRole() *BetRole {
if x != nil {
return x.BetRole
@ -1440,8 +1456,9 @@ type BetRole struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
MinChip int32 `protobuf:"varint,1,opt,name=minChip,proto3" json:"minChip,omitempty"` // 最低下注额:小盲注加注(按惯例至少2倍与大盲注)
MaxChip int32 `protobuf:"varint,2,opt,name=maxChip,proto3" json:"maxChip,omitempty"` // 最高下注额:
BetMin int32 `protobuf:"varint,1,opt,name=betMin,proto3" json:"betMin,omitempty"` // 最低下注额
BetMax int32 `protobuf:"varint,2,opt,name=betMax,proto3" json:"betMax,omitempty"` // 最高下注额
BetOpts []int32 `protobuf:"varint,13,rep,packed,name=betOpts,proto3" json:"betOpts,omitempty"` // status=[4,6]时下注可操作按钮: 1跟注,2加注(-[0]+),3All-In,4弃牌,5过牌
}
func (x *BetRole) Reset() {
@ -1476,20 +1493,27 @@ func (*BetRole) Descriptor() ([]byte, []int) {
return file_poker_proto_rawDescGZIP(), []int{25}
}
func (x *BetRole) GetMinChip() int32 {
func (x *BetRole) GetBetMin() int32 {
if x != nil {
return x.MinChip
return x.BetMin
}
return 0
}
func (x *BetRole) GetMaxChip() int32 {
func (x *BetRole) GetBetMax() int32 {
if x != nil {
return x.MaxChip
return x.BetMax
}
return 0
}
func (x *BetRole) GetBetOpts() []int32 {
if x != nil {
return x.BetOpts
}
return nil
}
// 开始游戏
type ReqGameStart struct {
state protoimpl.MessageState
@ -1607,17 +1631,17 @@ func (*ResDismissGameTable) Descriptor() ([]byte, []int) {
}
// 下注
type ReqPlaceBet struct {
type ReqBetting struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
BetType int32 `protobuf:"varint,1,opt,name=betType,proto3" json:"betType,omitempty"` // 1跟注,2加注(-[0]+),3All-In,4弃牌,5过牌
BetType int32 `protobuf:"varint,1,opt,name=betType,proto3" json:"betType,omitempty"` // 1跟注,2加注或跟注(-[0]+),3All-In,4弃牌,5过牌
BetChip int32 `protobuf:"varint,2,opt,name=betChip,proto3" json:"betChip,omitempty"` // 跟注/加注金额
}
func (x *ReqPlaceBet) Reset() {
*x = ReqPlaceBet{}
func (x *ReqBetting) Reset() {
*x = ReqBetting{}
if protoimpl.UnsafeEnabled {
mi := &file_poker_proto_msgTypes[29]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -1625,13 +1649,13 @@ func (x *ReqPlaceBet) Reset() {
}
}
func (x *ReqPlaceBet) String() string {
func (x *ReqBetting) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ReqPlaceBet) ProtoMessage() {}
func (*ReqBetting) ProtoMessage() {}
func (x *ReqPlaceBet) ProtoReflect() protoreflect.Message {
func (x *ReqBetting) ProtoReflect() protoreflect.Message {
mi := &file_poker_proto_msgTypes[29]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -1643,19 +1667,19 @@ func (x *ReqPlaceBet) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use ReqPlaceBet.ProtoReflect.Descriptor instead.
func (*ReqPlaceBet) Descriptor() ([]byte, []int) {
// Deprecated: Use ReqBetting.ProtoReflect.Descriptor instead.
func (*ReqBetting) Descriptor() ([]byte, []int) {
return file_poker_proto_rawDescGZIP(), []int{29}
}
func (x *ReqPlaceBet) GetBetType() int32 {
func (x *ReqBetting) GetBetType() int32 {
if x != nil {
return x.BetType
}
return 0
}
func (x *ReqPlaceBet) GetBetChip() int32 {
func (x *ReqBetting) GetBetChip() int32 {
if x != nil {
return x.BetChip
}
@ -1734,6 +1758,101 @@ func (x *ResNoticePlayerLine) GetLine3() string {
return ""
}
type ResGameEndSettle struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Game *ResGameFullStatus `protobuf:"bytes,11,opt,name=game,proto3" json:"game,omitempty"`
}
func (x *ResGameEndSettle) Reset() {
*x = ResGameEndSettle{}
if protoimpl.UnsafeEnabled {
mi := &file_poker_proto_msgTypes[31]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ResGameEndSettle) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ResGameEndSettle) ProtoMessage() {}
func (x *ResGameEndSettle) ProtoReflect() protoreflect.Message {
mi := &file_poker_proto_msgTypes[31]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ResGameEndSettle.ProtoReflect.Descriptor instead.
func (*ResGameEndSettle) Descriptor() ([]byte, []int) {
return file_poker_proto_rawDescGZIP(), []int{31}
}
func (x *ResGameEndSettle) GetGame() *ResGameFullStatus {
if x != nil {
return x.Game
}
return nil
}
// 玩家输赢筹码通知
type ResCalcWinnerChip struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
PlayersWinChip map[int64]int32 `protobuf:"bytes,9,rep,name=playersWinChip,proto3" json:"playersWinChip,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
}
func (x *ResCalcWinnerChip) Reset() {
*x = ResCalcWinnerChip{}
if protoimpl.UnsafeEnabled {
mi := &file_poker_proto_msgTypes[32]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ResCalcWinnerChip) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ResCalcWinnerChip) ProtoMessage() {}
func (x *ResCalcWinnerChip) ProtoReflect() protoreflect.Message {
mi := &file_poker_proto_msgTypes[32]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ResCalcWinnerChip.ProtoReflect.Descriptor instead.
func (*ResCalcWinnerChip) Descriptor() ([]byte, []int) {
return file_poker_proto_rawDescGZIP(), []int{32}
}
func (x *ResCalcWinnerChip) GetPlayersWinChip() map[int64]int32 {
if x != nil {
return x.PlayersWinChip
}
return nil
}
var File_poker_proto protoreflect.FileDescriptor
var file_poker_proto_rawDesc = []byte{
@ -1830,7 +1949,7 @@ var file_poker_proto_rawDesc = []byte{
0x61, 0x72, 0x64, 0x12, 0x2a, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x0f,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65,
0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x22,
0x9a, 0x02, 0x0a, 0x0b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12,
0xe4, 0x02, 0x0a, 0x0b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12,
0x14, 0x0a, 0x05, 0x72, 0x6f, 0x62, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05,
0x72, 0x6f, 0x62, 0x6f, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d,
@ -1842,36 +1961,56 @@ var file_poker_proto_rawDesc = []byte{
0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61,
0x74, 0x75, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x53,
0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x18,
0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x12, 0x26, 0x0a,
0x07, 0x62, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x42, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x07, 0x62, 0x65,
0x74, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x25, 0x0a, 0x08, 0x68, 0x61, 0x6e, 0x64, 0x43, 0x61, 0x72,
0x64, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x61,
0x72, 0x64, 0x52, 0x08, 0x68, 0x61, 0x6e, 0x64, 0x43, 0x61, 0x72, 0x64, 0x22, 0x2c, 0x0a, 0x04,
0x43, 0x61, 0x72, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
0x05, 0x52, 0x03, 0x64, 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x75, 0x69, 0x74, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x75, 0x69, 0x74, 0x22, 0x3d, 0x0a, 0x07, 0x42, 0x65,
0x74, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x69, 0x6e, 0x43, 0x68, 0x69, 0x70,
0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6d, 0x69, 0x6e, 0x43, 0x68, 0x69, 0x70, 0x12,
0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x43, 0x68, 0x69, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
0x52, 0x07, 0x6d, 0x61, 0x78, 0x43, 0x68, 0x69, 0x70, 0x22, 0x0e, 0x0a, 0x0c, 0x52, 0x65, 0x71,
0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x12, 0x24, 0x0a,
0x0d, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x42, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x0b,
0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x42, 0x65, 0x74, 0x54, 0x69,
0x6d, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x65, 0x74, 0x43,
0x68, 0x69, 0x70, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c,
0x42, 0x65, 0x74, 0x43, 0x68, 0x69, 0x70, 0x12, 0x26, 0x0a, 0x07, 0x62, 0x65, 0x74, 0x52, 0x6f,
0x6c, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x42,
0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x07, 0x62, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x12,
0x25, 0x0a, 0x08, 0x68, 0x61, 0x6e, 0x64, 0x43, 0x61, 0x72, 0x64, 0x18, 0x0f, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x09, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x61, 0x72, 0x64, 0x52, 0x08, 0x68, 0x61,
0x6e, 0x64, 0x43, 0x61, 0x72, 0x64, 0x22, 0x2c, 0x0a, 0x04, 0x43, 0x61, 0x72, 0x64, 0x12, 0x10,
0x0a, 0x03, 0x64, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x64, 0x6f, 0x74,
0x12, 0x12, 0x0a, 0x04, 0x73, 0x75, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x73, 0x75, 0x69, 0x74, 0x22, 0x53, 0x0a, 0x07, 0x42, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x12,
0x16, 0x0a, 0x06, 0x62, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
0x06, 0x62, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x65, 0x74, 0x4d, 0x61,
0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x62, 0x65, 0x74, 0x4d, 0x61, 0x78, 0x12,
0x18, 0x0a, 0x07, 0x62, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x05,
0x52, 0x07, 0x62, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x73, 0x22, 0x0e, 0x0a, 0x0c, 0x52, 0x65, 0x71,
0x47, 0x61, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x65, 0x71,
0x44, 0x69, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x47, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65,
0x22, 0x15, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x44, 0x69, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x47, 0x61,
0x6d, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x41, 0x0a, 0x0b, 0x52, 0x65, 0x71, 0x50, 0x6c,
0x61, 0x63, 0x65, 0x42, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x65, 0x74, 0x54, 0x79, 0x70,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x62, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65,
0x12, 0x18, 0x0a, 0x07, 0x62, 0x65, 0x74, 0x43, 0x68, 0x69, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28,
0x05, 0x52, 0x07, 0x62, 0x65, 0x74, 0x43, 0x68, 0x69, 0x70, 0x22, 0x73, 0x0a, 0x13, 0x52, 0x65,
0x73, 0x4e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4c, 0x69, 0x6e,
0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x03, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a,
0x05, 0x6c, 0x69, 0x6e, 0x65, 0x31, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x69,
0x6e, 0x65, 0x31, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x32, 0x18, 0x0c, 0x20, 0x01,
0x28, 0x09, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x32, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6e,
0x65, 0x33, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x33, 0x42,
0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x61, 0x70, 0x69, 0x3b, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
0x6d, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x40, 0x0a, 0x0a, 0x52, 0x65, 0x71, 0x42, 0x65,
0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x62, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12,
0x18, 0x0a, 0x07, 0x62, 0x65, 0x74, 0x43, 0x68, 0x69, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
0x52, 0x07, 0x62, 0x65, 0x74, 0x43, 0x68, 0x69, 0x70, 0x22, 0x73, 0x0a, 0x13, 0x52, 0x65, 0x73,
0x4e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x65,
0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x03, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05,
0x6c, 0x69, 0x6e, 0x65, 0x31, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x69, 0x6e,
0x65, 0x31, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x32, 0x18, 0x0c, 0x20, 0x01, 0x28,
0x09, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x32, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x65,
0x33, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x33, 0x22, 0x3e,
0x0a, 0x10, 0x52, 0x65, 0x73, 0x47, 0x61, 0x6d, 0x65, 0x45, 0x6e, 0x64, 0x53, 0x65, 0x74, 0x74,
0x6c, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x67, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x47, 0x61, 0x6d, 0x65, 0x46, 0x75,
0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x04, 0x67, 0x61, 0x6d, 0x65, 0x22, 0xaa,
0x01, 0x0a, 0x11, 0x52, 0x65, 0x73, 0x43, 0x61, 0x6c, 0x63, 0x57, 0x69, 0x6e, 0x6e, 0x65, 0x72,
0x43, 0x68, 0x69, 0x70, 0x12, 0x52, 0x0a, 0x0e, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x57,
0x69, 0x6e, 0x43, 0x68, 0x69, 0x70, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x43, 0x61, 0x6c, 0x63, 0x57, 0x69, 0x6e, 0x6e, 0x65, 0x72,
0x43, 0x68, 0x69, 0x70, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x57, 0x69, 0x6e, 0x43,
0x68, 0x69, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72,
0x73, 0x57, 0x69, 0x6e, 0x43, 0x68, 0x69, 0x70, 0x1a, 0x41, 0x0a, 0x13, 0x50, 0x6c, 0x61, 0x79,
0x65, 0x72, 0x73, 0x57, 0x69, 0x6e, 0x43, 0x68, 0x69, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6b, 0x65,
0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0b, 0x5a, 0x09, 0x2e,
0x2f, 0x61, 0x70, 0x69, 0x3b, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -1886,7 +2025,7 @@ func file_poker_proto_rawDescGZIP() []byte {
return file_poker_proto_rawDescData
}
var file_poker_proto_msgTypes = make([]protoimpl.MessageInfo, 31)
var file_poker_proto_msgTypes = make([]protoimpl.MessageInfo, 34)
var file_poker_proto_goTypes = []interface{}{
(*ProtoWrap)(nil), // 0: api.ProtoWrap
(*Ping)(nil), // 1: api.Ping
@ -1917,8 +2056,11 @@ var file_poker_proto_goTypes = []interface{}{
(*ReqGameStart)(nil), // 26: api.ReqGameStart
(*ReqDismissGameTable)(nil), // 27: api.ReqDismissGameTable
(*ResDismissGameTable)(nil), // 28: api.ResDismissGameTable
(*ReqPlaceBet)(nil), // 29: api.ReqPlaceBet
(*ReqBetting)(nil), // 29: api.ReqBetting
(*ResNoticePlayerLine)(nil), // 30: api.ResNoticePlayerLine
(*ResGameEndSettle)(nil), // 31: api.ResGameEndSettle
(*ResCalcWinnerChip)(nil), // 32: api.ResCalcWinnerChip
nil, // 33: api.ResCalcWinnerChip.PlayersWinChipEntry
}
var file_poker_proto_depIdxs = []int32{
9, // 0: api.ResLobbyView.tables:type_name -> api.LobbyTable
@ -1927,11 +2069,13 @@ var file_poker_proto_depIdxs = []int32{
23, // 3: api.ResGameFullStatus.players:type_name -> api.TablePlayer
25, // 4: api.TablePlayer.betRole:type_name -> api.BetRole
24, // 5: api.TablePlayer.handCard:type_name -> api.Card
6, // [6:6] is the sub-list for method output_type
6, // [6:6] is the sub-list for method input_type
6, // [6:6] is the sub-list for extension type_name
6, // [6:6] is the sub-list for extension extendee
0, // [0:6] is the sub-list for field type_name
22, // 6: api.ResGameEndSettle.game:type_name -> api.ResGameFullStatus
33, // 7: api.ResCalcWinnerChip.playersWinChip:type_name -> api.ResCalcWinnerChip.PlayersWinChipEntry
8, // [8:8] is the sub-list for method output_type
8, // [8:8] is the sub-list for method input_type
8, // [8:8] is the sub-list for extension type_name
8, // [8:8] is the sub-list for extension extendee
0, // [0:8] is the sub-list for field type_name
}
func init() { file_poker_proto_init() }
@ -2289,7 +2433,7 @@ func file_poker_proto_init() {
}
}
file_poker_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReqPlaceBet); i {
switch v := v.(*ReqBetting); i {
case 0:
return &v.state
case 1:
@ -2312,6 +2456,30 @@ func file_poker_proto_init() {
return nil
}
}
file_poker_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ResGameEndSettle); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_poker_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ResCalcWinnerChip); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
@ -2319,7 +2487,7 @@ func file_poker_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_poker_proto_rawDesc,
NumEnums: 0,
NumMessages: 31,
NumMessages: 34,
NumExtensions: 0,
NumServices: 0,
},

18
api/poker.proto

@ -148,7 +148,10 @@ message TablePlayer {
int32 chip = 5; //
int32 status = 6; // : 1,2,(3,4,5,6,7)
int32 lastStatus = 7; // TODO ,
bool master = 8; // `
bool master = 8; //
int32 roundBetTimes = 11; //
int32 totalBetChip = 13; //
BetRole betRole = 14; //
repeated Card handCard = 15; //
}
@ -160,8 +163,9 @@ message Card {
// player status in (4,6)
message BetRole {
int32 minChip = 1; // (2)
int32 maxChip = 2; //
int32 betMin = 1; //
int32 betMax = 2; //
repeated int32 betOpts = 13; // status=[4,6]: 1,2(-[0]+),3All-In,4,5
}
// ============= end
@ -178,8 +182,8 @@ message ResDismissGameTable {
}
//
message ReqPlaceBet {
int32 betType = 1; // 1,2(-[0]+),3All-In,4,5
message ReqBetting {
int32 betType = 1; // 1,2(-[0]+),3All-In,4,5
int32 betChip = 2; // /
}
@ -192,6 +196,10 @@ message ResNoticePlayerLine {
string line3 = 13;
}
message ResGameEndSettle {
ResGameFullStatus game = 11;
}
//
message ResCalcWinnerChip {
map<int64, int32> playersWinChip = 9;

723
api/proto.js

@ -5289,6 +5289,8 @@ export const api = $root.api = (() => {
* @property {number|null} [status] TablePlayer status
* @property {number|null} [lastStatus] TablePlayer lastStatus
* @property {boolean|null} [master] TablePlayer master
* @property {number|null} [roundBetTimes] TablePlayer roundBetTimes
* @property {number|null} [totalBetChip] TablePlayer totalBetChip
* @property {api.IBetRole|null} [betRole] TablePlayer betRole
* @property {Array.<api.ICard>|null} [handCard] TablePlayer handCard
*/
@ -5373,6 +5375,22 @@ export const api = $root.api = (() => {
*/
TablePlayer.prototype.master = false;
/**
* TablePlayer roundBetTimes.
* @member {number} roundBetTimes
* @memberof api.TablePlayer
* @instance
*/
TablePlayer.prototype.roundBetTimes = 0;
/**
* TablePlayer totalBetChip.
* @member {number} totalBetChip
* @memberof api.TablePlayer
* @instance
*/
TablePlayer.prototype.totalBetChip = 0;
/**
* TablePlayer betRole.
* @member {api.IBetRole|null|undefined} betRole
@ -5429,6 +5447,10 @@ export const api = $root.api = (() => {
writer.uint32(/* id 7, wireType 0 =*/56).int32(message.lastStatus);
if (message.master != null && Object.hasOwnProperty.call(message, "master"))
writer.uint32(/* id 8, wireType 0 =*/64).bool(message.master);
if (message.roundBetTimes != null && Object.hasOwnProperty.call(message, "roundBetTimes"))
writer.uint32(/* id 11, wireType 0 =*/88).int32(message.roundBetTimes);
if (message.totalBetChip != null && Object.hasOwnProperty.call(message, "totalBetChip"))
writer.uint32(/* id 13, wireType 0 =*/104).int32(message.totalBetChip);
if (message.betRole != null && Object.hasOwnProperty.call(message, "betRole"))
$root.api.BetRole.encode(message.betRole, writer.uint32(/* id 14, wireType 2 =*/114).fork()).ldelim();
if (message.handCard != null && message.handCard.length)
@ -5500,6 +5522,14 @@ export const api = $root.api = (() => {
message.master = reader.bool();
break;
}
case 11: {
message.roundBetTimes = reader.int32();
break;
}
case 13: {
message.totalBetChip = reader.int32();
break;
}
case 14: {
message.betRole = $root.api.BetRole.decode(reader, reader.uint32());
break;
@ -5569,6 +5599,12 @@ export const api = $root.api = (() => {
if (message.master != null && message.hasOwnProperty("master"))
if (typeof message.master !== "boolean")
return "master: boolean expected";
if (message.roundBetTimes != null && message.hasOwnProperty("roundBetTimes"))
if (!$util.isInteger(message.roundBetTimes))
return "roundBetTimes: integer expected";
if (message.totalBetChip != null && message.hasOwnProperty("totalBetChip"))
if (!$util.isInteger(message.totalBetChip))
return "totalBetChip: integer expected";
if (message.betRole != null && message.hasOwnProperty("betRole")) {
let error = $root.api.BetRole.verify(message.betRole);
if (error)
@ -5621,6 +5657,10 @@ export const api = $root.api = (() => {
message.lastStatus = object.lastStatus | 0;
if (object.master != null)
message.master = Boolean(object.master);
if (object.roundBetTimes != null)
message.roundBetTimes = object.roundBetTimes | 0;
if (object.totalBetChip != null)
message.totalBetChip = object.totalBetChip | 0;
if (object.betRole != null) {
if (typeof object.betRole !== "object")
throw TypeError(".api.TablePlayer.betRole: object expected");
@ -5667,6 +5707,8 @@ export const api = $root.api = (() => {
object.status = 0;
object.lastStatus = 0;
object.master = false;
object.roundBetTimes = 0;
object.totalBetChip = 0;
object.betRole = null;
}
if (message.robot != null && message.hasOwnProperty("robot"))
@ -5688,6 +5730,10 @@ export const api = $root.api = (() => {
object.lastStatus = message.lastStatus;
if (message.master != null && message.hasOwnProperty("master"))
object.master = message.master;
if (message.roundBetTimes != null && message.hasOwnProperty("roundBetTimes"))
object.roundBetTimes = message.roundBetTimes;
if (message.totalBetChip != null && message.hasOwnProperty("totalBetChip"))
object.totalBetChip = message.totalBetChip;
if (message.betRole != null && message.hasOwnProperty("betRole"))
object.betRole = $root.api.BetRole.toObject(message.betRole, options);
if (message.handCard && message.handCard.length) {
@ -5960,8 +6006,9 @@ export const api = $root.api = (() => {
* Properties of a BetRole.
* @memberof api
* @interface IBetRole
* @property {number|null} [minChip] BetRole minChip
* @property {number|null} [maxChip] BetRole maxChip
* @property {number|null} [betMin] BetRole betMin
* @property {number|null} [betMax] BetRole betMax
* @property {Array.<number>|null} [betOpts] BetRole betOpts
*/
/**
@ -5973,6 +6020,7 @@ export const api = $root.api = (() => {
* @param {api.IBetRole=} [properties] Properties to set
*/
function BetRole(properties) {
this.betOpts = [];
if (properties)
for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
@ -5980,20 +6028,28 @@ export const api = $root.api = (() => {
}
/**
* BetRole minChip.
* @member {number} minChip
* BetRole betMin.
* @member {number} betMin
* @memberof api.BetRole
* @instance
*/
BetRole.prototype.minChip = 0;
BetRole.prototype.betMin = 0;
/**
* BetRole maxChip.
* @member {number} maxChip
* BetRole betMax.
* @member {number} betMax
* @memberof api.BetRole
* @instance
*/
BetRole.prototype.maxChip = 0;
BetRole.prototype.betMax = 0;
/**
* BetRole betOpts.
* @member {Array.<number>} betOpts
* @memberof api.BetRole
* @instance
*/
BetRole.prototype.betOpts = $util.emptyArray;
/**
* Creates a new BetRole instance using the specified properties.
@ -6019,10 +6075,16 @@ export const api = $root.api = (() => {
BetRole.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.minChip != null && Object.hasOwnProperty.call(message, "minChip"))
writer.uint32(/* id 1, wireType 0 =*/8).int32(message.minChip);
if (message.maxChip != null && Object.hasOwnProperty.call(message, "maxChip"))
writer.uint32(/* id 2, wireType 0 =*/16).int32(message.maxChip);
if (message.betMin != null && Object.hasOwnProperty.call(message, "betMin"))
writer.uint32(/* id 1, wireType 0 =*/8).int32(message.betMin);
if (message.betMax != null && Object.hasOwnProperty.call(message, "betMax"))
writer.uint32(/* id 2, wireType 0 =*/16).int32(message.betMax);
if (message.betOpts != null && message.betOpts.length) {
writer.uint32(/* id 13, wireType 2 =*/106).fork();
for (let i = 0; i < message.betOpts.length; ++i)
writer.int32(message.betOpts[i]);
writer.ldelim();
}
return writer;
};
@ -6058,11 +6120,22 @@ export const api = $root.api = (() => {
let tag = reader.uint32();
switch (tag >>> 3) {
case 1: {
message.minChip = reader.int32();
message.betMin = reader.int32();
break;
}
case 2: {
message.maxChip = reader.int32();
message.betMax = reader.int32();
break;
}
case 13: {
if (!(message.betOpts && message.betOpts.length))
message.betOpts = [];
if ((tag & 7) === 2) {
let end2 = reader.uint32() + reader.pos;
while (reader.pos < end2)
message.betOpts.push(reader.int32());
} else
message.betOpts.push(reader.int32());
break;
}
default:
@ -6100,12 +6173,19 @@ export const api = $root.api = (() => {
BetRole.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.minChip != null && message.hasOwnProperty("minChip"))
if (!$util.isInteger(message.minChip))
return "minChip: integer expected";
if (message.maxChip != null && message.hasOwnProperty("maxChip"))
if (!$util.isInteger(message.maxChip))
return "maxChip: integer expected";
if (message.betMin != null && message.hasOwnProperty("betMin"))
if (!$util.isInteger(message.betMin))
return "betMin: integer expected";
if (message.betMax != null && message.hasOwnProperty("betMax"))
if (!$util.isInteger(message.betMax))
return "betMax: integer expected";
if (message.betOpts != null && message.hasOwnProperty("betOpts")) {
if (!Array.isArray(message.betOpts))
return "betOpts: array expected";
for (let i = 0; i < message.betOpts.length; ++i)
if (!$util.isInteger(message.betOpts[i]))
return "betOpts: integer[] expected";
}
return null;
};
@ -6121,10 +6201,17 @@ export const api = $root.api = (() => {
if (object instanceof $root.api.BetRole)
return object;
let message = new $root.api.BetRole();
if (object.minChip != null)
message.minChip = object.minChip | 0;
if (object.maxChip != null)
message.maxChip = object.maxChip | 0;
if (object.betMin != null)
message.betMin = object.betMin | 0;
if (object.betMax != null)
message.betMax = object.betMax | 0;
if (object.betOpts) {
if (!Array.isArray(object.betOpts))
throw TypeError(".api.BetRole.betOpts: array expected");
message.betOpts = [];
for (let i = 0; i < object.betOpts.length; ++i)
message.betOpts[i] = object.betOpts[i] | 0;
}
return message;
};
@ -6141,14 +6228,21 @@ export const api = $root.api = (() => {
if (!options)
options = {};
let object = {};
if (options.arrays || options.defaults)
object.betOpts = [];
if (options.defaults) {
object.minChip = 0;
object.maxChip = 0;
object.betMin = 0;
object.betMax = 0;
}
if (message.betMin != null && message.hasOwnProperty("betMin"))
object.betMin = message.betMin;
if (message.betMax != null && message.hasOwnProperty("betMax"))
object.betMax = message.betMax;
if (message.betOpts && message.betOpts.length) {
object.betOpts = [];
for (let j = 0; j < message.betOpts.length; ++j)
object.betOpts[j] = message.betOpts[j];
}
if (message.minChip != null && message.hasOwnProperty("minChip"))
object.minChip = message.minChip;
if (message.maxChip != null && message.hasOwnProperty("maxChip"))
object.maxChip = message.maxChip;
return object;
};
@ -6706,25 +6800,25 @@ export const api = $root.api = (() => {
return ResDismissGameTable;
})();
api.ReqPlaceBet = (function() {
api.ReqBetting = (function() {
/**
* Properties of a ReqPlaceBet.
* Properties of a ReqBetting.
* @memberof api
* @interface IReqPlaceBet
* @property {number|null} [betType] ReqPlaceBet betType
* @property {number|null} [betChip] ReqPlaceBet betChip
* @interface IReqBetting
* @property {number|null} [betType] ReqBetting betType
* @property {number|null} [betChip] ReqBetting betChip
*/
/**
* Constructs a new ReqPlaceBet.
* Constructs a new ReqBetting.
* @memberof api
* @classdesc Represents a ReqPlaceBet.
* @implements IReqPlaceBet
* @classdesc Represents a ReqBetting.
* @implements IReqBetting
* @constructor
* @param {api.IReqPlaceBet=} [properties] Properties to set
* @param {api.IReqBetting=} [properties] Properties to set
*/
function ReqPlaceBet(properties) {
function ReqBetting(properties) {
if (properties)
for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
@ -6732,43 +6826,43 @@ export const api = $root.api = (() => {
}
/**
* ReqPlaceBet betType.
* ReqBetting betType.
* @member {number} betType
* @memberof api.ReqPlaceBet
* @memberof api.ReqBetting
* @instance
*/
ReqPlaceBet.prototype.betType = 0;
ReqBetting.prototype.betType = 0;
/**
* ReqPlaceBet betChip.
* ReqBetting betChip.
* @member {number} betChip
* @memberof api.ReqPlaceBet
* @memberof api.ReqBetting
* @instance
*/
ReqPlaceBet.prototype.betChip = 0;
ReqBetting.prototype.betChip = 0;
/**
* Creates a new ReqPlaceBet instance using the specified properties.
* Creates a new ReqBetting instance using the specified properties.
* @function create
* @memberof api.ReqPlaceBet
* @memberof api.ReqBetting
* @static
* @param {api.IReqPlaceBet=} [properties] Properties to set
* @returns {api.ReqPlaceBet} ReqPlaceBet instance
* @param {api.IReqBetting=} [properties] Properties to set
* @returns {api.ReqBetting} ReqBetting instance
*/
ReqPlaceBet.create = function create(properties) {
return new ReqPlaceBet(properties);
ReqBetting.create = function create(properties) {
return new ReqBetting(properties);
};
/**
* Encodes the specified ReqPlaceBet message. Does not implicitly {@link api.ReqPlaceBet.verify|verify} messages.
* Encodes the specified ReqBetting message. Does not implicitly {@link api.ReqBetting.verify|verify} messages.
* @function encode
* @memberof api.ReqPlaceBet
* @memberof api.ReqBetting
* @static
* @param {api.IReqPlaceBet} message ReqPlaceBet message or plain object to encode
* @param {api.IReqBetting} message ReqBetting message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
ReqPlaceBet.encode = function encode(message, writer) {
ReqBetting.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.betType != null && Object.hasOwnProperty.call(message, "betType"))
@ -6779,33 +6873,33 @@ export const api = $root.api = (() => {
};
/**
* Encodes the specified ReqPlaceBet message, length delimited. Does not implicitly {@link api.ReqPlaceBet.verify|verify} messages.
* Encodes the specified ReqBetting message, length delimited. Does not implicitly {@link api.ReqBetting.verify|verify} messages.
* @function encodeDelimited
* @memberof api.ReqPlaceBet
* @memberof api.ReqBetting
* @static
* @param {api.IReqPlaceBet} message ReqPlaceBet message or plain object to encode
* @param {api.IReqBetting} message ReqBetting message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
ReqPlaceBet.encodeDelimited = function encodeDelimited(message, writer) {
ReqBetting.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes a ReqPlaceBet message from the specified reader or buffer.
* Decodes a ReqBetting message from the specified reader or buffer.
* @function decode
* @memberof api.ReqPlaceBet
* @memberof api.ReqBetting
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {api.ReqPlaceBet} ReqPlaceBet
* @returns {api.ReqBetting} ReqBetting
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
ReqPlaceBet.decode = function decode(reader, length) {
ReqBetting.decode = function decode(reader, length) {
if (!(reader instanceof $Reader))
reader = $Reader.create(reader);
let end = length === undefined ? reader.len : reader.pos + length, message = new $root.api.ReqPlaceBet();
let end = length === undefined ? reader.len : reader.pos + length, message = new $root.api.ReqBetting();
while (reader.pos < end) {
let tag = reader.uint32();
switch (tag >>> 3) {
@ -6826,30 +6920,30 @@ export const api = $root.api = (() => {
};
/**
* Decodes a ReqPlaceBet message from the specified reader or buffer, length delimited.
* Decodes a ReqBetting message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof api.ReqPlaceBet
* @memberof api.ReqBetting
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {api.ReqPlaceBet} ReqPlaceBet
* @returns {api.ReqBetting} ReqBetting
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
ReqPlaceBet.decodeDelimited = function decodeDelimited(reader) {
ReqBetting.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies a ReqPlaceBet message.
* Verifies a ReqBetting message.
* @function verify
* @memberof api.ReqPlaceBet
* @memberof api.ReqBetting
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
ReqPlaceBet.verify = function verify(message) {
ReqBetting.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.betType != null && message.hasOwnProperty("betType"))
@ -6862,17 +6956,17 @@ export const api = $root.api = (() => {
};
/**
* Creates a ReqPlaceBet message from a plain object. Also converts values to their respective internal types.
* Creates a ReqBetting message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof api.ReqPlaceBet
* @memberof api.ReqBetting
* @static
* @param {Object.<string,*>} object Plain object
* @returns {api.ReqPlaceBet} ReqPlaceBet
* @returns {api.ReqBetting} ReqBetting
*/
ReqPlaceBet.fromObject = function fromObject(object) {
if (object instanceof $root.api.ReqPlaceBet)
ReqBetting.fromObject = function fromObject(object) {
if (object instanceof $root.api.ReqBetting)
return object;
let message = new $root.api.ReqPlaceBet();
let message = new $root.api.ReqBetting();
if (object.betType != null)
message.betType = object.betType | 0;
if (object.betChip != null)
@ -6881,15 +6975,15 @@ export const api = $root.api = (() => {
};
/**
* Creates a plain object from a ReqPlaceBet message. Also converts values to other types if specified.
* Creates a plain object from a ReqBetting message. Also converts values to other types if specified.
* @function toObject
* @memberof api.ReqPlaceBet
* @memberof api.ReqBetting
* @static
* @param {api.ReqPlaceBet} message ReqPlaceBet
* @param {api.ReqBetting} message ReqBetting
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
ReqPlaceBet.toObject = function toObject(message, options) {
ReqBetting.toObject = function toObject(message, options) {
if (!options)
options = {};
let object = {};
@ -6905,32 +6999,32 @@ export const api = $root.api = (() => {
};
/**
* Converts this ReqPlaceBet to JSON.
* Converts this ReqBetting to JSON.
* @function toJSON
* @memberof api.ReqPlaceBet
* @memberof api.ReqBetting
* @instance
* @returns {Object.<string,*>} JSON object
*/
ReqPlaceBet.prototype.toJSON = function toJSON() {
ReqBetting.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
/**
* Gets the default type url for ReqPlaceBet
* Gets the default type url for ReqBetting
* @function getTypeUrl
* @memberof api.ReqPlaceBet
* @memberof api.ReqBetting
* @static
* @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
* @returns {string} The default type url
*/
ReqPlaceBet.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
ReqBetting.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
if (typeUrlPrefix === undefined) {
typeUrlPrefix = "type.googleapis.com";
}
return typeUrlPrefix + "/api.ReqPlaceBet";
return typeUrlPrefix + "/api.ReqBetting";
};
return ReqPlaceBet;
return ReqBetting;
})();
api.ResNoticePlayerLine = (function() {
@ -7220,6 +7314,455 @@ export const api = $root.api = (() => {
return ResNoticePlayerLine;
})();
api.ResGameEndSettle = (function() {
/**
* Properties of a ResGameEndSettle.
* @memberof api
* @interface IResGameEndSettle
* @property {api.IResGameFullStatus|null} [game] ResGameEndSettle game
*/
/**
* Constructs a new ResGameEndSettle.
* @memberof api
* @classdesc Represents a ResGameEndSettle.
* @implements IResGameEndSettle
* @constructor
* @param {api.IResGameEndSettle=} [properties] Properties to set
*/
function ResGameEndSettle(properties) {
if (properties)
for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
this[keys[i]] = properties[keys[i]];
}
/**
* ResGameEndSettle game.
* @member {api.IResGameFullStatus|null|undefined} game
* @memberof api.ResGameEndSettle
* @instance
*/
ResGameEndSettle.prototype.game = null;
/**
* Creates a new ResGameEndSettle instance using the specified properties.
* @function create
* @memberof api.ResGameEndSettle
* @static
* @param {api.IResGameEndSettle=} [properties] Properties to set
* @returns {api.ResGameEndSettle} ResGameEndSettle instance
*/
ResGameEndSettle.create = function create(properties) {
return new ResGameEndSettle(properties);
};
/**
* Encodes the specified ResGameEndSettle message. Does not implicitly {@link api.ResGameEndSettle.verify|verify} messages.
* @function encode
* @memberof api.ResGameEndSettle
* @static
* @param {api.IResGameEndSettle} message ResGameEndSettle message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
ResGameEndSettle.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.game != null && Object.hasOwnProperty.call(message, "game"))
$root.api.ResGameFullStatus.encode(message.game, writer.uint32(/* id 11, wireType 2 =*/90).fork()).ldelim();
return writer;
};
/**
* Encodes the specified ResGameEndSettle message, length delimited. Does not implicitly {@link api.ResGameEndSettle.verify|verify} messages.
* @function encodeDelimited
* @memberof api.ResGameEndSettle
* @static
* @param {api.IResGameEndSettle} message ResGameEndSettle message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
ResGameEndSettle.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes a ResGameEndSettle message from the specified reader or buffer.
* @function decode
* @memberof api.ResGameEndSettle
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {api.ResGameEndSettle} ResGameEndSettle
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
ResGameEndSettle.decode = function decode(reader, length) {
if (!(reader instanceof $Reader))
reader = $Reader.create(reader);
let end = length === undefined ? reader.len : reader.pos + length, message = new $root.api.ResGameEndSettle();
while (reader.pos < end) {
let tag = reader.uint32();
switch (tag >>> 3) {
case 11: {
message.game = $root.api.ResGameFullStatus.decode(reader, reader.uint32());
break;
}
default:
reader.skipType(tag & 7);
break;
}
}
return message;
};
/**
* Decodes a ResGameEndSettle message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof api.ResGameEndSettle
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {api.ResGameEndSettle} ResGameEndSettle
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
ResGameEndSettle.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies a ResGameEndSettle message.
* @function verify
* @memberof api.ResGameEndSettle
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
ResGameEndSettle.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.game != null && message.hasOwnProperty("game")) {
let error = $root.api.ResGameFullStatus.verify(message.game);
if (error)
return "game." + error;
}
return null;
};
/**
* Creates a ResGameEndSettle message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof api.ResGameEndSettle
* @static
* @param {Object.<string,*>} object Plain object
* @returns {api.ResGameEndSettle} ResGameEndSettle
*/
ResGameEndSettle.fromObject = function fromObject(object) {
if (object instanceof $root.api.ResGameEndSettle)
return object;
let message = new $root.api.ResGameEndSettle();
if (object.game != null) {
if (typeof object.game !== "object")
throw TypeError(".api.ResGameEndSettle.game: object expected");
message.game = $root.api.ResGameFullStatus.fromObject(object.game);
}
return message;
};
/**
* Creates a plain object from a ResGameEndSettle message. Also converts values to other types if specified.
* @function toObject
* @memberof api.ResGameEndSettle
* @static
* @param {api.ResGameEndSettle} message ResGameEndSettle
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
ResGameEndSettle.toObject = function toObject(message, options) {
if (!options)
options = {};
let object = {};
if (options.defaults)
object.game = null;
if (message.game != null && message.hasOwnProperty("game"))
object.game = $root.api.ResGameFullStatus.toObject(message.game, options);
return object;
};
/**
* Converts this ResGameEndSettle to JSON.
* @function toJSON
* @memberof api.ResGameEndSettle
* @instance
* @returns {Object.<string,*>} JSON object
*/
ResGameEndSettle.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
/**
* Gets the default type url for ResGameEndSettle
* @function getTypeUrl
* @memberof api.ResGameEndSettle
* @static
* @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
* @returns {string} The default type url
*/
ResGameEndSettle.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
if (typeUrlPrefix === undefined) {
typeUrlPrefix = "type.googleapis.com";
}
return typeUrlPrefix + "/api.ResGameEndSettle";
};
return ResGameEndSettle;
})();
api.ResCalcWinnerChip = (function() {
/**
* Properties of a ResCalcWinnerChip.
* @memberof api
* @interface IResCalcWinnerChip
* @property {Object.<string,number>|null} [playersWinChip] ResCalcWinnerChip playersWinChip
*/
/**
* Constructs a new ResCalcWinnerChip.
* @memberof api
* @classdesc Represents a ResCalcWinnerChip.
* @implements IResCalcWinnerChip
* @constructor
* @param {api.IResCalcWinnerChip=} [properties] Properties to set
*/
function ResCalcWinnerChip(properties) {
this.playersWinChip = {};
if (properties)
for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
this[keys[i]] = properties[keys[i]];
}
/**
* ResCalcWinnerChip playersWinChip.
* @member {Object.<string,number>} playersWinChip
* @memberof api.ResCalcWinnerChip
* @instance
*/
ResCalcWinnerChip.prototype.playersWinChip = $util.emptyObject;
/**
* Creates a new ResCalcWinnerChip instance using the specified properties.
* @function create
* @memberof api.ResCalcWinnerChip
* @static
* @param {api.IResCalcWinnerChip=} [properties] Properties to set
* @returns {api.ResCalcWinnerChip} ResCalcWinnerChip instance
*/
ResCalcWinnerChip.create = function create(properties) {
return new ResCalcWinnerChip(properties);
};
/**
* Encodes the specified ResCalcWinnerChip message. Does not implicitly {@link api.ResCalcWinnerChip.verify|verify} messages.
* @function encode
* @memberof api.ResCalcWinnerChip
* @static
* @param {api.IResCalcWinnerChip} message ResCalcWinnerChip message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
ResCalcWinnerChip.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.playersWinChip != null && Object.hasOwnProperty.call(message, "playersWinChip"))
for (let keys = Object.keys(message.playersWinChip), i = 0; i < keys.length; ++i)
writer.uint32(/* id 9, wireType 2 =*/74).fork().uint32(/* id 1, wireType 0 =*/8).int64(keys[i]).uint32(/* id 2, wireType 0 =*/16).int32(message.playersWinChip[keys[i]]).ldelim();
return writer;
};
/**
* Encodes the specified ResCalcWinnerChip message, length delimited. Does not implicitly {@link api.ResCalcWinnerChip.verify|verify} messages.
* @function encodeDelimited
* @memberof api.ResCalcWinnerChip
* @static
* @param {api.IResCalcWinnerChip} message ResCalcWinnerChip message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
ResCalcWinnerChip.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes a ResCalcWinnerChip message from the specified reader or buffer.
* @function decode
* @memberof api.ResCalcWinnerChip
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {api.ResCalcWinnerChip} ResCalcWinnerChip
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
ResCalcWinnerChip.decode = function decode(reader, length) {
if (!(reader instanceof $Reader))
reader = $Reader.create(reader);
let end = length === undefined ? reader.len : reader.pos + length, message = new $root.api.ResCalcWinnerChip(), key, value;
while (reader.pos < end) {
let tag = reader.uint32();
switch (tag >>> 3) {
case 9: {
if (message.playersWinChip === $util.emptyObject)
message.playersWinChip = {};
let end2 = reader.uint32() + reader.pos;
key = 0;
value = 0;
while (reader.pos < end2) {
let tag2 = reader.uint32();
switch (tag2 >>> 3) {
case 1:
key = reader.int64();
break;
case 2:
value = reader.int32();
break;
default:
reader.skipType(tag2 & 7);
break;
}
}
message.playersWinChip[typeof key === "object" ? $util.longToHash(key) : key] = value;
break;
}
default:
reader.skipType(tag & 7);
break;
}
}
return message;
};
/**
* Decodes a ResCalcWinnerChip message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof api.ResCalcWinnerChip
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {api.ResCalcWinnerChip} ResCalcWinnerChip
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
ResCalcWinnerChip.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies a ResCalcWinnerChip message.
* @function verify
* @memberof api.ResCalcWinnerChip
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
ResCalcWinnerChip.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.playersWinChip != null && message.hasOwnProperty("playersWinChip")) {
if (!$util.isObject(message.playersWinChip))
return "playersWinChip: object expected";
let key = Object.keys(message.playersWinChip);
for (let i = 0; i < key.length; ++i) {
if (!$util.key64Re.test(key[i]))
return "playersWinChip: integer|Long key{k:int64} expected";
if (!$util.isInteger(message.playersWinChip[key[i]]))
return "playersWinChip: integer{k:int64} expected";
}
}
return null;
};
/**
* Creates a ResCalcWinnerChip message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof api.ResCalcWinnerChip
* @static
* @param {Object.<string,*>} object Plain object
* @returns {api.ResCalcWinnerChip} ResCalcWinnerChip
*/
ResCalcWinnerChip.fromObject = function fromObject(object) {
if (object instanceof $root.api.ResCalcWinnerChip)
return object;
let message = new $root.api.ResCalcWinnerChip();
if (object.playersWinChip) {
if (typeof object.playersWinChip !== "object")
throw TypeError(".api.ResCalcWinnerChip.playersWinChip: object expected");
message.playersWinChip = {};
for (let keys = Object.keys(object.playersWinChip), i = 0; i < keys.length; ++i)
message.playersWinChip[keys[i]] = object.playersWinChip[keys[i]] | 0;
}
return message;
};
/**
* Creates a plain object from a ResCalcWinnerChip message. Also converts values to other types if specified.
* @function toObject
* @memberof api.ResCalcWinnerChip
* @static
* @param {api.ResCalcWinnerChip} message ResCalcWinnerChip
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
ResCalcWinnerChip.toObject = function toObject(message, options) {
if (!options)
options = {};
let object = {};
if (options.objects || options.defaults)
object.playersWinChip = {};
let keys2;
if (message.playersWinChip && (keys2 = Object.keys(message.playersWinChip)).length) {
object.playersWinChip = {};
for (let j = 0; j < keys2.length; ++j)
object.playersWinChip[keys2[j]] = message.playersWinChip[keys2[j]];
}
return object;
};
/**
* Converts this ResCalcWinnerChip to JSON.
* @function toJSON
* @memberof api.ResCalcWinnerChip
* @instance
* @returns {Object.<string,*>} JSON object
*/
ResCalcWinnerChip.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
/**
* Gets the default type url for ResCalcWinnerChip
* @function getTypeUrl
* @memberof api.ResCalcWinnerChip
* @static
* @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
* @returns {string} The default type url
*/
ResCalcWinnerChip.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
if (typeUrlPrefix === undefined) {
typeUrlPrefix = "type.googleapis.com";
}
return typeUrlPrefix + "/api.ResCalcWinnerChip";
};
return ResCalcWinnerChip;
})();
return api;
})();

12
internal/game/player.go

@ -14,7 +14,7 @@ type Player struct {
Cards [2]*Card // 手牌
Chip int32 // 玩家筹码
RoundChip int32 // 该回合已下注筹码
TotalBetChip int32 // 本次游戏已下注筹码
Status int32 // 状态: 1待准备开始,2已准备开始,3等待其他玩家动作,4第一回合小盲注跟注, [5待大盲注,5待小盲注,] 6待跟注,7已弃牌
LastStatus int32 // 变化前一个状态
BetOpts []int32 // status=[4,6]时下注可操作按钮: 1跟注,2加注(-[0]+),3All-In,4弃牌,5过牌
@ -36,7 +36,15 @@ func (p *Player) Init() {
// RoundInit 下一回合初始化
func (p *Player) RoundInit() {
p.RoundChip = 0
p.SetStatus(1)
p.BetMin = 0
p.BetMax = 0
p.BetOpts = make([]int32, 0)
p.TotalBetChip = 0
p.Hand = nil
p.Cards[0] = nil
p.Cards[1] = nil
p.RoundInit()
}
func (p *Player) SetStatus(status int32) {

185
internal/game/table.go

@ -38,16 +38,29 @@ type Table struct {
// TODO game logs7
}
// Init 初始化桌面
func (t *Table) Init() {
// InitGameAndPlayerStatus 初始化桌面
func (t *Table) InitGameAndPlayerStatus() {
if t.PlayersLock == nil {
t.PlayersLock = &sync.Mutex{}
}
if t.ChipLock == nil {
t.ChipLock = &sync.Mutex{}
}
t.PublicCards = [5]*Card{nil, nil, nil, nil, nil}
if t.Dealer == nil {
t.Dealer = NewDealer()
t.RoundTimes = 0
} else {
t.Dealer.Init()
}
t.Stage = 1
t.BigBlindPos = 0
t.SmallBlindPos = 0
for _, p := range t.Players {
if p != nil {
p.RoundInit()
}
}
}
func (t *Table) PlayerCount() int32 {
@ -150,7 +163,14 @@ func (t *Table) BuildResGameFullStatus() *api.ResGameFullStatus {
Status: p.Status,
LastStatus: p.LastStatus,
Master: t.MasterId == p.Id,
RoundBetTimes: p.RoundBetTimes,
TotalBetChip: p.TotalBetChip,
HandCard: make([]*api.Card, 2),
BetRole: &api.BetRole{
BetMin: p.BetMin,
BetMax: p.BetMax,
BetOpts: p.BetOpts,
},
}
// 玩家手牌
for j, card := range p.Cards {
@ -162,8 +182,6 @@ func (t *Table) BuildResGameFullStatus() *api.ResGameFullStatus {
}
resGame.Players[i] = player
}
// TODO 机器人
return resGame
}
@ -185,6 +203,7 @@ func (t *Table) NoticeGameFullStatus() {
}
}
// NoticeAllPlayer 发送消息到牌桌所有玩家
func (t *Table) NoticeAllPlayer(message proto.Message) {
for _, player := range t.Players {
if player != nil && player.ProtoWriter != nil {
@ -193,13 +212,75 @@ func (t *Table) NoticeAllPlayer(message proto.Message) {
}
}
// CurrentRoundEnd 当前回合结束
func (t *Table) CurrentRoundEnd() error {
// TODO 游戏结束,开牌结算
if t.RoundTimes >= 4 {
// 比牌
t.Stage = 7
// RoundOver 当前回合结束
func (t *Table) RoundOver() error {
// 游戏结束,开牌结算
if t.RoundTimes >= 4 || 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 {
case 2: // 发3张公共牌(翻牌)
for i := 0; i < 5; i++ {
if i < 3 {
t.PublicCards[i] = t.Dealer.Deal()
continue
}
// 第4,5张牌置空
t.PublicCards[i] = nil
}
case 3: // 发第4张公共牌(转牌turn)
t.PublicCards[3] = t.Dealer.Deal()
t.Stage = 5
case 4: // 发第5张公共牌(河牌river)
t.PublicCards[4] = t.Dealer.Deal()
t.Stage = 6
}
return nil
}
// 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) {
return errors.New("未到最后一轮下注且由1一个以上玩家持有牌")
}
t.Stage = 7
if 1 == len(leftPlayers) {
// 还剩一个玩家未弃牌
winners = leftPlayers
} else {
// 剩余玩家大于1: 比牌
for _, p := range t.Players {
if p != nil {
continue
@ -220,6 +301,7 @@ func (t *Table) CurrentRoundEnd() error {
}
}
}
}
winnerCount := int32(len(winners))
// TODO 所有玩家输赢消息 ResCalcWinnerChip
if winnerCount == 1 {
@ -252,54 +334,17 @@ func (t *Table) CurrentRoundEnd() error {
t.Chip = 0
}
// TODO 通知输赢金额
// TODO 初始化牌桌及状态
t.InitGameAndPlayerStatus();
go func() {
// TODO 等前端展示3秒钟后,牌桌回到初始状态,剔除掉线玩家
}()
return nil
}
// 开启下一回合, 重置一些状态
t.RoundRaiseTimes = 0
t.RoundTimes++
for _, p := range t.Players {
if p != nil {
p.RoundBetTimes = 0
p.RoundChip = 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 {
case 2: // 发3张公共牌(翻牌)
for i := 0; i < 5; i++ {
if i < 3 {
t.PublicCards[i] = t.Dealer.Deal()
continue
}
// 第4,5张牌置空
t.PublicCards[i] = nil
}
case 3: // 发第4张公共牌(转牌turn)
t.PublicCards[3] = t.Dealer.Deal()
t.Stage = 5
case 4: // 发第5张公共牌(河牌river)
t.PublicCards[4] = t.Dealer.Deal()
t.Stage = 6
}
return nil
}
// DiscardAllPlayerWin 其他玩家弃牌,玩家赢
func (t *Table) DiscardAllPlayerWin(player *Player) {
@ -310,20 +355,20 @@ func (t *Table) DiscardAllPlayerWin(player *Player) {
//
//}
type Stage int
func (s *Stage) String() string {
return stageNames[*s]
}
// 游戏阶段名称
var stageNames = []string{"Stage00WaitBegin", "Stage10Perflop", "Stage20Flop", "Stage30Turn", "Stage40River"}
// 游戏阶段
const (
Stage00WaitBegin Stage = iota // 等待游戏开始
Stage10Perflop Stage = iota // 下大小盲注,然后没人发2张底牌,大盲注后面第一个玩家跟注、加注或放弃,依次顺时针表态
Stage20Flop Stage = iota // 发三张公牌,由小盲注开始顺时针表态
Stage30Turn Stage = iota // 发第四张公共牌,由小盲注开始顺时针表态
Stage40River Stage = iota // 发第五张牌,由小盲注开始顺时针表态,然后亮牌比大小
)
//type Stage int
//
//func (s *Stage) String() string {
// return stageNames[*s]
//}
//
//// 游戏阶段名称
//var stageNames = []string{"Stage00WaitBegin", "Stage10Perflop", "Stage20Flop", "Stage30Turn", "Stage40River"}
//
//// 游戏阶段
//const (
// Stage00WaitBegin Stage = iota // 等待游戏开始
// Stage10Perflop Stage = iota // 下大小盲注,然后没人发2张底牌,大盲注后面第一个玩家跟注、加注或放弃,依次顺时针表态
// Stage20Flop Stage = iota // 发三张公牌,由小盲注开始顺时针表态
// Stage30Turn Stage = iota // 发第四张公共牌,由小盲注开始顺时针表态
// Stage40River Stage = iota // 发第五张牌,由小盲注开始顺时针表态,然后亮牌比大小
//)

2
internal/server/wsroute.go

@ -37,6 +37,8 @@ func init() {
HandleNetPlayerMsg(&api.ReqCancelReady{}, service.HandleReqCancelReady)
// 开始游戏
HandleNetPlayerMsg(&api.ReqGameStart{}, service.HandleReqGameStart)
// 筹码下注
HandleNetPlayerMsg(&api.ReqBetting{}, service.HandleReqBetting)
}
func checkExistsTypeHandler(op int32, err error) {

63
internal/service/table.go

@ -48,7 +48,7 @@ func HandleReqCreateTable(account *session.NetAccount, msg *api.ReqCreateTable)
LimitInAmount: msg.BigBlind * 100,
TexasType: msg.TexasType,
}
table.Init()
table.InitGameAndPlayerStatus()
// 房主 [0]
// 扣除DB账户余额
@ -60,6 +60,7 @@ func HandleReqCreateTable(account *session.NetAccount, msg *api.ReqCreateTable)
Status: 1,
LastStatus: 0,
Chip: table.LimitInAmount,
TotalBetChip: 0,
Cards: [2]*game.Card{},
GameTable: table,
ProtoWriter: account.Client,
@ -154,6 +155,7 @@ func HandleReqJoinTable(account *session.NetAccount, msg *api.ReqJoinTable) (pro
Status: 1,
LastStatus: 0,
Chip: 0,
TotalBetChip: 0,
Cards: [2]*game.Card{nil, nil},
GameTable: table,
ProtoWriter: account.Client,
@ -360,8 +362,11 @@ func HandleReqGameStart(player *game.Player, msg *api.ReqGameStart) (proto.Messa
// 扣除大小盲注金额
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.Players[table.BigBlindPos].RoundBetTimes++
// table.Players[table.SmallBlindPos].RoundBetTimes++
@ -401,7 +406,7 @@ func HandleReqGameStart(player *game.Player, msg *api.ReqGameStart) (proto.Messa
optPos := table.NextPlayerPos(table.BigBlindPos)
optPlayer := table.Players[optPos]
optPlayer.SetStatus(4)
optPlayer.BetOpts = []int32{1, 2, 4}
optPlayer.BetOpts = []int32{2, 4}
optPlayer.BetMax = table.BigBlindChip
// 游戏类型处理最大下注额
switch table.TexasType {
@ -447,7 +452,7 @@ func HandleReqGameStart(player *game.Player, msg *api.ReqGameStart) (proto.Messa
return &api.ResSuccess{}, nil
}
// HandleReqPlaceBet 下注
// HandleReqBetting 下注
// 网易德州扑克:http://sports.163.com/special/poker_rule/?ivk_sa=1025883k
// 天天德州: http://game.people.com.cn/n/2014/0220/c40130-24413078.html
// wiki: https://zh.wikipedia.org/wiki/%E5%BE%B7%E5%B7%9E%E6%92%B2%E5%85%8B
@ -459,7 +464,7 @@ func HandleReqGameStart(player *game.Player, msg *api.ReqGameStart) (proto.Messa
// 盖牌(fold),即舍弃并覆盖手中的牌,放弃已投入底池的筹码退出该局。
// 跟注(call)投入了与所有其他未盖牌的牌手等量的筹码。
// 全下(all-in),投入了尚余的全部筹码。
func HandleReqPlaceBet(player *game.Player, msg *api.ReqPlaceBet) (proto.Message, error) {
func HandleReqBetting(player *game.Player, msg *api.ReqBetting) (proto.Message, error) {
player.Lock.Lock()
defer player.Lock.Unlock()
player.GameTable.ChipLock.Lock()
@ -472,10 +477,13 @@ func HandleReqPlaceBet(player *game.Player, msg *api.ReqPlaceBet) (proto.Message
return &api.ResFail{Msg: fmt.Sprintf("当前不可执行该操作#%d", msg.BetType)}, nil
}
// 投注结束广播牌桌状态
defer player.GameTable.NoticeGameFullStatus()
table := player.GameTable
var line1 string
var line2 string
var raise bool // 是否加注
betNotice := &api.ResNoticePlayerLine{PlayerId: player.Id}
switch msg.BetType {
case 1: // 跟注
if msg.BetChip != player.BetMin {
@ -516,48 +524,55 @@ func HandleReqPlaceBet(player *game.Player, msg *api.ReqPlaceBet) (proto.Message
case 4: // 弃牌
player.SetStatus(7)
line1 = "弃牌"
betNotice.Line1 = "弃牌"
// 剩余牌手数为1则结束
leftPlayers := collect.Filter(player.GameTable.Players, func(i int, p *game.Player) bool {
return p != nil && p.Status != 7
})
if len(leftPlayers) == 1 {
playerWin(leftPlayers[0])
err := table.RoundOver()
if err != nil {
return &api.ResFail{Code: 500, Msg: err.Error()}, nil
}
return &api.ResSuccess{}, nil
}
case 5: // 过牌
player.RoundBetTimes++
line1 = "过牌"
betNotice.Line1 = "过牌"
default:
return &api.ResFail{Msg: fmt.Sprintf("未知操作#%d", msg.BetType)}, nil
}
player.TotalBetChip += msg.BetChip
// 通知下注结果
if line1 != "" {
notice := &api.ResNoticePlayerLine{PlayerId: player.Id, Line1: line1, Line2: line2}
player.GameTable.NoticeAllPlayer(notice)
if betNotice.Line1 != "" {
player.GameTable.NoticeAllPlayer(betNotice)
}
player.SetStatus(3)
// 下注完成:若还有玩家未下注、加注,下一玩家继续下注;若该轮下注完成,发牌开启下一轮下注
// 下一位玩家:跟注
var nextPlayer *game.Player = player
for {
nextPlayerPos := table.NextPlayerPos(nextPlayer.PosIndex)
nextPlayer = table.Players[nextPlayerPos]
nextPlayerPos := table.NextHoldingCardPlayerPos(player.PosIndex)
nextPlayer := table.Players[nextPlayerPos]
if nextPlayer.Id == player.Id {
// TODO 开启下一轮
break
// 开启下一轮
err := table.RoundOver()
if err != nil {
return &api.ResFail{Code: 500, Msg: err.Error()}, nil
}
if nextPlayer.Status == 7 { // 已弃牌..
continue
return &api.ResSuccess{}, nil
}
if !raise {
// 当前玩家未加注, 判断是否结束本轮下注
if nextPlayer.RoundBetTimes > 0 {
// TODO 开启下一轮
// 开启下一轮
err := table.RoundOver()
if err != nil {
return &api.ResFail{Code: 500, Msg: err.Error()}, nil
}
}
}
// 判断下一玩家是否需要再下注: 下一玩家是否已下注,当前玩家是否跟注,
@ -595,7 +610,6 @@ func HandleReqPlaceBet(player *game.Player, msg *api.ReqPlaceBet) (proto.Message
nextPlayer.BetMax = msg.BetChip
}
}
}
// 依赌场规则而异,
// 若所余筹码All-in后仍低于最低加注金额,则此注仅视为跟注(call)而不能被当成加注(raise),亦及该圈若未有其他人再加注,则原加注者(此例中的第一位牌手)仅可跟注补齐或盖牌,于此圈不可再行加注
@ -603,8 +617,3 @@ func HandleReqPlaceBet(player *game.Player, msg *api.ReqPlaceBet) (proto.Message
return &api.ResSuccess{}, nil
}
// playerWin 玩家获胜,结算牌局
func playerWin(player *game.Player) {
}

2
tool/collect/collect.go

@ -20,7 +20,7 @@ func Count[T any](slice []T, isCount func(int, T) bool) int {
}
func Filter[T any](slice []T, predicate func(int, T) bool) []T {
res := []T{}
var res []T
for i, item := range slice {
if predicate(i, item) {
res = append(res, item)

Loading…
Cancel
Save