コード例 #1
0
        public int RootAlphaBeta(int alpha, int beta, Board board, int depth)
        {
            Stopwatch s = new Stopwatch();

            s.Start();
            Board bCopy = board;

            int[] moves = bCopy.GetInterestingMoves();
            if (moves.Length == 0)
            {
                return((board.width * board.width) / 2);
            }
            int    bestId = 0;
            int    color  = board.blackTurn ? 1 : -1;
            string deb    = "";

            for (int i = 0; i < moves.Length; i++)
            {
                bCopy = new Board(board);
                bCopy.ChangeSquare(moves[i]);
                bCopy.EndTurn();
                int score = -AlphaBeta(-beta, -alpha, bCopy, depth - 1, color);
                if (score > alpha)
                {
                    alpha  = score;
                    bestId = i;
                    deb   += "Move: " + moves[i].ToString() + " has value " + score.ToString() + ".\n  ";
                }
            }
            s.Stop();
            deb += "\n\n  Execution took " + s.ElapsedMilliseconds.ToString() + " miliseconds.";
            board.DebugWrite(deb);
            return(moves[bestId]);
        }
コード例 #2
0
        public int MonteCarloSearch(Board rootState, double searchTimer)
        {
            //Check if we can find a winning move in one move
            string deb = "";

            if (true)
            {
                int winCheck = GetHighestValueMove(rootState, 1);
                if (winCheck == (rootState.width * rootState.width) / 2)
                {
                    return((rootState.width * rootState.width) / 2);
                }
                Board copy = new Board(rootState);
                copy.ChangeSquare(winCheck);
                int value = rootState.blackTurn ? EvaluateBoard(copy) : -EvaluateBoard(copy);
                deb += "Highest 1 ply value move is: " + winCheck.ToString() + ", value " + value.ToString() + ".\n  ";
                if (value > 9999)
                {
                    rootState.DebugWrite(deb);
                    return(winCheck);
                }
            }
            Node      root = new Node(rootState.lastSquare, null, rootState, 1);
            Stopwatch s    = new Stopwatch();

            s.Start();
            while (s.Elapsed.Seconds < searchTimer)
            {
                Node  node  = root;
                Board state = new Board(rootState);
                //Select
                while (node.untriedMoves.Count == 0 && node.nodes.Count != 0)
                {
                    node = NodeSelection(node);
                    state.ChangeSquare(node.move);
                    state.EndTurn();
                }
                //Expand
                if (node.untriedMoves.Count != 0)
                {
                    int move = node.GetRandomMove();
                    state.ChangeSquare(move);
                    state.EndTurn();
                    node = node.AddChild(move, state);
                }
                //Rollout
                int lastMove = node.move;
                while (EvaluateBoard(state) == 0)
                {
                    //int move = RootAlphaBeta(int.MinValue, int.MaxValue, state, 2);
                    int move = GetHighestValueMove(state, 1);
                    state.ChangeSquare(move);
                    state.EndTurn();
                    lastMove = move;
                }
                //Backpropagate
                int result = state.CheckWin(lastMove);
                while (node != null)
                {
                    node.games++;
                    if (result == -1)
                    {
                        node.wins += 0.4;
                    }
                    else if ((result == 1 && rootState.blackTurn) || (result == 2 && !rootState.blackTurn))
                    {
                        node.wins += 1;
                    }
                    else
                    {
                        node.wins += 0;
                    }
                    node = node.parent;
                }
            }
            int    bestI     = 0;
            double bestValue = double.MinValue;

            for (int i = 0; i < root.nodes.Count; i++)
            {
                double val = root.nodes[i].games * (root.nodes[i].wins / root.nodes[i].games);
                if (val > bestValue)
                {
                    deb      += "Move: " + root.nodes[i].move.ToString() + " has Wins " + root.nodes[i].wins.ToString("0.0") + ", games " + root.nodes[i].games.ToString() + ", = " + (root.nodes[i].wins / root.nodes[i].games).ToString("0.000") + ".\n  ";
                    bestI     = i;
                    bestValue = val;
                }
            }
            rootState.DebugWrite(deb);
            //rootState.DebugWrite("Done finding move from " + root.nodes.Count.ToString() + " available.");
            return(root.nodes[bestI].move);
        }
コード例 #3
0
        public int MultiThreadedRAlphaBeta(Board board, int depth, int maxThreadNum)
        {
            Stopwatch s = new Stopwatch();

            s.Start();
            Queue <int> moves;

            if (depth > 4)
            {
                moves = new Queue <int>(FindMoves(board, 3));
            }
            else
            {
                moves = new Queue <int>(board.GetInterestingMoves());
            }
            //Queue<int> moves = new Queue<int>(board.GetInterestingMoves());
            int moveNum = moves.Count;

            if (moves.Count == 0)
            {
                return((board.width * board.width) / 2);
            }
            else if (moves.Count == 1)
            {
                board.DebugWrite("Execution took " + s.ElapsedMilliseconds.ToString() + " miliseconds for " + moveNum + " move. (defmoves) = " + board.GetInterestingMoves().Length);
                return(moves.Dequeue());
            }
            int    bestMove  = 0;
            int    alpha     = int.MinValue;
            int    color     = board.blackTurn ? 1 : -1;
            string deb       = "";
            int    threadNum = 4;

            if (moves.Count <= 4)
            {
                threadNum = moves.Count;
            }
            else if (moves.Count >= 32)
            {
                threadNum = maxThreadNum - 2 > 4 ? maxThreadNum - 2 : 4;
            }
            else
            {
                for (int i = maxThreadNum; i >= 4; i--)
                {
                    if (moves.Count % i == 0)
                    {
                        threadNum = i;
                        break;
                    }
                }
            }
            Thread[] threads = new Thread[threadNum];
            results.Clear();
            for (int i = 0; i < threadNum; i++)
            {
                int[] threadMoves;
                if (moves.Count > moveNum / threadNum)
                {
                    threadMoves = new int[moveNum / threadNum];
                }
                else
                {
                    threadMoves = new int[moves.Count];
                }
                for (int j = 0; j < threadMoves.Length; j++)
                {
                    threadMoves[j] = moves.Dequeue();
                }
                threads[i] = new Thread(() => { AlphaBetaFromMoves(board, depth, threadMoves); });
                threads[i].Start();
            }
            for (int i = 0; i < threadNum; i++)
            {
                threads[i].Join();
            }
            for (int i = 0; i < threadNum; i++)
            {
                deb += "Move: " + results[i].Key.ToString() + " has value " + results[i].Value.ToString() + ".\n  ";
                if (results[i].Value > alpha && results[i].Key != -1)
                {
                    bestMove = results[i].Key;
                    alpha    = results[i].Value;
                }
            }
            s.Stop();
            deb += "\n\n  Execution took " + s.ElapsedMilliseconds.ToString() + " miliseconds for " + moveNum + " moves. (defmoves) = " + board.GetInterestingMoves().Length;
            //deb += "\n\n After last move FindNewMoves found " + FindNewMoves(board, board.lastMove).Length + " new moves.";
            board.DebugWrite(deb);
            return(bestMove);
        }