Golang faz um servidor de jogo Doudizhu [6]: cartas de baralho e cartas
A chamada anterior para proprietários e proprietários acabou, este capítulo basicamente pertence à categoria de jogos de cartas.
Primeiro, estenda o período de tempo limite. Não limite mais o tempo limite. Devemos esperar terminar antes de continuar
select {
case <-ch:
log.Println("模拟打牌")
case <-time.After(time.Second * 10000): // 临时改成10000秒超时
log.Println("roundStart 超时")
}
Em segundo lugar, o cliente precisa colocar dois botões, um para passar ,,, e outro para remover os cartões marcados
// 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点击事件
A interface resultante é provavelmente tão feia ...
O cliente está pronto. O protocolo é mais complicado de lidar. Existem dois protocolos. O primeiro é que o cliente diz ao servidor se eu quero jogar cartas e quais cartas eu joguei.
A segunda é que o servidor transmite para 3 empresas, quais cartas estão sendo jogadas e quais cartas estão em sua mão e, claro, pode conter algumas informações adicionais, como quantas cartas faltam em todas as 3 empresas? A bomba atual dobrou Quantas vezes
Olhe primeiro o primeiro contrato, pode ser necessário adicionar conteúdo, que será diferente dos anteriores
// 我过, 我要出对三
message TOutCardReq
{
optional int32 Status = 1; // 状态, 其实可以不要( 目前暂时定, 1过牌, 2打牌)
optional int32 OutCount = 2; // 出牌的牌的数量
repeated int32 OutCards = 3; // 出牌的牌的具体内容
}
Olhando para o segundo contrato, você também pode precisar adicionar conteúdo, que será diferente do anterior.
//"游戏正式开始, 请出牌"
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; // 你的牌
}
Em seguida, faça uma lógica de jogo de cartas no cliente
// 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)
}