欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

.Net Core使用SignalR實(shí)現(xiàn)斗地主游戲

 更新時(shí)間:2022年01月07日 11:52:19   作者:老馬-Max  
本文詳細(xì)講解了.Net Core使用SignalR實(shí)現(xiàn)斗地主游戲的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

之前開內(nèi)部培訓(xùn),說(shuō)到實(shí)時(shí)web應(yīng)用這一塊講到了SignalR,我說(shuō)找時(shí)間用它做個(gè)游戲玩玩,后面時(shí)間緊張就一直沒安排。這兩天閑了又想起這個(gè)事,考慮后決定用2天時(shí)間寫個(gè)斗D主,安排了前端同學(xué)寫客戶端,我寫游戲邏輯和服務(wù)。

這個(gè)項(xiàng)目難度并不高,但是游戲邏輯還是挺繞的,聯(lián)調(diào)過(guò)程中也發(fā)現(xiàn)解決了很多小問(wèn)題。來(lái)園子里整理一篇文章,記錄一下。

基礎(chǔ)的介紹就免了,畢竟官網(wǎng)跟著走兩圈啥都懂了。沒基礎(chǔ)的可以戳這里,是我之前寫的一篇SignalR基礎(chǔ)介紹,帶有一個(gè)極簡(jiǎn)聊天室。

tips:文章結(jié)尾有開源地址,游戲數(shù)據(jù)都是本地的,改下IP運(yùn)行起來(lái)就可以玩了。

直接上干貨,首先是數(shù)據(jù)模型:

/// <summary>
    /// 用戶信息
    /// </summary>
    public class Customer
    {
        /// <summary>
        /// 唯一ID
        /// </summary>
        public string? ID { get; set; }

        /// <summary>
        /// 昵稱
        /// </summary>
        public string? NickName { get; set; }

        /// <summary>
        /// 卡片
        /// </summary>
        public List<string> Card { get; set; }
    }


    /// <summary>
    /// 房間
    /// </summary>
    public class Room
    {
        /// <summary>
        /// 房間名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 房主id
        /// </summary>
        public string Masterid { get; set; }

        /// <summary>
        /// 當(dāng)前出牌人
        /// </summary>
        public int Curr { get; set; }

        /// <summary>
        /// 當(dāng)前卡片
        /// </summary>
        public List<string> CurrCard { get; set; } = new List<string>();

        /// <summary>
        /// 當(dāng)前卡片打出人
        /// </summary>
        public string ExistingCardClient { get; set; }

        /// <summary>
        /// 房間成員列表
        /// </summary>
        public List<Customer> Customers { get; set; } = new List<Customer>();
    }

tips:只是單純?yōu)榱硕稤主設(shè)計(jì)的,商用版肯定不能這么搞,參考請(qǐng)慎用。

有了數(shù)據(jù)模型,自然少不了CRUD:

