/// <summary> /// Attempt to get a valid player move. /// If the player chooses a location that is taken, the CurrentRoundState remains unchanged, /// the player is given a message indicating so, and the game loop is cycled to allow the player /// to make a new choice. /// </summary> /// <param name="currentPlayerPiece">identify as either the X or O player</param> private void ManagePlayerTurn(Gameboard.PlayerPiece currentPlayerPiece) { GameboardPosition gameboardPosition = _gameView.GetPlayerPositionChoice(); if (_gameView.CurrentViewState != ConsoleView.ViewState.PlayerUsedMaxAttempts) { try { // // player chose an open position on the game board, add it to the game board // if (_gameboard.GameboardPositionAvailable(gameboardPosition)) { _gameboard.SetPlayerPiece(gameboardPosition, currentPlayerPiece); } // // player chose a taken position on the game board // else { _gameView.DisplayGamePositionChoiceNotAvailableScreen(); } } catch (Gameboard.GamePositionException pe) { _gameView.DisplayGamePositionChoiceNotAvailableScreen(); Console.WriteLine(pe.Message); } } }
/// <summary> /// Get a player's position choice within the correct range of the array /// Note: The ConsoleView is allowed access to the GameboardPosition struct. /// </summary> /// <returns>GameboardPosition</returns> public GameboardPosition GetPlayerPositionChoice() { // // Initialize gameboardPosition with -1 values // GameboardPosition gameboardPosition = new GameboardPosition(-1, -1, -1); // // Get row number from player. // gameboardPosition.Row = PlayerCoordinateChoice("Column"); // // Get column number. // if (CurrentViewState != ViewState.PlayerUsedMaxAttempts) { gameboardPosition.Column = PlayerCoordinateChoice("Row"); if (CurrentViewState != ViewState.PlayerUsedMaxAttempts) { gameboardPosition.Depth = PlayerCoordinateChoice("Depth"); } } return(gameboardPosition); }
/// <summary> /// Determine if the game board position is taken /// </summary> /// <param name="gameboardPosition"></param> /// <returns>true if position is open</returns> public bool GameboardPositionAvailable(GameboardPosition gameboardPosition) { // // Confirm that the board position is empty // Note: gameboardPosition converted to array index by subtracting 1 // Boolean isAvailable = false; switch (gameboardPosition.Layer) { case 1: if (_firstBoard[gameboardPosition.Row - 1, gameboardPosition.Column - 1] == PlayerPiece.None) { isAvailable = true; } break; case 2: if (_secondBoard[gameboardPosition.Row - 1, gameboardPosition.Column - 1] == PlayerPiece.None) { isAvailable = true; } break; case 3: if (_thirdBoard[gameboardPosition.Row - 1, gameboardPosition.Column - 1] == PlayerPiece.None) { isAvailable = true; } break; } return(isAvailable); }
/// <summary> /// Add player's move to the game board. /// </summary> /// <param name="gameboardPosition"></param> /// <param name="PlayerPiece"></param> public void SetPlayerPiece(GameboardPosition gameboardPosition, PlayerPiece PlayerPiece) { // // Row and column value adjusted to match array structure // Note: gameboardPosition converted to array index by subtracting 1 // switch (gameboardPosition.Layer) { case 1: _firstBoard[gameboardPosition.Row - 1, gameboardPosition.Column - 1] = PlayerPiece; break; case 2: _secondBoard[gameboardPosition.Row - 1, gameboardPosition.Column - 1] = PlayerPiece; break; case 3: _thirdBoard[gameboardPosition.Row - 1, gameboardPosition.Column - 1] = PlayerPiece; break; } // // Change game board state to next player // SetNextPlayer(); }
/// <summary> /// Count linear consecutive pieces /// </summary> private int ConsecutivePieces(PlayerPiece piece, GameboardPosition gameboardPosition, PositionMovement[] movements) { //Max number of pieces to check in any direction from last move const int piecesTocheck = 3; int counter = 1; //Check consecutive linear pieces in each direction for (int j = 0; j < movements.Length; j++) { if (movements[j] != PositionMovement.None) { for (int i = 0; i < piecesTocheck; i++) { if (CheckNextPiece(piece, gameboardPosition, movements[j], i + 1)) { counter = counter + 1; } else { break; } } } } return(counter); }
/// <summary> /// Move position up one row, one column to the left /// </summary> /// <param name="gameboardPosition"></param> /// <param name="number"></param> /// <returns></returns> private GameboardPosition MovePositionUpLeft(GameboardPosition gameboardPosition, int number) { gameboardPosition.Column = gameboardPosition.Column - number; gameboardPosition.Row = gameboardPosition.Row - number; return(gameboardPosition); }
/// <summary> /// Move position down one row, one column to the right /// </summary> /// <param name="gameboardPosition"></param> /// <param name="number"></param> /// <returns></returns> private GameboardPosition MovePositionDownRight(GameboardPosition gameboardPosition, int number) { gameboardPosition.Column = gameboardPosition.Column + number; gameboardPosition.Row = gameboardPosition.Row + number; return(gameboardPosition); }
/// <summary> /// Update the game board state if a player wins or a cat's game happens. /// </summary> public void UpdateGameboardState(int column, Sound applause) { //Get the row index of the most recent move in the column int row = LastMoveInColumn(column); //Create a gameboard position for the most recent move GameboardPosition gameboardPosition = new GameboardPosition(row, column); //Get the piece (X or O) of the most recent move PlayerPiece piece = GetPlayerPieceByGameBoardPosition(gameboardPosition); //Check for a win if (FourInARow(piece, gameboardPosition)) { applause.playSound(); if (piece == PlayerPiece.X) { _currentRoundState = GameboardState.PlayerXWin; } else { _currentRoundState = GameboardState.PlayerOWin; } } //Check if all positions are filled else if (IsCatsGame()) { _currentRoundState = GameboardState.CatsGame; } }
/// <summary> /// Add player's move to the game board. /// </summary> /// <param name="gameboardPosition"></param> /// <param name="PlayerPiece"></param> public void SetPlayerPiece(GameboardPosition gameboardPosition, PlayerPiece PlayerPiece) { // // Row and column value adjusted to match array structure // Note: gameboardPosition converted to array index by subtracting 1 // _positionState[gameboardPosition.Row - 1, gameboardPosition.Column - 1] = PlayerPiece; // // Change game board state to next player // SetNextPlayer(); }
/// <summary> /// Determine if the game board position is taken /// </summary> /// <param name="gameboardPosition"></param> /// <returns>true if position is open</returns> public bool GameboardPositionAvailable(GameboardPosition gameboardPosition) { // // Confirm that the board position is empty // Note: gameboardPosition converted to array index by subtracting 1 // if (_positionState[gameboardPosition.XAxis - 1, gameboardPosition.YAxis - 1, gameboardPosition.ZAxis - 1] == PlayerPiece.None) { return(true); } else { return(false); } }
/// <summary> /// Check for any four in a row. /// </summary> /// <param name="playerPieceToCheck">Player's game piece to check</param> /// <returns>true if a player has won</returns> private bool FourInARow(PlayerPiece playerPieceToCheck, GameboardPosition gameboardPosition) { //Define linear checks for a win PositionMovement[] down = new PositionMovement[] { PositionMovement.Down }; PositionMovement[] leftRight = new PositionMovement[] { PositionMovement.Left, PositionMovement.Right }; PositionMovement[] UrightDleft = new PositionMovement[] { PositionMovement.UpRight, PositionMovement.DownLeft }; PositionMovement[] UleftDright = new PositionMovement[] { PositionMovement.UpLeft, PositionMovement.DownRight }; int counter = 0; //Check down counter = ConsecutivePieces(playerPieceToCheck, gameboardPosition, down); if (CheckForFourPieces(counter)) { return(true); } //Check left and right counter = ConsecutivePieces(playerPieceToCheck, gameboardPosition, leftRight); if (CheckForFourPieces(counter)) { return(true); } //Check up right and down left counter = ConsecutivePieces(playerPieceToCheck, gameboardPosition, UrightDleft); if (CheckForFourPieces(counter)) { return(true); } //Check up left and down right counter = ConsecutivePieces(playerPieceToCheck, gameboardPosition, UleftDright); if (CheckForFourPieces(counter)) { return(true); } return(false); }
/// <summary> /// Attempt to get a valid player move. /// If the player chooses a location that is taken, the CurrentRoundState remains unchanged, /// the player is given a message indicating so, and the game loop is cycled to allow the player /// to make a new choice. /// </summary> /// <param name="currentPlayerPiece">identify as either the X or O player</param> private void ManagePlayerTurn(Gameboard.PlayerPiece currentPlayerPiece) { GameboardPosition gameboardPosition = _gameView.GetPlayerPositionChoice(); if (_gameView.CurrentViewState == ConsoleView.ViewState.ViewCurrentStats) { _gameView.DisplayCurrentGameStatus(_roundNumber, _playerXNumberOfWins, _playerONumberOfWins, _numberOfCatsGames); _gameView.CurrentViewState = ConsoleView.ViewState.Active; _gameView.DisplayGameArea(); gameboardPosition = _gameView.GetPlayerPositionChoice(); } if (_gameView.CurrentViewState != ConsoleView.ViewState.ResetCurrentRound) { // //Proceed with turn as normal. // if (_gameView.CurrentViewState != ConsoleView.ViewState.PlayerUsedMaxAttempts) { // // player chose an open position on the game board, add it to the game board // if (_gameboard.GameboardPositionAvailable(gameboardPosition)) { _gameboard.SetPlayerPiece(gameboardPosition, currentPlayerPiece); } // // player chose a taken position on the game board // else { _gameView.DisplayGamePositionChoiceNotAvailableScreen(); } } } }
/// <summary> /// Get a player's position choice within the correct range of the array /// Note: The ConsoleView is allowed access to the GameboardPosition struct. /// </summary> /// <returns>GameboardPosition</returns> public GameboardPosition GetPlayerPositionChoice() { //Variable Declaratoins. GameboardPosition gameboardPosition = new GameboardPosition(-1, -1, -1); string userInput = ""; SidebarMenuOptions menuOptionChoice = SidebarMenuOptions.None; //Validate the coordinates entered by the user. int[] userCoords = { 0, 0, 0 }; do { userInput = GetCoordinates(); if (SBMenuOptions.ContainsKey(userInput.ToUpper()) == true) { //If a menu option was entered... //Display the appropriate screen based on the menu option entered by the user. menuOptionChoice = SBMenuOptions[userInput.ToUpper()]; switch (menuOptionChoice) { case SidebarMenuOptions.ViewTheRules: //Display the game instructions. Console.Clear(); DisplayGameInstructions(); Console.WriteLine(""); Console.WriteLine(""); //Hold the execution of the application until the user presses a key. DisplayContinuePrompt(); //Redraw the game board. DisplayGameArea(); break; case SidebarMenuOptions.ResetCurrentRound: _gameboard.CurrentRoundState = Gameboard.GameboardState.NewRound; _currentViewStat = ViewState.ResetCurrentRound; return(gameboardPosition); case SidebarMenuOptions.ViewGameStats: _currentViewStat = ViewState.ViewCurrentStats; return(gameboardPosition); //break; case SidebarMenuOptions.ExitApplication: //Ask the user if they want to leave the application. Console.Clear(); if (DisplayGetYesNoPrompt("Do you wish to exit the application?") == true) { //If the user enters yes... //Display the closing screen. DisplayClosingScreen(); //Exit. Environment.Exit(0); } else { //If the user enters yes... //Redraw the game board. DisplayGameArea(); } break; default: break; } userCoords[0] = 0; userCoords[1] = 0; userCoords[2] = 0; continue; } else { //If a menu option was not entered... //Split up and validate the coordinates entered by the user. userCoords = SplitCoords(userInput); if ((userCoords[0] == 0 && userCoords[1] == 0 && userCoords[2] == 0) == true) { Console.ReadKey(); } } } while (userCoords[0] == 0 && userCoords[1] == 0 && userCoords[2] == 0); //Save the user's position choice. gameboardPosition.XAxis = userCoords[0]; gameboardPosition.YAxis = userCoords[1]; gameboardPosition.ZAxis = userCoords[2]; //Return the user's positon choice. return(gameboardPosition); }
/// <summary> /// Move position down one row /// </summary> /// <param name="gameboardPosition"></param> /// <param name="number"></param> /// <returns></returns> private GameboardPosition MovePositionDown(GameboardPosition gameboardPosition, int number) { gameboardPosition.Row = gameboardPosition.Row + number; return(gameboardPosition); }
/// <summary> /// Check if the next piece in line is a valid consecutive piece /// </summary> /// <param name="piece"></param> /// <param name="gameboardPosition"></param> /// <param name="movement"></param> /// <param name="numberOfMoves"></param> /// <returns></returns> private bool CheckNextPiece(PlayerPiece piece, GameboardPosition gameboardPosition, PositionMovement movement, int numberOfMoves) { //Define constraints const int top = -1; const int bottom = 6; const int right = 7; const int left = -1; //The next position that we are checking GameboardPosition newPosition = new GameboardPosition(-1, -1); //Based on the given Movement, set newPosition to the next position in line switch (movement) { case PositionMovement.UpRight: newPosition = MovePositionUpRight(gameboardPosition, numberOfMoves); break; case PositionMovement.Right: newPosition = MovePositionRight(gameboardPosition, numberOfMoves); break; case PositionMovement.DownRight: newPosition = MovePositionDownRight(gameboardPosition, numberOfMoves); break; case PositionMovement.Down: newPosition = MovePositionDown(gameboardPosition, numberOfMoves); break; case PositionMovement.DownLeft: newPosition = MovePositionDownLeft(gameboardPosition, numberOfMoves); break; case PositionMovement.Left: newPosition = MovePositionLeft(gameboardPosition, numberOfMoves); break; case PositionMovement.UpLeft: newPosition = MovePositionUpLeft(gameboardPosition, numberOfMoves); break; default: break; } //Check if new position is within the borders if (newPosition.Row < bottom && newPosition.Row > top && newPosition.Column < right && newPosition.Column > left) { //Check if the new position is the right piece if (GetPlayerPieceByGameBoardPosition(newPosition) == piece) { return(true); } else { return(false); } } else { return(false); } }
/// <summary> /// Return the PlayerPiece at the gameboardPosition /// </summary> /// <param name="gameboardPosition"></param> /// <returns></returns> public PlayerPiece GetPlayerPieceByGameBoardPosition(GameboardPosition gameboardPosition) { return(_positionState[gameboardPosition.Row, gameboardPosition.Column]); }