Пример #1
0
        public void VerifyDoubleTurn()
        {
            MessagePayload body = new MessagePayload()
            {
                Move = 0,
                AzurePlayerSymbol = "O",
                HumanPlayerSymbol = "X",
                GameBoard         = new string[9] {
                    "O", "?", "X",
                    "X", "?", "?",
                    "O", "O", "?"
                }
            };

            try
            {
                ExecuteMoveResponse response = client.ExecuteMove(body);

                // Fail if an HttpOperationException is not thrown
                Assert.IsTrue(false);
            }
            catch (HttpOperationException error)
            {
                Assert.AreEqual(HttpStatusCode.BadRequest, error.Response.StatusCode);
                Assert.IsTrue(error.Response.Content.Equals("\"There should be less AzurePlayerSymbols than humanPlayerSymbols on the gameBoard\""));
            }
        }
Пример #2
0
        public void VerifyEmptyBoard()
        {
            MessagePayload body = new MessagePayload()
            {
                Move = 0,
                AzurePlayerSymbol = "O",
                HumanPlayerSymbol = "X",
                GameBoard         = new string[9] {
                    "?", "?", "?",
                    "?", "?", "?",
                    "?", "?", "?"
                }
            };

            ExecuteMoveResponse response = client.ExecuteMove(body);

            // Verify that Azure took the first move
            var azurePlayerSymbolCount = response.GameBoard
                                         .Select((value, index) => new { value, index })
                                         .Where((tile) => tile.value.Equals(body.AzurePlayerSymbol))
                                         .Select((tile) => tile.index)
                                         .ToArray()
                                         .Length;

            Assert.AreEqual(1, azurePlayerSymbolCount);
        }
Пример #3
0
        public void VerifyLargerGameBoardLength()
        {
            MessagePayload body = new MessagePayload()
            {
                Move = 0,
                AzurePlayerSymbol = "O",
                HumanPlayerSymbol = "X",
                GameBoard         = new string[12] {
                    "X", "?", "X",
                    "X", "O", "?",
                    "X", "O", "?",
                    "X", "O", "?"
                }
            };

            try
            {
                ExecuteMoveResponse response = client.ExecuteMove(body);

                // Fail if an HttpOperationException is not thrown
                Assert.IsTrue(false);
            }
            catch (HttpOperationException error)
            {
                Assert.AreEqual(HttpStatusCode.BadRequest, error.Response.StatusCode);
                Assert.IsTrue(error.Response.Content.Equals("\"gameboard must have a length of 9 (0 - 8)\""));
            }
        }
Пример #4
0
        public void VerifyGameBoardImbalance()
        {
            MessagePayload body = new MessagePayload()
            {
                Move = 0,
                AzurePlayerSymbol = "O",
                HumanPlayerSymbol = "X",
                GameBoard         = new string[9] {
                    "X", "?", "?",
                    "O", "?", "?",
                    "X", "X", "?",
                }
            };

            try
            {
                ExecuteMoveResponse response = client.ExecuteMove(body);

                // Fail if an HttpOperationException is not thrown
                Assert.IsTrue(false);
            }
            catch (HttpOperationException error)
            {
                Assert.AreEqual(HttpStatusCode.BadRequest, error.Response.StatusCode);
                Assert.IsTrue(error.Response.Content.Equals("\"The difference in symbol counts should be no greater than 1\""));
            }
        }
Пример #5
0
        public void VerifySamePlayerSymbols()
        {
            MessagePayload body = new MessagePayload()
            {
                Move = 0,
                AzurePlayerSymbol = "X",
                HumanPlayerSymbol = "X",
                GameBoard         = new string[9] {
                    "O", "?", "X",
                    "X", "O", "?",
                    "O", "?", "?"
                }
            };

            try
            {
                ExecuteMoveResponse response = client.ExecuteMove(body);

                // Fail if an HttpOperationException is not thrown
                Assert.IsTrue(false);
            }
            catch (HttpOperationException error)
            {
                Assert.AreEqual(HttpStatusCode.BadRequest, error.Response.StatusCode);
                Assert.IsTrue(error.Response.Content.Equals("\"azurePlayerSymbol and humanPlayerSymbol must be opposites\""));
            }
        }
