【问题标题】:Php proc_open() and stockfish chess engine anomaly depth 1php proc_open() 和stockfish 国际象棋引擎异常深度1
【发布时间】:2019-10-20 21:31:10
【问题描述】:

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

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

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


从 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 线程。

【问题讨论】:

    标签: php shell chess proc-open


    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2015-10-27
      • 1970-01-01
      • 1970-01-01
      • 2015-05-02
      • 2021-12-28
      • 1970-01-01
      • 2022-01-11
      • 2022-01-05
      • 1970-01-01
      相关资源
      最近更新 更多