official-pikafish / Pikafish

UCI xiangqi engine
http://pikafish.org
GNU General Public License v3.0
867 stars 162 forks source link

使用python subprocess调用pikafish.exe文件无法工作 #48

Closed DimariaW closed 12 months ago

DimariaW commented 1 year ago

Describe the issue

本人在使用python 开发一个象棋游戏, 有需求调用 皮卡鱼提供AI支持, 目前打算采用subprocess直接调用exe文件,但是不work

python 代码如下:

import subprocess

p = subprocess.Popen("pikafish-bmi2.exe", stdin=subprocess.PIPE, stdout=subprocess.PIPE)

cmd = "uci\nisready\nposition startpos\ngo movetime 1000\n"

out, errs = p.communicate(cmd.encode())

print(out.decode("utf-8"))`

程序输出如下:

Pikafish dev 2023-03-05 by the Pikafish developers (see AUTHORS file)
id name Pikafish dev 2023-03-05
id author the Pikafish developers (see AUTHORS file)

option name Debug Log File type string default 
option name Threads type spin default 1 min 1 max 1024
option name Hash type spin default 16 min 1 max 33554432
option name Clear Hash type button
option name Ponder type check default false
option name MultiPV type spin default 1 min 1 max 500
option name Skill Level type spin default 20 min 0 max 20
option name Move Overhead type spin default 10 min 0 max 5000
option name Slow Mover type spin default 100 min 10 max 1000
option name nodestime type spin default 0 min 0 max 10000
option name Sixty Move Rule type check default true
option name Mate Threat Depth type spin default 1 min 0 max 10
option name Repetition Fold type combo default RootThreeFold var TwoFold var RootThreeFold var ThreeFold
option name Repetition Rule type combo default AsianRule var AsianRule var ChineseRule
option name UCI_LimitStrength type check default false
option name UCI_Elo type spin default 1350 min 1350 max 2850
option name UCI_WDLCentipawn type check default true
option name UCI_ShowWDL type check default false
option name EvalFile type string default pikafish.nnue
uciok
readyok
info string NNUE evaluation using pikafish.nnue enabled
bestmove a0a1

看上去皮卡鱼没有搜索就直接返回了, 有解决办法吗?

Expected behavior

import subprocess

p = subprocess.Popen("pikafish-bmi2.exe", stdin=subprocess.PIPE, stdout=subprocess.PIPE)
cmd = "uci\nisready\nposition startpos\ngo movetime 1000\n"
out, errs = p.communicate(cmd.encode())

print(out.decode("utf-8"))

Steps to reproduce

Pikafish dev 2023-03-05 by the Pikafish developers (see AUTHORS file)
id name Pikafish dev 2023-03-05
id author the Pikafish developers (see AUTHORS file)

option name Debug Log File type string default 
option name Threads type spin default 1 min 1 max 1024
option name Hash type spin default 16 min 1 max 33554432
option name Clear Hash type button
option name Ponder type check default false
option name MultiPV type spin default 1 min 1 max 500
option name Skill Level type spin default 20 min 0 max 20
option name Move Overhead type spin default 10 min 0 max 5000
option name Slow Mover type spin default 100 min 10 max 1000
option name nodestime type spin default 0 min 0 max 10000
option name Sixty Move Rule type check default true
option name Mate Threat Depth type spin default 1 min 0 max 10
option name Repetition Fold type combo default RootThreeFold var TwoFold var RootThreeFold var ThreeFold
option name Repetition Rule type combo default AsianRule var AsianRule var ChineseRule
option name UCI_LimitStrength type check default false
option name UCI_Elo type spin default 1350 min 1350 max 2850
option name UCI_WDLCentipawn type check default true
option name UCI_ShowWDL type check default false
option name EvalFile type string default pikafish.nnue
uciok
readyok
info string NNUE evaluation using pikafish.nnue enabled
bestmove a0a1

Anything else?

No response

Operating system

Windows

Pikafish version

Pikafish 2023-3-5

PikaCat-OuO commented 12 months ago

以下内容由OpenAI GPT4辅助编写:

你需要等待软件加载完成之后也就是接收到readyok后再发送position startpos和go movetime 1000之类的,下面是一个正确调用的案例:

import subprocess

# 启动子进程
p = subprocess.Popen("pikafish-bmi2.exe", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, bufsize=1, universal_newlines=True)

# 发送 "uci" 和 "isready" 指令
p.stdin.write("uci\n")
p.stdin.write("isready\n")
p.stdin.flush()

# 等待 "readyok" 响应
while True:
    output = p.stdout.readline().strip()
    print(f"Received: {output}")
    if "readyok" in output:
        break

# 发送其他指令
p.stdin.write("position startpos\n")
p.stdin.write("go movetime 1000\n")
p.stdin.flush()

# 读取输出
while True:
    output = p.stdout.readline().strip()
    print(f"Received: {output}")
    if "bestmove" in output:  # 替换为实际的结束条件
        break

# 关闭子进程
p.terminate()

你想要的效果(即发送isready指令并等待readyok响应,然后再发送其他指令),你可以使用stdin.write()和stdout.readline()方法来分步与子进程进行交互。 注意:

  1. 我使用了text=True和universal_newlines=True选项,这样就可以直接使用字符串进行读写,而不需要进行编码和解码。
  2. 使用bufsize=1来设置行缓冲,这样stdout.readline()就可以每次读取一行。
  3. 请替换"bestmove"为实际的结束条件。 这样,你就可以实现发送isready后等待readyok响应,然后再发送其他指令的效果了。希望这能帮助你!

以下是输出案例:

Received: Pikafish dev-20230907-e9a2871e by the Pikafish developers (see AUTHORS file)
Received: id name Pikafish dev-20230907-e9a2871e
Received: id author the Pikafish developers (see AUTHORS file)
Received:
Received: option name Debug Log File type string default
Received: option name Threads type spin default 1 min 1 max 1024
Received: option name Hash type spin default 16 min 1 max 33554432
Received: option name Clear Hash type button
Received: option name Ponder type check default false
Received: option name MultiPV type spin default 1 min 1 max 500
Received: option name Move Overhead type spin default 10 min 0 max 5000
Received: option name Slow Mover type spin default 100 min 10 max 1000
Received: option name nodestime type spin default 0 min 0 max 10000
Received: option name Mate Threat Depth type spin default 1 min 0 max 10
Received: option name Repetition Rule type combo default AsianRule var AsianRule var ChineseRule
Received: option name UCI_ShowWDL type check default false
Received: option name EvalFile type string default pikafish.nnue
Received: uciok
Received: readyok
Received: info string NNUE evaluation using pikafish.nnue enabled
Received: info depth 1 seldepth 1 multipv 1 score cp -13 nodes 89 nps 89000 hashfull 0 tbhits 0 time 1 pv b2e2
Received: info depth 2 seldepth 2 multipv 1 score cp 0 nodes 162 nps 162000 hashfull 0 tbhits 0 time 1 pv f0e1
Received: info depth 3 seldepth 2 multipv 1 score cp 0 nodes 210 nps 210000 hashfull 0 tbhits 0 time 1 pv f0e1
Received: info depth 4 seldepth 2 multipv 1 score cp 16 nodes 263 nps 263000 hashfull 0 tbhits 0 time 1 pv f0e1
Received: info depth 5 seldepth 3 multipv 1 score cp 53 nodes 425 nps 425000 hashfull 0 tbhits 0 time 1 pv b2e2
Received: info depth 6 seldepth 4 multipv 1 score cp 31 nodes 1060 nps 1060000 hashfull 0 tbhits 0 time 1 pv h2e2 h9g7 h0g2
Received: info depth 7 seldepth 5 multipv 1 score cp 29 nodes 1819 nps 909500 hashfull 0 tbhits 0 time 2 pv h2e2 b9c7 h0g2 h9g7
Received: info depth 8 seldepth 5 multipv 1 score cp 34 nodes 2200 nps 1100000 hashfull 0 tbhits 0 time 2 pv b2e2 b9c7 b0c2
Received: info depth 9 seldepth 6 multipv 1 score cp 44 nodes 2721 nps 1360500 hashfull 0 tbhits 0 time 2 pv b2e2 b9c7 b0c2
Received: info depth 10 seldepth 8 multipv 1 score cp 41 nodes 4038 nps 1346000 hashfull 0 tbhits 0 time 3 pv h2e2 h7e7 h0g2
Received: info depth 11 seldepth 12 multipv 1 score cp 39 nodes 12411 nps 2068500 hashfull 5 tbhits 0 time 6 pv b2e2 h7e7 h0g2 h9g7 i0h0 b7d7 h2i2
Received: info depth 12 seldepth 16 multipv 1 score cp 36 nodes 41143 nps 2057150 hashfull 19 tbhits 0 time 20 pv b2e2 b9c7 c3c4 h7e7 h0g2 h9g7 i0h0 i9h9 h2h6 g6g5 b0c2 a9b9 a0b0 b7b3
Received: info depth 13 seldepth 19 multipv 1 score cp 38 nodes 57762 nps 2062928 hashfull 26 tbhits 0 time 28 pv h2e2 h9g7 h0g2 g6g5 i0h0 i9h9 h0h6 b9c7 c3c4 h7i7 h6g6 h9h7 b0c2
Received: info depth 14 seldepth 18 multipv 1 score cp 36 nodes 83099 nps 1978547 hashfull 40 tbhits 0 time 42 pv h2e2 h9g7 h0g2 g6g5 i0h0 i9h9 h0h4 b9c7 b0c2 b7a7 a0b0
Received: info depth 15 seldepth 17 multipv 1 score cp 38 nodes 112851 nps 2015196 hashfull 55 tbhits 0 time 56 pv h2e2 h9g7 h0g2 g6g5 i0h0 i9h9 h0h6 c6c5 b0a2 b9c7 h6g6
Received: info depth 16 seldepth 18 multipv 1 score cp 33 nodes 213296 nps 2012226 hashfull 98 tbhits 0 time 106 pv b2e2 b9c7 b0c2 a9b9 a0b0 c6c5 b0b4 h9g7 h0g2 g6g5 e3e4 b7a7 b4b9 c7b9 i0i1
Received: info depth 17 seldepth 18 multipv 1 score cp 39 nodes 254325 nps 2018452 hashfull 114 tbhits 0 time 126 pv b2e2 b9c7 b0c2 a9b9 a0b0 c6c5 b0b6 h9g7 e3e4 b7b8
Received: info depth 18 seldepth 23 multipv 1 score cp 34 nodes 548277 nps 1944244 hashfull 246 tbhits 0 time 282 pv h2e2 h9g7 h0g2 i9h9 i0h0 c6c5 g3g4 b9c7 b2c2 c7b5 g2f4 c9e7 h0h6 b5c3 b0a2
Received: info depth 19 seldepth 23 multipv 1 score cp 37 nodes 669548 nps 1918475 hashfull 296 tbhits 0 time 349 pv h2e2 h9g7 h0g2 i9h9 i0h0 g6g5 h0h6 b9c7 c3c4 a9a8 e3e4 a8d8 e4e5 h7h8
Received: info depth 20 seldepth 26 multipv 1 score cp 30 nodes 1067979 nps 1924286 hashfull 462 tbhits 0 time 555 pv h2e2 h9g7 h0g2 i9h9 i0h0 g6g5 h0h6 c6c5 b0a2 b9c7 b2d2 b7b6 h6h4 h7i7 h4h9 g7h9 a0b0 a9b9 b0b4 d9e8 b4h4 h9g7 g3g4
Received: info depth 21 seldepth 31 multipv 1 score cp 27 upperbound nodes 1917977 nps 1916060 hashfull 708 tbhits 0 time 1001 pv h2e2 h9g7
Received: bestmove h2e2 ponder h9g7
DimariaW commented 12 months ago

解决问题