之前的叫地主和抢地主, 都是通过golang 的协程去模拟的
我们现在已经有正牌的客户端了. 首先要把超时时间从原先的5秒钟, 暂时延长到足够长的1000秒
然后去掉协程中的模拟. 改成通过服务器收到客户端消息来判断模拟
首先先在客户端 放两个按钮 一个叫 叫地主 一个叫不叫
self.Btn3 = vcl.NewButton(self)
self.Btn3.SetParent(self) //设置爸爸
self.Btn3.SetBounds(210, 50, 88, 28) //设置位置
self.Btn3.SetCaption("叫地主") //
self.Btn3.SetOnClick(self.OnButton3Click) // 叫地主按钮3点击事件
self.Btn4 = vcl.NewButton(self)
self.Btn4.SetParent(self) //设置爸爸
self.Btn4.SetBounds(310, 50, 88, 28) //设置位置
self.Btn4.SetCaption("不叫") //
self.Btn4.SetOnClick(self.OnButton4Click) // 不叫按钮1点击事件
叫地主和不叫的协议是
// 叫地主"
// 叫地主"
message TCallDZReq
{
optional int32 CallDZ = 1; // 叫地主的结果 1 叫地主 2明牌叫地主 其他不叫
optional uint32 TableIndex = 2; // 桌子号
}
// OnButton3Click 按钮点击事件
func (self *TMainForm) OnButton3Click(sender vcl.IObject) {
pack := &ddzpb.TDDZ{}
pack.Command = proto.Int32(23)
pack.CallDZReq = &ddzpb.TCallDZReq{}
pack.CallDZReq.CallDZ = proto.Int32(1)
buff, _ := proto.Marshal(pack)
self.pClient.WritePack(buff)
}
// OnButton4Click 按钮点击事件
func (self *TMainForm) OnButton4Click(sender vcl.IObject) {
pack := &ddzpb.TDDZ{}
pack.Command = proto.Int32(23)
pack.CallDZReq = &ddzpb.TCallDZReq{}
pack.CallDZReq.CallDZ = proto.Int32(0)
buff, _ := proto.Marshal(pack)
self.pClient.WritePack(buff)
}
回到服务器开始处理这个23协议
case 23: // 23 叫地主或者不叫
req := pack.GetCallDZReq()
nTableIndex := req.GetTableIndex()
// 找一下有没有这个桌子
pTable := GetTableByIndex(int(nTableIndex))
if pTable == nil {
return
}
// 找一下桌子上的玩家是否合法, 这里用的是connection来判断, 不支持断线重连, 因为没有账号系统
if !pTable.checkPlayerValid(pData) {
log.Println("发现一个非法的用户发包")
return
}
// 对玩家发来的数据进线解析
nCallDZ := req.GetCallDZ()
// 传进去
pTable.ddz.chDefineDZ <- int(nCallDZ)
}
// GetTableByIndex 得到指定的桌子
func GetTableByIndex(nIndex int) *TTable {
v, ok := mpTableList.Load(nIndex)
if ok {
return v.(*TTable)
}
return nil
}
// 检查玩家是否合法
func (self *TTable) checkPlayerValid(pData *connection.TData) bool {
for i := 0; i < 3; i++ {
if self.pPlayerList[i] != nil {
if self.pPlayerList[i].Conn == pData.GetConnection() {
return true
}
}
}
return false
}
里面的准备处理接收到的chan
// defineDZ 叫(抢)地主阶段
func (self *TDDZ) defineDZ() {
// 三家的选择. 叫地主或者不叫
// -----------------------------------------------------
// 叫地主
ch := make(chan int, 1)
self.chDefineDZ = ch
bFirstPlayerCallDz := false // 第一个玩家是否进行叫地主 如果是的话, 那么第四次他还能抢回去
select {
case n := <-ch:
if n == 1 {
log.Println("叫地主")
self.nDZPosition = 1 // 1号位叫地主
self.nMultiples *= 2 // 倍数要乘以2
bFirstPlayerCallDz = true
} else {
log.Println("不叫")
}
case <-time.After(time.Second * 5000): // 假设5000秒超时
log.Println("超时")
}
// -----------------------------------------------------
// 超时...
ch = make(chan int, 1)
self.chDefineDZ = ch
select {
case n := <-ch:
if n == 1 {
log.Println("抢地主")
self.nDZPosition = 2 // 2号位抢地主
self.nMultiples *= 2 // 倍数要乘以2
} else {
log.Println("不叫")
}
case <-time.After(time.Second * 5000): // 假设5000秒超时
log.Println("超时")
}
// -----------------------------------------------------
// 抢地主
ch = make(chan int, 1)
self.chDefineDZ = ch
select {
case n := <-ch:
if n == 1 {
log.Println("抢地主")
self.nDZPosition = 3 // 2号位抢地主
self.nMultiples *= 2 // 倍数要乘以2
} else {
log.Println("不叫")
}
case <-time.After(time.Second * 5000): // 假设5000秒超时
log.Println("超时")
}
// 判断第一个玩家是否抢地主
if bFirstPlayerCallDz {
// -----------------------------------------------------
// 不加倍
ch = make(chan int, 1)
self.chDefineDZ = ch
select {
case <-ch:
log.Println("抢地主")
//
self.nDZPosition = 1
self.nMultiples *= 2
case <-time.After(time.Second * 5000): // 假设5000秒超时
log.Println("超时")
}
}
// 地主不拍
self.supplycard()
}