-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adapts to games-core changes + adds AbstractBasicQuiesceEvaluator
- Loading branch information
Showing
6 changed files
with
159 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
src/main/java/com/fathzer/chess/utils/evaluators/quiesce/AbstractBasicQuiesceEvaluator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package com.fathzer.chess.utils.evaluators.quiesce; | ||
|
||
import java.util.List; | ||
|
||
import com.fathzer.games.MoveGenerator; | ||
import com.fathzer.games.MoveGenerator.MoveConfidence; | ||
import com.fathzer.games.ai.SearchContext; | ||
import com.fathzer.games.ai.SearchStatistics; | ||
import com.fathzer.games.ai.evaluation.QuiesceEvaluator; | ||
|
||
/** A basic quiescence search evaluator. | ||
*/ | ||
public abstract class AbstractBasicQuiesceEvaluator<M, B extends MoveGenerator<M>> implements QuiesceEvaluator<M,B> { | ||
/** Constructor. | ||
*/ | ||
protected AbstractBasicQuiesceEvaluator() { | ||
super(); | ||
} | ||
|
||
@Override | ||
public int evaluate(SearchContext<M, B> context, int alpha, int beta) { | ||
return quiesce(context, alpha, beta, 0); | ||
} | ||
|
||
private int quiesce(SearchContext<M, B> context, int alpha, int beta, int quiesceDepth) { | ||
final SearchStatistics statistics = context.getStatistics(); | ||
final int standPat = context.getEvaluator().evaluate(context.getGamePosition()); | ||
statistics.evaluationDone(); | ||
if (standPat>=beta) { | ||
return beta; | ||
} | ||
if (alpha < standPat) { | ||
alpha = standPat; | ||
} | ||
final List<M> moves = getMoves(context, quiesceDepth); | ||
statistics.movesGenerated(moves.size()); | ||
for (M move : moves) { | ||
if (makeMove(context, move)) { | ||
statistics.movePlayed(); | ||
final int score = -quiesce(context, -beta, -alpha, quiesceDepth+1); | ||
context.unmakeMove(); | ||
if (score >= beta) { | ||
return beta; | ||
} | ||
if (score > alpha) { | ||
alpha = score; | ||
} | ||
} | ||
} | ||
return alpha; | ||
} | ||
|
||
/** Gets the list of quiesce moves. | ||
* @param context The search context (can be used to get the board) | ||
* @param quiesceDepth The quiesce depth. 0 for the first level | ||
* @return A list of moves to analyze deeper, an empty list to stop deepening. | ||
*/ | ||
protected abstract List<M> getMoves(SearchContext<M, B> context, int quiesceDepth); | ||
|
||
/** Make a move. | ||
* <br>The default implementation make the move with a {@link MoveConfidence#PSEUDO_LEGAL} confidence. | ||
* @param context The context on which to apply the move | ||
* @param move The move to play | ||
* @return true if the move was successfully played, false if the move is illegal | ||
*/ | ||
protected boolean makeMove(SearchContext<M, B> context, M move) { | ||
return context.makeMove(move, MoveConfidence.PSEUDO_LEGAL); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
src/test/java/com/fathzer/chess/utils/evaluators/ChessLibNaiveEvaluator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package com.fathzer.chess.utils.evaluators; | ||
|
||
import com.fathzer.chess.utils.adapters.BoardExplorer; | ||
import com.fathzer.chess.utils.adapters.chesslib.BasicMoveDecoder; | ||
import com.fathzer.chess.utils.adapters.chesslib.ChessLibBoardExplorer; | ||
import com.fathzer.chess.utils.adapters.chesslib.ChessLibMoveGenerator; | ||
import com.github.bhlangonijr.chesslib.move.Move; | ||
|
||
public class ChessLibNaiveEvaluator extends AbstractNaiveEvaluator<Move, ChessLibMoveGenerator> { | ||
public ChessLibNaiveEvaluator() { | ||
super(); | ||
} | ||
|
||
private ChessLibNaiveEvaluator(int score) { | ||
super(score); | ||
} | ||
|
||
@Override | ||
public AbstractNaiveEvaluator<Move, ChessLibMoveGenerator> fork(int score) { | ||
return new ChessLibNaiveEvaluator(score); | ||
} | ||
|
||
@Override | ||
public BoardExplorer getExplorer(ChessLibMoveGenerator board) { | ||
return new ChessLibBoardExplorer(board.getBoard()); | ||
} | ||
|
||
@Override | ||
protected int getCapturedType(ChessLibMoveGenerator board, Move move) { | ||
return BasicMoveDecoder.getCapturedType(board, move); | ||
} | ||
|
||
@Override | ||
protected int getPromotionType(ChessLibMoveGenerator board, Move move) { | ||
return BasicMoveDecoder.getPromotionType(board, move); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
src/test/java/com/fathzer/chess/utils/evaluators/quiesce/MinimaxTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package com.fathzer.chess.utils.evaluators.quiesce; | ||
|
||
import static com.github.bhlangonijr.chesslib.Square.*; | ||
import static org.junit.jupiter.api.Assertions.*; | ||
|
||
import java.util.List; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import com.fathzer.chess.utils.adapters.chesslib.ChessLibMoveGenerator; | ||
import com.fathzer.chess.utils.evaluators.ChessLibNaiveEvaluator; | ||
import com.fathzer.games.MoveGenerator.MoveConfidence; | ||
import com.fathzer.games.ai.SearchContext; | ||
import com.fathzer.games.ai.evaluation.Evaluator; | ||
import com.fathzer.games.ai.evaluation.QuiesceEvaluator; | ||
|
||
import com.github.bhlangonijr.chesslib.Board; | ||
import com.github.bhlangonijr.chesslib.move.Move; | ||
|
||
class MinimaxTest { | ||
static class SimpleQuiesce extends AbstractBasicQuiesceEvaluator<Move, ChessLibMoveGenerator> { | ||
private SimpleQuiesce() { | ||
super(); | ||
} | ||
|
||
@Override | ||
protected List<Move> getMoves(SearchContext<Move, ChessLibMoveGenerator> context, int quiesceDepth) { | ||
return context.getGamePosition().getBoard().pseudoLegalCaptures(); | ||
} | ||
} | ||
|
||
@Test | ||
void testQuiesce() { | ||
final Evaluator<Move, ChessLibMoveGenerator> ev = new ChessLibNaiveEvaluator(); | ||
final Board board = new Board(); | ||
board.loadFromFen("3n1rk1/1pp2p1p/2r2bq1/2P1p1p1/3pP3/PQ1P2PP/1R3PB1/2B2RK1 w - - 2 26"); | ||
final ChessLibMoveGenerator mg = new ChessLibMoveGenerator(board); | ||
final SearchContext<Move, ChessLibMoveGenerator> context = SearchContext.get(mg, ()->ev); | ||
final QuiesceEvaluator<Move, ChessLibMoveGenerator> qev = new SimpleQuiesce(); | ||
|
||
assertTrue(context.makeMove(new Move(B3, F7), MoveConfidence.UNSAFE)); | ||
assertEquals(800, qev.evaluate(context, Integer.MIN_VALUE+1, Integer.MAX_VALUE)); | ||
context.unmakeMove(); | ||
|
||
assertTrue(context.makeMove(new Move(B3, B7), MoveConfidence.UNSAFE)); | ||
assertEquals(600, qev.evaluate(context, Integer.MIN_VALUE+1, Integer.MAX_VALUE)); | ||
context.unmakeMove(); | ||
} | ||
} |