Ejemplo n.º 1
0
        // Recursive part of iterative deepening
        private Tuple<Move, bool> RecursiveIterativeDeepening(State state, int depth, double alpha, double beta, int timeLimit, Stopwatch timer, Deck deck)
        {
            Move bestMove;
            if (depth == 0 || state.IsGameOver())
            {
                if (state.Player == GameEngine.PLAYER)
                {
                    bestMove = new PlayerMove(); // default constructor creates dummy action
                    bestMove.Score = AI.Evaluate(state);
                    return new Tuple<Move, Boolean>(bestMove, true);
                }
                else if (state.Player == GameEngine.COMPUTER)
                {
                    bestMove = new ComputerMove(); // default constructor creates dummy action
                    bestMove.Score = AI.Evaluate(state);
                    return new Tuple<Move, Boolean>(bestMove, true);
                }
                else
                {
                    throw new Exception();
                }
            }
            if (state.Player == GameEngine.PLAYER){

                bestMove = new PlayerMove();
                double highestScore = Double.MinValue, currentScore = Double.MinValue;

                List<Move> moves = state.GetAllMoves();

                foreach (Move move in moves)
                {
                    State resultingState = state.ApplyMove(move);
                    currentScore = RecursiveIterativeDeepening(resultingState, depth - 1, alpha, beta, timeLimit, timer, deck).Item1.Score;
                    if (currentScore > highestScore)
                    {
                        highestScore = currentScore;
                        bestMove = (PlayerMove)move;
                    }
                    alpha = Math.Max(alpha, highestScore);
                    if (beta <= alpha)
                        break;
                    if (timer.ElapsedMilliseconds > timeLimit)
                    {
                        bestMove.Score = highestScore;
                        return new Tuple<Move, Boolean>(bestMove, false); // recursion not completed, return false
                    }
                }

                bestMove.Score = highestScore;
                return new Tuple<Move, Boolean>(bestMove, true);
            }
            else
            {
                bestMove = new ComputerMove();
                double lowestScore = Double.MaxValue, currentScore = Double.MaxValue;

                List<Move> moves = null;
                if (depth == definedDepth - 1)
                {
                    int nextCard = game.nextCard;
                    moves = state.GetAllComputerMoves(nextCard);
                }
                else
                {
                    if (deck.IsEmpty()) deck = new Deck();
                    moves = state.GetAllComputerMoves(deck);
                }

                foreach (Move move in moves)
                {
                    deck.Remove(((ComputerMove)move).Card);
                    State resultingState = state.ApplyMove(move);
                    currentScore = RecursiveIterativeDeepening(resultingState, depth - 1, alpha, beta, timeLimit, timer, deck).Item1.Score;
                    if (currentScore < lowestScore)
                    {
                        lowestScore = currentScore;
                        bestMove = (ComputerMove)move;
                    }
                    beta = Math.Min(beta, lowestScore);
                    if (beta <= alpha)
                        break;
                    deck.Add(((ComputerMove)move).Card);
                    if (timer.ElapsedMilliseconds > timeLimit)
                    {
                        bestMove.Score = lowestScore;
                        return new Tuple<Move, Boolean>(bestMove, false); // recursion not completed, return false
                    }
                }
                bestMove.Score = lowestScore;
                return new Tuple<Move, Boolean>(bestMove, true);
            }
        }
Ejemplo n.º 2
0
        // Evaluation function used by Minimax and Expectimax
        public static double Evaluate(State state)
        {
            if (state.IsGameOver()) return -1000;

            double smoothness = Smoothness(state);
            double monotonicity = Monotonicity(state);
            double emptycells = EmptyCells(state);
            double highestvalue = HighestCard(state);
            double trappedpenalty = TrappedPenalty(state);
            return smoothness_weight * smoothness + monotonicity_weight * monotonicity + emptycells_weight * emptycells + highestvalue_weight * highestvalue - trappedpenalty_weight * trappedpenalty;
        }
Ejemplo n.º 3
0
 // Classic Minimax using alpha-beta pruning
 private Move MinimaxAlgorithm(State state, int depth, double alpha, double beta, Deck deck)
 {
     Move bestMove;
     if (depth == 0 || state.IsGameOver())
     {
         if (state.Player == GameEngine.PLAYER)
         {
             bestMove = new PlayerMove(); // default constructor creates dummy action
             bestMove.Score = AI.Evaluate(state);
             return bestMove;
         }
         else if (state.Player == GameEngine.COMPUTER)
         {
             bestMove = new ComputerMove(); // default constructor creates dummy action
             bestMove.Score = AI.Evaluate(state);
             return bestMove;
         }
         else
         {
             throw new Exception();
         }
     }
     if (state.Player == GameEngine.PLAYER)
         return Max(state, depth, alpha, beta);
     else
         return Min(state, depth, alpha, beta);
 }
Ejemplo n.º 4
0
 // Starts the time limited Monte Carlo Tree Search and returns the best child node
 // resulting from the search
 public Node TimeLimitedMCTS(State rootState, int timeLimit, Deck deck)
 {
     Stopwatch timer = new Stopwatch();
     Node bestNode = null;
     while (bestNode == null && !rootState.IsGameOver())
     {
         timer.Start();
         Node rootNode = TimeLimited(rootState, timeLimit, timer, deck);
         bestNode = FindBestChild(rootNode.Children);
         timeLimit += 10;
         timer.Reset();
     }
     return bestNode;
 }