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/UCIHandle.java

201 lines
5.9 KiB
Java

package dev.kske.chess.uci;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.StringJoiner;
import dev.kske.chess.board.Move;
/**
* Project: <strong>Chess</strong><br>
* File: <strong>UCIHandle.java</strong><br>
* Created: <strong>18.07.2019</strong><br>
*
* @since Chess v0.3-alpha
* @author Kai S. K. Engelbart
*/
public class UCIHandle {
private final Process process;
private final PrintWriter out;
private final UCIReceiver receiver;
public UCIHandle(String enginePath) throws IOException {
process = new ProcessBuilder(enginePath).start();
out = new PrintWriter(process.getOutputStream(), true);
receiver = new UCIReceiver(process.getInputStream());
}
public void start() {
new Thread(receiver, "UCI Receiver").start();
uci();
}
/**
* Tells the engine to use UCI.
*/
public void 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"); }
/**
* Signifies a button press to the engine.
*
* @param name The name of the button
*/
public void setOption(String name) { out.println("setoption name " + name); }
/**
* Changes an internal parameter of the engine.
*
* @param name The name of the parameter
* @param value The value of the parameter
*/
public void setOption(String name, String value) { out.printf("setoption name %s value %s%n", name, value); }
/**
* 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"); }
/**
* Tells the engine that the next search will be from a different game.
*/
public void uciNewGame() { out.println("ucinewgame"); }
/**
* Sets up the position in its initial state.
*/
public void positionStartpos() { out.println("position startpos"); }
/**
* Sets up the position described in the FEN string.
*
* @param fen FEN representation of the current board
*/
public void positionFEN(String fen) { out.println("position fen " + fen); }
/**
* Sets up the position described by a list of moves.
*
* @param moves the moves to execute from the starting position to reach the
* desired position
*/
public void positionMoves(List<Move> moves) {
StringJoiner joiner = new StringJoiner(" ");
moves.forEach(m -> joiner.add(m.toLAN()));
out.println("position moves " + joiner);
}
/**
* Starts calculating on the current position.
*/
public void go() { out.println("go"); }
/**
* Starts calculating on the current position.
* This command has multiple optional parameters which will only be included in
* the call if they are not {@code null}, greater than zero or {@code true} for
* {@code searchMoves}, all integer parameters and all boolean parameters
* respectively.
*
* @param searchMoves restrict the search to these moves only
* @param ponder start the search in ponder mode
* @param wTime the amount of milliseconds left on white's clock
* @param bTime the amount of milliseconds left on black's clocks
* @param wInc white's increment per move in milliseconds
* @param bInc black's increment per move in milliseconds
* @param movesToGo the number of moves left until the next time control
* @param depth the maximal amount of plies to search
* @param nodes the maximal amount of nodes to search
* @param mate the amount of moves in which to search for a mate
* @param moveTime the exact search time
* @param infinite search until the {@code stop} command
*/
public void go(List<Move> searchMoves, boolean ponder, int wTime, int bTime, int wInc, int bInc, int movesToGo, int depth, int nodes, int mate,
int moveTime, boolean infinite) {
StringJoiner joiner = new StringJoiner(" ");
joiner.add("go");
if (searchMoves != null && !searchMoves.isEmpty()) {
joiner.add("searchmoves");
searchMoves.forEach(m -> joiner.add(m.toLAN()));
}
if (ponder) joiner.add("ponder");
if (wTime > 0) {
joiner.add("wtime");
joiner.add(String.valueOf(wTime));
}
if (bTime > 0) {
joiner.add("btime");
joiner.add(String.valueOf(bTime));
}
if (wInc > 0) {
joiner.add("winc");
joiner.add(String.valueOf(wInc));
}
if (bInc > 0) {
joiner.add("bind");
joiner.add(String.valueOf(bInc));
}
if (movesToGo > 0) {
joiner.add("movestogo");
joiner.add(String.valueOf(movesToGo));
}
if (depth > 0) {
joiner.add("depth");
joiner.add(String.valueOf(depth));
}
if (nodes > 0) {
joiner.add("nodes");
joiner.add(String.valueOf(nodes));
}
if (mate > 0) {
joiner.add("mate");
joiner.add(String.valueOf(mate));
}
if (moveTime > 0) {
joiner.add("movetime");
joiner.add(String.valueOf(moveTime));
}
if (infinite) joiner.add("infinite");
out.println(joiner);
}
/**
* Stops calculation as soon as possible.
*/
public void stop() { out.println("stop"); }
/**
* Tells the engine that the user has played the expected move.
*/
public void ponderHit() { out.println("ponderhit"); }
/**
* Quits the engine process as soon as possible.
*/
public void quit() { out.println("quit"); }
public void setListener(UCIListener listener) { receiver.addListener(listener); }
}