Example #1
0
        /// <summary>
        /// Allows two AI players to play against each other. Records the state of the game after each turn to
        /// allow the game to be replayed
        /// </summary>
        /// <param name="board"></param>
        private static void AiVsAi(Board board)
        {
            Square currentPlayer = Square.Red;

            // list for storing all subsequent states of the game
            List <State> states = new List <State>();

            // add initial state of the game to the list
            State firstState = new State(board.GetState(), currentPlayer);

            states.Add(firstState);

            // initialize pointer variable and point it to the initial state of the game
            int pointer = 0;

            Ai bot = new Ai();

            // continue the game as long as current player has any pieces left
            while (board.GetPlayersPieces(currentPlayer).Any())
            {
                Console.WriteLine("\n\nTurn #{0} Player: {1}", pointer + 1, currentPlayer);
                board.PrintBoard();

                // get the list of pieces belonging to current player
                var playersPieces = board.GetPlayersPieces(currentPlayer);
                // get the list of legal non-jump moves that player can make
                var legalMoves = board.GetLegalMoves(playersPieces);
                // get the list of legal jumps that player can (have to) make
                var legalJumps = board.GetLegalJumps(playersPieces);

                // if current player has no jumps and no regular moves to make, he's lost
                if (legalJumps.Count + legalMoves.Count == 0)
                {
                    break;
                }

                State state = new State(board.GetState(), currentPlayer);

                // get the move from the AI player based on the current state of the board
                Move bestMove = bot.GetBestMove(board, state);

                // AI is jumping
                if (bestMove.IsJump)
                {
                    while (legalJumps.Any())
                    {
                        Piece jumpingPiece =
                            playersPieces.Find(piece => piece.X == bestMove.FromRow && piece.Y == bestMove.FromCol);
                        bool kingBeforeJump = jumpingPiece.IsKing;

                        board.DoJump(bestMove, jumpingPiece);
                        Console.WriteLine("AI's move: from {0} to {1}", bestMove.CoordinateFrom, bestMove.CoordinateTo);

                        // update variables of the piece that has just jumped
                        jumpingPiece.HasJustJumped = true;
                        jumpingPiece.X             = bestMove.ToRow;
                        jumpingPiece.Y             = bestMove.ToCol;

                        // all pieces other than the one that has just jumped are irrelevant when checking if more jumps can be made
                        playersPieces.RemoveAll(piece => piece.HasJustJumped == false);

                        legalJumps = board.GetLegalJumps(playersPieces);

                        // update position of the jumping piece on the board
                        board.UpdatePosition(jumpingPiece, bestMove.FromRow, bestMove.FromCol);

                        // no further jumps can be made if piece became a king after the first jump
                        if (!kingBeforeJump && bestMove.ToRow == 0 | bestMove.ToRow == 7)
                        {
                            break;
                        }

                        // make a subsequent jump if there is one
                        if (legalJumps.Any())
                        {
                            bestMove = legalJumps.First();
                        }
                    }
                }
                else
                {
                    board.MovePiece(bestMove);
                    Console.WriteLine("AI's move: from {0} to {1}", bestMove.CoordinateFrom, bestMove.CoordinateTo);
                }

                currentPlayer = ChangeTurn(currentPlayer);

                // create new state of the game after move was made
                State newState = new State(board.GetState(), currentPlayer);

                // move was made after performing undo operation since pointer is not pointing to the last state
                if (pointer < states.Count - 1)
                {
                    // newState now becomes the last state, remove all states that happened after it
                    states.RemoveAll(other => states.IndexOf(other) > pointer);
                }

                states.Add(newState);

                // set pointer to the new state
                pointer = states.IndexOf(newState);
            }

            Console.WriteLine("\n\n{0} player won!", ChangeTurn(currentPlayer));

            // print the final state of the board once the game has ended
            board.PrintBoard();

            // add states all subsequent states of the game to the list of previous games
            previousGames.Add(states);

            Console.WriteLine("Replay the game? Plase answer Y/N");
            string answer = Console.ReadLine();

            while (!answer.Equals("y") && !answer.Equals("n"))
            {
                Console.WriteLine("Please type 'Y' to replay the game or 'N' to skip");
                answer = Console.ReadLine();
            }

            if (answer.Equals("y"))
            {
                ReplayGame(states);
            }
        }
