2014-02-17 3 views
4

초보자입니다. 나는 이동의 exec 꾸러미로 체스 엔진과 통신하려했지만, 표준 입력을 닫아야합니다. 제가하고 싶은 것은 엔진과 대화를하는 것입니다.콘솔 앱과 통신하기

이동을 어떻게해야합니까?

가 똑바로 앞으로 꽤 많이있는 의사 소통의 파이썬 구현, 단순 들어 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()) 
} 

을이 프로그램은 인쇄하지 않고 대기하는 아무것도. 그러나 표준을 닫으면 프로그램이 결과를 인쇄하지만 표준을 닫으면 엔진과 프로그램 간 통신이 방해 받게됩니다.

솔루션 :

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

당신은 여전히 ​​Cmd를 방법 cmd.StdinPipe(), cmd.StdoutPipe()으로 다음 exec.Command이 작업을 수행하고 할 수 있어야하고, exec.Cmd에 대한 문서에서 cmd.Start()

예제해야한다. StdoutPipe가 당신을 시작할 수 있어야합니다 : http://golang.org/pkg/os/exec/#Cmd.StdoutPipe

하지만 당신의 경우에는 루프에서 파이프로부터 읽기와 쓰기를 할 것입니다. 나는 당신의 아키텍처가 채널을 통해 나머지 코드를 이리저리 넘기는 goroutine에서이 루프처럼 보일 것이라고 생각합니다.

+0

예 exec를 사용하여 외부 앱을 호출 할 수 있지만 통신을 차단하는 stdin을 닫아야합니다. – addy

+0

'cmd.Run()'을 사용하지 말고'cmd.Start()'를 사용하십시오. 'Run' 블록을 실행하고 명령이 완료되기를 기다립니다. 'Start'는 프로그램이 계속 실행되는 동안 stdin/stdout과 대화 할 수있게합니다. – pauljz

+0

트릭을 시작했습니다! – addy

관련 문제