/// <summary>
        /// 发地主牌
        /// </summary>
        /// <param name="self"></param>
        /// <param name="id"></param>
        public static void CardsOnTable(this GameControllerComponent self, long id)
        {
            LandlordsRoom            room            = self.GetParent <LandlordsRoom>();
            DeskCardsCacheComponent  deskCardsCache  = room.GetComponent <DeskCardsCacheComponent>();
            OrderControllerComponent orderController = room.GetComponent <OrderControllerComponent>();
            HandCardsComponent       handCards       = room.GetGamerFromUserID(id).GetComponent <HandCardsComponent>();

            orderController.Start(id);

            for (int i = 0; i < 3; i++)
            {
                Card card = deskCardsCache.Deal();
                handCards.AddCard(card);
            }

            //更新玩家身份
            foreach (var gamer in room.gamers)
            {
                Identity gamerIdentity = gamer.UserID == id ? Identity.Landlord : Identity.Farmer;
                self.UpdateInIdentity(gamer, gamerIdentity);
            }

            //广播地主消息
            room.Broadcast(new Actor_SetLandlord_Ntt()
            {
                UserID = id, LordCards = To.RepeatedField(deskCardsCache.LordCards)
            });

            //广播地主先手出牌消息
            room.Broadcast(new Actor_AuthorityPlayCard_Ntt()
            {
                UserID = id, IsFirst = true
            });
        }
