与控制台应用程序通信

时间:2014-02-17 15:18:28

标签: go

我是初学者。我试图通过go exec包与一个国际象棋引擎进行通信,但它需要我关闭标准输入。我想做的是与引擎建立对话。

我怎么用go去做?

这是沟通的python实现,非常简单,可以在How to Communicate with a Chess engine in Python?

找到
    import subprocess, time

    engine = subprocess.Popen(
    'stockfish-x64.exe',
    universal_newlines=True,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    )

    def put(command):
    print('\nyou:\n\t'+command)
    engine.stdin.write(command+'\n')

    def get():
    # using the 'isready' command (engine has to answer 'readyok')
    # to indicate current last line of stdout
    engine.stdin.write('isready\n')
    print('\nengine:')
    while True:
        text = engine.stdout.readline().strip()
        if text == 'readyok':
            break
        if text !='':
            print('\t'+text)

    get()
    put('uci')
    get()

put('setoption name Hash value 128')
get()
put('ucinewgame')
get()
put('position startpos moves e2e4 e7e5 f2f4')
get()
put('go infinite')
time.sleep(3)
get()
put('stop')
get()
put('quit')

为简单起见,请考虑一下:

package main

import ( 
    "bytes"
    "fmt"
    "io"
    "os/exec"
)

func main() {
    cmd := exec.Command("stockfish")
    stdin, _ := cmd.StdinPipe()
    io.Copy(stdin, bytes.NewBufferString("isready\n"))
    var out bytes.Buffer
    cmd.Stdout = &out
    cmd.Run()
    fmt.Printf(out.String())
}

程序在不打印任何内容的情况下等待。但是当我关闭stdin时程序打印结果,但关闭stdin会阻碍引擎和程序之间的通信。

解决方案:

package main

    import ( 
        "bytes"
        "fmt"
        "io"
        "os/exec"
        "time"
    )

    func main() {
        cmd := exec.Command("stockfish")
        stdin, _ := cmd.StdinPipe()
        io.Copy(stdin, bytes.NewBufferString("isready\n"))
        var out bytes.Buffer
        cmd.Stdout = &out
        cmd.Start()
        time.Sleep(1000 * time.Millisecond)
        fmt.Printf(out.String())
    }

1 个答案:

答案 0 :(得分:2)

您仍然可以使用exec.Command,然后使用Cmd方法cmd.StdinPipe()cmd.StdoutPipe()cmd.Start()

来执行此操作

exec.Cmd.StdoutPipe文档中的示例应该可以帮助您入门:http://golang.org/pkg/os/exec/#Cmd.StdoutPipe

但是在你的情况下,你将在循环中从管道进行读写。我想你的架构在goroutine中看起来像这个循环,通过通道传递其他代码的命令。