/* * 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.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; /** * External UCI Engine Runner. * * @author Dmitry Samoshin aka gotty */ public final class ExternalEngineRunner implements EngineRunner { private Process process; private ProcessBuilder processBuilder; private BufferedReader reader; private BufferedWriter writer; private boolean isInit = false; ExternalEngineRunner(String extEngineCommand) { processBuilder = new ProcessBuilder(extEngineCommand); } ExternalEngineRunner(List extEngineCommands) { processBuilder = new ProcessBuilder(extEngineCommands); } @Override public Engine init() throws EngineException { if (isInit) throw new EngineException("uci.engine.already.init"); try { process = processBuilder.start(); } 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() ) ); isInit = true; return new ExternalEngine( writer ); } @Override public void run(final CommandExecutor commandExecutor) throws EngineException { if (!isInit) throw new EngineException("uci.engine.not.init"); Thread engineThread = new Thread( new Runnable() { public void run() { try { Scanner scanner = new Scanner(reader); while (scanner.hasNextLine()) { String command = scanner.nextLine(); if (command.isEmpty()) continue; CommandParams commandParams = new CommandParams(command); commandExecutor.exec( commandParams.getName(), CommandDirection.FROM_ENGINE, commandParams.getParams() ); } } finally { try { writer.close(); reader.close(); } catch (IOException ignored) { } commandExecutor.exec( UCIConstants.TERMINATE, CommandDirection.FROM_ENGINE, null ); } } } ); 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(); } }