Example #1
0
        /// <summary>
        ///     Informs players about the last roll of the dices.
        /// </summary>
        /// <param name="rollResult">Whether the roll succeeded.</param>
        /// <param name="state">Current state of the turn.</param>
        private void InformDicesRolled(GameActionResult rollResult, TurnState state)
        {
            var dices = "";

            if (rollResult == GameActionResult.Failure)
            {
                InformPlayer(game.CurrentPlayer, "-- Bad luck! Nothing scorable was rolled!");
                foreach (var d in game.CurrentPlayer.State.Dices)
                {
                    dices += $"{d.Value} ";
                }
                InformPlayer(game.CurrentPlayer,
                             CommunicationConstants.CommentStart + " " + CommunicationConstants.DicesInfo + " " + dices);
                return;
            }

            dices = "";
            InformPlayer(game.CurrentPlayer, "-- Roll succesful");
            InformPlayer(game.CurrentPlayer, CommunicationConstants.CurrentTurnScoreInfo + " " + state.Score);
            foreach (var d in game.CurrentPlayer.State.Dices)
            {
                dices += $"{d.Value} ";
            }
            InformPlayer(game.CurrentPlayer, CommunicationConstants.DicesInfo + " " + dices);
        }
        public void DefaultGameFlowGenerated_PlayerSpecifiesCoordsInSequence_GameIsWon()
        {
            var coordinates = GenerateAllBoardCoordinates();

            var flow = Generate.GameFlow().Build();

            var winningCoords           = new List <string>();
            GameActionResult shotResult = new GameActionResult();

            foreach (var coords in coordinates)
            {
                shotResult = flow.MakeShot(coords);

                if (IsHit(shotResult))
                {
                    winningCoords.Add(coords);
                }

                if (IsWin(shotResult))
                {
                    break;
                }
            }

            shotResult.Outcome.Should().Be(GameActionOutcome.Win);
            winningCoords.Should().HaveCount(5 + 4 * 2);
        }
        public async Task <GameActionResult> SubmitAction(int nActionType, int nActionArguement, int gameId, string strIdentity)
        {
            GameActionResult result = new GameActionResult(nActionType, gameId);
            GameAction       action = new GameAction(nActionType, nActionArguement, gameId, strIdentity);

            // post action to game database
            string request = "api/game/submit";

            var httpResponse = await httpClient.PostAsJsonAsync(request, action);

            if (httpResponse.Content is object && httpResponse.Content.Headers.ContentType.MediaType == "application/json")
            {
                var contentStream = await httpResponse.Content.ReadAsStreamAsync();

                try
                {
                    return(await JsonSerializer.DeserializeAsync <GameActionResult>(contentStream,
                                                                                    new JsonSerializerOptions { IgnoreNullValues = true, PropertyNameCaseInsensitive = true }));
                }
                catch (JsonException) // Invalid JSON
                {
                    Console.WriteLine("Invalid JSON.");
                }
            }
            else
            {
                Console.WriteLine("HTTP Response was invalid and cannot be deserialised.");
            }

            return(result); // Unknown error by default
        }
        private async Task <GameActionResult> AddUser(GameAction action)
        {
            GameActionResult result = new GameActionResult(action.nActionType); // unknown error by default

            // confirm action type
            if (action.nActionType != 7)
            {
                return(result);
            }

            var users = await GetUsers();

            foreach (User user in users)
            {
                if (user.Identity == action.strIdentity)
                {
                    result.nResponseCode = 8;
                    return(result);
                }
            }

            // minimum Identity string length = 8
            if (action.strIdentity.Length < 9)
            {
                result.nResponseCode = 5; // bad player name
                return(result);
            }

            await AddUser(action.strIdentity);

            result.nResponseCode = 1;
            return(result);
        }
Example #5
0
        public GameActionResult GetNextAction(GameStage currentStage)
        {
            var input  = Console.ReadLine()?.Trim();
            var result = new GameActionResult {
                GameAction = GameAction.Invalid
            };

            switch (input)
            {
            case Constants.NewGame:
                if (currentStage == GameStage.MainMenu)
                {
                    result.GameAction = GameAction.NewGame;
                }
                break;

            case Constants.ContinueGame:
                if (currentStage == GameStage.MainMenu)
                {
                    result.GameAction = GameAction.Continue;
                }
                break;

            case Constants.NewSession:
                if (currentStage != GameStage.MainMenu)
                {
                    result.GameAction = GameAction.OpenOrNewSession;
                }
                break;

            case Constants.EndSession:
                if (currentStage == GameStage.InGame)
                {
                    result.GameAction = GameAction.EndGame;
                }
                break;

            case Constants.ExitGame:
                result.GameAction = GameAction.ExitGame;
                break;

            default:
                if (currentStage == GameStage.InGame && int.TryParse(input, out var userNumber))
                {
                    result.GameAction = GameAction.InputNumber;
                    result.Number     = userNumber;
                }
                break;
            }
            return(result);
        }
