golang製作一個鬥地主遊戲服務器[14]:再寫打牌和跟牌(上)

golang製作一個鬥地主遊戲服務器[6]:打牌和跟牌

前面叫地主和搶地主結束了,  本篇基本上就是屬於打牌的範疇了.

首先把超時的時間延長起來. 不要再超時了.  一定等着我們操作完再繼續

	select {
	case <-ch:
		log.Println("模擬打牌")
	case <-time.After(time.Second * 10000): // 臨時改成10000秒超時
		log.Println("roundStart 超時")
	}

其次,  客戶端需要放兩個按鈕, 一個過,,, 一個打掉勾選的牌

// 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點擊事件

做出來的界面大概是這樣一個醜陋的.....

客戶端弄好了. 協議上面處理起來就比較複雜了.  協議有兩個, 第一個是客戶端要告訴服務器我是否要打牌, 打了什麼牌. 

第二個是服務器廣播給3家,  當前打出了什麼牌 , 和你手裏目前是什麼牌,  當然可能還有包含一些額外的信息,  比如3家他們都剩餘多少牌了? 當前炸彈翻倍了多少倍之類

先看第一個協議 , 可能要添加內容,  會和前面講的不一樣

// 我過, 我要出對三
message TOutCardReq
{
    optional int32 Status           = 1; // 狀態,   其實可以不要( 目前暫時定, 1過牌, 2打牌)
    optional int32 OutCount         = 2; // 出牌的牌的數量
    repeated int32 OutCards         = 3; // 出牌的牌的具體內容
}

在看第二個協議,  可能也要添加內容, 會和前面講的不一樣

//"遊戲正式開始, 請出牌"
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)
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章