Exemple #1
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // METHOD SEPARATOR METHOD SEPARATOR METHOD SEPARATOR METHOD SEPARATOR METHOD SEPARATOR METHOD SEPARATOR METHOD SEPARATOR
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Method calculates the move the AI Player should choose.
        /// </summary>
        /// <param name="b">Game Board object</param>
        ///
        /// <returns>the move the AI chose to make</returns>
        public override int ChooseMove(Board b)
        {
            // If AI Player is Position TOP
            if (b.WhoseMove() == Position.Top)
            {
                // Try first go-again.
                for (int i = 12; i >= 7; i--)
                {
                    if (b.StonesAt(i) == 13 - i)
                    {
                        return(i);
                    }
                }
                // Otherwise, choose first available move.
                for (int i = 12; i >= 7; i--)
                {
                    if (b.StonesAt(i) > 0)
                    {
                        return(i);
                    }
                }
            }
            // If AI Player is Position  BOTTOM
            else
            {
                // Try first go-again.
                for (int i = 5; i >= 0; i--)
                {
                    if (b.StonesAt(i) == 6 - i)
                    {
                        return(i);
                    }
                }
                // Otherwise, choose first available move.
                for (int i = 5; i >= 0; i--)
                {
                    if (b.StonesAt(i) > 0)
                    {
                        return(i);
                    }
                }
            }
            // Return illegal move, if no legal moves are possible. (only if game is over)
            return(-1);
        }
Exemple #2
0
 public override int chooseMove(Board b)
 {
     if (b.WhoseMove() == Position.Top)
     {
         for (int i = 12; i >= 7; i--)                       // try first go-again
         {
             if (b.StonesAt(i) == 13 - i)
             {
                 return(i);
             }
         }
         for (int i = 12; i >= 7; i--)                   // otherwise, first
         {
             if (b.StonesAt(i) > 0)
             {
                 return(i);                              // available move
             }
         }
     }
     else
     {
         for (int i = 5; i >= 0; i--)
         {
             if (b.StonesAt(i) == 6 - i)
             {
                 return(i);
             }
         }
         for (int i = 5; i >= 0; i--)
         {
             if (b.StonesAt(i) > 0)
             {
                 return(i);
             }
         }
     }
     return(-1);                 // an illegal move if there aren't any legal ones
 }                               // this can't happen unless game is over
Exemple #3
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // METHOD SEPARATOR METHOD SEPARATOR METHOD SEPARATOR METHOD SEPARATOR METHOD SEPARATOR METHOD SEPARATOR METHOD SEPARATOR
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Play a Mankalah game with the two given players, with the firstPlayer starting.
        /// Returns TOP's score.
        /// </summary>
        /// <param name="playerTop">the player on the top</param>
        /// <param name="playerBottom">the player on the bottom</param>
        /// <param name="firstPlayer">the player who is starting the game</param>
        /// <returns>the score of the TOP player</returns>
        public static int PlayGame(Player playerTop, Player playerBottom, Position firstPlayer)
        {
            // Create a new game board.
            _board = new Board(firstPlayer);

            // Determine the player who starts.
            if (firstPlayer == Position.Top)
            {
                Console.WriteLine("Player " + playerTop.GetName() + " starts.");
            }
            else
            {
                Console.WriteLine("Player " + playerBottom.GetName() + " starts.");
            }

            // Display the current state of the game board.
            _board.Display();

            // Continue rotating turns till the game is over.
            while (!_board.GameOver())
            {
                Console.WriteLine();

                // Get the player's move and output what move the player made.
                if (_board.WhoseMove() == Position.Top)
                {
                    _move = playerTop.ChooseMove(_board);
                    Console.WriteLine(playerTop.GetName() + " chooses move " + _move);
                }

                else
                {
                    _move = playerBottom.ChooseMove(_board);
                    Console.WriteLine(playerBottom.GetName() + " chooses move " + _move);
                }

                // Commit the move to the game state. (true = verbose, false = non-verbose)
                _board.MakeMove(_move, true);

                // Display the new state of the game board.
                _board.Display();

                // Game is over, determine final results.
                if (_board.GameOver())
                {
                    if (_board.Winner() == Position.Top)
                    {
                        Console.WriteLine("Player " + playerTop.GetName() +
                                          " (TOP) wins " + _board.ScoreTopPlayer() + " to " + _board.ScoreBottomPlayer());
                    }
                    else if (_board.Winner() == Position.Bottom)
                    {
                        Console.WriteLine("Player " + playerBottom.GetName() +
                                          " (BOTTOM) wins " + _board.ScoreBottomPlayer() + " to " + _board.ScoreTopPlayer());
                    }
                    else
                    {
                        Console.WriteLine("A tie!");
                    }
                }
                // Game is not over, ask player to make their move.
                else
                if (_board.WhoseMove() == Position.Top)
                {
                    Console.WriteLine(playerTop.GetName() + " to move.");
                }
                else
                {
                    Console.WriteLine(playerBottom.GetName() + " to move.");
                }
            }

            // Return the final score for the match.
            return(_board.ScoreTopPlayer());
        }
