使用c++与Stockfish shell接口

Interfacing with Stockfish shell using C++

本文关键字:shell 接口 Stockfish c++ 使用      更新时间:2023-10-16

我正试图通过命令行编写与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发送和接收文本?

while循环只有在检测到管道上的EOF时才会结束,直到打开的命令终止才会结束。等待输入的事实基本上是无法检测到的。

由于popen只重定向了标准输出,因此打开的stockfish与您的程序共享标准输出。当你开始stockfish时,它会尝试读取输入。如果你不输入什么,什么也不会发生。

所以你应该尝试向stockfish发送你想让它执行的命令,以"quit"命令结束。

Popen只允许您发送接收数据,具体取决于模式操作数。两者不可兼得。你可以用通常的forkexec技术,或者你可以打开像stockfish < sfcmds.txt这样的东西。