/// <summary>
    /// 用戶操作
    /// </summary>
    public static class CustomerAction
    {
        /// <summary>
        /// 用戶列表
        /// </summary>
        private static List<Customer> cusList = new List<Customer>();

        /// <summary>
        /// 不存在則新增,存在則修改昵稱
        /// </summary>
        /// <param name="customer"></param>
        public static void Create(Customer customer)
        {
            Customer curr = null;

            if (cusList.Count > 0)
                curr = cusList.Where(x => x.ID == customer.ID).FirstOrDefault();

            if (curr is null)
                cusList.Add(customer);
            else
            {
                curr.NickName = customer.NickName;

                Up4ID(curr);
            }
        }

        /// <summary>
        /// 用戶列表
        /// </summary>
        /// <returns></returns>
        public static List<Customer> GetList()
        {
            return cusList;
        }

        /// <summary>
        /// 獲取單個(gè)
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static Customer GetOne(string id)
        {
            return cusList.Where(x => x.ID == id).FirstOrDefault();
        }

        /// <summary>
        /// 刪除用戶
        /// </summary>
        /// <param name="id"></param>
        public static void Delete(string id)
        {
            cusList.RemoveAll(x => x.ID == id);
        }

        /// <summary>
        /// 增加卡片
        /// </summary>
        /// <param name="id"></param>
        /// <param name="cards"></param>
        public static void InCard(string id, List<string> cards)
        {
            Customer customer = cusList.Where(x => x.ID == id).FirstOrDefault();

            if (customer.Card is null)
                customer.Card = cards;
            else
                customer.Card.AddRange(cards);

            Up4ID(customer);
        }

        /// <summary>
        /// 扣除卡片
        /// </summary>
        /// <param name="id"></param>
        /// <param name="cards"></param>
        /// <param name="group"></param>
        /// <returns></returns>
        public static bool OutCard(string id, List<string> cards, Room group)
        {
            Customer client = cusList.Where(x => x.ID == id).FirstOrDefault();

            if (client is null)
                return false;

            //卡片不匹配直接失敗
            if (client.Card.Where(x => cards.Contains(x)).ToList().Count != cards.Count)
                return false;

            //不符合出牌規(guī)則直接失敗
            if (!new Game.WithCard().Rule(group.CurrCard, cards, group.ExistingCardClient is null || group.ExistingCardClient == id))
                return false;

            foreach (var item in cards)
            {
                client.Card.Remove(item);
            }

            group.CurrCard = cards;

            group.ExistingCardClient = id;

            Up4ID(client);

            RoomAction.Up4Name(group);

            return true;
        }

        /// <summary>
        /// 更新(根據(jù)ID)
        /// </summary>
        /// <param name="customer"></param>
        /// <returns></returns>
        public static bool Up4ID(Customer customer)
        {
            if (cusList.Count == 0)
                return false;

            cusList.RemoveAll(x => x.ID == customer.ID);

            cusList.Add(customer);

            return true;
        }
    }


    /// <summary>
    /// 房間操作
    /// </summary>
    public static class RoomAction
    {
        /// <summary>
        /// 房間列表
        /// </summary>
        private static List<Room> roomList = new List<Room>();

        /// <summary>
        /// 新增房間
        /// 如果房間已存在則不新增
        /// </summary>
        /// <param name="group"></param>
        public static void Create(Room group)
        {
            if (!roomList.Where(x => x.Name == group.Name).Any())
                roomList.Add(group);
        }

        /// <summary>
        /// 獲取列表
        /// </summary>
        /// <returns></returns>
        public static List<Room> GetList()
        {
            return roomList;
        }

        /// <summary>
        /// 獲取單個(gè)
        /// </summary>
        /// <param name="masterid">房主id</param>
        /// <param name="roomName">房間名稱</param>
        /// <returns></returns>
        public static Room GetOne(string masterid = null, string roomName = null)
        {
            if (roomList.Count == 0)
                return null;

            if (masterid != null)
                return roomList.Where(x => x.Masterid == masterid).FirstOrDefault();

            if (roomName != null)
                return roomList.Where(x => x.Name == roomName).FirstOrDefault();

            return null;
        }

        /// <summary>
        /// 加入房間
        /// </summary>
        /// <param name="client"></param>
        /// <param name="roomName"></param>
        public static bool Join(Customer client, string roomName)
        {
            if (roomList.Count == 0)
                return false;

            var room = roomList.Where(x => x.Name == roomName).FirstOrDefault();

            if (room is null)
                return false;

            if (room.Customers.Count == 3)
                return false;

            room.Customers.Add(client);

            Up4Name(room);

            return true;
        }

        /// <summary>
        /// 刪除房間
        /// </summary>
        /// <param name="masterid">房主id</param>
        public static bool Delete(string masterid)
        {
            if (roomList.Count == 0)
                return false;

            var room = roomList.Where(x => x.Masterid == masterid).FirstOrDefault();

            if (room == null)
                return false;

            roomList.Remove(room);

            return true;
        }

        /// <summary>
        /// 更新(根據(jù)房名)
        /// </summary>
        /// <param name="room"></param>
        /// <returns></returns>
        public static bool Up4Name(Room room)
        {
            if (roomList.Count == 0)
                return false;

            roomList.RemoveAll(x => x.Name == room.Name);

            roomList.Add(room);

            return true;
        }

        /// <summary>
        /// 更新當(dāng)前出牌人
        /// </summary>
        /// <param name="roomName"></param>
        /// <param name="index">傳入則強(qiáng)制修改,不傳按規(guī)則走</param>
        public static Customer ChangeCurr(string roomName, int index = -1)
        {
            var room = roomList.Where(x => x.Name == roomName).FirstOrDefault();

            if (index != -1)
                room.Curr = index;
            else
                room.Curr = (room.Curr + 1) % 3;

            Up4Name(room);

            return room.Customers[room.Curr];
        }
    }

因?yàn)樗袛?shù)據(jù)都是通過(guò)靜態(tài)屬性保存的,所以大部分都是linq操作(原諒我linq水平有限)。

接下來(lái)是游戲邏輯:

