2014-02-17 156 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

相關問題