コード例 #1
0
ファイル: UCIEngine.cs プロジェクト: Chaosus/ModernShogi
    /// <summary>
    /// Инициализирует движок. Если движок уже инициализирован не делает ничего,
    /// если же processFolder или processName при этом не будет равен предыдущим параметрам,
    /// то переинициализирует процесс на новый движок.
    /// </summary>
    /// <param name="processFolder">Папка процесса.</param>
    /// <param name="processName">Имя процесса.</param>
    public static void Init(string processFolder = null, string processName = null)
    {
        if (string.IsNullOrEmpty(processFolder))
        {
            Print("ERROR: processFolder == null", AI.MessageType.Info);
            IsReady = false;
            return;
        }
        if (string.IsNullOrEmpty(processName))
        {
            Print("ERROR: processName == null", AI.MessageType.Info);
            IsReady = false;
            return;
        }

        var path = processFolder + "\\" + processName;

        if (!System.IO.File.Exists(path))
        {
            Print($"ERROR: Process {path} not exist !", AI.MessageType.Info);
            IsReady = false;
            return;
        }

        if (IsReady)
        {
            if (ProcessFolder != processFolder || ProcessName != processName)
            {
                Print($"New engine is loaded : {ProcessFolder}\\{ProcessName} -> {processFolder}\\{processName}", AI.MessageType.Info);
                Process.CloseMainWindow();
                Process.Dispose();
            }
            else
            {
                // Тот же самый движок - можно ничего не менять
                return;
            }
        }
        else
        {
            Print($"Engine loading : {path}", AI.MessageType.Info);
        }

        ProcessFolder = processFolder;
        ProcessName   = processName;

        IsReady = true;
        HasMove = false;
        Asks.Clear();
        CurrentAnswer = null;
        Message       = null;
        Move          = null;
        Thinking      = ThinkingMode.None;

        try
        {
            ProcessStartInfo info = new ProcessStartInfo(path)
            {
                UseShellExecute        = false,
                WorkingDirectory       = ProcessFolder,
                CreateNoWindow         = true,
                RedirectStandardInput  = true,
                RedirectStandardOutput = true
            };
            Process = Process.Start(info);
            Writer  = Task.Factory.StartNew(() =>
            {
                while (!Process.HasExited)
                {
                    if (CurrentAnswer == null)
                    {
                        if (Asks.Count > 0)
                        {
                            var t = Asks.Dequeue();

                            Process.StandardInput.WriteLine(t.Ask);
                            Process.StandardInput.Flush();

                            if (t.Answer != null)
                            {
                                CurrentAnswer = t.Answer;
                            }
                            else
                            {
                                CurrentAnswer = null;
                            }
                        }
                    }
                }
            });

            Reader = Task.Factory.StartNew(() =>
            {
                while (!Process.HasExited)
                {
                    if (!string.IsNullOrEmpty(CurrentAnswer))
                    {
                        var symbol = Process.StandardOutput.Peek();

                        if (symbol != '\0')
                        {
                            var str = Process.StandardOutput.ReadLine();

                            if (string.IsNullOrEmpty(str))
                            {
                                continue;
                            }

                            if (PrintAll)
                            {
                                if (str != "readyok")
                                {
                                    Print(str, AI.MessageType.Output);
                                }
                            }

                            if (str.Length >= CurrentAnswer.Length)
                            {
                                if (str.Substring(0, CurrentAnswer.Length) == CurrentAnswer)
                                {
                                    if (!PrintAll)
                                    {
                                        if (str != "readyok")
                                        {
                                            Print(str, AI.MessageType.Output);
                                        }
                                    }

                                    if (CurrentAnswer == "bestmove")
                                    {
                                        Move    = str.Substring(9);
                                        HasMove = true;
                                    }
                                    else if (CurrentAnswer == "readyok")
                                    {
                                        switch (IsReadyAnswer)
                                        {
                                        case ReadyAnswer.OK:
                                            Print(str, AI.MessageType.Output);
                                            break;

                                        case ReadyAnswer.Position:
                                            if (Message != null)
                                            {
                                                string engineLine;
                                                if (moveCount == 0)
                                                {
                                                    engineLine = $"position {StartPos}";
                                                }
                                                else
                                                {
                                                    engineLine = $"position {StartPos} moves " + Message;
                                                    Message    = null;
                                                }
                                                Send(engineLine);

                                                if (Thinking != ThinkingMode.None)
                                                {
                                                    Print(engineLine, AI.MessageType.Input);
                                                    Go();
                                                }
                                            }
                                            break;

                                        case ReadyAnswer.Go:

                                            break;

                                        case ReadyAnswer.Move:
                                            break;
                                        }
                                    }
                                    IsReadyAnswer = ReadyAnswer.None;
                                    CurrentAnswer = null;
                                }
                            }
                        }
                    }
                }
            });

            Send("usi");
            ReadUSI();
        }
        catch (Exception ex)
        {
            Print($"ERROR: Exception throwed: {ex.ToString()}", AI.MessageType.Info);
        }

        Send("isready", "readyok");
    }
コード例 #2
0
ファイル: UCIEngine.cs プロジェクト: Chaosus/ModernShogi
 public static void SendWhenOK(ReadyAnswer what)
 {
     IsReadyAnswer = what;
     Send("isready", "readyok");
 }