Skip to content

Commit

Permalink
Fixes a bug when standard input returned a null line.
Browse files Browse the repository at this point in the history
This bug occurred in lichess interface when switching network. The UCI
app was no more able to read commands but doesn't quit (the main thread
died but not the worker threads).
Also adapts to games-core API changes
  • Loading branch information
fathzer committed Dec 12, 2023
1 parent 3fac0bb commit d3422f1
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 19 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ It also can be used to test move generator's performance as it outputs the numbe
*playleaves* plays, when used with *legal*, the leave moves. These moves are always played when using pseudo-legal moves. *playleaves* can be replaced by the shortcut *pl*.
*cut* is followed by the number of seconds allowed to process the test. This number should be strictly positive. Default is Integer.MAX_VALUE.
**Please note:**
- **This command is optional**, only engines that implement *com.fathzer.jchess.uci.TestableMoveGeneratorSupplier* interface support it.
- **This command is optional**, only engines that implement *com.fathzer.games.perft.TestableMoveGeneratorBuilder* interface support it.
- **This command requires the *com.fathzer.jchess.uci.UCI.readTestData()* method to be overridden** in order to return a non empty test data set.
A way to easily do that is to add the [com.fathzer::jchess-perft-dataset](https://central.sonatype.com/artifact/com.fathzer/jchess-perft-dataset) artifact to your classpath, then override *readTestData*:
```java
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<dependency>
<groupId>com.fathzer</groupId>
<artifactId>games-core</artifactId>
<version>0.0.5-SNAPSHOT</version>
<version>0.0.6-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.fathzer.games.MoveGenerator;

/** An interface of engines able to build instances of move generator.
* <br>The instance supplied are initialized on the current engine position.
* <br>The instance supplied is initialized to the current engine position.
* @param <M> The class of the moves returned by the move generator.
*/
public interface MoveGeneratorSupplier<M> extends Supplier<MoveGenerator<M>> {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/fathzer/jchess/uci/PerftTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.fathzer.games.MoveGenerator;
import com.fathzer.games.perft.PerfT;
import com.fathzer.games.perft.PerfTResult;
import com.fathzer.games.util.ContextualizedExecutor;
import com.fathzer.games.util.exec.ContextualizedExecutor;
import com.fathzer.jchess.uci.parameters.PerfTParameters;

class PerftTask<M> extends LongRunningTask<PerfTResult<M>> {
Expand All @@ -29,7 +29,7 @@ public PerfTResult<M> get() {
this.perft.setPlayLeaves(false);
}
}
return perft.divide(params.getDepth(), engine::get);
return perft.divide(params.getDepth(), engine.get());
}
}

Expand Down
34 changes: 20 additions & 14 deletions src/main/java/com/fathzer/jchess/uci/UCI.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.EOFException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
Expand All @@ -24,10 +25,11 @@
import java.util.function.Supplier;
import java.util.stream.Collectors;

import com.fathzer.games.perft.TestableMoveGeneratorSupplier;
import com.fathzer.games.MoveGenerator;
import com.fathzer.games.perft.MoveGeneratorChecker;
import com.fathzer.games.perft.PerfTResult;
import com.fathzer.games.perft.PerfTTestData;
import com.fathzer.games.perft.TestableMoveGeneratorBuilder;
import com.fathzer.jchess.uci.option.CheckOption;
import com.fathzer.jchess.uci.option.Option;
import com.fathzer.jchess.uci.parameters.GoParameters;
Expand All @@ -39,7 +41,7 @@
* <br>It does not support all UCI commands and contains some extensions. Please have a look at the project's <a href="https://github.com/fathzer-games/jchess-uci/">README</a> file.
* @see Engine
*/
public class UCI implements Runnable {
public class UCI implements Runnable, AutoCloseable {
private static final BufferedReader IN = new BufferedReader(new InputStreamReader(System.in));
private static final String MOVES = "moves";
private static final String ENGINE_CMD = "engine";
Expand Down Expand Up @@ -277,8 +279,9 @@ private <M> String toString(M move) {
}

protected void doPerfStat(Deque<String> tokens) {
if (! (getEngine() instanceof TestableMoveGeneratorSupplier)) {
if (! (getEngine() instanceof TestableMoveGeneratorBuilder)) {
debug("test is not supported by this engine");
return;
}
final Optional<PerfStatsParameters> params = parse(PerfStatsParameters::new, PerfStatsParameters.PARSER, tokens);
if (params.isPresent()) {
Expand All @@ -288,11 +291,11 @@ protected void doPerfStat(Deque<String> tokens) {
debug("You may override readTestData to read some data");
return;
}
doPerfStat(testData, (TestableMoveGeneratorSupplier<?>)getEngine(), params.get());
doPerfStat(testData, (TestableMoveGeneratorBuilder<?,?>)getEngine(), params.get());
}
}

private <M> void doPerfStat(Collection<PerfTTestData> testData, TestableMoveGeneratorSupplier<M> engine, PerfStatsParameters params) {
private <M, B extends MoveGenerator<M>> void doPerfStat(Collection<PerfTTestData> testData, TestableMoveGeneratorBuilder<M, B> engine, PerfStatsParameters params) {
final MoveGeneratorChecker test = new MoveGeneratorChecker(testData);
test.setErrorManager(e-> out(e,0));
test.setCountErrorManager(e -> out("Error for "+e.getStartPosition()+" expected "+e.getExpectedCount()+" got "+e.getActualCount()));
Expand Down Expand Up @@ -364,7 +367,6 @@ public void run() {
final String command=getNextCommand();
log(">",command);
if ("quit".equals(command) || "q".equals(command)) {
backTasks.close();
break;
}
final Deque<String> tokens = new LinkedList<>(Arrays.asList(command.split(" ")));
Expand Down Expand Up @@ -419,14 +421,13 @@ private synchronized void log(boolean append, String... messages) {
*/
protected String getNextCommand() {
String line;
if (System.console() != null) {
line = System.console().readLine();
} else {
try {
line = IN.readLine();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
try {
line = System.console() == null ? IN.readLine() : System.console().readLine();
if (line==null) {
throw new EOFException("End of system input has been reached");
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
return line.trim();
}
Expand All @@ -449,4 +450,9 @@ protected void debug(CharSequence message) {
System.out.println(message.toString());
}
}

@Override
public void close() {
backTasks.close();
}
}

0 comments on commit d3422f1

Please sign in to comment.