承接上文,本文詳細說明玩家點擊「叫地主」後的完整處理流程,包含本地狀態更新、網路廣播、地主牌發放與 UI 同步。
private void btnNeedLandLord_Click(object sender, EventArgs e) {
Player1.IsLandLord = true; // 本地標記為地主
Player1.HaveOrder = true; // 獲得首出權
Player1.IsBiggest = true; // 牌權最大標記
Player1.AreYouLandLord = false; // 清除叫地主提示狀態
HideLandLordButtons(); // 隱藏按鈕
if (Server != null) { // Server 玩家
Player1.SelectLandLordEnd(); // 顯示地主牌、加入手牌、重新排序
Server.SendDataForClient("LandLordPokers", LandLordPokers, 1);
Thread.Sleep(100);
Server.SendDataForClient("LandLordPokers", LandLordPokers, 2);
Thread.Sleep(100);
Server.SendDataForClient("ServerIsLandLord", 1);
Thread.Sleep(100);
Server.SendDataForClient("ServerIsLandLord", 2);
}
if (Client != null) { // Client 玩家
Client.SendDataForServer("IamLandLord");
Thread.Sleep(300);
}
}
public void SelectLandLordEnd() {
DConsole.PaintLandLord(true); // 視窗中央顯示地主三張牌
if (this.IsLandLord) { // 若自己是地主
foreach (var poker in DConsole.LandLordPokers)
this.Pokers.Add(poker); // 加入手牌
this.Sort(); // 重新排序
this.Paint(); // 重繪手牌區
}
}
Server 端:若為最後權限者 (LandLordNum==3) 則 Restart(),否則轉發 "AreYouLandLord" 給下家。
Client 端:直接發送 "AreYouLandLord" 給 Server 表示放棄。
if (msg.StartsWith("LandLordPokers")) {
// 解析地主牌並儲存
DConsole.LandLordPokers = ParsePokers(msg);
Player1.SelectLandLordEnd(); // 同步顯示
}
if (msg.StartsWith("ClientIsLandLord")) { /* 標記另一 Client 為地主 */ }
if (msg.StartsWith("ServerIsLandLord")) { /* 標記 Server 為地主 */ }
DConsole 靜態類別耦合 UI 控制項與網路邏輯,難以單元測試。async/await 非同步發送,配合 SemaphoreSlim 控制併發。