TProcess — перехват результатов нескольких команд Process.Input.Write (…)

Я хочу, чтобы шахматный движок анализировал некоторые игры в формате pgn.

До сих пор у меня есть.

begin
// ...
P:=TProcess.Create(nil);
stL:=TStringList.create;
P.Commandline:='Houdini'; // <- this is chess engine, Houdini.exe
P.Options:=P.Options+[poUsePipes];
P.ShowWindow:=swoHide;
P.Execute;

st:='uci'+ Lineending;
P.Input.Write(st[1], Length(st));
// st:=P.Output.ReadAnsiString;    <- this is my try
// showmessage(st);
st:='setoption name multipv value 3'+lineending;
P.Input.Write(st[1], Length(st)); // so after second command how to catch different output
st:='isready'+lineending;
P.Input.Write(st[1], Length(st));
st:='ucinewgame'+lineending;
P.Input.Write(st[1], Length(st));
st:='isready'+lineending;
P.Input.Write(st[1], Length(st));

// another part of code should be here ***

st:='quit'+lineending;
P.Input.Write(st[1], Length(st)); // quiting the engine
stL.LoadFromStream(P.Output);
stL.SaveToFile('AjDaVidime.txt');  // nothing stores particular

P.Free;
stL.Free;
end;

Так что вопрос в том, как получить выходную мощность от двигателя после каждого P.Input.Write …

Далее следует другая часть кода (это странное поведение stackoverflow для публикации моего вопроса.
Этот код должен быть первым в *

// This for loop is main loop for analyzing chess game
for i:=1 to moves do begin
st:='position fen '+arrayFen[i]+lineending;
P.Input.Write(st[1], Length(st));
st:='go movetime 1000'+lineending;  // Fen is position 1000ms is 1sec, so engine Must analyze 1 sec. that position, so go movetime 1000 is command.
P.Input.Write(st[1], Length(st));
Sleep(1000); // <- is this neccessary?
end;

0

Решение

Afaik не возможно ждать выхода с TProcess кроссплатформенным способом. Чтение канала может блокироваться до тех пор, пока не будут получены указанные байты.

Вероятно, это можно обойти, используя (baseunix.fp) select или (windows.) Waitforsingleobject на дескрипторе потока (который является дескриптором ОС).

Я не знаю ни одного кода, который делает это, но я думаю, что код отладчика в Lazarus является наиболее сложным TProcess с использованием кода (вызывающего GDB), поэтому я предлагаю рассмотреть это.

1

Другие решения

Других решений пока нет …