2014-02-17 154 views
4

我是一名初学者。我曾尝试通过去往exec包与国际象棋引擎进行交流,但它要求我关闭标准输入。我想做的是与引擎建立对话。与控制台应用程序通信

我该怎么做呢?

这是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程序打印结果,但关闭标准输入阻止引擎和去程序之间的沟通。

解决办法:

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()) 
    } 
+0

你可以告诉我们不起作用的代码吗? – nemo

+0

@nemo更新了代码 – addy

回答

2

您应该仍然能够与exec.Command做到这一点,然后用Cmd的方法cmd.StdinPipe()cmd.StdoutPipe()cmd.Start()

在文档的exec.Cmd的例子。 StdoutPipe应该可以让你开始:http://golang.org/pkg/os/exec/#Cmd.StdoutPipe

但在你的情况下,你会在循环中读取和写入管道。我想你的架构在goroutine中看起来就像这个循环,通过通道传递命令到你的代码的其余部分。

+0

是的我可以使用exec调用外部应用程序,但它需要关闭阻止通信的stdin。 – addy

+0

不要使用'cmd.Run()',使用'cmd.Start()'。 '运行'阻止并等待命令完成。当程序继续运行时,'Start'可以让你与stdin/stdout进行交互。 – pauljz

+0

让它开始做的伎俩! – addy

相关问题