From d8e01b4e01a458fad7ef2e641855d045b1c30af1 Mon Sep 17 00:00:00 2001 From: gotty Date: Sat, 8 Dec 2018 01:50:54 +0300 Subject: [PATCH] [LIB-9] Replace engine sending commands via transmitter --- .../chess/hedgefish/HedgefishEngineRunner.java | 3 +- .../chess/hedgefish/HedgefishTransmitter.java | 5 ++ .../hedgecode/chess/uci/CommandEnvironment.java | 4 - .../org/hedgecode/chess/uci/ConsoleAcceptor.java | 21 +++-- .../hedgecode/chess/uci/ConsoleAcceptorRunner.java | 12 +-- .../org/hedgecode/chess/uci/ExternalEngine.java | 25 +++--- .../hedgecode/chess/uci/ExternalEngineRunner.java | 96 +++------------------- .../chess/uci/ExternalEngineTransmitter.java | 67 +++++++++++++++ .../java/org/hedgecode/chess/uci/Receiver.java | 36 -------- .../java/org/hedgecode/chess/uci/Transmitter.java | 2 + 10 files changed, 121 insertions(+), 150 deletions(-) create mode 100644 src/main/java/org/hedgecode/chess/uci/ExternalEngineTransmitter.java delete mode 100644 src/main/java/org/hedgecode/chess/uci/Receiver.java diff --git a/src/main/java/org/hedgecode/chess/hedgefish/HedgefishEngineRunner.java b/src/main/java/org/hedgecode/chess/hedgefish/HedgefishEngineRunner.java index 0eaedc6..a47b3a5 100644 --- a/src/main/java/org/hedgecode/chess/hedgefish/HedgefishEngineRunner.java +++ b/src/main/java/org/hedgecode/chess/hedgefish/HedgefishEngineRunner.java @@ -54,8 +54,8 @@ public final class HedgefishEngineRunner implements EngineRunner { Thread engineThread = new Thread( new Runnable() { public void run() { + Transmitter engineTransmitter = engine.transmitter(); try { - Transmitter engineTransmitter = engine.transmitter(); while (engineTransmitter.isActive()) { if (engineTransmitter.hasCommand()) { HedgefishCommand command = engineTransmitter.transmitCommand(); @@ -72,6 +72,7 @@ public final class HedgefishEngineRunner implements EngineRunner { CommandDirection.FROM_ENGINE, null ); + engineTransmitter.close(); isRunning = false; } } diff --git a/src/main/java/org/hedgecode/chess/hedgefish/HedgefishTransmitter.java b/src/main/java/org/hedgecode/chess/hedgefish/HedgefishTransmitter.java index a945b02..9bda062 100644 --- a/src/main/java/org/hedgecode/chess/hedgefish/HedgefishTransmitter.java +++ b/src/main/java/org/hedgecode/chess/hedgefish/HedgefishTransmitter.java @@ -62,4 +62,9 @@ public class HedgefishTransmitter implements Transmitter { isActive = false; } + @Override + public void close() { + queue.clear(); + } + } diff --git a/src/main/java/org/hedgecode/chess/uci/CommandEnvironment.java b/src/main/java/org/hedgecode/chess/uci/CommandEnvironment.java index 348a902..1cc5d5f 100644 --- a/src/main/java/org/hedgecode/chess/uci/CommandEnvironment.java +++ b/src/main/java/org/hedgecode/chess/uci/CommandEnvironment.java @@ -28,7 +28,6 @@ public final class CommandEnvironment { private static final String ENGINE_BIN_DIR = Paths.get("bin").toAbsolutePath().toString(); - public static void main(String... args) throws Exception { EngineRunner engineRunner = new ExternalEngineRunner( @@ -38,14 +37,11 @@ public final class CommandEnvironment { AcceptorRunner acceptorRunner = new ConsoleAcceptorRunner(); // new AcceptorStubRunner(); Acceptor acceptor = acceptorRunner.init(); - //AcceptorStub acceptor = new AcceptorStub(); CommandExecutor commandExecutor = SyncCommandExecutor.Factory.create(engine, acceptor); - //acceptor.init(commandExecutor); engineRunner.run(commandExecutor); acceptorRunner.run(commandExecutor); - //acceptor.start(); } } diff --git a/src/main/java/org/hedgecode/chess/uci/ConsoleAcceptor.java b/src/main/java/org/hedgecode/chess/uci/ConsoleAcceptor.java index 028cdaf..f9da8e9 100644 --- a/src/main/java/org/hedgecode/chess/uci/ConsoleAcceptor.java +++ b/src/main/java/org/hedgecode/chess/uci/ConsoleAcceptor.java @@ -32,12 +32,12 @@ import org.hedgecode.chess.uci.command.OptionType; */ public class ConsoleAcceptor implements Acceptor { - private class ConsoleReceiver implements Receiver { + private class ConsoleTransmitter implements Transmitter { private Scanner scanner; private boolean isActive; - ConsoleReceiver(InputStream input) { + ConsoleTransmitter(InputStream input) { scanner = new Scanner(input); isActive = true; } @@ -53,11 +53,16 @@ public class ConsoleAcceptor implements Acceptor { } @Override - public String receiveCommand() { + public String transmitCommand() { return scanner.nextLine(); } @Override + public void addCommand(String command) { + // not supported for console acceptor + } + + @Override public void stop() { isActive = false; } @@ -68,16 +73,16 @@ public class ConsoleAcceptor implements Acceptor { } } - private ConsoleReceiver receiver; + private ConsoleTransmitter transmitter; private PrintWriter writer; ConsoleAcceptor(InputStream input, OutputStream output) { - receiver = new ConsoleReceiver(input); + transmitter = new ConsoleTransmitter(input); writer = new PrintWriter(output, true); } - public Receiver receiver() { - return receiver; + public Transmitter transmitter() { + return transmitter; } @Override @@ -165,7 +170,7 @@ public class ConsoleAcceptor implements Acceptor { @Override public void terminate(String params) { - receiver.stop(); + transmitter.stop(); } private void console(String name, String params) { diff --git a/src/main/java/org/hedgecode/chess/uci/ConsoleAcceptorRunner.java b/src/main/java/org/hedgecode/chess/uci/ConsoleAcceptorRunner.java index d699eed..e5a448f 100644 --- a/src/main/java/org/hedgecode/chess/uci/ConsoleAcceptorRunner.java +++ b/src/main/java/org/hedgecode/chess/uci/ConsoleAcceptorRunner.java @@ -61,11 +61,11 @@ public class ConsoleAcceptorRunner implements AcceptorRunner { Thread engineThread = new Thread( new Runnable() { public void run() { - Receiver acceptorReceiver = acceptor.receiver(); + Transmitter acceptorTransmitter = acceptor.transmitter(); try { - while (acceptorReceiver.isActive()) { - if (acceptorReceiver.hasCommand()) { - String command = acceptorReceiver.receiveCommand(); + while (acceptorTransmitter.isActive()) { + if (acceptorTransmitter.hasCommand()) { + String command = acceptorTransmitter.transmitCommand(); if (command.isEmpty()) continue; CommandParams commandParams = new CommandParams(command); commandExecutor.exec( @@ -74,11 +74,11 @@ public class ConsoleAcceptorRunner implements AcceptorRunner { commandParams.getParams() ); if (UCIConstants.QUIT.equals(commandParams.getName())) - acceptorReceiver.stop(); + acceptorTransmitter.stop(); } } } finally { - acceptorReceiver.close(); + acceptorTransmitter.close(); isRunning = false; } } diff --git a/src/main/java/org/hedgecode/chess/uci/ExternalEngine.java b/src/main/java/org/hedgecode/chess/uci/ExternalEngine.java index 7b09fb5..fe4a8c9 100644 --- a/src/main/java/org/hedgecode/chess/uci/ExternalEngine.java +++ b/src/main/java/org/hedgecode/chess/uci/ExternalEngine.java @@ -16,8 +16,9 @@ package org.hedgecode.chess.uci; -import java.io.BufferedWriter; -import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintWriter; /** * External UCI Engine. @@ -27,21 +28,21 @@ import java.io.IOException; public class ExternalEngine implements Engine { private static final String COMMAND_FORMAT = "%s %s"; - private static final String CRLF = System.getProperty("line.separator"); - private BufferedWriter engineWriter; + private Transmitter transmitter; + private PrintWriter engineWriter; - ExternalEngine(BufferedWriter writer) { - engineWriter = writer; + ExternalEngine(InputStream input, OutputStream output) { + transmitter = new ExternalEngineTransmitter(input); + engineWriter = new PrintWriter(output, true); + } + + public Transmitter transmitter() { + return transmitter; } private void write(String command) { - try { - engineWriter.write(command); - engineWriter.write(CRLF); - engineWriter.flush(); - } catch (IOException ignored) { - } + engineWriter.println(command); } private String format(String name, String params) { diff --git a/src/main/java/org/hedgecode/chess/uci/ExternalEngineRunner.java b/src/main/java/org/hedgecode/chess/uci/ExternalEngineRunner.java index fd81352..cb84f03 100644 --- a/src/main/java/org/hedgecode/chess/uci/ExternalEngineRunner.java +++ b/src/main/java/org/hedgecode/chess/uci/ExternalEngineRunner.java @@ -16,15 +16,8 @@ package org.hedgecode.chess.uci; -import java.io.BufferedReader; -import java.io.BufferedWriter; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; import java.util.List; -import java.util.Scanner; import org.hedgecode.chess.uci.annotation.CommandDirection; import org.hedgecode.chess.uci.command.CommandParams; @@ -39,8 +32,7 @@ public final class ExternalEngineRunner implements EngineRunner { private Process process; private ProcessBuilder processBuilder; - private BufferedReader reader; - private BufferedWriter writer; + private ExternalEngine engine; private boolean isInit = false; @@ -62,21 +54,14 @@ public final class ExternalEngineRunner implements EngineRunner { } catch (IOException e) { throw new EngineException("uci.engine.external.start", e.getLocalizedMessage()); } - reader = new BufferedReader( - new InputStreamReader( - process.getInputStream() - ) - ); - writer = new BufferedWriter( - new OutputStreamWriter( - process.getOutputStream() - ) + + engine = new ExternalEngine( + process.getInputStream(), + process.getOutputStream() ); isInit = true; - return new ExternalEngine( - writer - ); + return engine; } @Override @@ -87,10 +72,10 @@ public final class ExternalEngineRunner implements EngineRunner { Thread engineThread = new Thread( new Runnable() { public void run() { + Transmitter engineTransmitter = engine.transmitter(); try { - Scanner scanner = new Scanner(reader); - while (scanner.hasNextLine()) { - String command = scanner.nextLine(); + while (engineTransmitter.hasCommand()) { + String command = engineTransmitter.transmitCommand(); if (command.isEmpty()) continue; CommandParams commandParams = new CommandParams(command); commandExecutor.exec( @@ -100,16 +85,15 @@ public final class ExternalEngineRunner implements EngineRunner { ); } } finally { - try { - writer.close(); - reader.close(); - } catch (IOException ignored) { - } commandExecutor.exec( UCIConstants.TERMINATE, CommandDirection.FROM_ENGINE, null ); + engineTransmitter.stop(); + engineTransmitter.close(); + if (process.isAlive()) process.destroy(); + isInit = false; } } } @@ -117,58 +101,4 @@ public final class ExternalEngineRunner implements EngineRunner { engineThread.start(); } - public void run() throws IOException, InterruptedException { - //Map environment = processBuilder.environment(); - Process process = processBuilder.start(); - InputStream is = process.getInputStream(); - BufferedReader br = new BufferedReader(new InputStreamReader(is)); - OutputStream os = process.getOutputStream(); - BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os)); - - Thread engineThread = new Thread( - new Runnable() { - public void run() { - Scanner scanner = new Scanner(br); // - while (scanner.hasNextLine()) { - System.out.println(scanner.nextLine()); - } -/* - String line; - try { - while ((line = br.readLine()) != null) { - System.out.println(line); - bw.write("isready"); - } - } catch (IOException e) { - e.printStackTrace(); - } -*/ - System.out.println("Engine terminated."); - } - } - ); - engineThread.start(); - - bw.write("uci\n"); - bw.flush(); - bw.write("isready\n"); - bw.flush(); - bw.write("quit\n"); - bw.flush(); - - //process.waitFor(); - - } - - - public static void main(String... args) throws Exception { -/* - String[] strings = " uci test one more test".trim().split("\\s+", 2); - for (String string : strings) - System.out.println(string); -*/ - - new ExternalEngineRunner("stockfish.exe").run(); - } - } diff --git a/src/main/java/org/hedgecode/chess/uci/ExternalEngineTransmitter.java b/src/main/java/org/hedgecode/chess/uci/ExternalEngineTransmitter.java new file mode 100644 index 0000000..3a20bb1 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/uci/ExternalEngineTransmitter.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2018. Developed by Hedgecode. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.hedgecode.chess.uci; + +import java.io.InputStream; +import java.util.Scanner; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public class ExternalEngineTransmitter implements Transmitter { + + private Scanner scanner; + private boolean isActive; + + ExternalEngineTransmitter(InputStream input) { + scanner = new Scanner(input); + isActive = true; + } + + @Override + public boolean isActive() { + return isActive; + } + + @Override + public boolean hasCommand() { + return isActive && scanner.hasNextLine(); + } + + @Override + public String transmitCommand() { + return scanner.nextLine(); + } + + @Override + public void addCommand(String command) { + // not supported for external engine + } + + @Override + public void stop() { + isActive = false; + } + + @Override + public void close() { + scanner.close(); + } + +} diff --git a/src/main/java/org/hedgecode/chess/uci/Receiver.java b/src/main/java/org/hedgecode/chess/uci/Receiver.java deleted file mode 100644 index e135642..0000000 --- a/src/main/java/org/hedgecode/chess/uci/Receiver.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2018. Developed by Hedgecode. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.hedgecode.chess.uci; - -/** - * - * - * @author Dmitry Samoshin aka gotty - */ -public interface Receiver { - - boolean isActive(); - - boolean hasCommand(); - - T receiveCommand(); - - void stop(); - - void close(); - -} diff --git a/src/main/java/org/hedgecode/chess/uci/Transmitter.java b/src/main/java/org/hedgecode/chess/uci/Transmitter.java index d030563..edb2fab 100644 --- a/src/main/java/org/hedgecode/chess/uci/Transmitter.java +++ b/src/main/java/org/hedgecode/chess/uci/Transmitter.java @@ -33,4 +33,6 @@ public interface Transmitter { void stop(); + void close(); + } -- 2.10.0