Example #6
0
        private static void HandleGameActionResult(TextBlock userActionMessage, GameActionResult result)
        {
            if (!string.IsNullOrEmpty(result.Description))
            {
                userActionMessage.Text = result.Description;
                return;
            }

            userActionMessage.Text = result.Outcome switch
            {
                GameActionOutcome.Error => "Unspecified error occured",
                GameActionOutcome.Miss => "Shot missed",
                GameActionOutcome.Hit => "It's a hit!",
                GameActionOutcome.Sink => "Sunken ship!",
                GameActionOutcome.Win => "Game Won!",
                _ => ""
            };
        }
        public async Task <GameActionResult> SubmitAction(GameAction action)
        {
            GameActionResult result = new GameActionResult(action.nActionType, action.gameId, 4); // action not implemented

            // check action is legit
            if (action.nActionType > 0 && action.nActionType < 5)
            {
                result = await IsActionAllowed(action);

                if (result.nResponseCode != 1)
                {
                    return(result);
                }
            }
            switch (action.nActionType)
            {
            case 1:
                result = await MovePiece(action);

                break;

            case 2:
                result = await Harvest(action);

                break;

            case 5:     // Create game
                result = await CreateGame(action);

                break;

            case 6:     // Join game
                result = await JoinGame(action);

                break;

            case 7:     // Add user
                break;
            }

            return(result);
        }
 private static bool IsWin(GameActionResult shotResult)
 {
     return(shotResult.Outcome == GameActionOutcome.Win);
 }
 private static bool IsHit(GameActionResult shotResult)
 {
     return(shotResult.Outcome != GameActionOutcome.Error && shotResult.Outcome != GameActionOutcome.Miss);
 }
        private async Task <GameActionResult> JoinGame(GameAction action)
        {
            GameActionResult result = new GameActionResult(action.nActionType, action.gameId); // unknown error by default

            // confirm action type
            if (action.nActionType != 6)
            {
                return(result);
            }

            var User = await GetUser(action.strIdentity);

            if (User == null)
            {
                return(result); // unknown error by default
            }
            // check if their game slots are full
            if (User.GameId1 != 0 && User.GameId2 != 0 && User.GameId3 != 0 && User.GameId4 != 0)
            {
                result.nResponseCode = 7;
                return(result);
            }

            Player player = new Player();

            player.Identity      = action.strIdentity;
            player.NPlayer       = 2;
            player.NScore        = 0;
            player.NPlayerStatus = 1;   // active

            // get game
            Game game = await GetGame(action.gameId);

            if (game == null)
            {
                result.nResponseCode = 2; // game not exist
                return(result);
            }

            // get player(s)
            var playerBulkList = await appDbContext.Player.ToListAsync();

            var playerList = playerBulkList.FindAll(p => p.GameId == action.gameId);

            // can't join a game with more than one player
            if (playerList.Count() > 1)
            {
                result.nResponseCode = 6; // game full
                return(result);
            }

            // add player
            playerList.Add(player);

            // assign player list
            game.Player = playerList;

            game.NGameStatus = 1 + 2; // setup complete + game incomplete

            appDbContext.Game.Update(game);

            // assign GameId one of the user's game slots
            if (User.GameId1 == 0)
            {
                User.GameId1 = action.gameId;
            }
            else if (User.GameId2 == 0)
            {
                User.GameId2 = action.gameId;
            }
            else if (User.GameId3 == 0)
            {
                User.GameId3 = action.gameId;
            }
            else
            {
                User.GameId4 = action.gameId;
            }

            appDbContext.User.Update(User);
            await appDbContext.SaveChangesAsync();

            result.nResponseCode = 1; // OK
            return(result);
        }
        private async Task <GameActionResult> CreateGame(GameAction action)
        {
            GameActionResult result = new GameActionResult(action.nActionType); // unknown error by default

            // confirm action type
            if (action.nActionType != 5)
            {
                return(result);
            }

            var User = await GetUser(action.strIdentity);

            if (User == null)
            {
                return(result); // unknown error by default
            }
            // check if their game slots are full
            if (User.GameId1 != 0 && User.GameId2 != 0 && User.GameId3 != 0 && User.GameId4 != 0)
            {
                result.nResponseCode = 7;
                return(result);
            }

            // create new player opject
            Player player = new Player();

            player.Identity      = action.strIdentity;
            player.NPlayer       = 1;
            player.NScore        = 0;
            player.NPlayerStatus = 1;   // active

            // new game database object
            Game game = new Game();

            game.Player.Add(player);

            /*
             * Bit  | On            | Off
             * 1    | setup complete| need player
             * 2    | Incomplete    | Complete
             * 4    | Player 2 turn | Player 1 turn
             * 8    | Bonus turn    | Normal turn
             */
            game.NGameStatus = 2;   // Need player (0) + Incomplete (2) + player1 turn (0) + normal turn (0)

            PiecesBag bag = new PiecesBag();

            // give the first 5 to the main board
            for (int i = 0; i < 5; i++)
            {
                Piece piece = new Piece();
                piece.NOwner     = (int)eOwner.mainboard;
                piece.NPosition  = i;
                piece.NPieceType = (int)bag.GetNextPiece();
                piece.HashIndex  = i;
                game.Piece.Add(piece);
            }

            // give the rest to the bag
            for (int i = 0; i < 85; i++)
            {
                Piece piece = new Piece();
                piece.NOwner     = (int)eOwner.bag;
                piece.NPosition  = 0;
                piece.NPieceType = (int)bag.GetNextPiece();
                piece.HashIndex  = i + 5;
                game.Piece.Add(piece);
            }

            var dBresult = await appDbContext.Game.AddAsync(game);

            await appDbContext.SaveChangesAsync();  // need to initialise GameId

            // assign GameId one of the user's game slots
            if (User.GameId1 == 0)
            {
                User.GameId1 = dBresult.Entity.GameId;
            }
            else if (User.GameId2 == 0)
            {
                User.GameId2 = dBresult.Entity.GameId;
            }
            else if (User.GameId3 == 0)
            {
                User.GameId3 = dBresult.Entity.GameId;
            }
            else
            {
                User.GameId4 = dBresult.Entity.GameId;
            }

            appDbContext.User.Update(User);
            await appDbContext.SaveChangesAsync();

            result.gameId        = dBresult.Entity.GameId;
            result.nResponseCode = 1; // OK
            return(result);
        }
        private async Task <GameActionResult> Harvest(GameAction action)
        {
            GameActionResult result = new GameActionResult(action.nActionType, action.gameId);

            var score = new Score(action.Pieces);

            action.player.NScore += score.Calculate();

            // add companion bonus
            action.player.NScore += action.nActionArguement;

            // increase score for each star
            foreach (var piece in action.Pieces)
            {
                // if bit 2 has not been set the piece has not been flipped
                if ((piece.NPieceStatus & 2) != 2)
                {
                    action.player.NScore++;
                }
            }

            // setup history object
            History history = new History();

            history.NPlayer     = action.player.NPlayer;
            history.NActionType = action.nActionType;
            history.GameId      = action.gameId;
            if (action.player.NPlayer == 1)
            {
                history.NScore1 = action.player.NScore;
                history.NScore2 = action.otherplayer.NScore;
                result.nScore1  = action.player.NScore;
                result.nScore2  = action.otherplayer.NScore;
            }
            else
            {
                history.NScore2 = action.player.NScore;
                history.NScore1 = action.otherplayer.NScore;
                result.nScore2  = action.player.NScore;
                result.nScore1  = action.otherplayer.NScore;
            }

            // Get turn count from nGameStatus (MSByte)
            int turns = (action.game.NGameStatus & 0b1111_1111_0000_0000) / 256;

            turns++;

            // flip player turn bit
            action.game.NGameStatus = (action.game.NGameStatus ^ 4);

            // reform nGameStatus
            action.game.NGameStatus = (action.game.NGameStatus & 0b0000_0000_1111_1111) + turns * 256;
            appDbContext.Game.Update(action.game);
            appDbContext.Player.Update(action.player);
            var historyResult = appDbContext.History.Add(history);

            // save required at this point to populate dBresult.HistoryId
            // and to allow the reload truck check to reflect the changes so far
            await appDbContext.SaveChangesAsync();

            // add linking HistoryPiece entries
            foreach (Piece piece in action.Pieces)
            {
                // we must get the piece tracked by the dB otherwise updating will
                // throw and exception
                var trackedPiece = await appDbContext.Piece.FindAsync(piece.PieceId);

                // mark piece as discarded
                trackedPiece.NOwner = (int)eOwner.discard;
                appDbContext.Piece.Update(trackedPiece);

                HistoryPiece historyPiece = new HistoryPiece
                {
                    HistoryId = historyResult.Entity.HistoryId,
                    PieceId   = trackedPiece.PieceId
                };
                appDbContext.HistoryPiece.Add(historyPiece);
            }

            await appDbContext.SaveChangesAsync();

            result.nGameStatus   = action.game.NGameStatus;
            result.nResponseCode = 1;   // OK
            return(result);
        }
        private async Task <GameActionResult> MovePiece(GameAction action)
        {
            GameActionResult result = new GameActionResult(action.nActionType, action.gameId);

            Piece piece;

            try
            {
                piece = await appDbContext.Piece.FindAsync(action.pieceId);
            }
            catch (Exception)
            {
                // piece has already been picked up
                result.nResponseCode = 11;
                return(result);
            }
            piece.NOwner = action.player.NPlayer;

            // setup history object
            History history = new History();

            history.NPlayer     = action.player.NPlayer;
            history.NActionType = action.nActionType;
            history.GameId      = piece.GameId;

            // check if placement will require piece to be turned over
            if (action.nActionArguement % 5 != piece.NPosition)
            {
                piece.NPieceStatus = (piece.NPieceStatus | 2); // set bit 2 - star side down
            }
            history.NSourcePos = piece.NPosition;
            history.NDestPos   = action.nActionArguement;
            piece.NPosition    = action.nActionArguement;
            appDbContext.Piece.Update(piece);

            var dBresult = appDbContext.History.Add(history);

            // save required at this point to populate dBresult.HistoryId
            // and to allow the reload truck check to reflect the changes so far
            await appDbContext.SaveChangesAsync();

            // add linking HistoryPiece entry
            HistoryPiece historyPiece = new HistoryPiece
            {
                HistoryId = history.HistoryId,
                PieceId   = piece.PieceId
            };

            appDbContext.HistoryPiece.Add(historyPiece);


            Piece unusedPiece;

            try
            {
                unusedPiece = await appDbContext.Piece.Where(p => p.GameId == action.gameId && p.NOwner == 0).FirstAsync();

                unusedPiece.NOwner    = (int)eOwner.mainboard;
                unusedPiece.NPosition = history.NSourcePos;
                appDbContext.Update(unusedPiece);
            }
            catch (Exception)
            {
                var truckPieces = appDbContext.Piece.Where(p => p.GameId == action.gameId && p.NOwner == 3);
                if (truckPieces.Count() == 0) // Game over condition
                {
                    action.game.NGameStatus = action.game.NGameStatus ^ 2;
                }
            }

            // Get turn count from nGameStatus (MSByte)
            int turns = (action.game.NGameStatus & 0b1111_1111_0000_0000) / 256;

            turns++;

            // flip player turn bit
            action.game.NGameStatus = (action.game.NGameStatus ^ 4);

            // reform nGameStatus
            action.game.NGameStatus = (action.game.NGameStatus & 0b0000_0000_1111_1111) + turns * 256;
            appDbContext.Game.Update(action.game);

            await appDbContext.SaveChangesAsync();

            result.nGameStatus   = action.game.NGameStatus;
            result.nResponseCode = 1;   // OK
            return(result);
        }
        private async Task <GameActionResult> IsActionAllowed(GameAction action)
        {
            GameActionResult result = new GameActionResult(action.nActionType, action.gameId);

            // get game
            Game game = await GetGame(action.gameId);

            if (game == null)
            {
                result.nResponseCode = 2;
                return(result);
            }

            action.game = game;

            // check if game setup is complete
            if ((game.NGameStatus & 1) == 0)
            {
                result.nResponseCode = 11;
                return(result);
            }

            // check if game is over
            if ((game.NGameStatus & 2) == 0)
            {
                result.nResponseCode = 10;
                return(result);
            }

            // get players
            List <Player> players = (List <Player>) await GetPlayers(action.gameId);

            // confirm player exists in game
            var player = players.Where(p => p.Identity == action.strIdentity).First();

            if (player == null)
            {
                result.nResponseCode = 3;
                return(result);
            }

            action.player      = player;
            action.otherplayer = players.Where(p => p.Identity != action.strIdentity).FirstOrDefault();


            // check it is this player's turn
            int nPlayerTurn;

            if ((game.NGameStatus & 4) != 0)
            {
                nPlayerTurn = 2;
            }
            else
            {
                nPlayerTurn = 1;
            }
            if (player.NPlayer != nPlayerTurn)
            {
                result.nResponseCode = 10;
                return(result);
            }

            result.nResponseCode = 1;
            return(result);
        }