Пример #6
0
        public void VerifyInvalidGameBoardSymbols()
        {
            MessagePayload body = new MessagePayload()
            {
                Move = 0,
                AzurePlayerSymbol = "O",
                HumanPlayerSymbol = "X",
                GameBoard         = new string[9] {
                    "U", "?", "X",
                    "X", "O", "?",
                    "O", "?", "?"
                }
            };

            try
            {
                ExecuteMoveResponse response = client.ExecuteMove(body);

                // Fail if an HttpOperationException is not thrown
                Assert.IsTrue(false);
            }
            catch (HttpOperationException error)
            {
                Assert.AreEqual(HttpStatusCode.BadRequest, error.Response.StatusCode);
                Assert.IsTrue(error.Response.Content.Equals("\"gameBoard can only contain 'X', 'O', or '?'\""));
            }
        }
Пример #7
0
        public void VerifyAzureOSymbol()
        {
            MessagePayload body = new MessagePayload()
            {
                Move = 0,
                AzurePlayerSymbol = "O",
                HumanPlayerSymbol = "X",
                GameBoard         = new string[9] {
                    "X", "?", "X",
                    "X", "O", "?",
                    "O", "?", "?"
                }
            };

            ExecuteMoveResponse response = client.ExecuteMove(body);

            // AzurePlayerSymbol is set to O,
            // verify that the API added another
            // O to the game board.
            var xIndicies = response.GameBoard
                            .Select((value, index) => new { value, index })
                            .Where((tile) => tile.value.Equals("O"))
                            .Select((tile) => tile.index)
                            .ToArray();

            Assert.AreEqual(3, xIndicies.Length);
        }
Пример #8
0
        public async Task OPlayerWinTestAsync()
        // Validate that the application properly detects a human player "O" victory
        {
            //�Arrange
            ExecuteMove payload = new ExecuteMove()
            {
                Move = 1,
                AzurePlayerSymbol = "X",
                HumanPlayerSymbol = "O",
                GameBoard         = new List <string> {
                    "X", "O", "X", "?", "O", "?", "?", "O", "?"
                }
            };

            // Act
            HttpOperationResponse <object> resultObject = await _client.ExecuteMoveResponseWithHttpMessagesAsync(payload);

            ExecuteMoveResponse resultPayload = resultObject.Body as ExecuteMoveResponse;


            // Assert
            if (resultObject != null)
            {
                Assert.AreEqual(resultPayload.Winner, "O");
            }
            else
            {
                Assert.Fail("Expected an ExecuteMoveResponse but didn't recieve one.");
            }
        }
        [ProducesResponseType(typeof(int), StatusCodes.Status400BadRequest)]         // Tells swagger that the response format will be an int for a BadRequest (400)
        public ActionResult <ExecuteMoveResponse> ExecuteMoveResponse([FromBody] ExecuteMove inputPayload)
        {
            if (PayloadValidation.ValidatePayload(inputPayload) == false)
            {
                return(BadRequest(4));
            }

            ExecuteMoveResponse response = CalculateResponse.CalculateMoveResponse(inputPayload);

            return(response);
        }
Пример #10
0
        public void VerifyInconclusive()
        {
            MessagePayload body = new MessagePayload()
            {
                Move = 0,
                AzurePlayerSymbol = "X",
                HumanPlayerSymbol = "O",
                GameBoard         = new string[9] {
                    "O", "?", "O",
                    "O", "X", "?",
                    "X", "?", "?"
                }
            };

            ExecuteMoveResponse response = client.ExecuteMove(body);

            Assert.AreEqual("inconclusive", response.Winner);
            Assert.IsNull(response.WinPositions);
            Assert.IsNotNull(response.Move);
        }