Example #2
0
        protected override async void Run(Gamer gamer, Actor_GamerDontPlay_Ntt message)
        {
            LandlordsRoom            room            = Game.Scene.GetComponent <LandlordsComponent>().GetGamingRoom(gamer);
            OrderControllerComponent orderController = room.GetComponent <OrderControllerComponent>();

            if (orderController.CurrentAuthority == gamer.UserID)
            {
                //转发玩家不出牌消息
                Actor_GamerDontPlay_Ntt transpond = new Actor_GamerDontPlay_Ntt();
                transpond.UserID = gamer.UserID;
                room.Broadcast(transpond);

                //轮到下位玩家出牌
                orderController.Turn();

                //判断是否先手
                bool isFirst = orderController.CurrentAuthority == orderController.Biggest;
                if (isFirst)
                {
                    room.GetComponent <DeskCardsCacheComponent>().Clear();
                }
                room.Broadcast(new Actor_AuthorityPlayCard_Ntt()
                {
                    UserID = orderController.CurrentAuthority, IsFirst = isFirst
                });
            }
            await Task.CompletedTask;
        }
        protected override async ETTask Run(Gamer gamer, Actor_GamerPrompt_Req message, Action <Actor_GamerPrompt_Back> reply)
        {
            Actor_GamerPrompt_Back response = new Actor_GamerPrompt_Back();

            try
            {
                LandlordsRoom            room            = Game.Scene.GetComponent <LandlordsComponent>().GetGamingRoom(gamer);
                OrderControllerComponent orderController = room.GetComponent <OrderControllerComponent>();
                DeskCardsCacheComponent  deskCardsCache  = room.GetComponent <DeskCardsCacheComponent>();

                List <Card> handCards = new List <Card>(gamer.GetComponent <HandCardsComponent>().GetAll());
                CardHelper.SortCards(handCards);

                if (gamer.UserID == orderController.Biggest)
                {
                    response.Cards = To.RepeatedField(handCards.Where(card => card.CardWeight == handCards[handCards.Count - 1].CardWeight).ToArray());
                }
                else
                {
                    List <Card[]> result = await CardHelper.GetPrompt(handCards, deskCardsCache, deskCardsCache.Rule);

                    if (result.Count > 0)
                    {
                        response.Cards = To.RepeatedField(result[RandomHelper.RandomNumber(0, result.Count)]);
                    }
                }

                reply(response);
            }
            catch (Exception e)
            {
                ReplyError(response, e, reply);
            }
        }
        /// <summary>
        /// 洗牌
        /// </summary>
        /// <param name="self"></param>
        public static void DealCards(this GameControllerComponent self)
        {
            LandlordsRoom room = self.GetParent <LandlordsRoom>();

            //牌库洗牌
            room.GetComponent <DeckComponent>().Shuffle();

            //玩家轮流发牌
            Gamer[] gamers = room.gamers;
            int     index  = 0;

            for (int i = 0; i < 51; i++)
            {
                if (index == 3)
                {
                    index = 0;
                }

                self.DealTo(gamers[index].UserID);

                index++;
            }

            //发地主牌
            for (int i = 0; i < 3; i++)
            {
                self.DealTo(room.Id);
            }

            self.Multiples = self.Config.Multiples;
        }
        /// <summary>
        /// 斗地主游戏开始
        /// </summary>
        /// <param name="self"></param>
        public static void GameStart(this LandlordsRoom self)
        {
            //更改房间状态 从空闲房间移除 添加到游戏中房间列表
            LandlordsComponent Match = Game.Scene.GetComponent <LandlordsComponent>();

            Match.FreeLandlordsRooms.Remove(self.Id);
            Match.GamingLandlordsRooms.Add(self.Id, self);

            //更该玩家状态
            for (int i = 0; i < self.gamers.Length; i++)
            {
                Gamer gamer = self.gamers[i];
                Match.Waiting.Remove(gamer.UserID);
                Match.Playing.Add(gamer.UserID, self);
            }

            //添加组件
            self.AddComponent <DeckComponent>();
            self.AddComponent <DeskCardsCacheComponent>();
            self.AddComponent <OrderControllerComponent>();
            self.AddComponent <GameControllerComponent, RoomConfig>(GateHelper.GetLandlordsConfig(RoomLevel.Lv100));

            //开始游戏
            self.GetComponent <GameControllerComponent>().StartGame();
        }
        /// <summary>
        /// 准备开始游戏
        /// </summary>
        /// <param name="self"></param>
        public static void StartGame(this GameControllerComponent self)
        {
            LandlordsRoom room = self.GetParent <LandlordsRoom>();

            Gamer[] gamers = room.gamers;

            //房间内有3名玩家且全部准备则开始游戏
            //if(room.Count == 3 && gamers.Where(g => g.IsReady).Count() == 3){}

            //初始玩家开始状态
            foreach (var _gamer in gamers)
            {
                if (_gamer.GetComponent <HandCardsComponent>() == null)
                {
                    _gamer.AddComponent <HandCardsComponent>();
                }
            }

            GameControllerComponent gameController = room.GetComponent <GameControllerComponent>();

            //洗牌发牌
            gameController.DealCards();

            List <GamerCardNum> gamersCardNum = new List <GamerCardNum>();

            Array.ForEach(gamers, (g) =>
            {
                HandCardsComponent handCards = g.GetComponent <HandCardsComponent>();
                //重置玩家身份
                handCards.AccessIdentity = Identity.None;
                //记录玩家手牌数
                gamersCardNum.Add(new GamerCardNum()
                {
                    UserID = g.UserID,
                    Num    = g.GetComponent <HandCardsComponent>().GetAll().Length
                });
            });

            //发送玩家手牌和其他玩家手牌数
            foreach (var _gamer in gamers)
            {
                ActorMessageSenderComponent actorProxyComponent = Game.Scene.GetComponent <ActorMessageSenderComponent>();
                ActorMessageSender          actorProxy          = actorProxyComponent.Get(_gamer.ActorIDofClient);

                actorProxy.Send(new Actor_GameStart_Ntt()
                {
                    HandCards     = To.RepeatedField(_gamer.GetComponent <HandCardsComponent>().GetAll()),
                    GamersCardNum = To.RepeatedField(gamersCardNum)
                });
            }

            //随机先手玩家
            gameController.RandomFirstAuthority();

            Log.Info($"房间{room.Id}开始游戏");
        }
        /// <summary>
        /// 场上的所有牌回到牌库中
        /// </summary>
        /// <param name="self"></param>
        public static void BackToDeck(this GameControllerComponent self)
        {
            LandlordsRoom           room           = self.GetParent <LandlordsRoom>();
            DeckComponent           deckComponent  = room.GetComponent <DeckComponent>();
            DeskCardsCacheComponent deskCardsCache = room.GetComponent <DeskCardsCacheComponent>();

            //回收牌桌卡牌
            deskCardsCache.Clear();
            deskCardsCache.LordCards.Clear();

            //回收玩家手牌
            foreach (var gamer in room.gamers)
            {
                HandCardsComponent handCards = gamer.GetComponent <HandCardsComponent>();
                while (handCards.CardsCount > 0)
                {
                    Card card = handCards.library[handCards.CardsCount - 1];
                    handCards.PopCard(card);
                    deckComponent.AddCard(card);
                }
            }
        }
        /// <summary>
        /// 发牌
        /// </summary>
        /// <param name="id"></param>
        public static void DealTo(this GameControllerComponent self, long id)
        {
            LandlordsRoom room = self.GetParent <LandlordsRoom>();
            Card          card = room.GetComponent <DeckComponent>().Deal();

            if (id == room.Id)
            {
                DeskCardsCacheComponent deskCardsCache = room.GetComponent <DeskCardsCacheComponent>();
                deskCardsCache.AddCard(card);
                deskCardsCache.LordCards.Add(card);
            }
            else
            {
                foreach (var gamer in room.gamers)
                {
                    if (id == gamer.UserID)
                    {
                        gamer.GetComponent <HandCardsComponent>().AddCard(card);
                        break;
                    }
                }
            }
        }
        /// <summary>
        /// 游戏继续
        /// </summary>
        /// <param name="self"></param>
        /// <param name="lastGamer"></param>
        public static void Continue(this GameControllerComponent self, Gamer lastGamer)
        {
            LandlordsRoom            room            = self.GetParent <LandlordsRoom>();
            OrderControllerComponent orderController = room.GetComponent <OrderControllerComponent>();

            //是否结束,当前出牌者手牌数为0时游戏结束
            bool isEnd = lastGamer.GetComponent <HandCardsComponent>().CardsCount == 0;

            if (isEnd)
            {
                //当前最大出牌者为赢家
                Identity          winnerIdentity = room.GetGamerFromUserID(orderController.Biggest).GetComponent <HandCardsComponent>().AccessIdentity;
                List <GamerScore> gamersScore    = new List <GamerScore>();

                //游戏结束所有玩家摊牌
                foreach (var gamer in room.gamers)
                {
                    //取消托管
                    gamer.RemoveComponent <TrusteeshipComponent>();
                    //计算玩家积分
                    gamersScore.Add(new GamerScore()
                    {
                        UserID = gamer.UserID,
                        Score  = self.GetGamerScore(gamer, winnerIdentity)
                    });

                    if (gamer.UserID != lastGamer.UserID)
                    {
                        //剩余玩家摊牌
                        Card[] _gamerCards = gamer.GetComponent <HandCardsComponent>().GetAll();
                        room.Broadcast(new Actor_GamerPlayCard_Ntt()
                        {
                            UserID = gamer.UserID, Cards = To.RepeatedField(_gamerCards)
                        });
                    }
                }

                self.GameOver(gamersScore, winnerIdentity);
            }
            else
            {
                //轮到下位玩家出牌
                orderController.Biggest = lastGamer.UserID;
                orderController.Turn();
                room.Broadcast(new Actor_AuthorityPlayCard_Ntt()
                {
                    UserID = orderController.CurrentAuthority, IsFirst = false
                });
            }
        }
        /// <summary>
        /// 游戏结束
        /// </summary>
        /// <param name="self"></param>
        public static async void GameOver(this GameControllerComponent self, List <GamerScore> gamersScore, Identity winnerIdentity)
        {
            LandlordsRoom room = self.GetParent <LandlordsRoom>();

            Gamer[] gamers = room.gamers;

            //清理所有卡牌
            self.BackToDeck();
            room.GetComponent <DeskCardsCacheComponent>().Clear();

            Dictionary <long, long> gamersMoney = new Dictionary <long, long>();

            foreach (GamerScore gamerScore in gamersScore)
            {
                //结算玩家余额
                Gamer gamer      = room.GetGamerFromUserID(gamerScore.UserID);
                long  gamerMoney = await self.StatisticalIntegral(gamer, gamerScore.Score);

                gamersMoney[gamer.UserID] = gamerMoney;
            }

            //广播游戏结束消息
            room.Broadcast(new Actor_Gameover_Ntt()
            {
                Winner            = (byte)winnerIdentity,
                BasePointPerMatch = self.BasePointPerMatch,
                Multiples         = self.Multiples,
                GamersScore       = To.RepeatedField(gamersScore)
            });

            //清理玩家
            foreach (var _gamer in gamers)
            {
                //踢出离线玩家
                if (_gamer.isOffline)
                {
                    ActorMessageSender actorProxy = Game.Scene.GetComponent <ActorMessageSenderComponent>().Get(_gamer.Id);
                    //await actorProxy.Call(new Actor_PlayerExitRoom_Req());
                }
                //踢出余额不足玩家
                else if (gamersMoney[_gamer.UserID] < self.MinThreshold)
                {
                    //ActorMessageSender actorProxy = _gamer.GetComponent<UnitGateComponent>().GetActorMessageSender();
                    //actorProxy.Send(new Actor_GamerMoneyLess_Ntt() { UserID = _gamer.UserID });
                }
            }
        }
        /// <summary>
        /// 随机先手玩家
        /// </summary>
        public static void RandomFirstAuthority(this GameControllerComponent self)
        {
            LandlordsRoom            room            = self.GetParent <LandlordsRoom>();
            OrderControllerComponent orderController = room.GetComponent <OrderControllerComponent>();

            Gamer[] gamers = room.gamers;

            int  index          = RandomHelper.RandomNumber(0, gamers.Length);
            long firstAuthority = gamers[index].UserID;

            orderController.Init(firstAuthority);

            //广播先手抢地主玩家
            room.Broadcast(new Actor_AuthorityGrabLandlord_Ntt()
            {
                UserID = firstAuthority
            });
        }
        public static async void Start(this TrusteeshipComponent self)
        {
            //找到玩家所在房间
            LandlordsComponent landordsMatchComponent = Game.Scene.GetComponent <LandlordsComponent>();
            Gamer                    gamer            = self.GetParent <Gamer>();
            LandlordsRoom            room             = landordsMatchComponent.GetGamingRoom(self.GetParent <Gamer>());
            ActorMessageSender       actorProxy       = Game.Scene.GetComponent <ActorMessageSenderComponent>().Get(gamer.InstanceId);
            OrderControllerComponent orderController  = room.GetComponent <OrderControllerComponent>();

            //这个托管组件是通过定时器实现的
            while (true)
            {
                //延迟1秒
                await Game.Scene.GetComponent <TimerComponent>().WaitAsync(3000);

                if (self.IsDisposed)
                {
                    return;
                }

                if (gamer.UserID != orderController?.CurrentAuthority)
                {
                    continue;
                }

                //给Map上的Gamer发送Actor消息
                //自动提示出牌
                Actor_GamerPrompt_Back response = (Actor_GamerPrompt_Back)await actorProxy.Call(new Actor_GamerPrompt_Req());

                if (response.Error > 0 || response.Cards.Count == 0)
                {
                    actorProxy.Send(new Actor_GamerDontPlay_Ntt());
                }
                else
                {
                    await actorProxy.Call(new Actor_GamerPlayCard_Req()
                    {
                        Cards = response.Cards
                    });
                }
            }
        }
        protected override async void Run(Gamer gamer, Actor_Trusteeship_Ntt message)
        {
            LandlordsRoom room = Game.Scene.GetComponent <LandlordsComponent>().GetGamingRoom(gamer);

            //是否已经托管
            bool isTrusteeship = gamer.GetComponent <TrusteeshipComponent>() != null;

            if (message.IsTrusteeship && !isTrusteeship)
            {
                gamer.AddComponent <TrusteeshipComponent>();
                Log.Info($"玩家{gamer.UserID}切换为自动模式");
            }
            else if (isTrusteeship)
            {
                gamer.RemoveComponent <TrusteeshipComponent>();
                Log.Info($"玩家{gamer.UserID}切换为手动模式");
            }

            //当玩家切换为手动模式时 补发出牌权
            if (isTrusteeship)
            {
                OrderControllerComponent orderController = room.GetComponent <OrderControllerComponent>();
                if (gamer.UserID == orderController.CurrentAuthority)
                {
                    bool isFirst = gamer.UserID == orderController.Biggest;

                    //向客户端发送出牌权消息
                    ActorMessageSender actorProxy = Game.Scene.GetComponent <ActorMessageSenderComponent>().Get(gamer.ActorIDofClient);
                    actorProxy.Send(new Actor_AuthorityPlayCard_Ntt()
                    {
                        UserID = orderController.CurrentAuthority, IsFirst = isFirst
                    });
                }
            }

            await Task.CompletedTask;
        }
