php proc_open()和Stockfish国际象棋引擎异常深度1

时间:2019-10-20 21:31:10

标签: php shell chess proc-open

期待将stockfish chess engine集成到php-cli脚本中。

有一个意外行为,stockfish程序直接退出而没有“思考”,当从php调用时,它仅返回深度1的位置。

为了更好地理解,从命令行运行stockfish程序时,这是预期的行为(gif):

enter image description here


从php 开始,以下代码正在工作(开始位置,白人玩,要求50深度),它返回移动 a2a3 ,位于深度1的位置,这是一个非常糟糕的举动!

答案是瞬时的,要经过所有深度级别至少要花费几秒钟。

它与任何FEN positions相同,总是返回深度1。

$descr = array(
    0 => array("pipe", "r"),
    1 => array("pipe", "w"),
    2 => array("pipe", "w")
);
$pipes = array();
$process = proc_open("stockfish", $descr, $pipes);
if (is_resource($process)) {
    fwrite($pipes[0], "uci\n");
    fwrite($pipes[0], "ucinewgame\n");
    fwrite($pipes[0], "position fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - - 0 1\n");    
    fwrite($pipes[0], "go depth 50\n");
    fclose($pipes[0]);    
    // Read all output from the pipe
    while (!feof($pipes[1])) {    
        echo fgets($pipes[1]);
    }
    fclose($pipes[1]);
    proc_close($process);

}
// RETURN last line:  bestmove a2a3

stockfish的所有版本均已测试8、9、10,结果相同。

我尝试了许多选项和不同方式来从php运行shell命令,包括posix_mkfifo()管道,但没有一个按预期工作,总是返回深度为1的移动。

另一个示例,相同的行为,始终返回“ a2a3”。

  file_put_contents(".COMFISH","uci\nucinewgame\nsetoption name Threads value 1\nposition fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - - 0 1\ngo depth 50");
  $COM = explode(" ",system("stockfish < .COMFISH"))[1];
  var_dump($COM);
  // RETURN a2a3

这可能与如何编写stockfish二进制文件(多线程)而不是php行为直接相关,但是我在这里寻找解释?

来自wiki

  

在多处理器系统中,Stockfish最多可以使用512个CPU线程。

1 个答案:

答案 0 :(得分:1)

嗯,这很简单,管道关闭得太早了。

将工作代码留给以后的读者。

$descr = [0 => ["pipe", "r"], 1 => ["pipe", "w"]];
$pipes = [];
$process = proc_open("stockfish", $descr, $pipes);
if (is_resource($process)) {
    fwrite($pipes[0], "uci\n");
    fwrite($pipes[0], "ucinewgame\n");
    fwrite($pipes[0], "position fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - - 0 1\n");    
    fwrite($pipes[0], "setoption name Skill Level value 17\n"); // Set level between 1 and 20
    fwrite($pipes[0], "go movetime 5000\n"); // Return bestmove after 5 seconds          
    while (!feof($pipes[1])) {    
        echo fgets($pipes[1]);
    }
    fclose($pipes[0]);
    fclose($pipes[1]);
    proc_close($process);    
}
// RETURN last line: bestmove e2e4 ponder e7e6
相关问题