Example #2
0
        /// <summary>
        /// Allows human player to play against AI player. Records the state of the game after each turn to provide
        /// undo/redo/replay functionalities
        /// </summary>
        /// <param name="board"></param>
        private static void HumanVsAi(Board board)
        {
            Square currentPlayer = Square.Red;

            // list for storing all subsequent states of the game
            List <State> states = new List <State>();

            // add initial state of the game to the list
            State firstState = new State(board.GetState(), currentPlayer);

            states.Add(firstState);

            // initialize pointer variable and point it to the initial state of the game
            int pointer = 0;

            Ai bot = new Ai();

            // continue the game as long as current player has any pieces left
            while (board.GetPlayersPieces(currentPlayer).Any())
            {
                Console.WriteLine("\n\nTurn #{0} Player: {1}", pointer + 1, currentPlayer);
                board.PrintBoard();

                // get the list of pieces belonging to current player
                var playersPieces = board.GetPlayersPieces(currentPlayer);
                // get the list of legal non-jump moves that player can make
                var legalMoves = board.GetLegalMoves(playersPieces);
                // get the list of legal jumps that player can (have to) make
                var legalJumps = board.GetLegalJumps(playersPieces);

                // if current player has no jumps and no regular moves to make, he's lost
                if (legalJumps.Count + legalMoves.Count == 0)
                {
                    break;
                }

                // human player's turn
                if (currentPlayer == Square.Red)
                {
                    Console.WriteLine("What would you like to do? Type 'Undo', 'Redo', or press enter to carry on");
                    var choice = Console.ReadLine();

                    if (choice.Equals("undo", StringComparison.CurrentCultureIgnoreCase))
                    {
                        // check whether there were any states before current state
                        if (pointer > 0)
                        {
                            pointer -= 2;

                            // get a deep copy of the previous state of the game
                            State previousState = states[pointer].DeepCopy();

                            //Console.WriteLine("RESTORED STATE: " + pointer);

                            // set previous state of the game to be the current state and reverse player's turn
                            board.SetState(previousState.BoardState);
                            currentPlayer = previousState.CurrentPlayer;
                        }
                        else
                        {
                            Console.WriteLine("You can't go back any further");
                        }
                    }
                    else if (choice.Equals("redo", StringComparison.CurrentCultureIgnoreCase))
                    {
                        // check whether there were any states after current state
                        if (pointer < states.Count - 1)
                        {
                            pointer += 2;

                            // get a deep copy of the next state of the game
                            State redoState = states[pointer].DeepCopy();

                            //Console.WriteLine("RESTORED STATE: " + pointer);

                            // set next state of the game to be the current state and reverse player's turn
                            board.SetState(redoState.BoardState);
                            currentPlayer = redoState.CurrentPlayer;
                        }
                        else
                        {
                            Console.WriteLine("There are no moves to redo");
                        }
                    }
                    else
                    {
                        var move = RequestMove();

                        // no jumps can be made so a regular move has to be made
                        if (!legalJumps.Any())
                        {
                            while (!legalMoves.Contains(move))
                            {
                                Console.WriteLine("--------------------Please provide a legal move--------------------");
                                move = RequestMove();
                            }

                            // move can be made as it's in the list of legal moves, perform it
                            board.MovePiece(move);
                        }

                        // force the player to make a jump
                        while (legalJumps.Any())
                        {
                            // see if player's move matches any of the possible jumps
                            if (legalJumps.Contains(move))
                            {
                                // get reference to the piece that will be jumping
                                Piece jumpingPiece = playersPieces.Find(piece =>
                                                                        piece.X == move.FromRow && piece.Y == move.FromCol);
                                bool kingBeforeJump = jumpingPiece.IsKing;

                                board.DoJump(move, jumpingPiece);

                                // update variables of the piece that has just jumped
                                jumpingPiece.HasJustJumped = true;
                                jumpingPiece.X             = move.ToRow;
                                jumpingPiece.Y             = move.ToCol;

                                // all pieces other than the one that has just jumped are irrelevant when checking if more jumps can be made
                                playersPieces.RemoveAll(piece => piece.HasJustJumped == false);

                                legalJumps = board.GetLegalJumps(playersPieces);

                                // update position of the jumping piece on the board
                                board.UpdatePosition(jumpingPiece, move.FromRow, move.FromCol);

                                // show the state of the board after first jump if another one can be made
                                if (legalJumps.Any())
                                {
                                    board.PrintBoard();
                                }

                                // no further jumps can be made if piece became a king after the first jump
                                if (!kingBeforeJump && move.ToRow == 0 | move.ToRow == 7)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                Console.WriteLine("--------------------You have to jump--------------------");
                                move = RequestMove();
                            }
                        }

                        // change turn
                        currentPlayer = ChangeTurn(currentPlayer);

                        // create new state of the game after move was made
                        State newState = new State(board.GetState(), currentPlayer);

                        // move was made after performing undo operation since pointer is not pointing to the last state
                        if (pointer < states.Count - 1)
                        {
                            // newState now becomes the last state, remove all states that happened after it
                            states.RemoveAll(other => states.IndexOf(other) > pointer);
                        }

                        states.Add(newState);

                        // set pointer to the new state
                        pointer = states.IndexOf(newState);
                    }
                }
                // AI player's turn
                else if (currentPlayer == Square.White)
                {
                    State state = new State(board.GetState(), currentPlayer);

                    // get the move from the AI player based on the current state of the board
                    Move bestMove = bot.GetBestMove(board, state);

                    // AI is jumping
                    if (bestMove.IsJump)
                    {
                        while (legalJumps.Any())
                        {
                            Piece jumpingPiece =
                                playersPieces.Find(piece => piece.X == bestMove.FromRow && piece.Y == bestMove.FromCol);
                            bool kingBeforeJump = jumpingPiece.IsKing;

                            board.DoJump(bestMove, jumpingPiece);
                            Console.WriteLine("AI's move from {0} to {1}", bestMove.CoordinateFrom, bestMove.CoordinateTo);

                            // update variables of the piece that has just jumped
                            jumpingPiece.HasJustJumped = true;
                            jumpingPiece.X             = bestMove.ToRow;
                            jumpingPiece.Y             = bestMove.ToCol;

                            // all pieces other than the one that has just jumped are irrelevant when checking if more jumps can be made
                            playersPieces.RemoveAll(piece => piece.HasJustJumped == false);

                            legalJumps = board.GetLegalJumps(playersPieces);

                            // update position of the jumping piece on the board
                            board.UpdatePosition(jumpingPiece, bestMove.FromRow, bestMove.FromCol);

                            // no further jumps can be made if piece became a king after the first jump
                            if (!kingBeforeJump && bestMove.ToRow == 0 | bestMove.ToRow == 7)
                            {
                                break;
                            }

                            // make a subsequent jump if there is one
                            if (legalJumps.Any())
                            {
                                bestMove = legalJumps.First();
                            }
                        }
                    }
                    else
                    {
                        board.MovePiece(bestMove);
                        Console.WriteLine("AI's move from {0} to {1}", bestMove.CoordinateFrom, bestMove.CoordinateTo);
                    }

                    currentPlayer = ChangeTurn(currentPlayer);

                    // create new state of the game after move was made
                    State newState = new State(board.GetState(), currentPlayer);

                    // move was made after performing undo operation since pointer is not pointing to the last state
                    if (pointer < states.Count - 1)
                    {
                        // newState now becomes the last state, remove all states that happened after it
                        states.RemoveAll(other => states.IndexOf(other) > pointer);
                    }

                    states.Add(newState);

                    // set pointer to the new state
                    pointer = states.IndexOf(newState);
                }
            }

            Console.WriteLine("\n\n{0} player won!", ChangeTurn(currentPlayer));

            // print the final state of the board once the game has ended
            board.PrintBoard();

            // add states all subsequent states of the game to the list of previous games
            previousGames.Add(states);

            Console.WriteLine("Replay the game? Plase answer Y/N");
            string answer = Console.ReadLine();

            while (!answer.Equals("y") && !answer.Equals("n"))
            {
                Console.WriteLine("Please type 'Y' to replay the game or 'N' to skip");
                answer = Console.ReadLine();
            }

            if (answer.Equals("y"))
            {
                ReplayGame(states);
            }
        }