Exemple #1
0
 public SearchResult GetBestMove(SearchArgs settings)
 {
     return(search.GetBestMove(Board, settings));
 }
Exemple #2
0
        public void AnalyzePosition(Position position, int depth, string file)
        {
            Semaphore s = new Semaphore(1, 1);

            using (StreamWriter w = new StreamWriter(file, false))
            {
                w.WriteLine("Last Move,Best Move,Move Score,Primary Variation,Depth,Evaluations,Seconds");
            }

            // Create a list of positions so we can process in parallel
            List <Position> positions = new List <Position>();

            positions.Add(position);
            foreach (Move move in position.GetValidMoves())
            {
                Position copy = position.Clone();
                copy.MakeMove(move);
                positions.Add(copy);
            }

            // Create a list of actions to run in parallel
            List <Action> actions = new List <Action>();

            foreach (Position p in positions)
            {
                actions.Add(() =>
                {
                    Stopwatch timer   = Stopwatch.StartNew();
                    Search search     = new Search();
                    SearchArgs args   = new SearchArgs(depth, -1, false);
                    SearchResult best = search.GetBestMove(p, args);
                    timer.Stop();

                    s.WaitOne();
                    using (StreamWriter w = new StreamWriter(file, true))
                    {
                        string history = "";
                        if (!string.IsNullOrEmpty(p.MovesHistory))
                        {
                            string move = p.MovesHistory;
                            if (move.Contains(" "))
                            {
                                move = move.Split(' ')[0];
                            }

                            history = "After " + move;
                        }
                        else
                        {
                            history = "Starting Position";
                        }

                        w.WriteLine(history + "," + best.BestMove.ToString() + "," + best.Score + "," + best.PrimaryVariation + "," + depth + "," + best.Evaluations + "," + (timer.ElapsedMilliseconds / 1000.0).ToString("0.000"));
                    }
                    s.Release();
                });
            }

            // Analyze all positions in parallel
            actions.ForEach(a => Task.Run(a));
        }
Exemple #3
0
        public SearchResult GetBestMove(Position position, SearchArgs settings)
        {
            SearchResult result = new SearchResult();

            initiatingPlayer = position.PlayerToMove;

            timer                 = Stopwatch.StartNew();
            cutoff                = false;
            evaluations           = 0;
            hashLookups           = 0;
            useCache              = settings.EnableCaching;
            timeLimitMilliseconds = settings.MaxSeconds < 0 ? long.MaxValue : settings.MaxSeconds * 1000;

            List <Move> moves  = null;
            List <int>  depths = new List <int>();

            // Instead of creating some complicated for loop, just store up the depths we intend to search ahead of time
            if (settings.MaxSeconds < 0)
            {
                if (settings.MaxDepth != 1)
                {
                    // If we're searching deeper than 3 (6 half moves) then do a fast two level deep search to help with move ordering
                    depths.Add(4);
                }
                else if (settings.MaxDepth > 1)
                {
                    // If we're searching deeper than 1 (2 half moves) then do a super fast one level deep search to help with move ordering
                    depths.Add(2);
                }
                depths.Add(settings.MaxDepth * 2);
            }
            else
            {
                // All the depths we intend to search, in order
                for (int depth = 2; depth <= settings.MaxDepth * 2; depth += 2)
                {
                    depths.Add(depth);
                }
            }

            // Iterative deepening
            // Increment depth by 2 since we always want to consider pairs of move (our move and opponent's move)
            foreach (int depth in depths)
            {
                // Need to re-initialize hash table at each depth
                hashtable = new Dictionary <ulong, SearchResult>();

                currentDepth = depth;

                SearchResult nextDepth = AlphaBetaSearch(position, int.MinValue, int.MaxValue, depth, 1, 1, ref moves);

                // Move ordering for next iteration
                if (initiatingPlayer == Player.Red)
                {
                    moves.Sort((c, n) => c.Evaluation.CompareTo(n.Evaluation));
                }
                else
                {
                    moves.Sort((c, n) => n.Evaluation.CompareTo(c.Evaluation));
                }

                if (!cutoff)
                {
                    result = nextDepth;
                }
            }

            result.Evaluations = evaluations;
            result.HashLookups = hashLookups;

            return(result);
        }