예제 #1
0
파일: Game.cs 프로젝트: litsungyi/Hanabi
        private void PlayerQuitRoom(IHanabiPlayer player, RequestQuitRoom request)
        {
            RoomInfo       roomInfo = new RoomInfo();
            QuitRoomResult result   = QuitRoomResult.Fail;

            if (player.RoomStatus != PlayerRoomStatus.Idle)
            {
                RoomIndexType roomIndex = new RoomIndexType(request.RoomIndex);
                if (Rooms.ContainsKey(roomIndex))
                {
                    Room room = Rooms[roomIndex];
                    room.Players.Remove(player);
                    roomInfo = room.Info;
                    player.OnQuitRoom();

                    if (room.Players.Count == 0)
                    {
                        room.Clear();
                    }
                    result = QuitRoomResult.Success;
                }
            }

            ResponseQuitRoom response = new ResponseQuitRoom();

            response.Result = result;
            response.Room   = roomInfo;

            SendCommand(player, ActionType.QuitRoom, response);
        }
예제 #2
0
파일: Game.cs 프로젝트: litsungyi/Hanabi
        private void PlayerJoinRoom(IHanabiPlayer player, RequestJoinRoom request)
        {
            RoomInfo       roomInfo = new RoomInfo();
            JoinRoomResult result   = JoinRoomResult.Fail;

            if (player.RoomStatus == PlayerRoomStatus.Idle)
            {
                RoomIndexType roomIndex = new RoomIndexType(request.RoomIndex);
                if (Rooms.ContainsKey(roomIndex))
                {
                    Room room = Rooms[roomIndex];
                    if (room.Players.Count < room.Setting.MaxPlayers)
                    {
                        room.Players.Add(player);
                        roomInfo = room.Info;
                        player.OnJoinRoom(room);

                        result = JoinRoomResult.Success;
                    }
                }
            }

            ResponseJoinRoom response = new ResponseJoinRoom();

            response.Result = result;
            response.Room   = roomInfo;

            SendCommand(player, ActionType.JoinRoom, response);
        }
예제 #3
0
파일: Game.cs 프로젝트: litsungyi/Hanabi
        private void PlayerReady(IHanabiPlayer player)
        {
            player.OnReady();

            SendCommand(player, ActionType.Ready);

            if (Players.Count <= 1)
            {
                return;
            }

            bool allReady = true;

            foreach (var playerPair in Players)
            {
                if (playerPair.Value.RoomStatus != PlayerRoomStatus.Ready)
                {
                    allReady = false;
                    break;
                }
            }

            if (allReady)
            {
                GameBegin(player.Room.RoomIndex);
            }
        }
예제 #4
0
        /// <summary>
        /// 打出卡牌
        ///   從手牌中打出 1張卡牌,正面朝上置於桌面場內。
        ///   從牌堆抽取最上方一張牌,正面朝外,置於手牌上。
        ///   打出的卡牌必須符合下列原則:
        ///     牌上數字須為桌面場內同色牌未出現,且須接續在已出現同色牌數字後。
        ///   若打出的卡牌不符合以上原則,即算施放失敗。
        ///     取 1個紅色錯誤指示物,施放失敗的花火卡則正面朝上置於棄牌區
        ///   若玩家完成一組顏色花火卡牌施放(即數字1~5依照順序排列的「同花順」)
        ///     得到 1個藍色傳達指示物做為獎勵。
        ///     若已無藍色傳達指示物,則無此獎勵行動。
        /// </summary>
        /// <param name="cardIndex">打出的牌</param>
        /// <param name="player">出牌玩家</param>
        /// <param name="board">遊戲資訊</param>
        /// <param name="drawedCard">出牌後的補牌</param>
        /// <returns>出牌的結果</returns>
        public PlayCardResult PlayCard(CardIndexType cardIndex, IHanabiPlayer player, GameBoard board, out Card drawedCard)
        {
            Card playedCard = player.GetCard(cardIndex);

            if (playedCard == null)
            {
                drawedCard = null;
                return(PlayCardResult.InvalidCardIndex);
            }
            player.PlayCard(cardIndex);

            drawedCard = board.Draw();
            if (drawedCard != null)
            {
                player.DrawCard(drawedCard);
            }

            if (board.Play(playedCard))
            {
                if (playedCard.Value == CardValueType.Value5)
                {
                    board.Reward();
                }
                return(PlayCardResult.Success);
            }
            else
            {
                board.Punish();
                board.Discard(playedCard);
                return(PlayCardResult.FailNoSlot);
            }
        }
