Skip to content

Commit

Permalink
Start implementing info support
Browse files Browse the repository at this point in the history
  • Loading branch information
fathzer committed Mar 27, 2024
1 parent bdbec51 commit 6d0b6e1
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 36 deletions.
30 changes: 0 additions & 30 deletions src/main/java/com/fathzer/jchess/uci/BestMoveReply.java

This file was deleted.

2 changes: 1 addition & 1 deletion src/main/java/com/fathzer/jchess/uci/Engine.java
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ default List<Option<?>> getOptions() {
* @param params The go parameters.
* @return A long running task able to compute the engine's move.
*/
LongRunningTask<BestMoveReply> go(GoParameters params);
LongRunningTask<GoReply> go(GoParameters params);

/** Tests whether a position is set.
* @return true if a position is set
Expand Down
146 changes: 146 additions & 0 deletions src/main/java/com/fathzer/jchess/uci/GoReply.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package com.fathzer.jchess.uci;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;

/** The reply to a go request.
*/
public class GoReply {
/** A score.*/
public sealed interface Score {
/** Gets the UCI representation of a score.
* @return a String
*/
String toUCI();
}
/** An exact score expressed in centipawns.
* @param cp The number of centipawns
*/
public final record CpScore (int cp) implements Score {
@Override
public String toUCI() {
return "cp "+cp;
}
}
/** A lower bound score expressed in centipawns.
* @param cp The number of centipawns
*/
public final record LowerScore (int cp) implements Score {
@Override
public String toUCI() {
return "lowerbound "+cp;
}
}
/** An upper bound score expressed in centipawns.
* @param cp The number of centipawns
*/
public final record UpperScore (int cp) implements Score {
@Override
public String toUCI() {
return "upperbound "+cp;
}
}
/** A mate score.
* @param moveNumber The number of moves (not plies) before mate. A negative number if engine is mated.
*/
public final record MateScore (int moveNumber) implements Score {
@Override
public String toUCI() {
return "mate "+moveNumber;
}
}

/** The information attached to the reply (the information returned in info lines).
*/
public static class Info {
private final int depth;
private List<UCIMove> extraMoves;
private Function<UCIMove, Optional<List<UCIMove>>> pvBuilder;
private Function<UCIMove, Optional<Score>> scoreBuilder;

/** Constructor.
* @param depth The search depth.
*/
public Info(int depth) {
this.depth = depth;
this.extraMoves = Collections.emptyList();
this.pvBuilder = m -> Optional.empty();
this.scoreBuilder = m -> Optional.empty();
}

public int getDepth() {
return depth;
}

public List<UCIMove> getExtraMoves() {
return extraMoves;
}

public void setExtraMoves(List<UCIMove> extraMoves) {
this.extraMoves = extraMoves;
}

public Function<UCIMove, Optional<List<UCIMove>>> getPvBuilder() {
return pvBuilder;
}

public void setPvBuilder(Function<UCIMove, Optional<List<UCIMove>>> pvBuilder) {
this.pvBuilder = pvBuilder;
}

public Function<UCIMove, Optional<Score>> getScoreBuilder() {
return scoreBuilder;
}

public void setScoreBuilder(Function<UCIMove, Optional<Score>> scoreBuilder) {
this.scoreBuilder = scoreBuilder;
}
}

private final UCIMove bestMove;
private final UCIMove ponderMove;
private Info info;

public GoReply(UCIMove move) {
this(move, null);
}

public GoReply(UCIMove move, UCIMove ponderMove) {
this.bestMove = move;
this.ponderMove = ponderMove;
}

public Optional<UCIMove> getMove() {
return Optional.ofNullable(bestMove);
}

public Optional<UCIMove> getPonderMove() {
return Optional.ofNullable(ponderMove);
}

public Optional<Info> getInfo() {
return Optional.ofNullable(info);
}

@Override
/** Gets the uci representation of the reply.
* @return a String
* @see #getMainInfoString()
*/
public String toString() {
return "bestmove "+(bestMove==null?"(none)":bestMove)+(ponderMove==null?"":(" "+ponderMove));
}

/** Gets the uci info line to return just before sending the reply.
* @return The line or an empty optional if no information is available
*/
public Optional<String> getMainInfoString() {
if (info==null) {
return Optional.empty();
}
//TODO
return Optional.of("depth "+info.depth);
}
}
2 changes: 1 addition & 1 deletion src/main/java/com/fathzer/jchess/uci/UCI.java
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ protected void doGo(Deque<String> tokens) {
} else {
final Optional<GoParameters> goOptions = parse(GoParameters::new, GoParameters.PARSER, tokens);
if (goOptions.isPresent()) {
final LongRunningTask<BestMoveReply> task = engine.go(goOptions.get());
final LongRunningTask<GoReply> task = engine.go(goOptions.get());
final boolean started = doBackground(() -> out(task.get().toString()), task::stop);
if (!started) {
debug("Engine is already working");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import com.fathzer.games.ai.iterativedeepening.IterativeDeepeningEngine;
import com.fathzer.games.ai.time.TimeManager;
import com.fathzer.games.ai.transposition.TranspositionTable;
import com.fathzer.jchess.uci.BestMoveReply;
import com.fathzer.jchess.uci.GoReply;
import com.fathzer.jchess.uci.Engine;
import com.fathzer.jchess.uci.LongRunningTask;
import com.fathzer.jchess.uci.UCIMove;
Expand Down Expand Up @@ -113,16 +113,16 @@ public void move(UCIMove move) {
}

@Override
public LongRunningTask<BestMoveReply> go(GoParameters options) {
public LongRunningTask<GoReply> go(GoParameters options) {
return new LongRunningTask<>() {
@Override
public BestMoveReply get() {
public GoReply get() {
final UCIEngineSearchConfiguration<M, B> c = new UCIEngineSearchConfiguration<>(timeManager);
final UCIEngineSearchConfiguration.EngineConfiguration previous = c.configure(engine, options, board);
final List<M> candidates = options.getMoveToSearch().stream().map(AbstractEngine.this::toMove).toList();
final M move = engine.getBestMove(board, candidates.isEmpty() ? null : candidates);
c.set(engine, previous);
return new BestMoveReply(move==null ? null : toUCI(move));
return new GoReply(move==null ? null : toUCI(move));
}

@Override
Expand Down

0 comments on commit 6d0b6e1

Please sign in to comment.