private static void UciSetOption(string[] tokens) { if (tokens[1] == "name" && tokens[2] == "Hash" && tokens[3] == "value" && int.TryParse(tokens[4], out int hashSizeMBytes)) { Transpositions.Resize(hashSizeMBytes); } }
private static void CompareBestMove(string filePath, int timeBudgetMs) { var file = File.OpenText(filePath); double freq = Stopwatch.Frequency; long totalTime = 0; long totalNodes = 0; int count = 0; int foundBest = 0; List <Move> bestMoves = new List <Move>(); while (!file.EndOfStream) { ParseEpd(file.ReadLine(), out Board board, bestMoves); Transpositions.Clear(); IterativeSearch search = new IterativeSearch(board); Move pvMove = default; long t0 = Stopwatch.GetTimestamp(); long tStop = t0 + (timeBudgetMs * Stopwatch.Frequency) / 1000; //search until running out of time while (true) { search.SearchDeeper(() => Stopwatch.GetTimestamp() > tStop); if (search.Aborted) { break; } pvMove = search.PrincipalVariation[0]; } long t1 = Stopwatch.GetTimestamp(); long dt = t1 - t0; totalTime += dt; totalNodes += search.NodesVisited; count++; string pvString = string.Join(' ', search.PrincipalVariation); bool foundBestMove = bestMoves.Contains(pvMove); if (foundBestMove) { foundBest++; } Console.WriteLine($"{count,4}. {(foundBestMove ? "[X]" : "[ ]")} {pvString} = {search.Score:+0.00;-0.00}, {search.NodesVisited / 1000}K nodes, { 1000 * dt / freq}ms"); Console.WriteLine($"{totalNodes,14} nodes, { (int)(totalTime / freq)} seconds, {foundBest} solved."); } Console.WriteLine(); Console.WriteLine($"Searched {count} positions for {timeBudgetMs}ms each. {totalNodes/1000}K nodes visited. Took {totalTime/freq:0.###} seconds!"); Console.WriteLine($"Best move found in {foundBest} / {count} positions!"); }
private static void ParseUciCommand(string input) { //remove leading & trailing whitecases and split using ' ' as delimiter string[] tokens = input.Trim().Split(); switch (tokens[0]) { case "uci": Console.WriteLine($"id name {NAME_VERSION}"); Console.WriteLine($"id author {AUTHOR}"); Console.WriteLine($"option name Hash type spin default {Transpositions.DEFAULT_SIZE_MB} min 1 max 2047"); //consider gcAllowVeryLargeObjects if larger TT is needed Console.WriteLine("uciok"); break; case "isready": Console.WriteLine("readyok"); break; case "position": UciPosition(tokens); break; case "go": UciGo(tokens); break; case "ucinewgame": Transpositions.Clear(); break; case "stop": _engine.Stop(); break; case "quit": _engine.Quit(); break; case "setoption": UciSetOption(tokens); break; default: Console.WriteLine("UNKNOWN INPUT " + input); return; } }
private Move[] GetPrintablePV(Move[] pv, int depth) { List <Move> result = new(pv); //Try to extend from TT to reach the desired depth? if (result.Count < depth) { Board position = new Board(_board); foreach (Move move in pv) { position.Play(move); } while (result.Count < depth && Transpositions.GetBestMove(position, out Move move)) { position.Play(move); result.Add(move); } } return(result.ToArray()); }
//***************** //*** INTERNALS *** //***************** private void StartSearch(int maxDepth, long maxNodes) { //do the first iteration. it's cheap, no time check, no thread Uci.Log($"Search scheduled to take {_time.TimePerMoveWithMargin}ms!"); //add all history positions with a score of 0 (Draw through 3-fold repetition) and freeze them by setting a depth that is never going to be overwritten foreach (var position in _history) { Transpositions.Store(position.ZobristHash, Transpositions.HISTORY, 0, SearchWindow.Infinite, 0, default); } _search = new IterativeSearch(_board, maxNodes); _time.StartInterval(); _search.SearchDeeper(); Collect(); //start the search thread _maxSearchDepth = maxDepth; _searching = new Thread(Search) { Priority = ThreadPriority.Highest }; _searching.Start(); }
public Form1() { InitializeComponent(); t = new Transpositions(); }