예제 #5
0
파일: Game.cs 프로젝트: litsungyi/Hanabi
        private void SendCommand(IHanabiPlayer player, ActionType action)
        {
            Command command = new Command();

            command.Action  = action.ToString();
            command.Payload = null;
            player.SendCommand(command);
        }
예제 #6
0
파일: Game.cs 프로젝트: litsungyi/Hanabi
        private void SendCommand <T>(IHanabiPlayer player, ActionType action, T response)
        {
            Command command = new Command();

            command.Action  = action.ToString();
            command.Payload = JsonConvert.SerializeObject(response);
            player.SendCommand(command);
        }
예제 #7
0
        private void PlayerGetRoomList(Game game, IHanabiPlayer player)
        {
            RequestGetRoomList request = new RequestGetRoomList();

            Command command = new Command();

            command.action  = ActionType.GetRoomList.ToString();
            command.payload = JsonConvert.SerializeObject(request);
            game.DispatchRequest(player, JsonConvert.SerializeObject(command));
        }
예제 #8
0
        private void PlayerJoinRoom(Game game, IHanabiPlayer player, RoomIndexType roomIndex)
        {
            RequestJoinRoom request = new RequestJoinRoom();

            request.RoomIndex = roomIndex.Index;

            Command command = new Command();

            command.action  = ActionType.JoinRoom.ToString();
            command.payload = JsonConvert.SerializeObject(request);
            game.DispatchRequest(player, JsonConvert.SerializeObject(command));
        }
예제 #9
0
        private void PlayerExit(Game game, IHanabiPlayer player, NicknameType nickname)
        {
            RequestExitGame request = new RequestExitGame();

            request.Nickname = nickname.nickname;

            Command command = new Command();

            command.action  = ActionType.ExitGame.ToString();
            command.payload = JsonConvert.SerializeObject(request);
            game.DispatchRequest(player, JsonConvert.SerializeObject(command));
        }
예제 #10
0
파일: Game.cs 프로젝트: litsungyi/Hanabi
        private void PlayerExitGame(IHanabiPlayer player, RequestExitGame request)
        {
            ExitGameResult result = ExitGameResult.Success;

            if (Players.ContainsKey(player.Nickname))
            {
                player.OnExitGame();
                result = ExitGameResult.Success;
            }

            ResponseExitGame response = new ResponseExitGame(result);

            SendCommand(player, ActionType.ExitGame, response);
        }
예제 #11
0
        /// <summary>
        /// 傳遞訊息
        ///   消耗 1個藍色傳達指示物,若已無未消耗藍色傳達指示物,則不可執行此行動。
        ///   告訴另一玩家其手牌的線索
        ///   提供線索須遵循以下原則:
        ///     只能就玩家手牌內的某種顏色或某種數字提供線索
        /// </summary>
        /// <param name="color">提示的顏色</param>
        /// <param name="player">被提示的玩家</param>
        /// <param name="board">遊戲資訊</param>
        /// <returns>提示結果</returns>
        public PromptCardResult PromptCard(CardColorType color, IHanabiPlayer player, GameBoard board)
        {
            if (color == CardColorType.Unknown)
            {
                return(PromptCardResult.InvalidPrompt);
            }

            if (!board.Use())
            {
                return(PromptCardResult.PromptEmpty);
            }

            player.PromptCard(color);
            return(PromptCardResult.Success);
        }
