This repository has been archived on 2021-02-18. You can view files and clone it, but cannot push or open issues or pull requests.
chess/src/main/java/dev/kske/chess/uci/UCIReceiver.java

169 lines
4.2 KiB
Java

package dev.kske.chess.uci;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import dev.kske.chess.board.Move;
/**
* Project: <strong>Chess</strong><br>
* File: <strong>UCIReceiver.java</strong><br>
* Created: <strong>19.07.2019</strong><br>
*
* @since Chess v0.3-alpha
* @author Kai S. K. Engelbart
*/
public class UCIReceiver implements Runnable {
private final BufferedReader in;
private List<UCIListener> listeners;
/**
* Creates an instance of {@link UCIReceiver}.
*
* @param in the input stream to parse for commands generated by the engine
*/
public UCIReceiver(InputStream in) {
this.in = new BufferedReader(new InputStreamReader(in));
listeners = new ArrayList<>();
}
/**
* Starts listening for UCI commands passed through the input stream.
*/
@Override
public void run() {
String line;
while (!Thread.currentThread().isInterrupted())
try {
if ((line = in.readLine()) != null && !line.isEmpty())
parse(line);
} catch (IndexOutOfBoundsException ex) {
System.err.println("Too few arguments were provided!");
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
private void parse(String line) {
int spaceIndex = line.indexOf(' ');
String command
= spaceIndex == -1 ? line : line.substring(0, spaceIndex);
switch (command) {
case "id":
parseId(line.substring(command.length() + 1));
break;
case "uciok":
listeners.forEach(UCIListener::onUCIOk);
break;
case "readyok":
listeners.forEach(UCIListener::onReadyOk);
break;
case "bestmove":
parseBestMove(line.substring(command.length() + 1));
break;
case "copyprotection":
parseCopyProtection(line.substring(command.length() + 1));
break;
case "registration":
parseRegistration(line.substring(command.length() + 1));
break;
case "info":
parseInfo(line.substring(command.length() + 1));
break;
case "option":
parseOption(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(0, line.indexOf(' '));
String arg = line.substring(param.length() + 1);
switch (param) {
case "name":
listeners.forEach(l -> l.onIdName(arg));
break;
case "author":
listeners.forEach(l -> l.onIdAuthor(arg));
break;
default:
System.err.printf(
"Unknown parameter '%s' for command 'id' found!%n",
param
);
}
}
private void parseBestMove(String line) {
String[] tokens = line.split(" ");
String move = tokens[0];
// Ponder move
if (tokens.length == 3)
listeners.forEach(l -> l.onBestMove(move, Move.fromLAN(tokens[2])));
else
listeners.forEach(l -> l.onBestMove(move));
}
private void parseCopyProtection(String line) {
switch (line) {
case "checking":
listeners.forEach(UCIListener::onCopyProtectionChecking);
break;
case "ok":
listeners.forEach(UCIListener::onCopyProtectionOk);
break;
case "error":
listeners.forEach(UCIListener::onCopyProtectionError);
break;
default:
System.err.printf(
"Unknown parameter '%s' for command 'copyprotection' found!%n",
line
);
}
}
private void parseRegistration(String line) {
switch (line) {
case "checking":
listeners.forEach(UCIListener::onRegistrationChecking);
break;
case "ok":
listeners.forEach(UCIListener::onRegistrationOk);
break;
case "error":
listeners.forEach(UCIListener::onRegistrationError);
break;
default:
System.err.printf(
"Unknown parameter '%s' for command 'registration' found!%n",
line
);
}
}
private void parseInfo(String line) {
listeners.forEach(l -> l.onInfo(new UCIInfo(line)));
}
private void parseOption(String line) {
listeners.forEach(l -> l.onOption(new UCIOption(line)));
}
/**
* Registers a UCI listener
*
* @param listener the UCI listener to register
*/
public void registerListener(UCIListener listener) {
listeners.add(listener);
}
}