diff --git a/.project b/.project
index e8849b3..85fd998 100644
--- a/.project
+++ b/.project
@@ -20,4 +20,15 @@
org.eclipse.jdt.core.javanature
org.eclipse.m2e.core.maven2Nature
+
+
+ 1737039058705
+
+ 30
+
+ org.eclipse.core.resources.regexFilterMatcher
+ node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
+
+
+
diff --git a/README.md b/README.md
index e4a9f61..43ed93e 100644
--- a/README.md
+++ b/README.md
@@ -4,12 +4,12 @@
# chesslib-uci-engine
A basic [UCI](https://en.wikipedia.org/wiki/Universal_Chess_Interface) engine based on the [bhlangonijr/chesslib](https://github.com/bhlangonijr/chesslib) move generator, and the [games-core](https://github.com/fathzer-games/games-core) alpha beta search algorithm implementation. It uses the evaluation functions, the remaining move oracle and some other things from the [chess-utils](https://github.com/fathzer-games/chess-utils) library.
-You can play against it on [Lichess](https://lichess.org/@/fathzer-jchess). It runs on a Minisforum U300 with [3867U processor](https://www.cpubenchmark.net/cpu.php?cpu=Intel+Celeron+3867U+%40+1.80GHz&id=3442).
+You can play against it on [Lichess](https://lichess.org/@/fathzer-jchess). It runs on a Nipogi e2 with N97 processor](https://www.passmark.com/baselines/V11/display.php?id=284967660181).
## How to run the engine
It requires a Java 17+ virtual machine.
-Download the jar [here](https://fathzer-games.github.io/chesslib-uci-engine/chesslib-uci-engine.jar), then Launch the engine with the following command: ```java -jar chesslib-uci-engine.jar```
+Download the jar [here](https://fathzer-games.github.io/chesslib-uci-engine/chesslib-uci-engine.jar), then launch the engine with the following command: ```java -jar chesslib-uci-engine.jar```
### Openings library
You can use an opening library located at a URL using the ```openingsUrl``` system property.
diff --git a/pom.xml b/pom.xml
index 670b2cb..e079b06 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,13 +7,13 @@
com.fathzer
parent-pom
- 1.0.8
+ 1.0.9
chesslib-uci-engine
- 0.0.3
+ 0.0.4
chesslib-uci-engine
- A basic uci engine plugin for jchess-uci.
+ A basic uci engine based on chesslib move generator.
https://github.com/fathzer-games/chesslib-uci-engine
@@ -27,6 +27,7 @@
17
fathzer-games
chesslib-uci-engine
+ yyyyMMdd HH-mm-ss
@@ -40,60 +41,85 @@
com.github.bhlangonijr
chesslib
- 1.3.3
+ 1.3.4
com.fathzer
chess-utils
- 0.0.5-SNAPSHOT
+ 0.0.1
com.fathzer
games-core
- 0.0.12-SNAPSHOT
+ 0.0.1
com.fathzer
jchess-uci
- 2.0.4-SNAPSHOT
+ 2.0.0
org.json
json
- 20240205
+ 20250107
com.fathzer
jchess-perft-dataset
- 1.0.0
+ 2.0.0
org.slf4j
slf4j-api
- 2.0.7
+ 2.0.16
org.slf4j
slf4j-simple
- 2.0.7
+ 2.0.16
runtime
-
- org.junit.jupiter
- junit-jupiter
- 5.10.2
- test
-
org.awaitility
awaitility
4.2.2
test
+
+ com.fathzer
+ chess-test-utils
+ 0.0.1
+ test
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+ 3.1.0
+
+
+ generate-build-info
+ generate-resources
+
+ run
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
maven-shade-plugin
3.4.1
diff --git a/runConfigs/ChessLib-uci-engine (PerfTTest).launch b/runConfigs/ChessLib-uci-engine (PerfTTest).launch
index 435ad64..5e9c2ba 100644
--- a/runConfigs/ChessLib-uci-engine (PerfTTest).launch
+++ b/runConfigs/ChessLib-uci-engine (PerfTTest).launch
@@ -8,6 +8,7 @@
+
@@ -19,5 +20,5 @@
-
+
diff --git a/src/main/java/com/fathzer/jchess/chesslib/ai/DefaultLogger.java b/src/main/java/com/fathzer/jchess/chesslib/ai/DefaultLogger.java
index bd0a695..996e9ee 100644
--- a/src/main/java/com/fathzer/jchess/chesslib/ai/DefaultLogger.java
+++ b/src/main/java/com/fathzer/jchess/chesslib/ai/DefaultLogger.java
@@ -51,18 +51,15 @@ public void logEndedByPolicy(int depth) {
@Override
public void logSearchEnd(ChessLibMoveGenerator board, SearchHistory result) {
- log.info("--- End of iterative evaluation returns: {}", result.getBestMoves());
- }
-
- @Override
- public void logMoveChosen(ChessLibMoveGenerator board, EvaluatedMove evaluatedMove) {
- if (evaluatedMove==null) {
+ log.info("--- End of iterative evaluation returns: {}", result.getAccurateMoves());
+ if (result.isEmpty()) {
log.info("No valid move found");
} else {
- Move move = evaluatedMove.getContent();
+ //TODO Not the right place, the engine could return another move, especially when there is tie moves
+ EvaluatedMove evaluatedMove = result.getAccurateMoves().get(0);
+ Move move = evaluatedMove.getMove();
log.info("Move chosen :{}", move);
- final List pv = evaluatedMove.getPrincipalVariation();
- log.info("pv: {}", pv);
+ log.info("pv: {}", engine.getTranspositionTable().collectPV(board, move, result.getLastDepth()));
}
}
}
diff --git a/src/main/java/com/fathzer/jchess/chesslib/ai/TT.java b/src/main/java/com/fathzer/jchess/chesslib/ai/TT.java
index 935cee0..ff93453 100644
--- a/src/main/java/com/fathzer/jchess/chesslib/ai/TT.java
+++ b/src/main/java/com/fathzer/jchess/chesslib/ai/TT.java
@@ -2,11 +2,12 @@
import com.fathzer.games.ai.transposition.OneLongEntryTranspositionTable;
import com.fathzer.games.ai.transposition.SizeUnit;
+import com.fathzer.jchess.chesslib.ChessLibMoveGenerator;
import com.github.bhlangonijr.chesslib.Piece;
import com.github.bhlangonijr.chesslib.Square;
import com.github.bhlangonijr.chesslib.move.Move;
-public class TT extends OneLongEntryTranspositionTable {
+public class TT extends OneLongEntryTranspositionTable {
// Move is encoded as an int:
// 12 bits for source, 12 bits for destination
// 8 bits for promotion
diff --git a/src/main/java/com/fathzer/jchess/chesslib/uci/ChessLibEngine.java b/src/main/java/com/fathzer/jchess/chesslib/uci/ChessLibEngine.java
index 39ca7e8..460c28c 100644
--- a/src/main/java/com/fathzer/jchess/chesslib/uci/ChessLibEngine.java
+++ b/src/main/java/com/fathzer/jchess/chesslib/uci/ChessLibEngine.java
@@ -17,7 +17,7 @@
import com.fathzer.games.ai.time.BasicTimeManager;
import com.fathzer.games.ai.transposition.SizeUnit;
import com.fathzer.games.ai.transposition.TranspositionTable;
-import com.fathzer.games.perft.TestableMoveGeneratorBuilder;
+import com.fathzer.games.perft.FromPositionMoveGeneratorBuilder;
import com.fathzer.games.util.PhysicalCores;
import com.fathzer.games.util.exec.ExecutionContext;
import com.fathzer.jchess.chesslib.ChessLibMoveGenerator;
@@ -40,7 +40,7 @@
import com.github.bhlangonijr.chesslib.Square;
import com.github.bhlangonijr.chesslib.move.Move;
-public class ChessLibEngine extends AbstractEngine implements TestableMoveGeneratorBuilder, Displayable {
+public class ChessLibEngine extends AbstractEngine implements FromPositionMoveGeneratorBuilder, Displayable {
private static final List> EVALUATORS = Arrays.asList(
new EvaluatorConfiguration<>("pesto",PestoEvaluator::new),
new EvaluatorConfiguration<>("simplified",SimplifiedEvaluator::new),
@@ -54,7 +54,7 @@ public ChessLibEngine() {
}
public ChessLibEngine(DeferredReadMoveLibrary ownBook) {
- super (buildEngine(EVALUATORS.get(0).getBuilder(), 20), new BasicTimeManager<>(RemainingMoveOracle.INSTANCE));
+ super (buildEngine(EVALUATORS.get(0).evaluatorBuilder(), 20), new BasicTimeManager<>(RemainingMoveOracle.INSTANCE));
setEvaluators(EVALUATORS);
this.ownBook = ownBook;
}
@@ -85,7 +85,7 @@ public void setOwnBook(boolean activate) {
@Override
public void setStartPosition(String fen) {
- board = fromFEN(fen);
+ board = fromPosition(fen);
board.setMoveComparatorBuilder(BasicMoveComparator::new);
}
@@ -124,7 +124,7 @@ public String getFEN() {
}
@Override
- public ChessLibMoveGenerator fromFEN(String fen) {
+ public ChessLibMoveGenerator fromPosition(String fen) {
final Board internalBoard = new Board();
internalBoard.loadFromFen(fen);
return new ChessLibMoveGenerator(internalBoard);
@@ -133,8 +133,8 @@ public ChessLibMoveGenerator fromFEN(String fen) {
public static IterativeDeepeningEngine buildEngine(Supplier> evaluatorBuilder, int maxDepth) {
final IterativeDeepeningEngine engine = new IterativeDeepeningEngine<>(new ChessLibDeepeningPolicy(maxDepth), new TT(16, SizeUnit.MB), evaluatorBuilder) {
@Override
- protected Negamax buildAi(ExecutionContext> context) {
- final Negamax negaMax = (Negamax) super.buildAi(context);
+ protected Negamax buildAI(ExecutionContext> context) {
+ final Negamax negaMax = (Negamax) super.buildAI(context);
negaMax.setQuiesceEvaluator(new BasicQuiesceSearch());
return negaMax;
}
@@ -156,7 +156,7 @@ protected EvaluatedMove getSelected(ChessLibMoveGenerator b, SearchHistory
}
@Override
- protected TranspositionTable buildTranspositionTable(int sizeInMB) {
+ protected TranspositionTable buildTranspositionTable(int sizeInMB) {
return new TT(sizeInMB, SizeUnit.MB);
}
}
diff --git a/src/main/java/com/fathzer/jchess/chesslib/uci/Main.java b/src/main/java/com/fathzer/jchess/chesslib/uci/Main.java
index 194ddd1..7ea8e77 100644
--- a/src/main/java/com/fathzer/jchess/chesslib/uci/Main.java
+++ b/src/main/java/com/fathzer/jchess/chesslib/uci/Main.java
@@ -66,7 +66,7 @@ static MoveLibrary readOpenings(final URL location)
@Override
protected Collection readTestData() {
- try (InputStream stream = Main.class.getResourceAsStream("/Perft.txt")) {
+ try (InputStream stream = Main.class.getResourceAsStream("/com/fathzer/jchess/perft/Perft.txt")) {
return new PerfTParser().withStartPositionPrefix("position fen").withStartPositionCustomizer(s -> s+" 0 1").read(stream, StandardCharsets.UTF_8);
} catch (IOException e) {
throw new UncheckedIOException(e);
diff --git a/src/main/java/com/fathzer/jchess/lichess/AbstractDefaultOpenings.java b/src/main/java/com/fathzer/jchess/lichess/AbstractDefaultOpenings.java
index a083ea3..b63a9c7 100644
--- a/src/main/java/com/fathzer/jchess/lichess/AbstractDefaultOpenings.java
+++ b/src/main/java/com/fathzer/jchess/lichess/AbstractDefaultOpenings.java
@@ -2,9 +2,9 @@
import java.io.IOException;
import java.io.InputStream;
+import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
-import java.util.Optional;
import java.util.function.Supplier;
import java.util.zip.GZIPInputStream;
@@ -38,18 +38,18 @@ private String toReducedXFen(B board) {
}
@Override
- protected Optional> getRecord(B board) {
+ protected List getRecords(B board) {
final String fen = toReducedXFen(board);
final JSONObject theRecord = db.optJSONObject(fen);
final JSONArray moves = theRecord==null ? null : theRecord.optJSONArray("moves");
if (moves==null) {
- return Optional.empty();
+ return Collections.emptyList();
}
final List result = new LinkedList<>();
for (int i=0;i {
+
+ @Override
+ public ChessLibBoard fenToBoard(String fen, Variant variant) {
+ final ChessLibMoveGenerator from = FENUtils.from(fen);
+ return new ChessLibBoard(from);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/fathzer/chess/test/utils/ChessLibBoard.java b/src/test/java/com/fathzer/chess/test/utils/ChessLibBoard.java
new file mode 100644
index 0000000..6a4a23f
--- /dev/null
+++ b/src/test/java/com/fathzer/chess/test/utils/ChessLibBoard.java
@@ -0,0 +1,35 @@
+package com.fathzer.chess.test.utils;
+
+import java.util.List;
+
+import com.fathzer.jchess.chesslib.ChessLibMoveGenerator;
+import com.fathzer.chess.utils.model.IBoard;
+import com.fathzer.games.MoveGenerator.MoveConfidence;
+import com.github.bhlangonijr.chesslib.move.Move;
+
+public class ChessLibBoard implements IBoard{
+ private final ChessLibMoveGenerator board;
+
+ public ChessLibBoard(ChessLibMoveGenerator board) {
+ this.board = board;
+ }
+
+ @Override
+ public List getMoves() {
+ return board.getMoves();
+ }
+
+ @Override
+ public boolean makeMove(Move mv) {
+ return board.makeMove(mv, MoveConfidence.LEGAL);
+ }
+
+ @Override
+ public void unmakeMove() {
+ board.unmakeMove();
+ }
+
+ public ChessLibMoveGenerator getBoard() {
+ return board;
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/fathzer/chess/test/utils/SuiteTest.java b/src/test/java/com/fathzer/chess/test/utils/SuiteTest.java
new file mode 100644
index 0000000..a2bae1b
--- /dev/null
+++ b/src/test/java/com/fathzer/chess/test/utils/SuiteTest.java
@@ -0,0 +1,13 @@
+package com.fathzer.chess.test.utils;
+
+import org.junit.platform.suite.api.SelectClasses;
+import org.junit.platform.suite.api.Suite;
+import org.junit.platform.suite.api.SuiteDisplayName;
+
+import com.fathzer.chess.utils.test.PerftTest;
+
+@Suite
+@SuiteDisplayName("Tests from chess-test-utils")
+@SelectClasses({PerftTest.class})
+public class SuiteTest {
+}
\ No newline at end of file
diff --git a/src/test/java/com/fathzer/jchess/chesslib/ChessLibMoveGeneratorTest.java b/src/test/java/com/fathzer/jchess/chesslib/ChessLibMoveGeneratorTest.java
index b72a685..85a63aa 100644
--- a/src/test/java/com/fathzer/jchess/chesslib/ChessLibMoveGeneratorTest.java
+++ b/src/test/java/com/fathzer/jchess/chesslib/ChessLibMoveGeneratorTest.java
@@ -36,7 +36,7 @@ void testInvalidMovesWithUnsafe() {
assertFalse(mvg.makeMove(move, UNSAFE));
// Move a piece through another piece
- move = new Move(D6, B6);
+ move = new Move(D6, B8);
assertFalse(mvg.makeMove(move, UNSAFE));
// Piece takes own piece
@@ -83,8 +83,8 @@ void testInvalidMovesWithUnsafe() {
// assertFalse(mvg.makeMove(move, UNSAFE)); //FIXME
// Promotion of a piece that is not a pawn
- move = new Move(B7, B8);
-// assertFalse(mvg.makeMove(move, UNSAFE));
+ move = new Move(B7, B8, Piece.WHITE_QUEEN);
+ assertFalse(mvg.makeMove(move, UNSAFE));
// imaginary en-passant
move = new Move(H5, G6);
diff --git a/src/test/java/com/fathzer/jchess/chesslib/PerfTTest.java b/src/test/java/com/fathzer/jchess/chesslib/PerfTTest.java
deleted file mode 100644
index 9db9b50..0000000
--- a/src/test/java/com/fathzer/jchess/chesslib/PerfTTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package com.fathzer.jchess.chesslib;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.Iterator;
-import java.util.List;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fathzer.games.MoveGenerator;
-import com.fathzer.games.perft.PerfT;
-import com.fathzer.games.perft.PerfTParser;
-import com.fathzer.games.perft.PerfTResult;
-import com.fathzer.games.perft.PerfTTestData;
-import com.fathzer.games.util.PhysicalCores;
-import com.fathzer.games.util.exec.ContextualizedExecutor;
-import com.github.bhlangonijr.chesslib.Board;
-import com.github.bhlangonijr.chesslib.move.Move;
-
-class PerfTTest {
- private static final Logger log = LoggerFactory.getLogger(PerfTTest.class);
-
- @DisabledIfSystemProperty(named="perftDepth",matches = "0")
- @Test
- void test() throws IOException {
- final int depth = Integer.getInteger("perftDepth", 1);
- if (depth!=1) {
- log.info("PerfT test depth is set to {}",depth);
- }
- final Iterator iterator = readTests().iterator();
- try (ContextualizedExecutor> exec =new ContextualizedExecutor<>(PhysicalCores.count())) {
- while (iterator.hasNext()) {
- final PerfTTestData test = iterator.next();
- try {
- doTest(exec, test, depth);
- } catch (Exception e) {
- fail("Exception on "+test.getStartPosition(),e);
- }
- }
- }
- }
-
-// @Test
- void showDivide() {
- try (ContextualizedExecutor> exec =new ContextualizedExecutor<>(PhysicalCores.count())) {
- final Board board = new Board();
- board.loadFromFen("8/8/6b1/k3p2N/8/b1PB4/K6p/8 b - - 0 1");
- final PerfT perfT = new PerfT<>(exec);
- final PerfTResult divide = perfT.divide(2, new ChessLibMoveGenerator(board));
- System.out.println("Leaves: "+ divide.getNbLeaves());
- System.out.println("Divide is "+divide.getDivides());
- }
- }
-
- private void doTest(ContextualizedExecutor> exec, PerfTTestData test, int depth) {
- final Board board = new Board();
- board.loadFromFen(test.getStartPosition()+" 0 1");
- final PerfT perfT = new PerfT<>(exec);
- if (test.getSize()>=depth) {
-// try {
- final PerfTResult divide = perfT.divide(depth, new ChessLibMoveGenerator(board));
- assertEquals(test.getCount(depth), divide.getNbLeaves(), "Error for "+test.getStartPosition()+". Divide is "+divide.getDivides());
-// if (count != test.getCount(depth)) {
-// System.out.println("Error for "+test.getFen()+" expected "+test.getCount(depth)+" got "+count);
-// } else {
-// System.out.println("Ok for "+test.getFen());
-// }
-// } catch (RuntimeException e) {
-// System.out.println("Exception for "+test.getFen());
-// throw e;
-// }
- }
- }
-
- private List readTests() throws IOException {
- try (InputStream stream = getClass().getResourceAsStream("/Perft.txt")) {
- return new PerfTParser().withStartPositionPrefix("position fen").read(stream, StandardCharsets.UTF_8);
- }
- }
-}
diff --git a/src/test/java/com/fathzer/jchess/chesslib/ai/MinimaxEngineTest.java b/src/test/java/com/fathzer/jchess/chesslib/ai/MinimaxEngineTest.java
index fe28d3e..77bf5ae 100644
--- a/src/test/java/com/fathzer/jchess/chesslib/ai/MinimaxEngineTest.java
+++ b/src/test/java/com/fathzer/jchess/chesslib/ai/MinimaxEngineTest.java
@@ -15,7 +15,7 @@
import com.fathzer.games.MoveGenerator;
import com.fathzer.games.ai.Negamax;
import com.fathzer.games.ai.SearchContext;
-import com.fathzer.games.ai.SearchParameters;
+import com.fathzer.games.ai.DepthFirstSearchParameters;
import com.fathzer.games.ai.evaluation.EvaluatedMove;
import com.fathzer.games.ai.evaluation.Evaluation;
import com.fathzer.games.ai.evaluation.Evaluation.Type;
@@ -24,7 +24,6 @@
import com.fathzer.games.ai.evaluation.Evaluator;
import com.fathzer.games.util.SelectiveComparator;
import com.fathzer.games.util.exec.ExecutionContext;
-import com.fathzer.games.util.exec.SingleThreadContext;
import com.fathzer.jchess.chesslib.ChessLibMoveGenerator;
import com.fathzer.jchess.chesslib.ai.eval.NaiveEvaluator;
import com.fathzer.jchess.chesslib.uci.ChessLibEngine;
@@ -50,8 +49,8 @@ void blackPlayingTest() {
final List> moves = getBests(mme4, fromFEN("7k/5p1Q/5P1N/5PPK/6PP/8/8/8 b - - 6 5", StrictMoveEvaluator::new));
//show(moves);
assertEquals(1, moves.size());
- assertEquals(H8, moves.get(0).getContent().getFrom());
- assertEquals(H7, moves.get(0).getContent().getTo());
+ assertEquals(H8, moves.get(0).getMove().getFrom());
+ assertEquals(H7, moves.get(0).getMove().getTo());
assertEquals(-800, moves.get(0).getScore());
}
@@ -61,7 +60,7 @@ private void show(Collection> moves) {
private > List> getBests(IterativeDeepeningEngine engine, B moveGenerator) {
final SearchHistory bestMoves = engine.getBestMoves(moveGenerator);
- return bestMoves.getBestMoves();
+ return bestMoves.getAccurateMoves();
}
@Test
@@ -92,7 +91,7 @@ void test() {
max = moves.get(0).getEvaluation();
assertEquals(Type.WIN, max.getType());
assertEquals(1, max.getCountToEnd());
- mv = moves.get(0).getContent();
+ mv = moves.get(0).getMove();
assertEquals(C3, mv.getFrom());
assertEquals(C2, mv.getTo());
// Warning, due to transposition table effects, the second best move (M+3) can be detected even if we search at depth 4!
@@ -106,7 +105,7 @@ void test() {
assertEquals(Type.WIN, max.getType());
assertEquals(2, max.getCountToEnd());
assertTrue(moves.get(1).getScore() basicEvaluator = new NaiveEvaluator();
basicEvaluator.init(board);
SearchContext context = SearchContext.get(board, () -> basicEvaluator);
- try (ExecutionContext> exec = new SingleThreadContext<>(context)) {
+ try (ExecutionContext> exec = ExecutionContext.get(1, context)) {
Negamax ai = new Negamax<>(exec);
List l = new ArrayList<>();
l.add(new Move(H1, G1));
l.add(new Move(F2, F3));
l.add(new Move(F2, F4));
- final SearchParameters params = new SearchParameters(4, Integer.MAX_VALUE, 0);
+ final DepthFirstSearchParameters params = new DepthFirstSearchParameters(4, Integer.MAX_VALUE, 0);
final List> eval = ai.getBestMoves(l, params).getCut();
assertEquals(3, eval.size());
for (EvaluatedMove e : eval) {
@@ -207,7 +206,7 @@ void bug20230911() {
engine.getDeepeningPolicy().setSize(1);
engine.getDeepeningPolicy().setAccuracy(0);
final SearchHistory history = engine.getBestMoves(board);
- List> bestMoves = history.getBestMoves();
+ List> bestMoves = history.getAccurateMoves();
System.out.println(bestMoves);
assertEquals(2, bestMoves.size());
}
@@ -218,6 +217,6 @@ void bug20230911() {
void bug20230821() {
// Not a bug, just a problem with evaluation function
IterativeDeepeningEngine engine = ChessLibEngine.buildEngine(NaiveEvaluator::new, 7);
- System.out.println(engine.getBestMoves(fromFEN("8/6k1/6p1/1N6/6K1/R7/4B3/8 w - - 21 76")).getBest());
+ System.out.println(engine.getBestMoves(fromFEN("8/6k1/6p1/1N6/6K1/R7/4B3/8 w - - 21 76")).getAccurateMoves().get(0));
}
}
diff --git a/src/test/resources/META-INF/services/com.fathzer.chess.utils.model.TestAdapter b/src/test/resources/META-INF/services/com.fathzer.chess.utils.model.TestAdapter
new file mode 100644
index 0000000..5109cb4
--- /dev/null
+++ b/src/test/resources/META-INF/services/com.fathzer.chess.utils.model.TestAdapter
@@ -0,0 +1 @@
+com.fathzer.chess.test.utils.ChessLibAdapter
\ No newline at end of file