golang制作一个斗地主游戏服务器[13]:再写叫地主抢地主

GO 专栏收录该内容
26 篇文章 2 订阅

golang制作一个斗地主游戏服务器[4]:叫地主和抢地主

之前的叫地主和抢地主, 都是通过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()
}

 

  • 0
    点赞
  • 3
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值