예제 #12
0
파일: Game.cs 프로젝트: litsungyi/Hanabi
        private void PlayerGetRoomList(IHanabiPlayer player)
        {
            List <RoomInfo> roomList = new List <RoomInfo>();

            foreach (var room in Rooms.Values)
            {
                roomList.Add(room.Info);
            }

            ResponseRoomList response = new ResponseRoomList();

            response.Rooms = roomList;

            SendCommand(player, ActionType.GetRoomList, response);
        }
예제 #13
0
        /// <summary>
        /// 傳遞訊息
        ///   消耗 1個藍色傳達指示物,若已無未消耗藍色傳達指示物,則不可執行此行動。
        ///   告訴另一玩家其手牌的線索
        ///   提供線索須遵循以下原則:
        ///     只能就玩家手牌內的某種顏色或某種數字提供線索
        /// </summary>
        /// <param name="value">提示的數字</param>
        /// <param name="player">被提示的玩家</param>
        /// <param name="board">遊戲資訊</param>
        /// <returns>提示結果</returns>
        public PromptCardResult PromptCard(CardValueType value, IHanabiPlayer player, GameBoard board)
        {
            if (value == CardValueType.Unknown)
            {
                return(PromptCardResult.InvalidPrompt);
            }

            if (!board.Use())
            {
                return(PromptCardResult.PromptEmpty);
            }

            player.PromptCard(value);
            return(PromptCardResult.Success);
        }
예제 #14
0
파일: Game.cs 프로젝트: litsungyi/Hanabi
        private void PlayerEnterGame(IHanabiPlayer player, RequestEnterGame request)
        {
            ExitGameResult result   = ExitGameResult.Fail;
            NicknameType   nickname = new NicknameType(request.Nickname);

            if (!Players.ContainsKey(nickname))
            {
                result = ExitGameResult.Success;

                player.OnEnterGame(nickname);
                Players.Add(player.Nickname, player);
            }

            ResponseEnterGame response = new ResponseEnterGame(result);

            SendCommand(player, ActionType.EnterGame, response);
        }
예제 #15
0
        /// <summary>
        /// 丟棄手牌
        ///   從手牌中丟棄一張牌,正面朝上置於棄牌區。
        ///   從牌堆抽取最上方一張牌,正面朝外,置於手牌上。
        ///   得到 1個藍色傳達指示物,若已無已消耗藍色傳達指示物,則不可執行此行動。
        /// </summary>
        /// <param name="cardIndex">丟棄的牌</param>
        /// <param name="player">丟牌玩家</param>
        /// <param name="board">遊戲資訊</param>
        /// <param name="drawedCard">出牌後的補牌</param>
        /// <returns>棄牌結果</returns>
        public DiscardCardResult DiscardCard(CardIndexType cardIndex, IHanabiPlayer player, GameBoard board, out Card drawedCard)
        {
            Card discardedCard = player.GetCard(cardIndex);

            if (discardedCard == null)
            {
                drawedCard = null;
                return(DiscardCardResult.InvalidCardIndex);
            }
            player.DiscardCard(cardIndex);

            drawedCard = board.Draw();
            if (drawedCard != null)
            {
                player.DrawCard(drawedCard);
            }

            board.Discard(discardedCard);
            board.Reward();

            return(DiscardCardResult.Success);
        }