Пример #11
0
        public async Task ValidResponseTestAsync()
        // Validates that the ExecuteMove Response is properly formatted
        // Validate that the Azure and Human player symbols are either "X" or "O" and are not the same.
        {
            //�Arrange
            ExecuteMove payload = new ExecuteMove()
            {
                Move = 2,
                AzurePlayerSymbol = "O",
                HumanPlayerSymbol = "X",
                GameBoard         = new List <string> {
                    "X", "O", "X", "O", "?", "?", "?", "?", "?"
                }
            };

            // Act
            HttpOperationResponse <object> resultObject = await _client.ExecuteMoveResponseWithHttpMessagesAsync(payload);

            ExecuteMoveResponse resultPayload = resultObject.Body as ExecuteMoveResponse;

            // Assert
            if (resultObject != null)
            {
                // Validate that the Azure and Human player symbols are either "X" or "O" and are not the same.
                Assert.IsTrue(resultPayload.AzurePlayerSymbol == "O" || resultPayload.AzurePlayerSymbol == "X");
                Assert.IsTrue(resultPayload.HumanPlayerSymbol == "O" || resultPayload.HumanPlayerSymbol == "X");
                Assert.AreNotEqual(resultPayload.AzurePlayerSymbol, resultPayload.HumanPlayerSymbol);

                // Validate that the gameBoard is the proper size and all values are 'X', 'O', or '?'
                Assert.AreEqual(resultPayload.GameBoard.Count, 9);

                for (int i = 0; i < resultPayload.GameBoard.Count; i++)
                {
                    Assert.IsTrue(resultPayload.GameBoard[i] == "X" || resultPayload.GameBoard[i] == "O" || resultPayload.GameBoard[i] == "?");
                }
            }
            else
            {
                Assert.Fail("Expected an ExecuteMoveResponse but didn't recieve one.");
            }
        }
Пример #12
0
        public void VerifyPlayerOWinner()
        {
            MessagePayload body = new MessagePayload()
            {
                Move = 0,
                AzurePlayerSymbol = "X",
                HumanPlayerSymbol = "O",
                GameBoard         = new string[9] {
                    "O", "X", "?",
                    "O", "X", "?",
                    "O", "?", "?"
                }
            };

            ExecuteMoveResponse response = client.ExecuteMove(body);

            Assert.AreEqual("O", response.Winner);
            Assert.IsTrue(new List <int?>()
            {
                0, 3, 6
            }.SequenceEqual(response.WinPositions));
            Assert.AreEqual(null, response.Move);
        }
