Moved board evaluation logic to MoveProcessor
This commit is contained in:
parent
acf6bf36c1
commit
9aea4bd9d4
@ -26,40 +26,6 @@ public class Board {
|
|||||||
private Map<Color, Position> kingPos = new HashMap<>();
|
private Map<Color, Position> kingPos = new HashMap<>();
|
||||||
private Log log = new Log();
|
private Log log = new Log();
|
||||||
|
|
||||||
private static final Map<Type, int[][]> positionScores;
|
|
||||||
|
|
||||||
static {
|
|
||||||
positionScores = new HashMap<>();
|
|
||||||
positionScores.put(Type.KING,
|
|
||||||
new int[][] { new int[] { -3, -4, -4, -5, -5, -4, -4, -3 }, new int[] { -3, -4, -4, -5, -4, -4, -4, -3 },
|
|
||||||
new int[] { -3, -4, -4, -5, -4, -4, -4, -3 }, new int[] { -3, -4, -4, -5, -4, -4, -4, -3 },
|
|
||||||
new int[] { -2, -3, -3, -2, -2, -2, -2, -1 }, new int[] { -1, -2, -2, -2, -2, -2, -2, -1 },
|
|
||||||
new int[] { 2, 2, 0, 0, 0, 0, 2, 2 }, new int[] { 2, 3, 1, 0, 0, 1, 3, 2 } });
|
|
||||||
positionScores.put(Type.QUEEN,
|
|
||||||
new int[][] { new int[] { -2, -1, -1, -1, -1, -1, -1, -2 }, new int[] { -1, 0, 0, 0, 0, 0, 0, -1 },
|
|
||||||
new int[] { -1, 0, 1, 1, 1, 1, 0, -1 }, new int[] { -1, 0, 1, 1, 1, 1, 0, -1 }, new int[] { 0, 0, 1, 1, 1, 1, 0, -1 },
|
|
||||||
new int[] { -1, 1, 1, 1, 1, 1, 0, -1 }, new int[] { -1, 0, 1, 0, 0, 0, 0, -1 },
|
|
||||||
new int[] { -2, -1, -1, -1, -1, -1, -1, -2 } });
|
|
||||||
positionScores.put(Type.ROOK,
|
|
||||||
new int[][] { new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }, new int[] { 1, 1, 1, 1, 1, 1, 1, 1 }, new int[] { -1, 0, 0, 0, 0, 0, 0, -1 },
|
|
||||||
new int[] { -1, 0, 0, 0, 0, 0, 0, -1 }, new int[] { -1, 0, 0, 0, 0, 0, 0, -1 }, new int[] { -1, 0, 0, 0, 0, 0, 0, -1 },
|
|
||||||
new int[] { -1, 0, 0, 0, 0, 0, 0, -1 }, new int[] { 0, 0, 0, 1, 1, 0, 0, 0 } });
|
|
||||||
positionScores.put(Type.KNIGHT,
|
|
||||||
new int[][] { new int[] { -5, -4, -3, -3, -3, -3, -4, -5 }, new int[] { -4, -2, 0, 0, 0, 0, -2, -4 },
|
|
||||||
new int[] { -3, 0, 1, 2, 2, 1, 0, -3 }, new int[] { -3, 1, 2, 2, 2, 2, 1, -3 }, new int[] { -3, 0, 2, 2, 2, 2, 0, -1 },
|
|
||||||
new int[] { -3, 1, 1, 2, 2, 1, 1, -3 }, new int[] { -4, -2, 0, 1, 1, 0, -2, -4 },
|
|
||||||
new int[] { -5, -4, -3, -3, -3, -3, -4, -5 } });
|
|
||||||
positionScores.put(Type.BISHOP,
|
|
||||||
new int[][] { new int[] { -2, -1, -1, -1, -1, -1, -1, 2 }, new int[] { -1, 0, 0, 0, 0, 0, 0, -1 },
|
|
||||||
new int[] { -1, 0, 1, 1, 1, 1, 0, -1 }, new int[] { -1, 1, 1, 1, 1, 1, 1, -1 }, new int[] { -1, 0, 1, 1, 1, 1, 0, -1 },
|
|
||||||
new int[] { -1, 1, 1, 1, 1, 1, 1, -1 }, new int[] { -1, 1, 0, 0, 0, 0, 1, -1 },
|
|
||||||
new int[] { -2, -1, -1, -1, -1, -1, -1, -2 } });
|
|
||||||
positionScores.put(Type.PAWN,
|
|
||||||
new int[][] { new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }, new int[] { 5, 5, 5, 5, 5, 5, 5, 5 }, new int[] { 1, 1, 2, 3, 3, 2, 1, 1 },
|
|
||||||
new int[] { 0, 0, 1, 3, 3, 1, 0, 0 }, new int[] { 0, 0, 0, 2, 2, 0, 0, 0 }, new int[] { 0, 0, -1, 0, 0, -1, 0, 0 },
|
|
||||||
new int[] { 0, 1, 1, -2, -2, 1, 1, 0 }, new int[] { 0, 0, 0, 0, 0, 0, 0, 0 } });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the board with the default chess starting position.
|
* Initializes the board with the default chess starting position.
|
||||||
*/
|
*/
|
||||||
@ -338,40 +304,6 @@ public class Board {
|
|||||||
: getMoves(color).isEmpty() || log.getLast().halfmoveClock >= 50 ? GameState.STALEMATE : GameState.NORMAL;
|
: getMoves(color).isEmpty() || log.getLast().halfmoveClock >= 50 ? GameState.STALEMATE : GameState.NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Evaluated the board.
|
|
||||||
*
|
|
||||||
* @param color The color to evaluate for
|
|
||||||
* @return An positive number representing how good the position is
|
|
||||||
*/
|
|
||||||
public int evaluate(Color color) {
|
|
||||||
int score = 0;
|
|
||||||
for (int i = 0; i < 8; i++)
|
|
||||||
for (int j = 0; j < 8; j++)
|
|
||||||
if (boardArr[i][j] != null && boardArr[i][j].getColor() == color) {
|
|
||||||
switch (boardArr[i][j].getType()) {
|
|
||||||
case QUEEN:
|
|
||||||
score += 90;
|
|
||||||
break;
|
|
||||||
case ROOK:
|
|
||||||
score += 50;
|
|
||||||
break;
|
|
||||||
case KNIGHT:
|
|
||||||
score += 30;
|
|
||||||
break;
|
|
||||||
case BISHOP:
|
|
||||||
score += 30;
|
|
||||||
break;
|
|
||||||
case PAWN:
|
|
||||||
score += 10;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (positionScores.containsKey(boardArr[i][j].getType()))
|
|
||||||
score += positionScores.get(boardArr[i][j].getType())[i][color == Color.WHITE ? j : 7 - j];
|
|
||||||
}
|
|
||||||
return score;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialized the board array with the default chess pieces and positions.
|
* Initialized the board array with the default chess pieces and positions.
|
||||||
*/
|
*/
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package dev.kske.chess.game.ai;
|
package dev.kske.chess.game.ai;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
import dev.kske.chess.board.Board;
|
import dev.kske.chess.board.Board;
|
||||||
import dev.kske.chess.board.Move;
|
import dev.kske.chess.board.Move;
|
||||||
import dev.kske.chess.board.Piece.Color;
|
import dev.kske.chess.board.Piece.Color;
|
||||||
|
import dev.kske.chess.board.Piece.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Project: <strong>Chess</strong><br>
|
* Project: <strong>Chess</strong><br>
|
||||||
@ -25,6 +28,40 @@ public class MoveProcessor implements Callable<ProcessingResult> {
|
|||||||
|
|
||||||
private Move bestMove;
|
private Move bestMove;
|
||||||
|
|
||||||
|
private static final Map<Type, int[][]> positionScores;
|
||||||
|
|
||||||
|
static {
|
||||||
|
positionScores = new HashMap<>();
|
||||||
|
positionScores.put(Type.KING,
|
||||||
|
new int[][] { new int[] { -3, -4, -4, -5, -5, -4, -4, -3 }, new int[] { -3, -4, -4, -5, -4, -4, -4, -3 },
|
||||||
|
new int[] { -3, -4, -4, -5, -4, -4, -4, -3 }, new int[] { -3, -4, -4, -5, -4, -4, -4, -3 },
|
||||||
|
new int[] { -2, -3, -3, -2, -2, -2, -2, -1 }, new int[] { -1, -2, -2, -2, -2, -2, -2, -1 },
|
||||||
|
new int[] { 2, 2, 0, 0, 0, 0, 2, 2 }, new int[] { 2, 3, 1, 0, 0, 1, 3, 2 } });
|
||||||
|
positionScores.put(Type.QUEEN,
|
||||||
|
new int[][] { new int[] { -2, -1, -1, -1, -1, -1, -1, -2 }, new int[] { -1, 0, 0, 0, 0, 0, 0, -1 },
|
||||||
|
new int[] { -1, 0, 1, 1, 1, 1, 0, -1 }, new int[] { -1, 0, 1, 1, 1, 1, 0, -1 }, new int[] { 0, 0, 1, 1, 1, 1, 0, -1 },
|
||||||
|
new int[] { -1, 1, 1, 1, 1, 1, 0, -1 }, new int[] { -1, 0, 1, 0, 0, 0, 0, -1 },
|
||||||
|
new int[] { -2, -1, -1, -1, -1, -1, -1, -2 } });
|
||||||
|
positionScores.put(Type.ROOK,
|
||||||
|
new int[][] { new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }, new int[] { 1, 1, 1, 1, 1, 1, 1, 1 }, new int[] { -1, 0, 0, 0, 0, 0, 0, -1 },
|
||||||
|
new int[] { -1, 0, 0, 0, 0, 0, 0, -1 }, new int[] { -1, 0, 0, 0, 0, 0, 0, -1 }, new int[] { -1, 0, 0, 0, 0, 0, 0, -1 },
|
||||||
|
new int[] { -1, 0, 0, 0, 0, 0, 0, -1 }, new int[] { 0, 0, 0, 1, 1, 0, 0, 0 } });
|
||||||
|
positionScores.put(Type.KNIGHT,
|
||||||
|
new int[][] { new int[] { -5, -4, -3, -3, -3, -3, -4, -5 }, new int[] { -4, -2, 0, 0, 0, 0, -2, -4 },
|
||||||
|
new int[] { -3, 0, 1, 2, 2, 1, 0, -3 }, new int[] { -3, 1, 2, 2, 2, 2, 1, -3 }, new int[] { -3, 0, 2, 2, 2, 2, 0, -1 },
|
||||||
|
new int[] { -3, 1, 1, 2, 2, 1, 1, -3 }, new int[] { -4, -2, 0, 1, 1, 0, -2, -4 },
|
||||||
|
new int[] { -5, -4, -3, -3, -3, -3, -4, -5 } });
|
||||||
|
positionScores.put(Type.BISHOP,
|
||||||
|
new int[][] { new int[] { -2, -1, -1, -1, -1, -1, -1, 2 }, new int[] { -1, 0, 0, 0, 0, 0, 0, -1 },
|
||||||
|
new int[] { -1, 0, 1, 1, 1, 1, 0, -1 }, new int[] { -1, 1, 1, 1, 1, 1, 1, -1 }, new int[] { -1, 0, 1, 1, 1, 1, 0, -1 },
|
||||||
|
new int[] { -1, 1, 1, 1, 1, 1, 1, -1 }, new int[] { -1, 1, 0, 0, 0, 0, 1, -1 },
|
||||||
|
new int[] { -2, -1, -1, -1, -1, -1, -1, -2 } });
|
||||||
|
positionScores.put(Type.PAWN,
|
||||||
|
new int[][] { new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }, new int[] { 5, 5, 5, 5, 5, 5, 5, 5 }, new int[] { 1, 1, 2, 3, 3, 2, 1, 1 },
|
||||||
|
new int[] { 0, 0, 1, 3, 3, 1, 0, 0 }, new int[] { 0, 0, 0, 2, 2, 0, 0, 0 }, new int[] { 0, 0, -1, 0, 0, -1, 0, 0 },
|
||||||
|
new int[] { 0, 1, 1, -2, -2, 1, 1, 0 }, new int[] { 0, 0, 0, 0, 0, 0, 0, 0 } });
|
||||||
|
}
|
||||||
|
|
||||||
public MoveProcessor(Board board, List<Move> rootMoves, Color color, int maxDepth, int alphaBetaThreshold) {
|
public MoveProcessor(Board board, List<Move> rootMoves, Color color, int maxDepth, int alphaBetaThreshold) {
|
||||||
this.board = board;
|
this.board = board;
|
||||||
this.rootMoves = rootMoves;
|
this.rootMoves = rootMoves;
|
||||||
@ -43,8 +80,8 @@ public class MoveProcessor implements Callable<ProcessingResult> {
|
|||||||
int bestValue = Integer.MIN_VALUE;
|
int bestValue = Integer.MIN_VALUE;
|
||||||
for (Move move : moves) {
|
for (Move move : moves) {
|
||||||
board.move(move);
|
board.move(move);
|
||||||
int teamValue = board.evaluate(color);
|
int teamValue = evaluate(board, color);
|
||||||
int enemyValue = board.evaluate(color.opposite());
|
int enemyValue = evaluate(board, color.opposite());
|
||||||
int valueChange = teamValue - enemyValue;
|
int valueChange = teamValue - enemyValue;
|
||||||
|
|
||||||
if (depth < maxDepth && valueChange >= alphaBetaThreshold)
|
if (depth < maxDepth && valueChange >= alphaBetaThreshold)
|
||||||
@ -59,4 +96,38 @@ public class MoveProcessor implements Callable<ProcessingResult> {
|
|||||||
}
|
}
|
||||||
return bestValue;
|
return bestValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluated a board.
|
||||||
|
*
|
||||||
|
* @param color The color to evaluate for
|
||||||
|
* @return An positive number representing how good the position is
|
||||||
|
*/
|
||||||
|
private int evaluate(Board board, Color color) {
|
||||||
|
int score = 0;
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
for (int j = 0; j < 8; j++)
|
||||||
|
if (board.getBoardArr()[i][j] != null && board.getBoardArr()[i][j].getColor() == color) {
|
||||||
|
switch (board.getBoardArr()[i][j].getType()) {
|
||||||
|
case QUEEN:
|
||||||
|
score += 90;
|
||||||
|
break;
|
||||||
|
case ROOK:
|
||||||
|
score += 50;
|
||||||
|
break;
|
||||||
|
case KNIGHT:
|
||||||
|
score += 30;
|
||||||
|
break;
|
||||||
|
case BISHOP:
|
||||||
|
score += 30;
|
||||||
|
break;
|
||||||
|
case PAWN:
|
||||||
|
score += 10;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (positionScores.containsKey(board.getBoardArr()[i][j].getType()))
|
||||||
|
score += positionScores.get(board.getBoardArr()[i][j].getType())[i][color == Color.WHITE ? j : 7 - j];
|
||||||
|
}
|
||||||
|
return score;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user