예제 #16
0
파일: Game.cs 프로젝트: litsungyi/Hanabi
        public void DispatchRequest(IPlayer player, string message)
        {
            IHanabiPlayer hanabiPlayer = player as IHanabiPlayer;

            if (hanabiPlayer == null)
            {
                return;
            }

            Command    command = JsonConvert.DeserializeObject <Command>(message);
            ActionType action  = ( ActionType )Enum.Parse(typeof(ActionType), command.Action, false);

            switch (action)
            {
            case ActionType.EnterGame:
            {
                RequestEnterGame request = JsonConvert.DeserializeObject <RequestEnterGame>(command.Payload);
                PlayerEnterGame(hanabiPlayer, request);
                break;
            }

            case ActionType.ExitGame:
            {
                RequestExitGame request = JsonConvert.DeserializeObject <RequestExitGame>(command.Payload);
                PlayerExitGame(hanabiPlayer, request);
                break;
            }

            case ActionType.GetRoomList:
            {
                PlayerGetRoomList(hanabiPlayer);
                break;
            }

            case ActionType.JoinRoom:
            {
                RequestJoinRoom request = JsonConvert.DeserializeObject <RequestJoinRoom>(command.Payload);
                PlayerJoinRoom(hanabiPlayer, request);
                break;
            }

            case ActionType.QuitRoom:
            {
                RequestQuitRoom request = JsonConvert.DeserializeObject <RequestQuitRoom>(command.Payload);
                PlayerQuitRoom(hanabiPlayer, request);
                break;
            }

            case ActionType.Message:
            {
                // TODO:
                break;
            }

            case ActionType.Ready:
            {
                PlayerReady(hanabiPlayer);
                break;
            }

            case ActionType.PromptCard:
            {
                RequestPromptCard request = JsonConvert.DeserializeObject <RequestPromptCard>(command.Payload);
                PlayerPrompt(hanabiPlayer, request);
                break;
            }

            case ActionType.PlayCard:
            {
                RequestPlayCard request = JsonConvert.DeserializeObject <RequestPlayCard>(command.Payload);
                PlayerPlayCard(hanabiPlayer, request);
                break;
            }

            case ActionType.DiscardCard:
            {
                RequestDiscardCard request = JsonConvert.DeserializeObject <RequestDiscardCard>(command.Payload);
                PlayerDiscardCard(hanabiPlayer, request);
                break;
            }

            default:
                break;
            }
        }
예제 #17
0
        /// <summary>
        /// 提示玩家卡牌資訊
        /// </summary>
        /// <param name="player">行動的玩家</param>
        /// <param name="prompt">提示資訊</param>
        public void Prompt(IHanabiPlayer player, RequestPromptCard prompt)
        {
            if (!IsCurrentPlayer(player))
            {
                ResponsePromptCard invalidResponse = new ResponsePromptCard();
                invalidResponse.Result            = PromptCardResult.InvalidTurn;
                invalidResponse.PromptInformation = prompt.PromptInformation;
                SendCommandToPlayer(player, ActionType.PromptCard, invalidResponse);
                return;
            }

            IHanabiPlayer targetPlayer = this.GetPlayer(prompt.Nickname);

            if (targetPlayer == null)
            {
                ResponsePromptCard invalidResponse = new ResponsePromptCard();
                invalidResponse.Result            = PromptCardResult.InvalidPlayer;
                invalidResponse.PromptInformation = prompt.PromptInformation;
                SendCommandToPlayer(player, ActionType.PromptCard, invalidResponse);
                return;
            }

            PromptCardResult result = PromptCardResult.InvalidPrompt;

            switch (prompt.PromptInformation)
            {
            case ( int )CardValueType.Value1:
            case ( int )CardValueType.Value2:
            case ( int )CardValueType.Value3:
            case ( int )CardValueType.Value4:
            case ( int )CardValueType.Value5:
                result = Rule.PromptCard(( CardValueType )prompt.PromptInformation, targetPlayer, Board);
                break;

            case ( int )CardColorType.Blue:
            case ( int )CardColorType.Green:
            case ( int )CardColorType.Yellow:
            case ( int )CardColorType.Red:
            case ( int )CardColorType.White:
                result = Rule.PromptCard(( CardColorType )prompt.PromptInformation, targetPlayer, Board);
                break;
            }

            if (result != PromptCardResult.Success)
            {
                ResponsePromptCard invalidResponse = new ResponsePromptCard();
                invalidResponse.Result            = result;
                invalidResponse.PromptInformation = prompt.PromptInformation;
                SendCommandToPlayer(player, ActionType.PromptCard, invalidResponse);
                return;
            }

            // 通知被提示玩家的命令
            ResponsePromptCard notify = new ResponsePromptCard();

            notify.Result            = result;
            notify.Nickname          = prompt.Nickname;
            notify.PromptInformation = prompt.PromptInformation;
            notify.Token             = Board.Tokens.Info;

            // 通知其他玩家的命令
            ResponsePromptCard response = new ResponsePromptCard();

            response.Result            = result;
            response.Nickname          = prompt.Nickname;
            response.PromptInformation = prompt.PromptInformation;
            response.Token             = Board.Tokens.Info;
            foreach (var handCard in targetPlayer.Cards)
            {
                CardInfo responseInfo = handCard.Info;
                response.Cards.Add(responseInfo);

                CardInfo notifyInfo = handCard.Info;
                notifyInfo.Color = ( int )CardColorType.Unknown;
                notifyInfo.Value = ( int )CardValueType.Unknown;
                notify.Cards.Add(notifyInfo);
            }

            foreach (var notifyPlayer in Players)
            {
                if (notifyPlayer == targetPlayer)
                {
                    SendCommandToPlayer(notifyPlayer, ActionType.PromptCard, notify);
                }
                else
                {
                    SendCommandToPlayer(notifyPlayer, ActionType.PromptCard, response);
                }
            }

            NextActivePlayer();
            NotifyNextPlayer();
        }
