Ejemplo n.º 1
0
        internal static int SetupStatePos = 0; // *SetupState = StateRingBuf;

        #endregion Fields

        #region Methods

        // go() is called when engine receives the "go" UCI command. The function sets
        // the thinking time and other parameters from the input string, and then starts
        // the main searching thread.
        internal static void go(Position pos, Stack<string> stack)
        {
            string token = string.Empty;
            LimitsType limits = new LimitsType();
            List<Move> searchMoves = new List<Phase>();

            while (stack.Count > 0)
            {
                token = stack.Pop();

                if (token == "wtime")
                    limits.time[ColorC.WHITE] = int.Parse(stack.Pop());
                else if (token == "btime")
                    limits.time[ColorC.BLACK] = int.Parse(stack.Pop());
                else if (token == "winc")
                    limits.inc[ColorC.WHITE] = int.Parse(stack.Pop());
                else if (token == "binc")
                    limits.inc[ColorC.BLACK] = int.Parse(stack.Pop());
                else if (token == "movestogo")
                    limits.movesToGo = int.Parse(stack.Pop());
                else if (token == "depth")
                    limits.depth = int.Parse(stack.Pop());
                else if (token == "nodes")
                    limits.nodes = int.Parse(stack.Pop());
                else if (token == "movetime")
                    limits.movetime = int.Parse(stack.Pop());
                else if (token == "infinite")
                    limits.infinite = 1;
                else if (token == "ponder")
                    limits.ponder = true;
                else if (token == "searchmoves")
                    while ((token = stack.Pop()) != null)
                    {
                        searchMoves.Add(Utils.move_from_uci(pos, token));
                    }
            }

            Threads.start_searching(pos, limits, searchMoves);
        }
Ejemplo n.º 2
0
        /// benchmark() runs a simple benchmark by letting Stockfish analyze a set
        /// of positions for a given limit each. There are five parameters; the
        /// transposition table size, the number of search threads that should
        /// be used, the limit value spent for each position (optional, default is
        /// depth 12), an optional file name where to look for positions in fen
        /// format (defaults are the positions defined above) and the type of the
        /// limit value: depth (default), time in secs or number of nodes.
        internal static void benchmark(Position current, Stack<string> stack)
        {
            List<string> fens = new List<string>();

            LimitsType limits = new LimitsType();
            Int64 nodes = 0;
            Int64 nodesAll = 0;
            long e = 0;
            long eAll = 0;

            // Assign default values to missing arguments
            string ttSize = (stack.Count > 0) ? (stack.Pop()) : "128";
            string threads = (stack.Count > 0) ? (stack.Pop()) : "1";
            string limit = (stack.Count > 0) ? (stack.Pop()) : "12";
            string fenFile = (stack.Count > 0) ? (stack.Pop()) : "default";
            string limitType = (stack.Count > 0) ? (stack.Pop()) : "depth";

            OptionMap.Instance["Hash"].v = ttSize;
            OptionMap.Instance["Threads"].v = threads;
            TT.clear();

            if (limitType == "time")
                limits.movetime = 1000 * int.Parse(limit); // maxTime is in ms

            else if (limitType == "nodes")
                limits.nodes = int.Parse(limit);

            else
                limits.depth = int.Parse(limit);

            if (fenFile == "default")
            {
                fens.AddRange(Defaults);
            }
            else if (fenFile == "current")
            {
                fens.Add(current.to_fen());
            }
            else
            {
            #if PORTABLE
                throw new Exception("File cannot be read.");
            #else
                System.IO.StreamReader sr = new System.IO.StreamReader(fenFile, true);
                string fensFromFile = sr.ReadToEnd();
                sr.Close();
                sr.Dispose();

                string[] split = fensFromFile.Replace("\r", "").Split('\n');
                foreach (string fen in split)
                {
                    if (fen.Trim().Length > 0)
                    {
                        fens.Add(fen.Trim());
                    }
                }
            #endif
            }

            Stopwatch time = new Stopwatch();
            long[] res = new long[fens.Count];
            for (int i = 0; i < fens.Count; i++)
            {
                time.Reset(); time.Start();
                Position pos = new Position(fens[i], bool.Parse(OptionMap.Instance["UCI_Chess960"].v), Threads.main_thread());

                Plug.Write("\nPosition: ");
                Plug.Write((i + 1).ToString());
                Plug.Write("/");
                Plug.Write(fens.Count.ToString());
                Plug.Write(Constants.endl);

                if (limitType == "perft")
                {
                    Int64 cnt = Search.perft(pos, limits.depth * DepthC.ONE_PLY);
                    Plug.Write("\nPerft ");
                    Plug.Write(limits.depth.ToString());
                    Plug.Write(" leaf nodes: ");
                    Plug.Write(cnt.ToString());
                    Plug.Write(Constants.endl);
                    nodes = cnt;
                }
                else
                {
                    Threads.start_searching(pos, limits, new List<Move>());
                    Threads.wait_for_search_finished();
                    nodes = Search.RootPosition.nodes;
                    res[i] = nodes;
                }

                e = time.ElapsedMilliseconds;

                nodesAll += nodes;
                eAll += e;

                Plug.Write("\n===========================");
                Plug.Write("\nTotal time (ms) : ");
                Plug.Write(e.ToString());
                Plug.Write("\nNodes searched  : ");
                Plug.Write(nodes.ToString());
                Plug.Write("\nNodes/second    : ");
                Plug.Write(((int)(nodes / (e / 1000.0))).ToString());
                Plug.Write(Constants.endl);

            }

            Plug.Write("\n===========================");
            Plug.Write("\nTotal time (ms) : ");
            Plug.Write(eAll.ToString());
            Plug.Write("\nNodes searched  : ");
            Plug.Write(nodesAll.ToString());
            Plug.Write("\nNodes/second    : ");
            Plug.Write(((int)(nodesAll / (eAll / 1000.0))).ToString());
            Plug.Write(Constants.endl);

            //for (int i = 0; i < res.Length; i++)
            //{
            //    Plug.Write(string.Format("{0}: {1}", i, res[i]));
            //    Plug.Write(Constants.endl);
            //}
        }
