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/dev/kske/chess/uci/UCIReceiver.java

196 lines
5.1 KiB
Java

package dev.kske.chess.uci;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import dev.kske.chess.uci.UCIListener.GUIType;
/**
* 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() {
String line;
while (!Thread.currentThread().isInterrupted())
try {
if ((line = in.readLine()) != null && !line.isBlank()) 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":
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;
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":
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);
}
}
private void parseInfo(String line) {
String[] tokens = line.split(" ");
Map<String, String> additionalInfo = new HashMap<>();
for (int i = 0; i < tokens.length; i++)
switch (tokens[i]) {
// Single parameter info
case "depth":
case "seldepth":
case "time":
case "nodes":
case "multipv":
case "currmove":
case "currmovenumber":
case "hashfull":
case "nps":
case "tbhits":
case "sbhits":
case "cpuload":
case "string":
additionalInfo.put(tokens[i], tokens[++i]);
break;
// TODO: pv
// TODO: score
// TODO: refutation
// TODO: currline
default:
System.err.printf("Unknown parameter '%s' for command 'info' found!%n", tokens[i]);
}
listener.onInfo(additionalInfo);
}
private void parseOption(String line) {
String[] tokens = line.split(" ");
StringJoiner name = new StringJoiner(" ");
GUIType type = null;
String defaultVal = null;
String minVal = null;
String maxVal = null;
List<String> var = new ArrayList<>();
for (int i = 0; i < tokens.length; i++)
switch (tokens[i]) {
case "name":
while (!Arrays.asList("type", "default", "min", "max", "var").contains(tokens[i + 1]))
name.add(tokens[++i]);
break;
case "type":
type = GUIType.valueOf(tokens[++i].toUpperCase());
break;
case "default":
// Default string may be empty
defaultVal = i == tokens.length - 1 ? "" : tokens[++i];
break;
case "min":
minVal = tokens[++i];
break;
case "max":
maxVal = tokens[++i];
break;
case "var":
var.add(tokens[++i]);
break;
default:
System.err.printf("Unknown parameter '%s' for command 'option' found!%n", tokens[i]);
}
listener.onOption(name.toString(), type, defaultVal, minVal, maxVal, var);
}
public void setListener(UCIListener listener) { this.listener = listener; }
}