예제 #18
0
        public void Discard(IHanabiPlayer player, RequestDiscardCard card)
        {
            if (!IsCurrentPlayer(player))
            {
                ResponseDiscardCard invalidResponse = new ResponseDiscardCard();
                invalidResponse.Result = DiscardCardResult.InvalidTurn;
                SendCommandToPlayer(player, ActionType.DiscardCard, invalidResponse);
                return;
            }

            CardIndexType cardIndex = new CardIndexType(card.CardIndex);
            Card          oldCard   = player.GetCard(cardIndex);

            Card newCard             = null;
            DiscardCardResult result = Rule.DiscardCard(cardIndex, player, Board, out newCard);

            if (result != DiscardCardResult.Success)
            {
                ResponseDiscardCard invalidResponse = new ResponseDiscardCard();
                invalidResponse.Result = result;
                SendCommandToPlayer(player, ActionType.DiscardCard, invalidResponse);
                return;
            }

            ResponseDiscardCard response = new ResponseDiscardCard();

            response.Result        = result;
            response.Nickname      = player.Nickname.Value;
            response.OldCard       = oldCard.Info;
            response.NewCard       = (newCard != null) ? newCard.Info : null;
            response.Token         = Board.Tokens.Info;
            response.DrawPileCount = Board.Size;

            CardInfo info = (newCard != null) ? newCard.Info : null;

            if (info != null)
            {
                info.Color = ( int )CardColorType.Unknown;
                info.Value = ( int )CardValueType.Unknown;
            }

            ResponseDiscardCard notify = new ResponseDiscardCard();

            notify.Result        = result;
            notify.Nickname      = player.Nickname.Value;
            notify.OldCard       = oldCard.Info;
            notify.NewCard       = info;
            notify.Token         = Board.Tokens.Info;
            notify.DrawPileCount = Board.Size;

            foreach (var notifyPlayer in Players)
            {
                if (notifyPlayer == player)
                {
                    SendCommandToPlayer(notifyPlayer, ActionType.DiscardCard, notify);
                }
                else
                {
                    SendCommandToPlayer(notifyPlayer, ActionType.DiscardCard, response);
                }
            }

            CheckLastRound();

            NextActivePlayer();
            NotifyNextPlayer();
        }
예제 #19
0
파일: Game.cs 프로젝트: litsungyi/Hanabi
 private void PlayerDiscardCard(IHanabiPlayer player, RequestDiscardCard card)
 {
     player.Room.Discard(player, card);
 }
예제 #20
0
파일: Game.cs 프로젝트: litsungyi/Hanabi
 private void PlayerPlayCard(IHanabiPlayer player, RequestPlayCard card)
 {
     player.Room.Play(player, card);
 }
예제 #21
0
파일: Game.cs 프로젝트: litsungyi/Hanabi
 private void PlayerPrompt(IHanabiPlayer player, RequestPromptCard prompt)
 {
     player.Room.Prompt(player, prompt);
 }
예제 #22
0
 private bool IsCurrentPlayer(IHanabiPlayer player)
 {
     return(Players[CurrentPlayer] == player);
 }