Ejemplo n.º 3
0
        // set_option() is called when engine receives the "setoption" UCI command. The
        // function updates the UCI option ("name") to the given value ("value").
        // setoption name Ponder value false
        internal static void set_option(Stack<string> stack)
        {
            string token, name = null, value = null;

            // Consume "name" token
            stack.Pop();

            // Read option name (can contain spaces)
            while ((stack.Count > 0) && ((token = stack.Pop()) != "value"))
            {
                name += (name == null ? string.Empty : " ") + token;
            }

            // Read option value (can contain spaces)
            while ((stack.Count > 0) && ((token = stack.Pop()) != "value"))
            {
                value += (value == null ? string.Empty : " ") + token;
            }

            if (OptionMap.Instance.Contains(name))
            {
                OptionMap.Instance[name].v = value;
            }
            else
            {
                Plug.Write("No such option: ");
                Plug.Write(name);
                Plug.Write(Constants.endl);
            }
        }
Ejemplo n.º 4
0
        // set_position() is called when engine receives the "position" UCI
        // command. The function sets up the position described in the given
        // fen string ("fen") or the starting position ("startpos") and then
        // makes the moves given in the following move list ("moves").
        internal static void set_position(Position pos, Stack<string> stack)
        {
            Move m;
            string token, fen = string.Empty;

            token = stack.Pop();

            if (token == "startpos")
            {
                fen = StartFEN;
                if (stack.Count > 0) { token = stack.Pop(); } // Consume "moves" token if any
            }
            else if (token == "fen")
                while ((stack.Count > 0) && (token = stack.Pop()) != "moves")
                    fen += token + " ";
            else
                return;

            pos.from_fen(fen, bool.Parse(OptionMap.Instance["UCI_Chess960"].v), Threads.main_thread());

            // Parse move list (if any)
            while ((stack.Count > 0) && (m = Utils.move_from_uci(pos, token = stack.Pop())) != MoveC.MOVE_NONE)
            {
                pos.do_move(m, StateRingBuf[SetupStatePos]);

                // Increment pointer to StateRingBuf circular buffer
                SetupStatePos = (SetupStatePos + 1) % 102;
            }
        }
Ejemplo n.º 5
0
        // Search::validmoves() will return the list of all valid moves for a 'square' in UCI notation - all valid moves for the piece occupying that square
        // The list will be empty if no square is given or there is no piece on that square or the piece have no possible moves
        internal static void validmoves(Position pos, Stack<string> stack)
        {
            if (stack.Count > 0)
            {
                var squareFromString = stack.Pop();

                var st = new StateInfo();
                var mlist = MListBroker.GetObject();
                mlist.pos = 0;
                Movegen.generate_legal(pos, mlist.moves, ref mlist.pos);

                var firstOne = true;
                for (var i = 0; i < mlist.pos; ++i)
                {
                    var ms = mlist.moves[i];
                    var m = ms.move;
                    var from = ((m >> 6) & 0x3F);
                    if (Utils.square_to_string(from) == squareFromString)
                    {
                        if (!firstOne)
                        {
                            Plug.Write(" ");
                        }
                        Plug.Write(Utils.move_to_uci(m, false));
                        firstOne = false;
                    }
                }
                MListBroker.Free();
            }
            Plug.Write(Constants.endl);
        }