-
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.
- Loading branch information
Showing
8 changed files
with
586 additions
and
0 deletions.
There are no files selected for viewing
89 changes: 89 additions & 0 deletions
89
src/main/java/com/fathzer/chess/utils/evaluators/pesto/PestoEvaluator.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,89 @@ | ||
package com.fathzer.chess.utils.evaluators.pesto; | ||
|
||
public class PestoEvaluator { | ||
// Piece types | ||
public static final int PAWN = 0; | ||
public static final int KNIGHT = 1; | ||
public static final int BISHOP = 2; | ||
public static final int ROOK = 3; | ||
public static final int QUEEN = 4; | ||
public static final int KING = 5; | ||
|
||
// Board representation | ||
public static final int WHITE = 0; | ||
public static final int BLACK = 1; | ||
|
||
// Piece definitions | ||
public static final int WHITE_PAWN = (2 * PAWN + WHITE); | ||
public static final int BLACK_PAWN = (2 * PAWN + BLACK); | ||
public static final int WHITE_KNIGHT = (2 * KNIGHT + WHITE); | ||
public static final int BLACK_KNIGHT = (2 * KNIGHT + BLACK); | ||
public static final int WHITE_BISHOP = (2 * BISHOP + WHITE); | ||
public static final int BLACK_BISHOP = (2 * BISHOP + BLACK); | ||
public static final int WHITE_ROOK = (2 * ROOK + WHITE); | ||
public static final int BLACK_ROOK = (2 * ROOK + BLACK); | ||
public static final int WHITE_QUEEN = (2 * QUEEN + WHITE); | ||
public static final int BLACK_QUEEN = (2 * QUEEN + BLACK); | ||
public static final int WHITE_KING = (2 * KING + WHITE); | ||
public static final int BLACK_KING = (2 * KING + BLACK); | ||
public static final int EMPTY = BLACK_KING + 1; | ||
|
||
public static int sideToMove; | ||
public static int[] board = new int[64]; | ||
|
||
public static int[] mgValue = {82, 337, 365, 477, 1025, 0}; | ||
public static int[] egValue = {94, 281, 297, 512, 936, 0}; | ||
|
||
public static int[][] mgPestoTable = { /* Add mg tables here */ }; | ||
public static int[][] egPestoTable = { /* Add eg tables here */ }; | ||
|
||
public static int[][] mgTable = new int[12][64]; | ||
public static int[][] egTable = new int[12][64]; | ||
|
||
public static final int[] gamePhaseInc = {0, 0, 1, 1, 1, 1, 2, 2, 4, 4, 0, 0}; | ||
|
||
public static void initTables() { | ||
for (int p = PAWN, pc = WHITE_PAWN; p <= KING; pc += 2, p++) { | ||
for (int sq = 0; sq < 64; sq++) { | ||
mgTable[pc][sq] = mgValue[p] + mgPestoTable[p][sq]; | ||
egTable[pc][sq] = egValue[p] + egPestoTable[p][sq]; | ||
mgTable[pc + 1][sq] = mgValue[p] + mgPestoTable[p][flip(sq)]; | ||
egTable[pc + 1][sq] = egValue[p] + egPestoTable[p][flip(sq)]; | ||
} | ||
} | ||
} | ||
|
||
public static int flip(int square) { | ||
return square ^ 56; | ||
} | ||
|
||
public static int other(int side) { | ||
return side ^ 1; | ||
} | ||
|
||
public static int pcolor(int p) { | ||
return p & 1; | ||
} | ||
|
||
public static int eval() { | ||
int[] mg = {0, 0}; | ||
int[] eg = {0, 0}; | ||
int gamePhase = 0; | ||
|
||
for (int sq = 0; sq < 64; ++sq) { | ||
int pc = board[sq]; | ||
if (pc != EMPTY) { | ||
mg[pcolor(pc)] += mgTable[pc][sq]; | ||
eg[pcolor(pc)] += egTable[pc][sq]; | ||
gamePhase += gamePhaseInc[pc]; | ||
} | ||
} | ||
|
||
int mgScore = mg[sideToMove] - mg[other(sideToMove)]; | ||
int egScore = eg[sideToMove] - eg[other(sideToMove)]; | ||
int mgPhase = Math.min(gamePhase, 24); | ||
int egPhase = 24 - mgPhase; | ||
|
||
return (mgScore * mgPhase + egScore * egPhase) / 24; | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
.../java/com/fathzer/chess/utils/evaluators/simplified/two/AbstractSimplifiedEvaluator2.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,11 @@ | ||
package com.fathzer.chess.utils.evaluators.simplified.two; | ||
|
||
import java.util.function.Supplier; | ||
|
||
import com.fathzer.chess.utils.adapters.MoveData; | ||
import com.fathzer.games.MoveGenerator; | ||
import com.fathzer.games.ai.evaluation.ZeroSumEvaluator; | ||
|
||
public abstract class AbstractSimplifiedEvaluator2 <M, B extends MoveGenerator<M>> implements ZeroSumEvaluator<M,B>, Supplier<MoveData<M,B>> { | ||
|
||
} |
97 changes: 97 additions & 0 deletions
97
src/main/java/com/fathzer/chess/utils/evaluators/simplified/two/PiecesOnlySquareTable.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,97 @@ | ||
package com.fathzer.chess.utils.evaluators.simplified.two; | ||
|
||
import com.fathzer.chess.utils.evaluators.utils.AbstractPieceSquareTableEvaluator; | ||
import com.fathzer.games.MoveGenerator; | ||
|
||
public abstract class PiecesOnlySquareTable<M, B extends MoveGenerator<M>> extends AbstractPieceSquareTableEvaluator<M, B> { | ||
private static final int[] PIECE_VALUES = {0, 100, 320, 330, 500, 900, 20000}; | ||
private static final int [][] PIECE_POSITION_VALUES = new int[][] { | ||
// Just to have index equals to piece type codes | ||
new int[0], | ||
// PAWN | ||
new int[] { | ||
0, 0, 0, 0, 0, 0, 0, 0, | ||
50, 50, 50, 50, 50, 50, 50, 50, | ||
10, 10, 20, 30, 30, 20, 10, 10, | ||
5, 5, 10, 25, 25, 10, 5, 5, | ||
0, 0, 0, 20, 20, 0, 0, 0, | ||
5, -5,-10, 0, 0,-10, -5, 5, | ||
5, 10, 10,-20,-20, 10, 10, 5, | ||
0, 0, 0, 0, 0, 0, 0, 0}, | ||
// KNIGHT | ||
new int[] { | ||
-50,-40,-30,-30,-30,-30,-40,-50, | ||
-40,-20, 0, 0, 0, 0,-20,-40, | ||
-30, 0, 10, 15, 15, 10, 0,-30, | ||
-30, 5, 15, 20, 20, 15, 5,-30, | ||
-30, 0, 15, 20, 20, 15, 0,-30, | ||
-30, 5, 10, 15, 15, 10, 5,-30, | ||
-40,-20, 0, 5, 5, 0,-20,-40, | ||
-50,-40,-30,-30,-30,-30,-40,-50}, | ||
// BISHOP | ||
new int[] { | ||
-20,-10,-10,-10,-10,-10,-10,-20, | ||
-10, 0, 0, 0, 0, 0, 0,-10, | ||
-10, 0, 5, 10, 10, 5, 0,-10, | ||
-10, 5, 5, 10, 10, 5, 5,-10, | ||
-10, 0, 10, 10, 10, 10, 0,-10, | ||
-10, 10, 10, 10, 10, 10, 10,-10, | ||
-10, 5, 0, 0, 0, 0, 5,-10, | ||
-20,-10,-10,-10,-10,-10,-10,-20}, | ||
// ROOK | ||
new int[] { | ||
0, 0, 0, 0, 0, 0, 0, 0, | ||
5, 10, 10, 10, 10, 10, 10, 5, | ||
-5, 0, 0, 0, 0, 0, 0, -5, | ||
-5, 0, 0, 0, 0, 0, 0, -5, | ||
-5, 0, 0, 0, 0, 0, 0, -5, | ||
-5, 0, 0, 0, 0, 0, 0, -5, | ||
-5, 0, 0, 0, 0, 0, 0, -5, | ||
0, 0, 0, 5, 5, 0, 0, 0}, | ||
// QUEEN | ||
new int[] { | ||
-20,-10,-10, -5, -5,-10,-10,-20, | ||
-10, 0, 0, 0, 0, 0, 0,-10, | ||
-10, 0, 5, 5, 5, 5, 0,-10, | ||
-5, 0, 5, 5, 5, 5, 0, -5, | ||
0, 0, 5, 5, 5, 5, 0, -5, | ||
-10, 5, 5, 5, 5, 5, 0,-10, | ||
-10, 0, 5, 0, 0, 0, 0,-10, | ||
-20,-10,-10, -5, -5,-10,-10,-20}, | ||
// KING | ||
new int[] { | ||
0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0 | ||
}}; | ||
|
||
static { | ||
for (int i = 0; i < PIECE_VALUES.length; i++) { | ||
add(PIECE_POSITION_VALUES[i], PIECE_VALUES[i]); | ||
} | ||
} | ||
|
||
protected PiecesOnlySquareTable() { | ||
super(); | ||
} | ||
|
||
protected PiecesOnlySquareTable(int eval) { | ||
super(eval); | ||
} | ||
|
||
private static void add(int[] array, int value) { | ||
for (int i = 0; i < array.length; i++) { | ||
array[i] = array[i]+value; | ||
} | ||
} | ||
|
||
@Override | ||
protected int getPositionValue(int piece, int index) { | ||
return PIECE_POSITION_VALUES[piece][index]; | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
src/main/java/com/fathzer/chess/utils/evaluators/utils/AbstractComposedEvaluator.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,48 @@ | ||
package com.fathzer.chess.utils.evaluators.utils; | ||
|
||
import java.util.LinkedList; | ||
import java.util.List; | ||
import java.util.function.Supplier; | ||
|
||
import com.fathzer.chess.utils.adapters.BoardExplorerBuilder; | ||
import com.fathzer.chess.utils.adapters.MoveData; | ||
import com.fathzer.games.MoveGenerator; | ||
import com.fathzer.games.ai.evaluation.ZeroSumEvaluator; | ||
|
||
public abstract class AbstractComposedEvaluator<M, B extends MoveGenerator<M>> implements ZeroSumEvaluator<M,B>, BoardExplorerBuilder<B>, Supplier<MoveData<M,B>> { | ||
private MoveData<M, B> moveData; | ||
private List<ComposableEvaluator<M, B>> evaluators; | ||
|
||
protected AbstractComposedEvaluator() { | ||
moveData = get(); | ||
evaluators = new LinkedList<>(); | ||
} | ||
|
||
@Override | ||
public void prepareMove(B board, M move) { | ||
if (!moveData.update(move, board)) { | ||
return; | ||
} | ||
evaluators.forEach(ev -> ev.prepareMove(moveData)); | ||
} | ||
|
||
@Override | ||
public void init(B board) { | ||
evaluators.forEach(ev -> ev.init(board)); | ||
} | ||
|
||
@Override | ||
public void commitMove() { | ||
evaluators.forEach(ZeroSumEvaluator::commitMove); | ||
} | ||
|
||
@Override | ||
public void unmakeMove() { | ||
evaluators.forEach(ev -> ev.unmakeMove()); | ||
} | ||
|
||
@Override | ||
public int evaluateAsWhite(B board) { | ||
return evaluators.stream().mapToInt(ev -> ev.evaluateAsWhite(board)).sum(); | ||
} | ||
} |
131 changes: 131 additions & 0 deletions
131
...main/java/com/fathzer/chess/utils/evaluators/utils/AbstractPieceSquareTableEvaluator.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,131 @@ | ||
package com.fathzer.chess.utils.evaluators.utils; | ||
|
||
import static com.fathzer.chess.utils.Pieces.KING; | ||
import static com.fathzer.chess.utils.Pieces.ROOK; | ||
|
||
import java.util.concurrent.atomic.AtomicInteger; | ||
|
||
import com.fathzer.chess.utils.Pieces; | ||
import com.fathzer.chess.utils.adapters.BoardExplorer; | ||
import com.fathzer.chess.utils.adapters.BoardExplorerBuilder; | ||
import com.fathzer.chess.utils.adapters.MoveData; | ||
import com.fathzer.games.MoveGenerator; | ||
import com.fathzer.games.ai.evaluation.Evaluator; | ||
import com.fathzer.games.util.Stack; | ||
|
||
/** An incremental evaluator based on a <a href="https://www.chessprogramming.org/Piece-Square_Tables"> piece square table</a> implementation. | ||
*/ | ||
public abstract class AbstractPieceSquareTableEvaluator<M, B extends MoveGenerator<M>> implements ComposableEvaluator<M,B>, BoardExplorerBuilder<B> { | ||
|
||
private final Stack<AtomicInteger> states; //TODO implement something lighter | ||
private int toCommit; | ||
|
||
protected AbstractPieceSquareTableEvaluator() { | ||
this.states = new Stack<>(AtomicInteger::new); | ||
} | ||
|
||
protected AbstractPieceSquareTableEvaluator(int eval) { | ||
this(); | ||
this.states.get().set(eval); | ||
} | ||
|
||
@Override | ||
public void init(B board) { | ||
states.clear(); | ||
states.set(new AtomicInteger(getRawEvaluation(getExplorer(board)))); | ||
} | ||
|
||
private int getRawEvaluation(BoardExplorer explorer) { | ||
int points = 0; | ||
do { | ||
final int p = explorer.getPiece(); | ||
final int piece = Math.abs(p); | ||
final int index = explorer.getIndex(); | ||
final boolean isBlack = p<0; | ||
points += getPositionValue(piece, isBlack, index); | ||
} while (explorer.next()); | ||
return points; | ||
} | ||
|
||
@Override | ||
public void prepareMove(MoveData<M, B> moveData) { | ||
final boolean isBlack = moveData.getMovingPiece()<0; | ||
int moving = Math.abs(moveData.getMovingPiece()); | ||
final int movingIndex = moveData.getMovingIndex(); | ||
int inc = 0; | ||
if (moving==KING) { | ||
// Be cautious with castling | ||
int rookIndex = moveData.getCastlingRookIndex(); | ||
if (rookIndex>=0) { | ||
// It's a castling move, update rook positions values | ||
inc = getPositionValue(ROOK, isBlack, moveData.getCastlingRookDestinationIndex()) - getPositionValue(ROOK, isBlack, rookIndex); | ||
} | ||
} | ||
// Remove the old position value of the moving piece | ||
inc -= getPositionValue(moving, isBlack, movingIndex); | ||
final int promoType = moveData.getPromotionType(); | ||
if (promoType!=0) { | ||
// If promotion, update the moving piece | ||
moving = promoType; | ||
} | ||
// Adds the new position value of the | ||
inc += getPositionValue(moving, isBlack, moveData.getMovingDestination()); | ||
int captured = moveData.getCapturedType(); | ||
if (captured!=0) { | ||
// If the move is a capture add its position value | ||
inc -= getPositionValue(captured, !isBlack, moveData.getCapturedIndex()); | ||
} | ||
toCommit = states.get().get() + inc; | ||
} | ||
|
||
@Override | ||
public void commitMove() { | ||
states.next(); | ||
states.set(new AtomicInteger(toCommit)); | ||
} | ||
|
||
@Override | ||
public void unmakeMove() { | ||
states.previous(); | ||
} | ||
|
||
@Override | ||
public Evaluator<M, B> fork() { | ||
return fork(states.get().get()); | ||
} | ||
|
||
@Override | ||
public int evaluateAsWhite(B board) { | ||
return states.get().get(); | ||
} | ||
|
||
/** Gets the position value associated with a white piece at an index. | ||
* @param piece The piece type as define in {@link Pieces} | ||
* @param index The index of the piece on the board as defined in {@link BoardExplorer} | ||
* @return an integer | ||
*/ | ||
protected abstract int getPositionValue(int piece, int index); | ||
|
||
/** Gets the value (from the white point of view) of a piece at a position. | ||
* @param piece The piece type as define in {@link Pieces} | ||
* @param black true if piece is black | ||
* @param index The index of the piece on the board as defined in {@link BoardExplorer} | ||
* @return an integer | ||
*/ | ||
private int getPositionValue(int piece, boolean black, int index) { | ||
if (black) { | ||
final int row = 7 - index/8; | ||
final int col = index%8; | ||
index = row*8 + col; | ||
return -getPositionValue(piece, index); | ||
} else { | ||
return getPositionValue(piece, index); | ||
} | ||
} | ||
|
||
/** Creates a new instance initialized with current evaluation that will become the initial state of created instance. | ||
* @param state The initial state. | ||
* @return a new evaluator of the same class as this, the same view point, and initialized with the state. | ||
*/ | ||
protected abstract AbstractPieceSquareTableEvaluator<M, B> fork(int evaluation); | ||
} |
14 changes: 14 additions & 0 deletions
14
src/main/java/com/fathzer/chess/utils/evaluators/utils/ComposableEvaluator.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,14 @@ | ||
package com.fathzer.chess.utils.evaluators.utils; | ||
|
||
import com.fathzer.chess.utils.adapters.MoveData; | ||
import com.fathzer.games.MoveGenerator; | ||
import com.fathzer.games.ai.evaluation.ZeroSumEvaluator; | ||
|
||
public interface ComposableEvaluator<M, B extends MoveGenerator<M>> extends ZeroSumEvaluator<M, B> { | ||
void prepareMove(MoveData<M, B> moveData); | ||
|
||
@Override | ||
default void prepareMove(B board, M move) { | ||
throw new IllegalStateException("Prepare move is not implemented"); | ||
} | ||
} |
Oops, something went wrong.