/// <summary>
    /// 卡片相關(guān)
    /// </summary>
    public class WithCard
    {
        /// <summary>
        /// 黑桃-S、紅桃-H、梅花-C、方塊-D
        /// BG大王,SG小王,14-A,15-2
        /// </summary>
        readonly List<string> Cards = new List<string>()
        {
            "S-14","S-15","S-3","S-4","S-5","S-6","S-7","S-8","S-9","S-10","S-11","S-12","S-13",
            "H-14","H-15","H-3","H-4","H-5","H-6","H-7","H-8","H-9","H-10","H-11","H-12","H-13",
            "C-14","C-15","C-3","C-4","C-5","C-6","C-7","C-8","C-9","C-10","C-11","C-12","C-13",
            "D-14","D-15","D-3","D-4","D-5","D-6","D-7","D-8","D-9","D-10","D-11","D-12","D-13",
            "BG-99","SG-88"
        };

        /// <summary>
        /// 發(fā)牌
        /// </summary>
        public List<List<string>> DrawCard()
        {
            List<string> a = new List<string>();
            List<string> b = new List<string>();
            List<string> c = new List<string>();

            Random ran = new Random();

            //剩3張底牌
            for (int i = 0; i < 51; i++)
            {
                //隨機(jī)抽取一張牌
                string item = Cards[ran.Next(Cards.Count)];

                switch (i % 3)
                {
                    case 0:
                        a.Add(item);
                        break;
                    case 1:
                        b.Add(item);
                        break;
                    case 2:
                        c.Add(item);
                        break;
                }

                Cards.Remove(item);
            }

            return new List<List<string>>()
            {
                a,b,c,Cards
            };
        }

        /// <summary>
        /// 規(guī)則
        /// </summary>
        /// <param name="existingCard"></param>
        /// <param name="newCard"></param>
        /// <param name="isSelf"></param>
        /// <returns></returns>
        public bool Rule(List<string> existingCard, List<string> newCard, bool isSelf)
        {
            //現(xiàn)有牌號(hào)
            List<int> existingCardNo = existingCard.Select(x => Convert.ToInt32(x.Split('-')[1])).ToList().OrderBy(x => x).ToList();

            //新出牌號(hào)
            List<int> newCardNo = newCard.Select(x => Convert.ToInt32(x.Split('-')[1])).ToList().OrderBy(x => x).ToList();

            //上一手是王炸,禁止其他人出牌
            if (existingCardNo.All(x => x > 50) && existingCardNo.Count == 2)
            {
                if (isSelf)
                    return true;
                else
                    return false;
            }

            //王炸最大
            if (newCardNo.All(x => x > 50) && newCard.Count == 2)
                return true;

            //單張
            if (newCardNo.Count == 1)
            {
                if (existingCardNo.Count == 0)
                    return true;

                if ((existingCardNo.Count == 1 && newCardNo[0] > existingCardNo[0]) || isSelf)
                    return true;
            }

            //對(duì)子/三只
            if (newCardNo.Count == 2 || newCardNo.Count == 3)
            {
                if (existingCardNo.Count == 0 && newCardNo.All(x => x == newCardNo[0]))
                    return true;

                if (newCardNo.All(x => x == newCardNo[0]) && (isSelf || newCardNo.Count == existingCardNo.Count && newCardNo[0] > existingCardNo[0]))
                    return true;
            }

            if (newCard.Count == 4)
            {
                //炸
                if (newCardNo.All(x => x == newCardNo[0]))
                {
                    if (existingCardNo.Count == 0 || isSelf)
                        return true;

                    if (existingCardNo.All(x => x == existingCardNo[0]) && existingCardNo.Count == 4)
                    {
                        if (newCardNo[0] > existingCardNo[0])
                            return true;
                    }

                    return true;
                }

                //三帶一
                {
                    List<int> flagA = newCardNo.Distinct().ToList();

                    //超過(guò)2種牌直接失敗
                    if (flagA.Count > 2)
                        return false;

                    //沒有上一手牌,或者上一手是自己出的牌
                    if (existingCardNo.Count == 0 || isSelf)
                        return true;

                    int newCardFlag = 0;

                    if (newCardNo.Where(x => x == flagA[0]).ToList().Count() > 1)
                    {
                        newCardFlag = flagA[0];
                    }
                    else
                        newCardFlag = flagA[1];

                    List<int> flagB = existingCardNo.Distinct().ToList();

                    //上一手牌不是三帶一
                    if (flagB.Count > 2)
                        return false;

                    int existingCardFlag = 0;

                    if (existingCardNo.Where(x => x == flagB[0]).ToList().Count() > 1)
                    {
                        existingCardFlag = flagB[0];
                    }
                    else
                        existingCardFlag = flagB[1];

                    if (newCardFlag > existingCardFlag)
                        return true;
                }
            }

            if (newCard.Count >= 5)
            {
                bool flag = true;

                for (int i = 0; i < newCardNo.Count - 1; i++)
                {
                    if (newCardNo[i] + 1 != newCardNo[i + 1])
                    {
                        flag = false;
                        break;
                    }
                }

                //順子
                if (flag)
                {
                    if (existingCardNo.Count == 0 || (newCardNo[0] > existingCardNo[0] && newCardNo.Count == existingCardNo.Count) || isSelf)
                        return true;
                }
            }

            return false;
        }
    }

