使用C++与Stockfish shell进行接口交互

4
我正在尝试编写一个程序,通过命令行与Stockfish国际象棋引擎交互。我已经研究了使用管道和重定向cin/cout的方法,但问题在于Stockfish运行其自己的shell而不是只输出单行结果,例如:
~$ stockfish 
Stockfish 261014 64 by Tord Romstad, Marco Costalba and Joona Kiiski
> go movetime 5000
[output]
...
> quit
~$

我试了下面的代码(来自这里)以执行命令并读取它们的输出,但当我尝试运行Stockfish并打印输出时,它从未结束:
#include <string>
#include <iostream>
#include <stdio.h>

std::string exec(char* cmd) {
    FILE* pipe = popen(cmd, "r");
    if (!pipe) return "ERROR";
    char buffer[128];
    std::string result = "";
    while(!feof(pipe)) {
        if(fgets(buffer, 128, pipe) != NULL)
            result += buffer;
    }
    pclose(pipe);
    return result;
}

int main(void)
{
    std::cout << exec("ls") << std::endl; // this works fine
    std::cout << exec("stockfish") << std::endl; // this never ends

    return 0;
}

我想问的是,为什么这个方法不起作用,以及如何编写一个程序来发送和接收Stockfish shell中的文本?


你没有在任何地方编写UCI命令,所以Stockfish正在等待它们。 - interjay
1个回答

1
你的 while 循环只有在检测到管道上的 EOF 后才会结束,而这只会在 popen 的命令终止后发生。它等待输入的事实基本上是不可检测的。
由于 popen 只重定向了 stdout,popen 的 stockfish 与你的程序共享 stdin。当你启动 stockfish 时,它会尝试读取输入。如果你没有输入任何内容,就什么也不会发生。
所以你应该尝试发送你想让 stockfish 执行的命令,最后以 "quit" 命令结束。
Popen 只允许你发送或接收数据,取决于模式操作数。你永远无法同时执行两者。你可以做常规的 fork 和 exec 技术,或者你可以 popen 一些像 stockfish < sfcmds.txt 这样的东西。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接