221 lines
5.5 KiB
Java
221 lines
5.5 KiB
Java
package dev.kske.chess.uci;
|
|
|
|
import java.util.*;
|
|
|
|
import dev.kske.chess.board.Move;
|
|
|
|
/**
|
|
* Project: <strong>Chess</strong><br>
|
|
* File: <strong>UCIInfo.java</strong><br>
|
|
* Created: <strong>28.07.2019</strong><br>
|
|
*
|
|
* @since Chess v0.3-alpha
|
|
* @author Kai S. K. Engelbart
|
|
*/
|
|
public class UCIInfo {
|
|
|
|
private int depth, seldepth, time, nodes, multipv, currmovenumber, hashfull,
|
|
nps, tbhits, sbhits, cpuload, cpunr;
|
|
private List<Move> pv = new ArrayList<>(), refutation = new ArrayList<>();
|
|
private Map<Integer, List<Move>> currline = new HashMap<>();
|
|
private Move currmove;
|
|
private Score score;
|
|
private String displayString;
|
|
|
|
/**
|
|
* Contains every parameter for the UCI info command. Helpful for parsing
|
|
* multi-value parameters.
|
|
*/
|
|
private static final List<String> params = Arrays.asList(
|
|
"depth",
|
|
"seldepth",
|
|
"time",
|
|
"nodes",
|
|
"multipv",
|
|
"currmove",
|
|
"currmovenumber",
|
|
"hashfull",
|
|
"nps",
|
|
"tbhits",
|
|
"sbhits",
|
|
"cpuload",
|
|
"string",
|
|
"score",
|
|
"pv",
|
|
"refutation",
|
|
"currline"
|
|
);
|
|
|
|
/**
|
|
* Creates an instance of {@link UCIInfo} by parsing the argument list of a
|
|
* UCI
|
|
* info command generated from an engine.
|
|
*
|
|
* @param line the UCI info argument list to parse
|
|
*/
|
|
public UCIInfo(String line) {
|
|
String[] tokens = line.split(" ");
|
|
|
|
for (int i = 0; i < tokens.length; i++)
|
|
switch (tokens[i]) {
|
|
// Single parameter info
|
|
case "depth":
|
|
depth = Integer.parseInt(tokens[++i]);
|
|
break;
|
|
case "seldepth":
|
|
seldepth = Integer.parseInt(tokens[++i]);
|
|
break;
|
|
case "time":
|
|
time = Integer.parseInt(tokens[++i]);
|
|
break;
|
|
case "nodes":
|
|
nodes = Integer.parseInt(tokens[++i]);
|
|
break;
|
|
case "multipv":
|
|
multipv = Integer.parseInt(tokens[++i]);
|
|
break;
|
|
case "currmove":
|
|
currmove = Move.fromLAN(tokens[++i]);
|
|
break;
|
|
case "currmovenumber":
|
|
currmovenumber = Integer.parseInt(tokens[++i]);
|
|
break;
|
|
case "hashfull":
|
|
hashfull = Integer.parseInt(tokens[++i]);
|
|
break;
|
|
case "nps":
|
|
nps = Integer.parseInt(tokens[++i]);
|
|
break;
|
|
case "tbhits":
|
|
tbhits = Integer.parseInt(tokens[++i]);
|
|
break;
|
|
case "sbhits":
|
|
sbhits = Integer.parseInt(tokens[++i]);
|
|
break;
|
|
case "cpuload":
|
|
cpuload = Integer.parseInt(tokens[++i]);
|
|
break;
|
|
case "string":
|
|
displayString = tokens[++i];
|
|
break;
|
|
case "score":
|
|
score
|
|
= new Score(line.substring(line.indexOf("score") + tokens[i].length() + 1));
|
|
i += score.getLength() + 1;
|
|
break;
|
|
case "pv":
|
|
while (++i < tokens.length && !params.contains(tokens[i]))
|
|
pv.add(Move.fromLAN(tokens[i]));
|
|
break;
|
|
case "refutation":
|
|
while (++i < tokens.length && !params.contains(tokens[i]))
|
|
refutation.add(Move.fromLAN(tokens[i]));
|
|
break;
|
|
case "currline":
|
|
// A CPU number of 1 can be omitted
|
|
final Integer cpu = tokens[i].matches("\\d+")
|
|
? Integer.parseInt(tokens[i++])
|
|
: 1;
|
|
final ArrayList<Move> moves = new ArrayList<>();
|
|
while (i < tokens.length && !params.contains(tokens[i]))
|
|
moves.add(Move.fromLAN(tokens[i++]));
|
|
currline.put(cpu, moves);
|
|
System.err.println(
|
|
"The parameter 'currline' for command 'info' is not yet implemented"
|
|
);
|
|
break;
|
|
default:
|
|
System.err.printf(
|
|
"Unknown parameter '%s' for command 'info' found!%n",
|
|
tokens[i]
|
|
);
|
|
}
|
|
}
|
|
|
|
public int getDepth() { return depth; }
|
|
|
|
public int getSeldepth() { return seldepth; }
|
|
|
|
public int getTime() { return time; }
|
|
|
|
public int getNodes() { return nodes; }
|
|
|
|
public int getMultipv() { return multipv; }
|
|
|
|
public int getCurrmovenumber() { return currmovenumber; }
|
|
|
|
public int getHashfull() { return hashfull; }
|
|
|
|
public int getNps() { return nps; }
|
|
|
|
public int getTbhits() { return tbhits; }
|
|
|
|
public int getSbhits() { return sbhits; }
|
|
|
|
public int getCpuload() { return cpuload; }
|
|
|
|
public int getCpunr() { return cpunr; }
|
|
|
|
public List<Move> getPv() { return pv; }
|
|
|
|
public List<Move> getRefutation() { return refutation; }
|
|
|
|
public Map<Integer, List<Move>> getCurrline() { return currline; }
|
|
|
|
public Move getCurrmove() { return currmove; }
|
|
|
|
public Score getScore() { return score; }
|
|
|
|
public String getDisplayString() { return displayString; }
|
|
|
|
public static class Score {
|
|
|
|
private int cp, mate;
|
|
private boolean lowerbound, upperbound;
|
|
private int length;
|
|
|
|
public Score(String line) {
|
|
String[] tokens = line.split(" ");
|
|
int i = 0;
|
|
for (; i < tokens.length; i++) {
|
|
if (params.contains(tokens[i]))
|
|
break;
|
|
switch (tokens[i]) {
|
|
case "cp":
|
|
cp = Integer.parseInt(tokens[++i]);
|
|
break;
|
|
case "mate":
|
|
mate = Integer.parseInt(tokens[++i]);
|
|
break;
|
|
case "lowerbound":
|
|
lowerbound = true;
|
|
break;
|
|
case "upperbound":
|
|
upperbound = true;
|
|
break;
|
|
default:
|
|
System.err.printf(
|
|
"Unknown parameter '%s' for command 'score' found!%n",
|
|
tokens[i]
|
|
);
|
|
}
|
|
}
|
|
length = i + 1;
|
|
}
|
|
|
|
public int getCp() { return cp; }
|
|
|
|
public int getMate() { return mate; }
|
|
|
|
public boolean isLowerbound() { return lowerbound; }
|
|
|
|
public boolean isUpperbound() { return upperbound; }
|
|
|
|
/**
|
|
* @return The number of tokens this 'score' command contains (including
|
|
* itself).
|
|
*/
|
|
public int getLength() { return length; }
|
|
}
|
|
}
|