Added UCIReceiver and UCIListner, implemented a part of the UCI protocol
This commit is contained in:
parent
495e784852
commit
2c6b801038
@ -35,6 +35,6 @@ public class UCIPlayer extends Player {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void disconnect() {
|
public void disconnect() {
|
||||||
|
handle.quit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package dev.kske.chess.uci;
|
package dev.kske.chess.uci;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -14,60 +12,83 @@ import java.io.PrintWriter;
|
|||||||
public class UCIHandle {
|
public class UCIHandle {
|
||||||
|
|
||||||
private final Process process;
|
private final Process process;
|
||||||
private final BufferedReader in;
|
|
||||||
private final PrintWriter out;
|
private final PrintWriter out;
|
||||||
|
private final UCIReceiver receiver;
|
||||||
|
|
||||||
private String name, author;
|
private String name, author;
|
||||||
|
|
||||||
public UCIHandle(String enginePath) throws IOException {
|
public UCIHandle(String enginePath) throws IOException {
|
||||||
process = new ProcessBuilder(enginePath).start();
|
process = new ProcessBuilder(enginePath).start();
|
||||||
in = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
|
||||||
out = new PrintWriter(process.getOutputStream());
|
out = new PrintWriter(process.getOutputStream());
|
||||||
|
receiver = new UCIReceiver(process.getInputStream());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processInput() {
|
public void start() {
|
||||||
try {
|
uci();
|
||||||
while (in.ready())
|
new Thread(receiver).start();
|
||||||
parse(in.readLine());
|
|
||||||
} catch (IndexOutOfBoundsException ex) {
|
|
||||||
System.err.println("Too few arguments were provided!");
|
|
||||||
ex.printStackTrace();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void parse(String line) {
|
|
||||||
String command = line.substring(0, line.indexOf(' '));
|
|
||||||
switch (command) {
|
|
||||||
case "id":
|
|
||||||
parseId(line.substring(command.length() + 1));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
System.err.printf("Unknown command '%s' found!%n", command);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void parseId(String line) {
|
|
||||||
String param = line.substring(line.indexOf(' '));
|
|
||||||
String arg = line.substring(param.length() + 1);
|
|
||||||
switch (line) {
|
|
||||||
case "name":
|
|
||||||
name = arg;
|
|
||||||
break;
|
|
||||||
case "author":
|
|
||||||
author = arg;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
System.err.printf("Unknown parameter '%s' for command 'id' found!%n", param);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells the engine to use UCI.
|
||||||
|
*/
|
||||||
public void uci() {
|
public void uci() {
|
||||||
out.println("uci");
|
out.println("uci");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Switches the debug mode of the engine on or off.
|
||||||
|
*
|
||||||
|
* @param debug Enables debugging if set to {@code true}, disables it otherwise
|
||||||
|
*/
|
||||||
|
public void debug(boolean debug) {
|
||||||
|
out.println("debug " + (debug ? "on" : "off"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronized the engine with the GUI
|
||||||
|
*/
|
||||||
|
public void isready() {
|
||||||
|
out.println("isready");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the engine
|
||||||
|
*
|
||||||
|
* @param name The name the engine should be registered with
|
||||||
|
* @param code The code the engine should be registered with
|
||||||
|
*/
|
||||||
|
public void register(String name, String code) {
|
||||||
|
out.printf("register %s %s%n", name, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells the engine to postpone the registration.
|
||||||
|
*/
|
||||||
|
public void registerLater() {
|
||||||
|
out.println("register later");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops calculation as soon as possible.
|
||||||
|
*/
|
||||||
|
public void stop() {
|
||||||
|
out.println("stop");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Quits the engine process as soon as possible.
|
||||||
|
*/
|
||||||
|
public void quit() {
|
||||||
|
out.println("quit");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The name of the engine
|
||||||
|
*/
|
||||||
public String getName() { return name; }
|
public String getName() { return name; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The author of the engine
|
||||||
|
*/
|
||||||
public String getAuthor() { return author; }
|
public String getAuthor() { return author; }
|
||||||
}
|
}
|
||||||
|
104
src/dev/kske/chess/uci/UCIListener.java
Normal file
104
src/dev/kske/chess/uci/UCIListener.java
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package dev.kske.chess.uci;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project: <strong>Chess</strong><br>
|
||||||
|
* File: <strong>UCIListener.java</strong><br>
|
||||||
|
* Created: <strong>19.07.2019</strong><br>
|
||||||
|
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||||
|
*/
|
||||||
|
public interface UCIListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identifies the name of the engine.
|
||||||
|
*
|
||||||
|
* @param name The name of the engine
|
||||||
|
*/
|
||||||
|
void onIdName(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identifies the author of the engine.
|
||||||
|
*
|
||||||
|
* @param author The name of the engine's author
|
||||||
|
*/
|
||||||
|
void onIdAuthor(String author);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The engine is ready in UCI mode.
|
||||||
|
*/
|
||||||
|
void onUCIOk();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The engine has processed all inputs and is ready for new commands.
|
||||||
|
*/
|
||||||
|
void onReadyOk();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The engine has stopped searching and has found the best move.
|
||||||
|
*
|
||||||
|
* @param move The best moves the engine has found
|
||||||
|
*/
|
||||||
|
void onBestMove(String move);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The engine has stopped searching and has found the best move.
|
||||||
|
*
|
||||||
|
* @param move The best move the engine has found
|
||||||
|
* @param ponderMove The move the engine likes to ponder on
|
||||||
|
*/
|
||||||
|
void onBestMove(String move, String ponderMove);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The engine will check the copy protection now.
|
||||||
|
*/
|
||||||
|
void onCopyProtectionChecking();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The engine has successfully checked the copy protection.
|
||||||
|
*/
|
||||||
|
void onCopyProtectionOk();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The engine has encountered an error during copy protection checking.
|
||||||
|
*/
|
||||||
|
void onCopyProtectionError();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The engine will check the registration now.
|
||||||
|
*/
|
||||||
|
void onRegistrationChecking();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The engine has successfully checked the registration.
|
||||||
|
*/
|
||||||
|
void onRegistrationOk();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The engine has encountered an error during registration checking.
|
||||||
|
*/
|
||||||
|
void onRegistrationError();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The engine sends information to the GUI.
|
||||||
|
*
|
||||||
|
* @param additionalInfo Contains all pieces of information to be sent
|
||||||
|
*/
|
||||||
|
void onInfo(Map<String, String> additionalInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells the GUI which parameters can be changed in the engine.
|
||||||
|
*
|
||||||
|
* @param name The name of the option
|
||||||
|
* @param type The GUI component through which the option should be set
|
||||||
|
* @param defaultVal The default value of this parameter
|
||||||
|
* @param minVal The minimum value of this parameter
|
||||||
|
* @param maxVal The maximum value of this parameter
|
||||||
|
* @param var A predefined value of this parameter
|
||||||
|
*/
|
||||||
|
void onOption(String name, GUIType type, String defaultVal, String minVal, String maxVal, String var);
|
||||||
|
|
||||||
|
public static enum GUIType {
|
||||||
|
CHECK, SPIN, COMBO, BUTTON, STRING
|
||||||
|
}
|
||||||
|
}
|
111
src/dev/kske/chess/uci/UCIReceiver.java
Normal file
111
src/dev/kske/chess/uci/UCIReceiver.java
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
package dev.kske.chess.uci;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project: <strong>Chess</strong><br>
|
||||||
|
* File: <strong>UCIReceiver.java</strong><br>
|
||||||
|
* Created: <strong>19.07.2019</strong><br>
|
||||||
|
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||||
|
*/
|
||||||
|
public class UCIReceiver implements Runnable {
|
||||||
|
|
||||||
|
private final BufferedReader in;
|
||||||
|
|
||||||
|
private UCIListener listener;
|
||||||
|
|
||||||
|
public UCIReceiver(InputStream in) {
|
||||||
|
this.in = new BufferedReader(new InputStreamReader(in));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
while (in.ready())
|
||||||
|
parse(in.readLine());
|
||||||
|
} catch (IndexOutOfBoundsException ex) {
|
||||||
|
System.err.println("Too few arguments were provided!");
|
||||||
|
ex.printStackTrace();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parse(String line) {
|
||||||
|
String command = line.substring(0, line.indexOf(' '));
|
||||||
|
switch (command) {
|
||||||
|
case "id":
|
||||||
|
parseId(line.substring(command.length() + 1));
|
||||||
|
break;
|
||||||
|
case "uciok":
|
||||||
|
listener.onUCIOk();
|
||||||
|
break;
|
||||||
|
case "readyok":
|
||||||
|
listener.onReadyOk();
|
||||||
|
break;
|
||||||
|
// TODO: bestmove
|
||||||
|
case "copyprotection":
|
||||||
|
parseCopyProtection(line.substring(command.length() + 1));
|
||||||
|
break;
|
||||||
|
case "registration":
|
||||||
|
parseRegistration(line.substring(command.length() + 1));
|
||||||
|
break;
|
||||||
|
// TODO: info
|
||||||
|
// TODO: option
|
||||||
|
default:
|
||||||
|
System.err.printf("Unknown command '%s' found!%n", command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseId(String line) {
|
||||||
|
String param = line.substring(line.indexOf(' '));
|
||||||
|
String arg = line.substring(param.length() + 1);
|
||||||
|
switch (line) {
|
||||||
|
case "name":
|
||||||
|
listener.onIdName(arg);
|
||||||
|
break;
|
||||||
|
case "author":
|
||||||
|
listener.onIdAuthor(arg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
System.err.printf("Unknown parameter '%s' for command 'id' found!%n", param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseCopyProtection(String line) {
|
||||||
|
switch (line) {
|
||||||
|
case "checking":
|
||||||
|
listener.onCopyProtectionChecking();
|
||||||
|
break;
|
||||||
|
case "ok":
|
||||||
|
listener.onCopyProtectionOk();
|
||||||
|
break;
|
||||||
|
case "error":
|
||||||
|
listener.onCopyProtectionError();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
System.err.printf("Unknown parameter '%s' for command 'copyprotection' found!%n", line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseRegistration(String line) {
|
||||||
|
switch (line) {
|
||||||
|
case "checking":
|
||||||
|
listener.onRegistrationChecking();
|
||||||
|
break;
|
||||||
|
case "ok":
|
||||||
|
listener.onRegistrationOk();
|
||||||
|
break;
|
||||||
|
case "error":
|
||||||
|
listener.onRegistrationError();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
System.err.printf("Unknown parameter '%s' for command 'registration' found!%n", line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setListener(UCIListener listener) { this.listener = listener; }
|
||||||
|
}
|
Reference in New Issue
Block a user