Exemple #4
0
        // this is a method that evaluates the current board using hueristics to find the best possible move
        public override int evaluate(Board board)
        {
            // declaring the evaulate hueristics
            int captures    = 0;
            int extraMoves  = 0;
            int finalState  = 0;
            int score       = 0;
            int upperStones = 0;
            int lowerStones = 0;

            if (board.WhoseMove() == Position.Top)
            {
                // score is increased or decreased by the current score (it's added both times because the score can be negative)
                if (position == Position.Top)
                {
                    score += board.StonesAt(13) - board.StonesAt(6);
                }
                else
                {
                    score += board.StonesAt(6) - board.StonesAt(13);
                }

                // extraMoves is increased or decreased by two because the player is being rewarded for both increasing their own score and getting to go again
                for (int i = 12; i >= 7; i--)
                {
                    if (board.StonesAt(i) == 13 - i)
                    {
                        if (position == Position.Top)
                        {
                            extraMoves += 2;
                        }
                        else
                        {
                            extraMoves -= 2;
                        }
                    }
                }

                // capture is increased or decreased by the number of stones that are captured if the move is executed
                for (int i = 12; i >= 7; i--)                                         // check for captures
                {
                    if (board.StonesAt((board.StonesAt(i) + i) % 14) == 0 &&          // check for an empty bowl
                        ((board.StonesAt(i) + i) % 14) <= 12 &&
                        ((board.StonesAt(i) + i) % 14) >= 7 &&                        // check that it is not landing on the other side
                        board.StonesAt(6 - (((board.StonesAt(i) + i) % 14) - 6)) > 0) // check that we aren't capturing zero
                    {
                        if (position == Position.Top)
                        {
                            captures += board.StonesAt(6 - (((board.StonesAt(i) + i) % 14) - 6));
                        }
                        else
                        {
                            captures -= board.StonesAt(6 - (((board.StonesAt(i) + i) % 14) - 6));
                        }
                    }
                }

                // finalState looks for moves that cause one side of the board to be empty and increases or decreases the score according to how many stones each player would capture
                for (int i = 12; i >= 7; i--)
                {
                    upperStones += board.StonesAt(i);
                }
                for (int i = 5; i >= 0; i--)
                {
                    lowerStones += board.StonesAt(i);
                }
                if (lowerStones == 0 && upperStones > 0)
                {
                    finalState += upperStones;
                }
                if (upperStones == 0 && lowerStones > 0)
                {
                    finalState -= lowerStones;
                }
            }
            else    // These are all the same methods with slight variation that takes into account if the Player is on the bottom
            {
                // score hueristic
                if (position == Position.Bottom)
                {
                    score += board.StonesAt(6) - board.StonesAt(13);
                }
                else
                {
                    score += board.StonesAt(13) - board.StonesAt(6);
                }

                // extraMoves hueristic
                for (int i = 5; i >= 0; i--)
                {
                    if (board.StonesAt(i) == 6 - i)
                    {
                        if (position == Position.Bottom)
                        {
                            extraMoves += 2;
                        }
                        else
                        {
                            extraMoves -= 2;
                        }
                    }
                }

                // captures hueristic
                for (int i = 5; i >= 0; i--)
                {
                    if (board.StonesAt((board.StonesAt(i) + i) % 14) == 0 &&
                        ((board.StonesAt(i) + i) % 14) >= 0 &&
                        ((board.StonesAt(i) + i) % 14) <= 5 &&
                        board.StonesAt(6 + (((board.StonesAt(i) + i) % 14) - 6)) > 0)
                    {
                        if (position == Position.Bottom)
                        {
                            captures += board.StonesAt(6 + (((board.StonesAt(i) + i) % 14) - 6));
                        }
                        else
                        {
                            captures -= board.StonesAt(6 + (((board.StonesAt(i) + i) % 14) - 6));
                        }
                    }
                }

                // finalState hueristic
                for (int i = 12; i >= 7; i--)
                {
                    upperStones += board.StonesAt(i);
                }
                for (int i = 5; i >= 0; i--)
                {
                    lowerStones += board.StonesAt(i);
                }
                if (lowerStones == 0 && upperStones > 0)
                {
                    finalState -= upperStones;
                }
                if (upperStones == 0 && lowerStones > 0)
                {
                    finalState += lowerStones;
                }
            }
            upperStones = lowerStones = 0;                      // reset the upper and lower stone values
            return(score + captures + extraMoves + finalState); // output the board quality
        }