Example #14
0
        protected override async ETTask Run(Gamer gamer, Actor_GamerPlayCard_Req message, Action <Actor_GamerPlayCard_Back> reply)
        {
            Actor_GamerPlayCard_Back response = new Actor_GamerPlayCard_Back();

            try
            {
                LandlordsRoom room = Game.Scene.GetComponent <LandlordsComponent>().GetGamingRoom(gamer);

                GameControllerComponent  gameController  = room.GetComponent <GameControllerComponent>();
                DeskCardsCacheComponent  deskCardsCache  = room.GetComponent <DeskCardsCacheComponent>();
                OrderControllerComponent orderController = room.GetComponent <OrderControllerComponent>();

                //检测是否符合出牌规则
                if (CardHelper.PopEnable(To.Array(message.Cards), out CardsType type))
                {
                    //当前出牌牌型是否比牌桌上牌型的权重更大
                    bool isWeightGreater = CardHelper.GetWeight(To.Array(message.Cards), type) > deskCardsCache.GetTotalWeight();
                    //当前出牌牌型是否和牌桌上牌型的数量一样
                    bool isSameCardsNum = message.Cards.Count == deskCardsCache.GetAll().Length;
                    //当前出牌玩家是否是上局最大出牌者
                    bool isBiggest = orderController.Biggest == orderController.CurrentAuthority;
                    //当前牌桌牌型是否是顺子
                    bool isStraight = deskCardsCache.Rule == CardsType.Straight || deskCardsCache.Rule == CardsType.DoubleStraight || deskCardsCache.Rule == CardsType.TripleStraight;
                    //当前出牌牌型是否和牌桌上牌型一样
                    bool isSameCardsType = type == deskCardsCache.Rule;

                    if (isBiggest ||                                                          //先手出牌玩家
                        type == CardsType.JokerBoom ||                                        //王炸
                        type == CardsType.Boom && isWeightGreater ||                          //更大的炸弹
                        isSameCardsType && isStraight && isSameCardsNum && isWeightGreater || //更大的顺子
                        isSameCardsType && isWeightGreater)                                   //更大的同类型牌
                    {
                        if (type == CardsType.JokerBoom)
                        {
                            //王炸翻4倍
                            gameController.Multiples *= 4;
                            room.Broadcast(new Actor_SetMultiples_Ntt()
                            {
                                Multiples = gameController.Multiples
                            });
                        }
                        else if (type == CardsType.Boom)
                        {
                            //炸弹翻2倍
                            gameController.Multiples *= 2;
                            room.Broadcast(new Actor_SetMultiples_Ntt()
                            {
                                Multiples = gameController.Multiples
                            });
                        }
                    }
                    else
                    {
                        response.Error = ErrorCode.ERR_PlayCardError;
                        reply(response);
                        return;
                    }
                }
                else
                {
                    response.Error = ErrorCode.ERR_PlayCardError;
                    reply(response);
                    return;
                }

                //如果符合将牌从手牌移到出牌缓存区
                deskCardsCache.Clear();
                deskCardsCache.Rule = type;
                HandCardsComponent handCards = gamer.GetComponent <HandCardsComponent>();
                foreach (var card in message.Cards)
                {
                    handCards.PopCard(card);
                    deskCardsCache.AddCard(card);
                }

                reply(response);

                //转发玩家出牌消息
                room.Broadcast(new Actor_GamerPlayCard_Ntt()
                {
                    UserID = gamer.UserID, Cards = message.Cards
                });

                //游戏控制器继续游戏
                gameController.Continue(gamer);

                await ETTask.CompletedTask;
            }
            catch (Exception e)
            {
                ReplyError(response, e, reply);
            }
        }
