Example #1
0
        private void GamingThread()
        {
            // 多线程状态机
            for (; ;)
            {
                // 等待信号量
                gameStateMachine.WaitSemaphore();

                switch (gameStateMachine.status)
                {
                case GameStateMachine.State.Idle:

                    break;

                case GameStateMachine.State.WaitPlayerAction:

                    break;

                case GameStateMachine.State.SendPlayerAction:
                    // 创建响应
                    List <PlayerAction> playerActions = new List <PlayerAction>();

                    // 判定荣和
                    List <RonAble> RonAbles = isCanRon();
                    if (RonAbles.Count() > 0)
                    {
                        // 发出可以荣和的消息到玩家
                        // 先根据玩家编号分类
                        IEnumerable <RonAble> player_ronable = from ronable in RonAbles group ronable by ronable.playerId into g select g.First();

                        foreach (RonAble ronable in player_ronable)
                        {
                            playerActions.Add(new PlayerAction(ronable));
                        }
                    }

                    // 判定鸣牌的可能性
                    List <FuruAble> Furuables = isCanFuru();
                    if (Furuables.Count > 0)
                    {
                        // 发出可以鸣牌的消息到玩家
                        // 先根据玩家编号分类
                        IEnumerable <FuruAble> player_furuable = from furuable in Furuables group furuable by furuable.playerId into g select g.First();

                        foreach (FuruAble furuable in player_furuable)
                        {
                            foreach (MahjongCardFuru furu in furuable.FuruableList)
                            {
                                playerActions.Add(new PlayerAction(furu, furuable.playerId));
                            }
                        }
                    }

                    // 清空动作预备列表
                    PrepareActionsList.Clear();

                    // 打开玩家动作通道
                    gameStateMachine.OpenPlayerActionChannel();

                    if (playerActions.Count > 0)
                    {
                        // 保存可能的玩家操作列表
                        PlayerActionsList = (from act in playerActions group act by act.playerId into g select g).ToList();

                        // 获得用户响应,将向其他用户广播其响应
                        // 使用响应回调函数
                        PlayerActionResponseCallback(playerActions);

                        // 进入接受用户响应的状态
                        gameStateMachine.SetState(GameStateMachine.State.AcceptingPlayerAction);
                    }
                    else
                    {
                        // 进入用户响应执行状态(跳过)
                        AcceptedPlayerActions.Clear();
                        gameStateMachine.SetState(GameStateMachine.State.ExecutePlayerAction);
                        gameStateMachine.ReleaseSemaphore();
                    }
                    break;

                case GameStateMachine.State.AcceptingPlayerAction:
                    // 取出队列
                    PlayerAction action = gameStateMachine.GetPlayerAction();

                    // 加入动作列表
                    PrepareActionsList.Add(action);

                    // 从可用列表中删除所有该玩家其他操作
                    PlayerActionsList.RemoveAll((match) => match.Key == action.playerId);

                    // 遍历其他所有动作进行优先级比对
                    bool isHighestPriority = true;
                    foreach (IGrouping <int, PlayerAction> player in PlayerActionsList)
                    {
                        foreach (PlayerAction player_act in player)
                        {
                            if (player_act.Priority < action.Priority)
                            {
                                isHighestPriority = false;
                                break;
                            }
                        }
                        if (isHighestPriority)
                        {
                            break;
                        }
                    }

                    if (isHighestPriority || (PlayerActionsList.Count == 0))
                    {
                        // 最高优先级
                        // 关闭动作通道
                        gameStateMachine.ClosePlayerActionChannel();

                        // 处理动作列表
                        int highestPriority = PrepareActionsList.Min((selector) => (selector.Priority));
                        IEnumerable <PlayerAction> accept_list = PrepareActionsList.FindAll((match) => (match.Priority == highestPriority) && (match.actionType != PlayerActionType.Cancel));
                        IEnumerable <PlayerAction> refuse_list = PrepareActionsList.Except(accept_list);

                        AcceptedPlayerActions = accept_list.ToList();

                        foreach (PlayerAction act in accept_list)
                        {
                            // 接受这些请求
                            PlayerActionAcceptedCallback(act.playerId, true);
                        }

                        foreach (PlayerAction act in refuse_list)
                        {
                            // 拒绝/取消这些请求
                            PlayerActionAcceptedCallback(act.playerId, false);
                        }

                        // 将没有反应(被忽略)的玩家拒绝
                        for (int i = 0; i < 4; i++)
                        {
                            if (i == Playing)
                            {
                                continue;
                            }
                            if (PrepareActionsList.FindIndex((match) => match.playerId == i) < 0)
                            {
                                PlayerActionAcceptedCallback(i, false);
                            }
                        }

                        // 进入执行玩家操作状态
                        gameStateMachine.SetState(GameStateMachine.State.ExecutePlayerAction);
                        gameStateMachine.ReleaseSemaphore();
                    }

                    break;

                case GameStateMachine.State.ExecutePlayerAction:
                    if (AcceptedPlayerActions.Count == 0)
                    {
                        // 没有接受的操作,直接跳转到下家
                        _NextPlayer();

                        gameStateMachine.SetState(GameStateMachine.State.Idle);
                    }
                    else
                    {
                        foreach (PlayerAction act in AcceptedPlayerActions)
                        {
                            switch (act.actionType)
                            {
                            case PlayerActionType.Ron:
                            case PlayerActionType.Tsumo:
                                // 和牌

                                break;

                            case PlayerActionType.ChiGrade:
                            case PlayerActionType.ChiSquad:
                            case PlayerActionType.Pong:
                            case PlayerActionType.Kong:
                            case PlayerActionType.Kong_Self:
                            case PlayerActionType.Kong_Add:
                                // 副露
                                // 获得刚刚打牌的玩家的牌河和打出的牌
                                List <MahjongCard> played_cards = GetPlayerCardPlayed(Playing);
                                MahjongCard        last_played  = played_cards.Last(); // 最后一张

                                // 副露对象和副露者
                                int target      = Playing;
                                int furu_player = act.playerId;

                                // 新的副露
                                MahjongCardFuru furu = new MahjongCardFuru()
                                {
                                    target = target,
                                    type   = ActionTypeToFuruType(act.actionType),
                                    cards  = new List <MahjongCard>(),
                                };

                                // 组成副露牌组
                                foreach (MahjongCard card in act.effectCards)
                                {
                                    furu.cards.Add(card);

                                    // 从手牌中删除
                                    player_info[furu_player].card_onhand.Remove(card);
                                }

                                furu.cards.Add(last_played);

                                // 添加到玩家副露
                                player_info[furu_player].card_furu.Add(furu);

                                // 从目标玩家牌河删除
                                player_info[target].card_played.RemoveAt(player_info[target].card_played.Count - 1);

                                // 直接跳转到副露家
                                _ToPlayer(furu_player);

                                gameStateMachine.SetState(GameStateMachine.State.Idle);

                                break;
                            }
                        }
                    }
                    break;

                case GameStateMachine.State.Exit:
                    return;
                }
            }
        }