Пример #13
0
        public static ExecuteMoveResponse CalculateMoveResponse(ExecuteMove messagePayload)
        // Calculates
        {
            int[,] victoryConditions = new int[8, 3]
                                       // Defines all 8 possible winning combinations in Tic Tac Toe
            {
                { 0, 1, 2 }, { 0, 3, 6 }, { 0, 4, 8 }, { 1, 4, 7 }, { 2, 4, 6 }, { 2, 5, 8 }, { 3, 4, 5 }, { 6, 7, 8 }
            };

            string[,] gameState = new string[8, 3]
                                  // Tracks player positions against possible victories
            {
                { "0", "1", "2" }, { "0", "3", "6" }, { "0", "4", "8" }, { "1", "4", "7" }, { "2", "4", "6" }, { "2", "5", "8" }, { "3", "4", "5" }, { "6", "7", "8" }
            };

            //========== 1. SET UP THE GAME BOARD ==========
            // This section sets Human/Azure positions on an array called "gameState".  It also checks if the Human has won or the game is tied.
            // (We can assume Azure has not won before making its move.)

            // Prepare known elements of Azure's response
            ExecuteMoveResponse response = new ExecuteMoveResponse()
            {
                azurePlayerSymbol = messagePayload.azurePlayerSymbol,
                humanPlayerSymbol = messagePayload.humanPlayerSymbol,
                gameBoard         = messagePayload.gameBoard
            };


            // Creates two lists: for gameBoard human and azure player positions
            List <int> humanPositions = new List <int>();
            List <int> azurePositions = new List <int>();

            for (int i = 0; i < messagePayload.gameBoard.Length; i++)
            {
                if (messagePayload.gameBoard[i] == messagePayload.humanPlayerSymbol)
                {
                    humanPositions.Add(i);
                }
                else if (messagePayload.gameBoard[i] == messagePayload.azurePlayerSymbol)
                {
                    azurePositions.Add(i);
                }
            }

            // Compare gameState to humanPositions.
            // Replace any values in gameState with humanSymbol if they match (indicating that the human owns that space)
            string humanSymbol = messagePayload.humanPlayerSymbol.ToString();

            foreach (int i in humanPositions)
            {
                for (int row = 0; row < gameState.GetLength(0); row++)
                {
                    for (int column = 0; column < gameState.GetLength(1); column++)
                    {
                        if (i.ToString() == gameState[row, column])
                        {
                            gameState[row, column] = humanSymbol;
                        }
                    }

                    // Check to see if the human has met any of the victory conditions
                    if (gameState[row, 0] == humanSymbol && gameState[row, 1] == humanSymbol && gameState[row, 2] == humanSymbol)
                    {
                        response.winner = humanSymbol;

                        // Set winPositions
                        response.winPositions = new int[3];
                        for (int j = 0; j < 3; j++)
                        {
                            response.winPositions[j] = victoryConditions[row, j];
                        }

                        return(response);
                    }
                }
            }

            // Check for a tie game resulting from Player's move
            if (Array.IndexOf(messagePayload.gameBoard, '?') == -1)
            {
                response.winner = "tie";
                return(response);
            }


            // Compare gameState to azurePositions.
            // Replace any values in gameState with azureSymbol if they match (indicating that Azure owns that space)
            string azureSymbol = messagePayload.azurePlayerSymbol.ToString();

            foreach (int i in azurePositions)
            {
                for (int row = 0; row < gameState.GetLength(0); row++)
                {
                    for (int column = 0; column < gameState.GetLength(1); column++)
                    {
                        if (i.ToString() == gameState[row, column])
                        {
                            gameState[row, column] = azureSymbol;
                        }
                    }
                }
            }

            //========== 2. CALCULATE AZURE'S MOVE ==========
            // This section calculate's Azure's next move and checks if that move results in a win or tie.

            // Look for any possible winning moves or blocking moves
            for (int row = 0; row < gameState.GetLength(0); row++)
            {
                string[] gameStateRow = { gameState[row, 0], gameState[row, 1], gameState[row, 2] };

                // Winning moves
                int?winningMove = WinBlock(gameStateRow, azureSymbol, humanSymbol);

                if (winningMove != null)
                {
                    response.move = winningMove;
                    response.gameBoard[(int)winningMove] = messagePayload.azurePlayerSymbol;
                    response.winner       = azureSymbol;
                    response.winPositions = new int[3];
                    for (int j = 0; j < 3; j++)
                    {
                        response.winPositions[j] = victoryConditions[row, j];
                    }
                    return(response);
                }

                // Blocking moves
                int?blockingMove = WinBlock(gameStateRow, humanSymbol, azureSymbol);

                if (blockingMove != null)
                {
                    response.move = blockingMove;
                    response.gameBoard[(int)blockingMove] = messagePayload.azurePlayerSymbol;
                }
            }

            // If no winning or blocking moves have been found, select the first available move from a predetermined order of priority
            if (response.move == null)
            {
                int[]      movePriority      = { 4, 8, 6, 2, 0, 7, 5, 3, 1 };
                List <int> occupiedPositions = humanPositions.Concat(azurePositions).ToList();

                for (int i = 0; i < movePriority.Length; i++)
                {
                    if (occupiedPositions.IndexOf(movePriority[i]) == -1)
                    {
                        response.move = movePriority[i];
                        response.gameBoard[movePriority[i]] = messagePayload.azurePlayerSymbol;
                        break;
                    }
                }
            }



            // Check for a tie game resulting from Azure's move
            if (Array.IndexOf(messagePayload.gameBoard, '?') == -1)
            {
                response.winner = "tie";
                return(response);
            }

            response.winner = "inconclusive";
            return(response);
        }