首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 網路版鬥地主:地主權限傳遞邏輯實作 (第二部分) - 叫地主按鈕與選擇結束處理

     編輯:關於C語言

叫地主按鈕事件與選擇結束邏輯

承接上文,本文詳細說明玩家點擊「叫地主」後的完整處理流程,包含本地狀態更新、網路廣播、地主牌發放與 UI 同步。

「叫地主」按鈕 Click 事件

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);
    }
}

Player.SelectLandLordEnd() 核心邏輯

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 表示放棄。

Client 端接收處理 (AcceptServerData 節錄)

if (msg.StartsWith("LandLordPokers")) {
    // 解析地主牌並儲存
    DConsole.LandLordPokers = ParsePokers(msg);
    Player1.SelectLandLordEnd(); // 同步顯示
}
if (msg.StartsWith("ClientIsLandLord")) { /* 標記另一 Client 為地主 */ }
if (msg.StartsWith("ServerIsLandLord")) { /* 標記 Server 為地主 */ }

同步機制缺陷分析

  • Thread.Sleep 硬性延遲:假設網路延遲 < 100ms,高延遲環境下會導致訊息亂序或遺失。
  • 無確認機制 (ACK):發送後不等待對方確認,不可靠。
  • UI 直接操作網路物件:DConsole 靜態類別耦合 UI 控制項與網路邏輯,難以單元測試。

重構建議

  1. 引入 async/await 非同步發送,配合 SemaphoreSlim 控制併發。
  2. 定義強型別訊息類別 (DTO),使用 JSON/Protobuf 序列化。
  3. 實作訊息佇列與重試機制,確保關鍵指令 (地主牌、出牌權) 必達。
  4. 採用 MVVM 模式,ViewModel 處理遊戲狀態,View 純綁定顯示。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved