Esempio n. 1
0
    /// 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;
    }
Esempio n. 2
0
    // 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
    }
Esempio n. 3
0
    /// 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;
    }