예제 #1
0
        private static void MCRollout(Node leaf)
        {
            Con4Board  board  = leaf.state;
            int        player = leaf.playerToMove;
            int        value  = 0;
            BoardState bs     = leaf.bs;

            while (true)
            {
                //BoardState bs = board.EvaluateBoard();
                //checkEqualityOfEval(board, bs);

                if (bs != BoardState.ongoing)
                {
                    value = BoardStateToValue(bs);
                    break;
                }
                else
                {
                    List <int> possMoves = board.GetPossibleMoves();
                    board = board.SimulateMove(player, possMoves[rnd.Next(possMoves.Count)]);
                    simulations++;
                    bs = Evaluate.EvaluateBoard(board);
                    evaluations++;
                    player *= -1;
                }
            }
            Backpropagate(leaf, value);
        }
예제 #2
0
        private static void HandleLeafNode(Node leaf)
        {
            if (leaf.totalVisits == 0)
            {
                MCRollout(leaf);
            }
            else
            {
                // EXPAND
                Con4Board board = leaf.state;
                //BoardState bs = board.EvaluateBoard();
                //checkEqualityOfEval(board, bs);
                //BoardState bs = Evaluate.EvaluateBoard(board);
                BoardState bs = leaf.bs;
                //evaluations++;
                if (bs != BoardState.ongoing)   // Terminal node, do not expand, just backprop
                {
                    Backpropagate(leaf, BoardStateToValue(bs));
                }
                else     // Not terminal, expand
                {
                    List <int> possMoves = board.GetPossibleMoves();
                    foreach (int move in possMoves)
                    {
                        leaf.children.Add(new Node(leaf, board.SimulateMove(leaf.playerToMove, move),
                                                   leaf.playerToMove * -1, move));
                        simulations++;
                    }

                    Node firstChild = leaf.children[0];
                    MCRollout(firstChild);
                }
            }
        }
예제 #3
0
        public static int FindMove(Con4Board board, long searchTimeMs)
        {
            simulations = 0;
            evaluations = 0;
            if (root == null)
            {
                // New tree
                root = new Node(null, board, 1, -1);
                List <int> possMoves = board.GetPossibleMoves();
                foreach (int move in possMoves)
                {
                    root.children.Add(new Node(root, board.SimulateMove(root.playerToMove, move),
                                               root.playerToMove * -1, move));
                    simulations++;
                }
            }
            else
            {
                // Continue from last tree
                // Set root to child which matches opponents move
                foreach (Node node in root.children)
                {
                    if (node.state.Equals(board))
                    {
                        root        = node;
                        root.parent = null; // Let GC remove rest of tree
                        Console.WriteLine("Found root, continuing where we left off!");
                        break;
                    }
                }
            }

            stopwatch.Restart();
            while (stopwatch.ElapsedMilliseconds < searchTimeMs)
            {
                //stopwatch.Restart();
                for (int i = 0; i < 100; i++)
                {
                    MCTSIteration();
                }
                //stopwatch.Stop();
                //Console.WriteLine(stopwatch.ElapsedMilliseconds);
                //searchTimeMs -= stopwatch.ElapsedMilliseconds;
            }

            List <Node> children  = root.children;
            int         bestMove  = children[0].previousMove;
            double      bestValue = children[0].totalValue;
            Node        nextRoot  = children[0]; // To continue on same tree next move

            Console.Write("Move values {m, v}: ");
            Console.Write("{" + children[0].previousMove + ", " + children[0].totalValue + "} ");
            for (int i = 1; i < children.Count; i++)
            {
                Node   child  = children[i];
                double totVal = child.totalValue;
                Console.Write("{" + child.previousMove + ", " + totVal + "}");
                if (totVal > bestValue)
                {
                    bestValue = totVal;
                    bestMove  = child.previousMove;
                    nextRoot  = child;
                }
            }
            Console.WriteLine(" => Playing move: " + bestMove);
            Console.WriteLine("Simulations: " + simulations + ", Evaluations: " + evaluations);
            root = nextRoot;
            return(bestMove);
        }