I am developing a program for analyzing chess problems - especially endgame problems - using the .exe version of the open-source chess-engine Stockfish 9.
Here is the (very simplified) EndgameAnalyzer
class:
class EndgameAnalyzer
{
private StockfishOracle oracle = new StockfishOracle();
public void AnalyzeByFEN(string fen)
{
var evaluation = oracle.GetEvaluation(fen);
Console.WriteLine($"{fen}\t{evaluation}");
}
}
The AnalyzeByFEN
method receives a FEN (a string representing a chess position) and writes down the engine evaluation for this position.
StockfishOracle
is the class which is used to communicate with the engine (like oracles are used to communicate with the gods :)), using the UCI protocol. The relevant UCI commands for this question are:
uci
: Enter uci mode.
position fen //followed by a FEN
: Set a position to analyze.
go depth 1
: Analyze the position one ply ("move") deep.
And here is the (again, very simplified) StockfishOracle
class:
class StockfishOracle
{
private Process process = new Process();
public StockfishOracle()
{
process.StartInfo = new ProcessStartInfo()
{
FileName = @"C:\stockfish_9_x64.exe",
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true
};
process.Start();
SendUCICommand("uci");
}
public string GetEvaluation(string fen)
{
SendUCICommand($"position fen {fen}");
SendUCICommand("go depth 1");
string result = string.Empty;
while (!process.StandardOutput.EndOfStream)
{
result = process.StandardOutput.ReadLine();
}
return result;
}
private void SendUCICommand(string command)
{
process.StandardInput.WriteLine(command);
process.StandardInput.Flush();
}
}
When calling the AnalyzeByFEN
method with a FEN, no output is shown in the console. A careful investigation led to the observation that the loop while (!process.StandardOutput.EndOfStream)
is going forever, so the output is never returned. I am pretty new to processes, so I am pretty sure there are some basic mistakes in my code. How to fix this?
Thanks!
Well, this appeared a nice riddle for me. Let's consider another approach and try to communicate with the chess oracle asynchronously:
As far as i understood you are looking for the prediction of the best move. Now you can wait until it appear in the output. Also using the same event handler you can analyze every string the oracle writes into output until you see desired one.