private static void UciPosition(string[] tokens) { //position [fen <fenstring> | startpos ] moves <move1> .... <movei> if (tokens[1] == "startpos") { _engine.SetupPosition(); } else if (tokens[1] == "fen") //rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 { string fen = string.Join(' ', tokens, 2, tokens.Length - 2); _engine.SetupPosition(fen); } else { Uci.Log("'position' parameters missing or not understood. Assuming 'startpos'."); _engine.SetupPosition(); } int firstMove = Array.IndexOf(tokens, "moves") + 1; if (firstMove == 0) { return; } for (int i = firstMove; i < tokens.Length; i++) { Move move = MoveFromUciNotation(tokens[i]); _engine.Play(move); } }
private static void UciGo(string[] tokens) { if (TryParse(tokens, "movetime", out int timePerMove)) { //Fixed move time e.g. 5 Minutes per Move = go movetime 300000 TryParse(tokens, "depth", out int searchDepth, int.MaxValue); _engine.Go(timePerMove, searchDepth); } else if (TryParse(tokens, "btime", out int blackTime) && TryParse(tokens, "wtime", out int whiteTime)) { //Searching on a budget that may increase at certain intervals //40 Moves in 5 Minutes = go wtime 300000 btime 300000 movestogo 40 //40 Moves in 5 Minutes, 1 second increment per Move = go wtime 300000 btime 300000 movestogo 40 winc 1000 binc 1000 movestogo 40 //5 Minutes total, no increment (sudden death) = go wtime 300000 btime 300000 TryParse(tokens, "binc", out int blackIncrement); TryParse(tokens, "winc", out int whiteIncrement); TryParse(tokens, "movestogo", out int movesToGo, 40); //assuming 30 e.g. spend 1/30th of total budget on the move TryParse(tokens, "depth", out int searchDepth, int.MaxValue); _engine.Go(blackTime, whiteTime, blackIncrement, whiteIncrement, movesToGo, searchDepth); } else if (TryParse(tokens, "depth", out int searchDepth)) { _engine.Go(searchDepth); } else if (IsDefined(tokens, "infinite")) { //Infinite = go infinite _engine.Go(); } else { Uci.Log("'go' parameters missing or not understood. Stop the search using 'stop'."); _engine.Go(); } }
internal void Go(int blackTime, int whiteTime, int blackIncrement, int whiteIncrement, int movesToGo, int maxSearchDepth) { Stop(); _searchDepth = maxSearchDepth; int myTime = _board.WhiteToMove ? whiteTime : blackTime; int myIncrement = _board.WhiteToMove ? whiteIncrement : blackIncrement; int totalTime = myTime + myIncrement * (movesToGo - 1) - MOVE_TIME_MARGIN; _timeBudget = totalTime / movesToGo; Uci.Log($"Search budget set to {_timeBudget}ms!"); StartSearch(); }
//***************** //*** 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(); }