/// <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"); }
public static void SendWhenOK(ReadyAnswer what) { IsReadyAnswer = what; Send("isready", "readyok"); }