コード例 #1
0
ファイル: Minimax.cs プロジェクト: kstrandby/Threes-AI
        // Runs an entire game using a parallelized version of iterative deepening minimax
        private Move ParallelIterativeDeepening(State state, int timeLimit, Deck deck)
        {
            Move bestMove = new PlayerMove();

            List<Move> moves = state.GetMoves(deck);
            ConcurrentBag<Tuple<double, Move>> scores = new ConcurrentBag<Tuple<double, Move>>();

            if (moves.Count == 0)
            {
                // game over
                return bestMove;
            }

            // create the resulting states before starting the threads
            List<State> resultingStates = new List<State>();
            foreach (Move move in moves)
            {
                State resultingState = state.ApplyMove(move);
                resultingStates.Add(resultingState);
            }

            Parallel.ForEach(resultingStates, resultingState =>
            {
                double score = IterativeDeepening(resultingState, timeLimit, deck.Clone()).Score;
                scores.Add(new Tuple<double, Move>(score, resultingState.GeneratingMove));
            });
            // find the best score
            double highestScore = Double.MinValue;
            foreach (Tuple<double, Move> score in scores)
            {
                PlayerMove move = (PlayerMove)score.Item2;
                if (score.Item1 > highestScore)
                {
                    highestScore = score.Item1;
                    bestMove = score.Item2;
                }
            }
            return bestMove;
        }
コード例 #2
0
ファイル: MCTS.cs プロジェクト: kstrandby/Threes-AI
        // Time limited MCTS
        private Node TimeLimited(State rootState, int timeLimit, Stopwatch timer, Deck deck)
        {
            Node rootNode = new Node(null, null, rootState, deck);

            while (true)
            {
                if (timer.ElapsedMilliseconds > timeLimit)
                {
                    if (FindBestChild(rootNode.Children) == null && !rootNode.state.IsGameOver())
                    {
                        timeLimit += 10;
                        timer.Restart();
                    }
                    else
                    {
                        return rootNode;
                    }

                }
                Node node = rootNode;
                State state = rootState.Clone();
                Deck clonedDeck = deck.Clone();

                // 1: Select
                while (node.UntriedMoves.Count == 0 && node.Children.Count != 0)
                {
                    node = node.SelectChild();
                    state = state.ApplyMove(node.GeneratingMove);
                    if (node.GeneratingMove is ComputerMove)
                    {
                        clonedDeck.Remove(((ComputerMove)node.GeneratingMove).Card);
                        if (clonedDeck.IsEmpty()) clonedDeck = new Deck();
                    }
                }

                // 2: Expand
                if (node.UntriedMoves.Count != 0)
                {
                    Move randomMove = node.UntriedMoves[random.Next(0, node.UntriedMoves.Count)];
                    if (randomMove is ComputerMove)
                    {
                        if (clonedDeck.IsEmpty()) clonedDeck = new Deck();
                        clonedDeck.Remove(((ComputerMove)randomMove).Card);
                        state = state.ApplyMove(randomMove);
                        node = node.AddChild(randomMove, state, clonedDeck);

                    }
                    else
                    {
                        state = state.ApplyMove(randomMove);
                        node = node.AddChild(randomMove, state, clonedDeck);
                    }
                }

                // 3: Simulation
                while (state.GetMoves(clonedDeck).Count != 0)
                {
                    Move move = state.GetRandomMove(clonedDeck);
                    if (move is ComputerMove)
                    {
                        if (clonedDeck.IsEmpty()) clonedDeck = new Deck();
                        clonedDeck.Remove(((ComputerMove)move).Card);
                        state = state.ApplyMove(move);
                    }
                    else
                    {
                        state = state.ApplyMove(move);
                    }
                }

                // 4: Backpropagation
                while (node != null)
                {
                    node.Update(state.GetResult());
                    node = node.Parent;
                }
            }
        }