0

我正在实现一个 C++ 程序,它将与一个与 UCI 兼容的国际象棋引擎进行通信。我的程序将打开国际象棋引擎并将其作为子进程运行,然后使用流和管道与其通信。我需要这样做,以便我可以获得引擎生成的所有合法动作。这样我就可以将它与我自己的引擎的移动生成器进行比较,看看它是否准确。

我以前写过与子进程通信的程序,它们工作得很好。我使用了 boost-process 并将 std_in 和 std_out 与 ipstream 和 opstream 一起路由。但是对于 LC0 国际象棋引擎,每当我尝试读取它的 std_out 数据时,我的程序都会挂起并且不会在启动时打印 LC0 输出的内容。对于其他命令行应用程序,我的代码工作得很好。它与 LC0 一起工作的唯一时间是当我不重新路由引擎 std_in 和 std_out 时,或者当我将 --help 选项传递给 lc0.exe 时,在这种情况下,程序会打印帮助消息并关闭。我想知道当 lc0.exe 的 std_out 被重新路由到管道时,它的行为是否不同。

这是我的代码的简化示例。

#include <iostream>
#include <string>

#include <boost/process.hpp>
#include <boost/filesystem.hpp>

using namespace std;

int main()
{
    boost::filesystem::path lc0Path{ R"dil(C:\Program Files\lc0\lc0.exe)dil" };
    
    cout << "Opening: " << lc0Path << "...";
    
    boost::process::ipstream is;
    boost::process::opstream os;
    boost::process::child lc0(lc0Path, /*"--help",*/ boost::process::std_out > is,  boost::process::std_in < os);   // Uncommenting help option produces some output
    // Uncommenting help option produces some output
    // when std_out and std_in are not rerouted, the output from LC0 shows up just fine.

    cout << "done" << endl;

    os << "uci";    // Tell LC0 to switch to UCI mode

    string line;
    while (lc0.running())
    {
        getline(is, line);                  // Hangs on getline

        cout << "line: " << line << endl;
    }
    
    cout << "Press any key...";
    cin.get();
    return 0;
}

我的代码应该是什么样子,以便它将 std_out 数据从 LC0 读取到字符串中而不会挂起。

我正在编译:操作系统:Windows 10 IDE:VS2019 Boost:1.76 版

4

0 回答 0