예제 #1
0
        /// <summary>
        /// Executes the parsing.
        /// </summary>
        public static void Run()
        {
            Restrictions.Output = OutputType.Universal;
            IEngine  engine   = new Zero();
            Position position = new Position(Position.StartingFEN);

            String command;

            while ((command = Console.ReadLine()) != null)
            {
                List <String> terms = new List <String>(command.Split(' '));

                switch (terms[0])
                {
                default:
                    Terminal.WriteLine("Unknown command: {0}", terms[0]);
                    Terminal.WriteLine("Enter \"help\" for assistance.");
                    break;

                case "uci":
                    Terminal.WriteLine("id name " + engine.Name);
                    Terminal.WriteLine("id author Zong Zheng Li");
                    Terminal.WriteLine("option name Hash type spin default " + Zero.DefaultHashAllocation + " min 1 max 2047");
                    Terminal.WriteLine("uciok");
                    break;

                case "ucinewgame":
                    engine.Reset();
                    break;

                case "setoption":
                    if (terms.Contains("Hash"))
                    {
                        engine.HashAllocation = Int32.Parse(terms[terms.IndexOf("value") + 1]);
                    }
                    break;

                case "position":
                    String fen = Position.StartingFEN;
                    if (terms[1] != "startpos")
                    {
                        fen = command.Substring(command.IndexOf("fen") + 4);
                    }
                    position = new Position(fen);

                    Int32 movesIndex = terms.IndexOf("moves");
                    if (movesIndex >= 0)
                    {
                        for (Int32 i = movesIndex + 1; i < terms.Count; i++)
                        {
                            position.Make(Move.Create(position, terms[i]));
                        }
                    }
                    break;

                case "go":
                    Restrictions.Reset();
                    for (Int32 i = 1; i < terms.Count; i++)
                    {
                        switch (terms[i])
                        {
                        default:
                        case "infinite":
                            break;

                        case "depth":
                            Restrictions.Depth           = Int32.Parse(terms[i + 1]);
                            Restrictions.UseTimeControls = false;
                            break;

                        case "movetime":
                            Restrictions.MoveTime        = Int32.Parse(terms[i + 1]);
                            Restrictions.UseTimeControls = false;
                            break;

                        case "wtime":
                            Restrictions.TimeControl[Colour.White] = Int32.Parse(terms[i + 1]);
                            Restrictions.UseTimeControls           = true;
                            break;

                        case "btime":
                            Restrictions.TimeControl[Colour.Black] = Int32.Parse(terms[i + 1]);
                            Restrictions.UseTimeControls           = true;
                            break;

                        case "winc":
                            Restrictions.TimeIncrement[Colour.White] = Int32.Parse(terms[i + 1]);
                            Restrictions.UseTimeControls             = true;
                            break;

                        case "binc":
                            Restrictions.TimeIncrement[Colour.Black] = Int32.Parse(terms[i + 1]);
                            Restrictions.UseTimeControls             = true;
                            break;

                        case "nodes":
                            Restrictions.Nodes           = Int32.Parse(terms[i + 1]);
                            Restrictions.UseTimeControls = false;
                            break;

                        case "ponder":
                            // TODO: implement command.
                            break;

                        case "mate":
                            // TODO: implement command.
                            break;

                        case "movestogo":
                            // TODO: implement command.
                            break;
                        }
                    }
                    new Thread(new ThreadStart(() => {
                        Int32 bestMove = engine.GetMove(position);
                        Terminal.WriteLine("bestmove " + Stringify.Move(bestMove));
                    }))
                    {
                        IsBackground = true
                    }.Start();
                    break;

                case "stop":
                    engine.Stop();
                    break;

                case "isready":
                    Terminal.WriteLine("readyok");
                    break;

                case "quit":
                    return;

                case "perft":
                    Perft.Iterate(position, Int32.Parse(terms[1]));
                    break;

                case "divide":
                    Perft.Divide(position, Int32.Parse(terms[1]));
                    break;

                case "draw":
                    Terminal.WriteLine(position);
                    break;

                case "fen":
                    Terminal.WriteLine(position.GetFEN());
                    break;

                case "ponderhit":
                    // TODO: implement command.
                    break;

                case "register":
                    // TODO: implement command.
                    break;

                case "help":
                    Terminal.WriteLine("Command             Function");
                    Terminal.WriteLine("-----------------------------------------------------------------------");
                    Terminal.WriteLine("position [fen]      Sets the current position to the position denoted");
                    Terminal.WriteLine("                    by the given FEN. \"startpos\" is accepted for the");
                    Terminal.WriteLine("                    starting position");
                    Terminal.WriteLine("go [type] [number]  Searches the current position. Search types include");
                    Terminal.WriteLine("                    \"movetime\", \"depth\", \"nodes\", \"wtime\", \"btime\",");
                    Terminal.WriteLine("                    \"winc\", and \"binc\"");
                    Terminal.WriteLine("perft [number]      Runs perft() on the current position to the given");
                    Terminal.WriteLine("                    depth");
                    Terminal.WriteLine("divide [number]     Runs divide() on the current position for the given");
                    Terminal.WriteLine("                    depth");
                    Terminal.WriteLine("fen                 Prints the FEN of the current position.");
                    Terminal.WriteLine("draw                Draws the current position");
                    Terminal.WriteLine("stop                Stops an ongoing search");
                    Terminal.WriteLine("quit                Exits the application");
                    Terminal.WriteLine("-----------------------------------------------------------------------");
                    break;
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Begins the test with the given positions.
        /// </summary>
        /// <param name="epd">A list of positions in EPD format.</param>
        public static void Run(List <String> epd)
        {
            // Perform testing on a background thread.
            new Thread(new ThreadStart(() => {
                IEngine engine       = new Zero();
                Restrictions.Output  = OutputType.None;
                Int32 totalPositions = 0;
                Int32 totalSolved    = 0;
                Int64 totalNodes     = 0;
                Double totalTime     = 0;

                Terminal.WriteLine(ResultFormat, "Position", "Result", "Time", "Nodes");
                Terminal.WriteLine("-----------------------------------------------------------------------");

                foreach (String line in epd)
                {
                    List <String> terms = new List <String>(line.Replace(";", " ;").Split(' '));

                    // Strip everything to get the FEN.
                    Int32 bmIndex = line.IndexOf("bm ");
                    bmIndex       = bmIndex < 0 ? Int32.MaxValue : bmIndex;
                    Int32 amIndex = line.IndexOf("am ");
                    amIndex       = amIndex < 0 ? Int32.MaxValue : amIndex;
                    String fen    = line.Remove(Math.Min(bmIndex, amIndex));

                    // Get the best moves.
                    List <String> solutions = new List <String>();
                    for (Int32 i = terms.IndexOf("bm") + 1; i >= 0 && i < terms.Count && terms[i] != ";"; i++)
                    {
                        solutions.Add(terms[i]);
                    }

                    // Get the ID of the position.
                    Int32 idIndex = line.IndexOf("id ") + 3;
                    String id     = line.Substring(idIndex, line.IndexOf(';', idIndex) - idIndex).Replace(@"\", "");
                    if (id.Length > IDWidthLimit)
                    {
                        id = id.Remove(IDWidthLimit) + "..";
                    }

                    // Set the position and invoke a search on it.
                    Position position = new Position(fen);
                    VisualPosition.Set(position);
                    engine.Reset();

                    Stopwatch stopwatch = Stopwatch.StartNew();
                    Int32 move          = engine.GetMove(position);
                    stopwatch.Stop();

                    Double elapsed = stopwatch.Elapsed.TotalMilliseconds;
                    totalPositions++;
                    totalTime  += elapsed;
                    totalNodes += engine.Nodes;

                    // Determine whether the engine found a solution.
                    String result = "fail";
                    if (solutions.Contains(Stringify.MoveAlgebraically(position, move)))
                    {
                        result = "pass";
                        totalSolved++;
                    }

                    // Print the result for the search on the position.
                    Terminal.WriteLine(ResultFormat, id, result, String.Format("{0:0} ms", elapsed), engine.Nodes);
                }

                // Print final results after all positions have been searched.
                Terminal.WriteLine("-----------------------------------------------------------------------");
                Terminal.WriteLine("Result         {0} / {1}", totalSolved, totalPositions);
                Terminal.WriteLine("Time           {0:0} ms", totalTime);
                Terminal.WriteLine("Average nodes  {0:0}", (Double)totalNodes / totalPositions);
            }))
            {
                IsBackground = true
            }.Start();

            // Open the GUI window to draw positions.
            Application.Run(new Window());
        }
예제 #3
0
        /// <summary>
        /// Begins the tournament with the given positions.
        /// </summary>
        /// <param name="epd">A list of positions to play in EPD format.</param>
        public static void Run(List <String> epd)
        {
            IEngine experimental = new Zero()
            {
                IsExperimental = true
            };
            IEngine standard = new Zero();

            Restrictions.Output = OutputType.None;
            Int32 wins   = 0;
            Int32 losses = 0;
            Int32 draws  = 0;

            using (StreamWriter sw = new StreamWriter(ID + ".txt")) {
                sw.WriteLine(new String(' ', UpdateInterval) + String.Format(ResultFormat, "Games", "Wins", "Losses", "Draws", "Elo", "Error"));
                sw.WriteLine("--------------------------------------------------------------------");

                // Play the tournament.
                for (Int32 games = 1; ; games++)
                {
                    sw.Flush();
                    experimental.Reset();
                    standard.Reset();
                    Position    position = new Position(epd[Random.Int32(epd.Count - 1)]);
                    MatchResult result   = Match.Play(experimental, standard, position, MatchOptions.RandomizeColour);

                    // Write the match result.
                    switch (result)
                    {
                    case MatchResult.Win:
                        sw.Write('1');
                        wins++;
                        break;

                    case MatchResult.Loss:
                        sw.Write('0');
                        losses++;
                        break;

                    case MatchResult.Draw:
                        sw.Write('-');
                        draws++;
                        break;

                    case MatchResult.Unresolved:
                        sw.Write('*');
                        draws++;
                        break;
                    }

                    // Write the cummulative results.
                    if (games % UpdateInterval == 0)
                    {
                        Double delta = Elo.GetDelta(wins, losses, draws);
                        String elo   = String.Format("{0:+0;-0}", delta);

                        Double[] bound    = Elo.GetError(Elo.Z95, wins, losses, draws);
                        Double   lower    = Math.Max(bound[0], -999);
                        Double   upper    = Math.Min(bound[1], 999);
                        String   asterisk = Elo.IsErrorValid(wins, losses, draws) ? String.Empty : "*";
                        String   error    = String.Format("{0:+0;-0} {1:+0;-0}{2}", lower, upper, asterisk);

                        sw.WriteLine(String.Format(ResultFormat, games, wins, losses, draws, elo, error));
                    }
                }
            }
        }