我正在使用 io 包來處理我的 PATH 中定義的可執行檔案。可執行檔案稱為“Stockfish”(國際象棋引擎),顯然可以通過命令列工具使用。
為了讓引擎搜索最佳移動,您使用“go depth n”——深度越高——搜索所需的時間越長。使用我的命令列工具,它使用 20 的深度搜索大約 5 秒,它看起來像這樣:
go depth 20
info string NNUE evaluation using nn-3475407dc199.nnue enabled
info depth 1 seldepth 1 multipv 1 score cp -161 nodes 26 nps 3714 tbhits 0 time 7 pv e7e6
info depth 2 seldepth 2 multipv 1 score cp -161 nodes 51 nps 6375 tbhits 0 time 8 pv e7e6 f1d3
info depth 3 seldepth 3 multipv 1 score cp -161 nodes 79 nps 7900 tbhits 0 time 10 pv e7e6 f1d3 g8f6
info depth 4 seldepth 4 multipv 1 score cp -161 nodes 113 nps 9416 tbhits 0 time 12 pv e7e6 f1d3 g8f6 b1c3
[...]
bestmove e7e6 ponder h2h4
現在,使用 io.WriteString 它在沒有任何(可見)計算的情況下在幾毫秒后完成:(這也是下面代碼的輸出)
Stockfish 14 by the Stockfish developers (see AUTHORS file)
info string NNUE evaluation using nn-3475407dc199.nnue enabled
bestmove b6b5
這是我使用的代碼:
func useStockfish(commands []string) string {
cmd := exec.Command("stockfish")
stdin, err := cmd.StdinPipe()
if err != nil {
log.Fatal(err)
}
for _, cmd := range commands {
writeString(cmd, stdin)
}
err = stdin.Close()
if err != nil {
log.Fatal(err)
}
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatal(err)
}
return string(out)
}
func writeString(cmd string, stdin io.WriteCloser) {
_, err := io.WriteString(stdin, cmd)
if err != nil {
log.Fatal(err)
}
這是我如何使用它的一個例子。第一個命令是設定位置,第二個命令是計算下一個最好的移動,深度為 20。結果如上所示。
func FetchComputerMove(game *internal.Game) {
useStockfish([]string{"position exmaplepos\n", "go depth 20"})
}
uj5u.com熱心網友回復:
要利用諸如stockfish- 您需要啟動該程序并保持其運行之類的引擎。
您正在執行它,通過 Stdin 管道傳遞 2 個命令,然后關閉管道。關閉管道向程式表明您不再對引擎所說的內容感興趣。
要運行它 - 并保持運行 - 您需要類似的東西:
func startEngine(enginePath string) (stdin io.WriteCloser, stdout io.ReadCloser, err error) {
cmd := exec.Command(enginePath )
stdin, err = cmd.StdinPipe()
if err != nil {
return
}
stdout, err = cmd.StdoutPipe()
if err != nil {
return
}
err = cmd.Start() // start command - but don't wait for it to complete
return
}
回傳的管道允許您發送命令并實時查看輸出:
stdin, stdout, err := startEngine("/usr/local/bin/stockfish")
sendCmd := func(cmd string) error {
_, err := stdin.Write([]byte(cmd "\n"))
return err
}
sendCmd("position examplepos")
sendCmd("go depth 20")
然后粗略地讀取異步回應:
b := make([]byte, 10240)
for {
n, err := stdout.Read(b)
if err != nil {
log.Fatalf("read error: %v", err)
}
log.Println(string(b[:n]))
}
一旦bestmove d2d4 ponder g8f6出現類似的行,您就知道當前的分析命令已完成。
然后,您可以關閉引擎(通過關閉stdin管道),如果這就是您所需要的,或者保持打開狀態以供進一步的命令提交。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/334891.html
