/// UCI::to_move() converts a string representing a move in coordinate notation /// (g1f3, a7a8q) to the corresponding legal Move, if any. private static MoveT to_move(Position pos, string str) { if (str.Length == 5) // Junior could send promotion piece in uppercase { var chars = str.ToCharArray(); chars[4] = Position.tolower(str[4]); str = new string(chars); } var ml = new MoveList(GenType.LEGAL, pos); for (var index = ml.begin(); index < ml.end(); index++) { var extMove = ml.moveList.table[index]; if (str == move(extMove, pos.is_chess960())) { return extMove; } } return Move.MOVE_NONE; }
// ThreadPool::start_thinking() wakes up the main thread sleeping in // MainThread::idle_loop() and starts a new search, then returns immediately. internal static void start_thinking(Position pos, LimitsType limits, StateInfoWrapper states) { main().join(); Search.Signals.stopOnPonderhit = Search.Signals.firstRootMove = false; Search.Signals.stop = Search.Signals.failedLowAtRoot = false; Search.RootMoves.Clear(); Search.RootPos = new Position(pos); Search.Limits = limits; var current = states[states.current]; if (current != null) // If we don't set a new position, preserve current state { Search.SetupStates = states; // Ownership transfer here Debug.Assert(current != null); } var ml = new MoveList(GenType.LEGAL, pos); for (var index = ml.begin(); index < ml.end(); index++) { var m = ml.moveList.table[index]; if (limits.searchmoves.Count == 0 || limits.searchmoves.FindAll(move => move == m.Move).Count > 0) { Search.RootMoves.Add(new RootMove(m)); } } main().thinking = true; main().notify_one(); // Wake up main thread: 'thinking' must be already set }
/// Search::perft() is our utility to verify move generation. All the leaf nodes /// up to the given depth are generated and counted and the sum returned. internal static long perft(bool Root, Position pos, Depth depth) { var st = new StateInfo(); long nodes = 0; var ci = new CheckInfo(pos); var leaf = (depth == 2*Depth.ONE_PLY); var ml = new MoveList(GenType.LEGAL, pos); for (var index = ml.begin(); index < ml.end(); index++) { var m = ml.moveList.table[index]; long cnt; if (Root && depth <= Depth.ONE_PLY_C) { cnt = 1; nodes++; } else { pos.do_move(m, st, pos.gives_check(m, ci)); cnt = leaf ? new MoveList(GenType.LEGAL, pos).size() : perft(false, pos, depth - Depth.ONE_PLY); nodes += cnt; pos.undo_move(m); } if (Root) { Output.WriteLine($"{UCI.move(m, pos.is_chess960())}: {cnt}"); } } return nodes; }