현재 GUI를 UCI 체스 엔진에 연결 중입니다. 이 목적을 위해 다음을 사용하여 엔진 프로세스를 만듭니다.스트림을 닫지 않으면 exe와 통신 한 후 Java println이 차단됩니다.
try {
process = Runtime.getRuntime().exec(enginePath);
} catch (IOException e) {
System.err.println("ENGINE NOT FOUND");
e.printStackTrace();
}
그리고 나는 엔진을 열 수 있다고 확신합니다.
엔진을 열면 엔진에서 출력되는 중요한 스트림이 없습니다. 통신을 시작하려면 특정 명령을 엔진에 보내야합니다. 그러면 엔진이 응답 할 것입니다. 따라서 명령/응답 방식으로 작업하고 있습니다 (열었을 때 즉시 데이터를 스트리밍하거나 말하지 않고 말하지 않음). 의사 소통을 위해 메시지 블록을 보냅니다. 이 블록에서 자사의 OutputStream을 사용하여 엔진에 메시지를 작성하고 다음과 같은 전송 방법으로 자사의 standart 입력 스트림을 사용하여 입력을 얻을 :
private String sendCommand(String command) {
stdin = new PrintWriter(new OutputStreamWriter(process.getOutputStream()));
BufferedReader inputReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader errReader = new BufferedReader(newInputStreamReader(process.getErrorStream()));
String answer = "";
stdin.println(command);
stdin.flush();
stdin.close();
try {
String line = "";
while ((line = inputReader.readLine()) != null) {
System.out.println(line);
answer = line;
}
inputReader.close();
} catch (IOException ioe) {
System.err.println("READ ERROR");
ioe.printStackTrace();
}
try {
String line = "";
while ((line = errReader.readLine()) != null) {
System.err.println(line);
}
errReader.close();
} catch (IOException ioe) {
System.err.println("READ ERROR");
ioe.printStackTrace();
}
return answer;
}
전체 엔진이 아닌 하나의 별도의 스레드에서 작업하는 방식으로 메인 GUI 스레드. 따라서 GUI에 과부하가 걸리지 않습니다. 그러나 나는 stdin과 stdr을 개별 스레드에 개별적으로 작성하지 않았다. 당분간 나는 그들이 충돌하지 않을 것이라고 추정한다.
이러한 코드를 사용하면 엔진과 통신 할 수 있으며 콘솔의 출력을 볼 수 있습니다. 그러나 stdin.close(); 이 메서드는 한 번만 사용할 수 있습니다 (초 단위 시간에 스트림 닫힘 오류가 있음). 체스 엔진은 매번 exe를 다시 시작하지 않고도 명령/응답 방식으로 여러 번 열어야합니다. 문제는 내가 줄을 제거하면 : stdin.close(); 예, 통신은 계속되지만 내 통신은이 통신에 의해 차단됩니다. 나는. 더 이상 디버깅 목적으로 콘솔에 println 할 수 없습니다. 내 디버깅 무기가 system.out.println이므로 매우 중요합니다. stdin.close()를 제거하지 않으면; 나는 메시지를 보내고 싶지 때마다 실행 파일을 다시 시작해야하고 나는 그것을 원하지 않는다. ** 이상한 부분은 "System.out.println (line);"으로 인해 내 콘솔에서 엔진에서 오는 메시지를 볼 수 있다는 것입니다. send 메소드의 라인. 그러나 일단 코드가 메서드를 끝내면 콘솔에 아무것도 인쇄 할 수 없습니다. **
편집 :
while ((line = inputReader.readLine()) != null) {
System.out.println(line);
answer = line;
}
에서 System.out.println이 작동하지 않을 시작합니다 사실이 블록 후.
편집 : 문제는 println이 아닌 while 루프 이후의 명령문과 같습니다.
Why statements after while loop is not getting executed?
이에 따르면, 스트림이 닫혀하지 않기 때문에, "루프 동안"붙어 것 같다 (?). 사실 while 루프 내부에서 인쇄 할 때, 어떤 시점 (스트림이 끝난 후)에서 인쇄가 멈추고, 이는 루프가 끝났음을 나타내야 만합니다. 그러므로 그것이 끝나면, 그것은 다음 진술에서 계속되어야합니다, 그렇지 않아야합니까? 어쨌든, 엔진의 메시지에는 각 스트림의 끝 부분에 일련의 문자열이 있습니다. 그러므로 내가 그들 중 하나를 만날 때 나는 while 루프를 깨고있다.
참고 : 다음과 같이 데이터를 축적하는 것도 흥미 롭습니다. "receivedString + = line"; doesnot work, 즉 데이터가 누적되지 않습니다. 운 좋게 그것을 고치기 위해서 "receivedString = receivedString + line +"\ n ""; 그리고 그것은 효과가 있었다. 나는 왜 그런지 모른다.