Example #15
0
        protected override async void Run(Gamer gamer, Actor_GamerGrabLandlordSelect_Ntt message)
        {
            LandlordsRoom               room                = Game.Scene.GetComponent <LandlordsComponent>().GetGamingRoom(gamer);
            OrderControllerComponent    orderController     = room.GetComponent <OrderControllerComponent>();
            GameControllerComponent     gameController      = room.GetComponent <GameControllerComponent>();
            ActorMessageSenderComponent actorProxyComponent = Game.Scene.GetComponent <ActorMessageSenderComponent>();

            if (orderController.CurrentAuthority == gamer.UserID)
            {
                //保存抢地主状态
                orderController.GamerLandlordState[gamer.UserID] = message.IsGrab;

                if (message.IsGrab)
                {
                    orderController.Biggest   = gamer.UserID;
                    gameController.Multiples *= 2;
                    room.Broadcast(new Actor_SetMultiples_Ntt()
                    {
                        Multiples = gameController.Multiples
                    });
                }

                //转发消息
                Actor_GamerGrabLandlordSelect_Ntt transpond = new Actor_GamerGrabLandlordSelect_Ntt();
                transpond.IsGrab = message.IsGrab;
                transpond.UserID = gamer.UserID;
                room.Broadcast(transpond);

                if (orderController.SelectLordIndex >= room.Count)
                {
                    /*
                     * 地主:√ 农民1:× 农民2:×
                     * 地主:× 农民1:√ 农民2:√
                     * 地主:√ 农民1:√ 农民2:√ 地主:√
                     *
                     * */
                    if (orderController.Biggest == 0)
                    {
                        //没人抢地主则重新发牌
                        gameController.BackToDeck();
                        gameController.DealCards();

                        //发送玩家手牌
                        Gamer[]             gamers        = room.gamers;
                        List <GamerCardNum> gamersCardNum = new List <GamerCardNum>();
                        Array.ForEach(gamers, _gamer => gamersCardNum.Add(new GamerCardNum()
                        {
                            UserID = _gamer.UserID,
                            Num    = _gamer.GetComponent <HandCardsComponent>().GetAll().Length
                        }));
                        Array.ForEach(gamers, _gamer =>
                        {
                            ActorMessageSender actorProxy = actorProxyComponent.Get(_gamer.ActorIDofClient);
                            actorProxy.Send(new Actor_GameStart_Ntt()
                            {
                                HandCards     = To.RepeatedField(_gamer.GetComponent <HandCardsComponent>().GetAll()),
                                GamersCardNum = To.RepeatedField(gamersCardNum)
                            });
                        });

                        //随机先手玩家
                        gameController.RandomFirstAuthority();
                        return;
                    }
                    else if ((orderController.SelectLordIndex == room.Count &&
                              ((orderController.Biggest != orderController.FirstAuthority.Key && !orderController.FirstAuthority.Value) ||
                               orderController.Biggest == orderController.FirstAuthority.Key)) ||
                             orderController.SelectLordIndex > room.Count)
                    {
                        gameController.CardsOnTable(orderController.Biggest);
                        return;
                    }
                }

                //当所有玩家都抢地主时先手玩家还有一次抢地主的机会
                if (gamer.UserID == orderController.FirstAuthority.Key && message.IsGrab)
                {
                    orderController.FirstAuthority = new KeyValuePair <long, bool>(gamer.UserID, true);
                }

                orderController.Turn();
                orderController.SelectLordIndex++;
                room.Broadcast(new Actor_AuthorityGrabLandlord_Ntt()
                {
                    UserID = orderController.CurrentAuthority
                });
            }
            await Task.CompletedTask;
        }