Exemple #5
0
        public Tuple <int, double> MiniMax(Board board, int depth, double alpha, double beta)
        {
            double bestResult = 0;
            double result     = 0;
            int    bestMove   = 0;

            if (board.GameOver() || depth == 0)
            {
                return(new Tuple <int, double>(0, evaluate(board)));
            }

            int start = 0;

            if (board.WhoseMove() == Position.Top)
            {
                start = 7;
            }
            else
            {
                start = 0;
            }

            if (board.WhoseMove() == position)
            {
                bestResult = double.NegativeInfinity;
                for (int move = start; move <= start + 5; move++)
                {
                    if (board.LegalMove(move) && timer.ElapsedMilliseconds < getTimePerMove())
                    {
                        Board tempBoard = new Board(board);             //duplicate board
                        tempBoard.MakeMove(move, false);                //make the move
                        result = MiniMax(tempBoard, depth - 1, alpha, beta).Item2;
                        if (result > bestResult)                        //find its value
                        {
                            bestResult = result;                        //remember if best
                            bestMove   = move;
                        }
                        if (bestResult > alpha)
                        {
                            alpha = bestResult;
                        }
                        if (beta <= alpha)
                        {
                            break;
                        }
                    }
                }
            }
            else
            {
                bestResult = double.PositiveInfinity;
                for (int move = start; move <= start + 5; move++)
                {
                    if (board.LegalMove(move) && timer.ElapsedMilliseconds < getTimePerMove())
                    {
                        Board tempBoard = new Board(board);             //duplicate board
                        tempBoard.MakeMove(move, false);                //make the move
                        result = MiniMax(tempBoard, depth - 1, alpha, beta).Item2;
                        if (result < bestResult)                        //find its value
                        {
                            bestResult = result;                        //remember if best
                            bestMove   = move;
                        }
                        if (beta < bestResult)
                        {
                            beta = bestResult;
                        }
                        if (beta <= alpha)
                        {
                            break;
                        }
                    }
                }
            }
            return(new Tuple <int, double>(bestMove, bestResult));
        }
Exemple #6
0
        /*
         * Play one Kalah game with the two given players, with firstPlayer
         * starting. This function returns TOP's score.
         */
        public static int playGame(Player pTop, Player pBot, Position firstPlayer)
        {
            b = new Board(firstPlayer);

            if (firstPlayer == Position.Top)
            {
                Console.WriteLine("Player " + pTop.getName() + " starts.");
            }
            else
            {
                Console.WriteLine("Player " + pBot.getName() + " starts.");
            }

            b.Display();

            while (!b.GameOver())
            {
                Console.WriteLine();
                if (b.WhoseMove() == Position.Top)
                {
                    move = pTop.chooseMove(b);
                    Console.WriteLine(pTop.getName() + " chooses move " + move);
                }
                else
                {
                    move = pBot.chooseMove(b);
                    Console.WriteLine(pBot.getName() + " chooses move " + move);
                }

                b.MakeMove(move, true);         // last parameter says to be chatty
                b.Display();

                if (b.GameOver())
                {
                    if (b.Winner() == Position.Top)
                    {
                        Console.WriteLine("Player " + pTop.getName() +
                                          " (TOP) wins " + b.ScoreTop() + " to " + b.ScoreBot());
                    }
                    else if (b.Winner() == Position.Bottom)
                    {
                        Console.WriteLine("Player " + pBot.getName() +
                                          " (BOTTOM) wins " + b.ScoreBot() + " to " + b.ScoreTop());
                    }
                    else
                    {
                        Console.WriteLine("A tie!");
                    }
                }
                else
                if (b.WhoseMove() == Position.Top)
                {
                    Console.WriteLine(pTop.getName() + " to move.");
                }
                else
                {
                    Console.WriteLine(pBot.getName() + " to move.");
                }
            }
            return(b.ScoreTop());
        }