zoukankan      html  css  js  c++  java
  • C#网络版斗地主——地主权限的传递

    C#斗地主网络版源码:http://www.cnblogs.com/zhubenwuzui/archive/2009/06/06/1497673.html

    本文是对C#网络版斗地主的总结。

    系列文章:

    网络部分实现:http://www.cnblogs.com/zhubenwuzui/archive/2009/06/07/1497968.html

    地主权限的传递:http://www.cnblogs.com/zhubenwuzui/archive/2009/06/07/1498097.html

    出牌权限的传递:http://www.cnblogs.com/zhubenwuzui/archive/2009/06/08/1498369.html

    首先服务器使用一个随机数来随即选出默认地主。然后发送信息给选出来的玩家。玩家接收到信息后显示两个按钮“叫地主”,“不叫”。如果选择不叫,则把可以叫地主的权限发送给另外一个玩家,如果另外两个玩家都不要的话,就执行Restart()方法重新发牌。

    叫地主权限的传递顺序如下图所示:

    具体实现方法:

    服务器得到一个1-3的随机数,1代表服务器是默认地主(默认地主就是随机选择的第一个有权限叫地主的玩家),2代表client1是默认地主,3代表client2是默认地主。只有服务器端能够选择地主,所以该方法在server类中

            public void SendOrder(int Num)
            {
                
    switch (Num)
                {
                    
    case 1:
                        DConsole.player1.areYouLandLord 
    = true//把叫地主权限给自己
                        break;
                    
    case 2:
                        
    this.SendDataForClient("AreYouLandLord"1);  //传递叫地主权限给client1
                        break;
                    
    case 3:
                        
    this.SendDataForClient("AreYouLandLord"2); //传递叫地主权限给client2
                        break;
                }
            }

    客户端的循环接收数据程序会分析服务端发送过来的数据,client类:

    (代码比较长,所以只贴出和地主权限传递有关的一部分)

            public void AcceptServerData() 
            {
                NetworkStream Ns 
    = client.GetStream();
                
    string str = "";
                
    while (true)
                {
                    
    byte[] bytes = new byte[108];
                    Ns.Read(bytes, 
    0108);
                    str 
    = Encoding.Default.GetString(bytes);
                   (省略一部分)
                    
    if (str.StartsWith("AreYouLandLord")) //如果服务器向客户端发送该消息,则客户端获取叫地主权限
                    {
                        DConsole.player1.areYouLandLord 
    = true//timer控件检测到该属性值为true时显示出叫地主和不叫按钮
                        continue;
                    }
                    
    if (str.StartsWith("LandLordPokers")) //获取服务器发送给客户端的地主的3张牌,收到这三张牌后地主权限的传递就结束了
                    {
                        PokerGroup pokers 
    = new PokerGroup();
                        str 
    = str.Replace("LandLordPokers""");
                        
    byte[] bytePg = Encoding.Default.GetBytes(str);
                        pokers.GetPokerGroup(bytePg);
                        DConsole.LandLordPokers 
    = pokers;//把接收到的地主牌保存起来
                        DConsole.player1.SelectLandLordEnd();//该方法在窗口中央显示出地主牌,然后判断自己是不是地主,如果是地主就将地主牌添加到自己的牌组.该方法的具体代码请看下文
                        continue;
                    }
                    
    if (str.StartsWith("ClientIsLandLord")) //另外一个客户端是地主
                    {
                        DConsole.lblClient2Name.Text 
    += "(地主)";
                        DConsole.lblClient2Name.ForeColor 
    = System.Drawing.Color.Red;
                        DConsole.PaintClient(
    20);
                        
    continue;
                    }
                    
    if (str.StartsWith("ServerIsLandLord")) //服务器是地主
                    {
                        DConsole.lblClient1Name.Text 
    += "(地主)";
                        DConsole.lblClient1Name.ForeColor 
    = System.Drawing.Color.Red;
                        DConsole.PaintServer(
    20);
                        
    continue;
                    }
                    (后面省略)
                }
            }

    player1.areYouLandLordtrue,timer控件会检测到,然后把叫地主和不叫按钮显示出来。

    叫地主按钮的click事件:

                this.player1.isLandLord = true//本地玩家为地主
                this.player1.haveOrder = true//获得出牌权限,下篇文章讲到出牌权限的传递
                this.player1.isBiggest = true//出的牌是否为最大的,主要用于当你出的牌其他两家都不要时,你自己不能不要,只能出牌,下篇文章会讲到的
                this.player1.areYouLandLord = false;//设置该值为false
                this.btnNeedLandLord.Visible = false
                
    this.btnNotLandLord.Visible = false//隐藏叫地主和不叫按钮

                
    if (this.server != null//当玩家为服务器时
                {
                    
    this.player1.SelectLandLordEnd();//该方法在窗口中央显示出地主牌,然后判断自己是不是地主,如果是地主就将地主牌添加到自己的牌组.该方法的具体代码请看下文
                    this.server.SendDataForClient("LandLordPokers", DConsole.LandLordPokers, 1); //把地主的三张牌发送给client1,因为不管谁是地主,客户端都需要获得地主的牌并且显示出来
                    Thread.Sleep(100);
                    
    this.server.SendDataForClient("LandLordPokers", DConsole.LandLordPokers, 2);//同上,把数据发送个client2
                    Thread.Sleep(100);
                    
    this.server.SendDataForClient("ServerIsLandLord"1);//通知client1,服务器是地主
                    Thread.Sleep(100);
                    
    this.server.SendDataForClient("ServerIsLandLord"2);//通知client2,服务器是地主
                    Thread.Sleep(100);
                }
                
    if (this.client != null//当玩家为客户端时
                {
                    
    this.client.SendDataForServer("IamLandLord"); //发送信息给服务器,服务器可以识别是哪个客户端叫了地主,服务器如何处理请看下文的server类代码
                    Thread.Sleep(300);
                }

    当玩家单击“不叫”按钮时。如果玩家是服务器,如第一张图所示,程序会向他的下家发送选择地主的权限,当LandLordNum3时,服务器就是最后一个玩家,如果他也不叫地主的话,就只能重新发牌了。

    如果玩家是客户端的话,直接向server端发送"AreYouLandLord"来表明自己不要地主。

    Server端会判断是client1还是client2发送的消息,然后做出不同的响应

    下面是"不叫"按钮的click事件处理程序

    Player类中,player1.SelectLandLordEnd的具体代码如下:

            public void SelectLandLordEnd()
            {
                DConsole.PaintLandLord(
    true); //传递true给该方法,在窗口中央显示地主三张牌的具体点数
                if (this.isLandLord)  //如果自己是地主的话
                {
                    
    foreach (Poker poker in DConsole.LandLordPokers)  //把这三张牌添加到自己的牌组中
                    {
                        
    this.pokers.Add(poker);
                    }
                    
    this.sort();  //重新排序
                    this.Paint();  //重新显示自己的牌
                }
            }

    地主的权限传递就这么多了,可能写的比较乱,但是并不复杂,相信大家仔细多看几遍应该能够明白的.。如果那里有错误的话欢迎在下面留言栏反馈。谢谢!

    下面是server类里面的监听客户端消息的程序:

    (由于篇幅所限,这里只贴出与地主权限传递有关的代码)

     

     

            public void AccpetClient1Data() //监听客户端1的消息
            {
                NetworkStream Ns1 
    = client1.GetStream();
                
    string str1 = "";
                
    while (true)
                {
                    PokerGroup pg 
    = new PokerGroup();
                    
    byte[] bytes1 = new byte[108];
                    Ns1.Read(bytes1, 
    0108);
                    str1 
    = Encoding.Default.GetString(bytes1);
    (省略部分)
                    
    if (str1.StartsWith("AreYouLandLord"))
                    {
                        
    if (DConsole.LandLordNum == 1//如果默认地主为服务器,那么根据文章开头的权限传递顺序图,server-client2-client1,client1为最后一个玩家,所以需要和牌重新来过
                        {
                            DConsole.Restart();
                            
    continue;
                        }
                        DConsole.player1.areYouLandLord 
    = true//当默认地主不是服务器时,设置服务器的叫地主权限为true,当timer控件读取到该值时,服务器的叫地主和不叫按钮马上就会显示出来.
                        continue;
                    }
                    
    if (str1.StartsWith("IamLandLord")) //客户端1为地主
                    {
                        DConsole.lblClient1Name.Text 
    += "(地主)";
                        DConsole.lblClient1Name.ForeColor 
    = System.Drawing.Color.Red;
                        SendDataForClient(
    "ClientIsLandLord"2); //通知客户端2,客户端1为地主
                        Thread.Sleep(sleep);
                        DConsole.PaintClient(
    201);
                        SendDataForClient(
    "LandLordPokers", DConsole.LandLordPokers, 1); //地主已选出,把牌发送给所有玩家
                        Thread.Sleep(sleep);
                        SendDataForClient(
    "LandLordPokers", DConsole.LandLordPokers, 2);//地主已选出,把牌发送给所有玩家
                        DConsole.player1.SelectLandLordEnd(); //该方法的具体代码请看下文
                        continue;
                    }
                }
            }
            
    /// <summary>
            
    /// 循环接收客户端2的请求数据
            
    /// </summary>
            public void AccpetClient2Data()
            {
                NetworkStream Ns2 
    = client2.GetStream();
                
    string str1 = "";
                
    while (true)
                {
                    PokerGroup pg 
    = new PokerGroup();
                    
    byte[] bytes2 = new byte[108];
                    Ns2.Read(bytes2, 
    0108);
                    str1 
    = Encoding.Default.GetString(bytes2);
    (省略部分)
                    
    if (str1.StartsWith("AreYouLandLord")) //客户端2不要地主
                    {
                        
    if (DConsole.LandLordNum == 2//如果默认地主为客户端1,那么根据文章开头的权限传递顺序图,client1-server-client2,client2为最后一个玩家,所以需要和牌重新来过
                        {
                            DConsole.Restart();
                            
    continue;
                        }
                        SendDataForClient(
    "AreYouLandLord"1);  //如果默认地主不是客户端1的话,按照顺序把叫地主权限传递给client1,client1的处理程序上文已经列出
                        continue;
                    }
                    
    if (str1.StartsWith("IamLandLord") ) //客户端2为地主
                    {
                        DConsole.lblClient2Name.Text 
    += "(地主)";
                        DConsole.lblClient2Name.ForeColor 
    = System.Drawing.Color.Red;
                        SendDataForClient(
    "LandLordPokers", DConsole.LandLordPokers, 1);
                        SendDataForClient(
    "LandLordPokers", DConsole.LandLordPokers, 2);
                        SendDataForClient(
    "ClientIsLandLord"1);
                        DConsole.PaintClient(
    202);
                        DConsole.player1.SelectLandLordEnd();
                        
    continue;
                    }
                }
            }

     

            private void btnNotLandLord_Click(object sender, EventArgs e)  
            {
                
    this.player1.areYouLandLord = false;
                
    this.player1.isLandLord = false;
                
    this.btnNeedLandLord.Visible = false;
                
    this.btnNotLandLord.Visible = false;
                
    if (this.server != null)  //玩家是服务端
                {
                    
    if (DConsole.LandLordNum == 3) 如果client2是默认地主,根据权限传递顺序client2-client1-server,server为最后玩家,如果server不叫地主,只能和牌重来
                    {
                        DConsole.Restart();
                        
    return;
                    }
                    
    this.server.SendDataForClient("AreYouLandLord"2);  //如果client2不是默认地主,就把权限传递给client2
                }
                
    if (this.client != null//如果玩家是客户端
                {
                    
    this.client.SendDataForServer("AreYouLandLord");//告诉服务器自己不叫
                }
            }

     

  • 相关阅读:
    windows mysql 的myini
    NuGet 程序源包
    链表更新
    程序包需要 NuGet 客户端版本“XXXXX”或更高版本,但当前的 NuGet 版本为“XXXXXXXXXX”
    chrome下调试安卓app 之 ionic
    ionic3 在ios9.0 系统下 会出现ReferenceError:Can't find variable:Intl 错误提示
    抓取html 生成图片
    grunt 打包 分解(并非原创)
    关于 vue 日期格式的过滤
    Android Studio
  • 原文地址:https://www.cnblogs.com/DreamCreator/p/1498097.html
Copyright © 2011-2022 走看看