單張規(guī)則和普通斗D主一樣(除了王以外2最大,其次是A),多張規(guī)則目前支持:王炸、對(duì)子、三只、順子、三帶一。目前只做到這里,各位同學(xué)可以拿回去自行擴(kuò)展。

上一些運(yùn)行圖。房主建房并加入:

新玩家加入:

房間人滿以后房主開始游戲,隨機(jī)分配地主:

出牌特效:

游戲結(jié)算:

最后附上開源地址(客戶端在web分支):https://gitee.com/muchengqingxin/card-game

tips:前端同學(xué)在沒有UI配合的情況下做到現(xiàn)在這樣,必須給個(gè)贊。最后提醒大家,不要拿去商用。

以上所述是小編給大家介紹的.Net Core使用SignalR實(shí)現(xiàn)斗地主游戲,希望對(duì)大家有所幫助。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • ASP.NET Core基礎(chǔ)之啟動(dòng)設(shè)置

    ASP.NET Core基礎(chǔ)之啟動(dòng)設(shè)置

    這篇文章介紹了ASP.NET Core基礎(chǔ)之啟動(dòng)設(shè)置,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-02-02
  • ASP.NET?Core在Linux下為dotnet創(chuàng)建守護(hù)進(jìn)程

    ASP.NET?Core在Linux下為dotnet創(chuàng)建守護(hù)進(jìn)程

    本篇主要是怎么樣為我們?cè)贚inux或者macOs中部署的dotnet程序創(chuàng)建一個(gè)守護(hù)進(jìn)程,來(lái)保證我們的程序在異?;蛘呤请娔X重啟的時(shí)候仍然能夠正常訪問(wèn)。需要的朋友可以收藏下,方便下次瀏覽觀看
    2021-12-12
  • 初識(shí) ASP.NET Membership 用戶管理

    初識(shí) ASP.NET Membership 用戶管理

    Membership 是用做用戶管理,進(jìn)行身份認(rèn)證使用的。通過(guò)ASP.NET Membership,我們可以創(chuàng)建用戶、刪除用戶和編輯用戶屬性。所以這是一個(gè)實(shí)現(xiàn)登錄相關(guān)控件的底層框架。
    2016-04-04
  • Asp.Net 和 AJAX.Net 的區(qū)別

    Asp.Net 和 AJAX.Net 的區(qū)別

    Asp.Net 和 AJAX.Net 的區(qū)別...
    2007-03-03
  • ASP.NET?Core中的wwwroot文件夾

    ASP.NET?Core中的wwwroot文件夾

    這篇文章介紹了ASP.NET?Core中的wwwroot文件夾,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-02-02
  • 搭建基礎(chǔ)結(jié)構(gòu)的ABP解決方案介紹

    搭建基礎(chǔ)結(jié)構(gòu)的ABP解決方案介紹

    這篇文章介紹了搭建基礎(chǔ)結(jié)構(gòu)的ABP解決方案的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02
  • Blazor組件事件處理功能

    Blazor組件事件處理功能

    這篇文章介紹了Blazor組件的事件處理功能,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-01-01
  • ASP.NET Core中的Razor頁(yè)面使用視圖組件

    ASP.NET Core中的Razor頁(yè)面使用視圖組件

    這篇文章介紹了ASP.NET Core中的Razor頁(yè)面使用視圖組件的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02
  • ASP.NET中Cookie的使用方法

    ASP.NET中Cookie的使用方法

    Cookie是一段文本信息,在客戶端存儲(chǔ) Cookie 是 ASP.NET 的會(huì)話狀態(tài)將請(qǐng)求與會(huì)話關(guān)聯(lián)的方法之一。瀏覽器對(duì) Cookie 的大小有限制,因此,只有不超過(guò) 4096 字節(jié)才能保證被接受。
    2016-04-04
  • ASP.NET Core應(yīng)用啟動(dòng)Startup類簡(jiǎn)介

    ASP.NET Core應(yīng)用啟動(dòng)Startup類簡(jiǎn)介

    這篇文章介紹了ASP.NET Core中的應(yīng)用啟動(dòng)Startup類,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04

最新評(píng)論