GolangはDoudizhuゲームサーバーを作成します[6]:トランプとカード
地主と地主への以前の呼びかけは終わりました、この章は基本的にカードゲームのカテゴリーに属します。
まず、タイムアウト期間を延長します。もうタイムアウトしないでください。続行する前に、終了するのを待つ必要があります。
select {
case <-ch:
log.Println("模拟打牌")
case <-time.After(time.Second * 10000): // 临时改成10000秒超时
log.Println("roundStart 超时")
}
次に、クライアントは2つのボタンを配置する必要があります。1つは合格、、、およびもう1つはチェック済みカードを削除するためのものです。
// TMainForm 主窗体
type TMainForm struct {
*vcl.TForm
pClient *tcpclient.TTCPClient
nTableIndex uint32 // 桌子编号
Btn1 *vcl.TButton //开始连接
Btn2 *vcl.TButton //快速加入
Edit1 *vcl.TEdit
Label1 *vcl.TLabel
Label2 *vcl.TLabel
Label3 *vcl.TLabel
CheckBoxGroup [20]*vcl.TCheckBox
Btn3 *vcl.TButton //叫地主
Btn4 *vcl.TButton // 不叫
Btn5 *vcl.TButton // 打掉指定的牌
Btn6 *vcl.TButton // 过牌
}
self.Btn5 = vcl.NewButton(self)
self.Btn5.SetParent(self) //设置爸爸
self.Btn5.SetBounds(410, 50, 88, 28) //设置位置
self.Btn5.SetCaption("打牌") //
self.Btn5.SetOnClick(self.OnButton3Click) // 打牌按钮点击事件
self.Btn6 = vcl.NewButton(self)
self.Btn6.SetParent(self) //设置爸爸
self.Btn6.SetBounds(510, 50, 88, 28) //设置位置
self.Btn6.SetCaption("过牌") //
self.Btn6.SetOnClick(self.OnButton4Click) // 不叫按钮1点击事件
結果として得られるインターフェースはおそらくそのような醜いです...
クライアントの準備ができています。プロトコルの処理はより複雑です。2つのプロトコルがあります。1つ目は、クライアントがサーバーにカードを再生するかどうかと、どのカードを再生したかを指示することです。
2つ目は、サーバーが3社にブロードキャストし、現在再生されているカードと現在手元にあるカードをブロードキャストすることです。もちろん、3社すべてに残っているカードの数など、追加情報が含まれている可能性があります。現在の爆弾は2倍になっています。何回
最初に最初の契約を見てください。以前の契約とは異なるコンテンツを追加する必要があるかもしれません。
// 我过, 我要出对三
message TOutCardReq
{
optional int32 Status = 1; // 状态, 其实可以不要( 目前暂时定, 1过牌, 2打牌)
optional int32 OutCount = 2; // 出牌的牌的数量
repeated int32 OutCards = 3; // 出牌的牌的具体内容
}
2番目の契約を見ると、前の契約とは異なるコンテンツを追加する必要がある場合もあります。
//"游戏正式开始, 请出牌"
message TOutCardBc
{
optional int32 Position = 1; // 轮到当前某个位置的玩家进行出牌
optional int32 StartPosition = 2; // 本轮开始的玩家的位置
optional int32 LargePosition = 3; // 本轮目前最大牌的玩家位置(也就是上一个出过牌的人)
optional int32 Round = 4; // 轮次是
optional int32 Hand = 5; // 手次是
optional int32 CardType = 6; // 已经出的牌的类型是
optional int32 CardPoint = 7; // 已经出的牌的点数是
optional TCards OutCards = 8; // 上一次出牌的牌的具体内容
optional TCards YourCards = 9; // 你的牌
}
次に、クライアントでカードゲームロジックを作成します
// OnButton5Click 打牌
func (self *TMainForm) OnButton5Click(sender vcl.IObject) {
// 选中所有被check的按钮, 把他弄成要打的牌
pack := &ddzpb.TDDZ{}
pack.Command = proto.Int32(26)
pack.OutCardReq = &ddzpb.TOutCardReq{}
pack.OutCardReq.Status = proto.Int32(1) // 1打掉, 2不打
pack.OutCardReq.TableIndex = proto.Uint32(self.nTableIndex) // 桌子号
// 在这里要准备插入牌
nOutCount := 0
pack.OutCardReq.OutCards = &ddzpb.TCards{}
for i := 0; i < 20; i++ {
// 如果被选上了.
if self.CheckBoxGroup[i].Checked() {
v := self.CheckBoxGroup[i].Tag()
pCard := c.NewCard(v)
log.Println(self.CheckBoxGroup[i].Tag(), pCard.ToStr())
nOutCount++
pack.OutCardReq.OutCards.CardValue = append(pack.OutCardReq.OutCards.CardValue, int32(v)) // 插入
}
}
pack.OutCardReq.OutCards.CardCount = proto.Int(nOutCount) // 补上数量
buff, _ := proto.Marshal(pack)
self.pClient.WritePack(buff)
}
// OnButton6Click 不打, 直接放弃, 要不起
func (self *TMainForm) OnButton6Click(sender vcl.IObject) {
pack := &ddzpb.TDDZ{}
pack.Command = proto.Int32(26)
pack.OutCardReq = &ddzpb.TOutCardReq{}
pack.OutCardReq.Status = proto.Int32(1) // 1打掉, 2不打
pack.OutCardReq.TableIndex = proto.Uint32(self.nTableIndex) // 桌子号
buff, _ := proto.Marshal(pack)
self.pClient.WritePack(buff)
}