From 9aea4bd9d433a80c77b490c1654d240736aa5f34 Mon Sep 17 00:00:00 2001 From: kske Date: Wed, 30 Oct 2019 17:11:57 +0100 Subject: [PATCH] Moved board evaluation logic to MoveProcessor --- src/dev/kske/chess/board/Board.java | 68 ----------------- src/dev/kske/chess/game/ai/MoveProcessor.java | 75 ++++++++++++++++++- 2 files changed, 73 insertions(+), 70 deletions(-) diff --git a/src/dev/kske/chess/board/Board.java b/src/dev/kske/chess/board/Board.java index 3de825a..60f0014 100644 --- a/src/dev/kske/chess/board/Board.java +++ b/src/dev/kske/chess/board/Board.java @@ -26,40 +26,6 @@ public class Board { private Map kingPos = new HashMap<>(); private Log log = new Log(); - private static final Map 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. */ @@ -338,40 +304,6 @@ public class Board { : 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. */ diff --git a/src/dev/kske/chess/game/ai/MoveProcessor.java b/src/dev/kske/chess/game/ai/MoveProcessor.java index f683983..2c73ddd 100644 --- a/src/dev/kske/chess/game/ai/MoveProcessor.java +++ b/src/dev/kske/chess/game/ai/MoveProcessor.java @@ -1,11 +1,14 @@ package dev.kske.chess.game.ai; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.Callable; import dev.kske.chess.board.Board; import dev.kske.chess.board.Move; import dev.kske.chess.board.Piece.Color; +import dev.kske.chess.board.Piece.Type; /** * Project: Chess
@@ -25,6 +28,40 @@ public class MoveProcessor implements Callable { private Move bestMove; + private static final Map 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 rootMoves, Color color, int maxDepth, int alphaBetaThreshold) { this.board = board; this.rootMoves = rootMoves; @@ -43,8 +80,8 @@ public class MoveProcessor implements Callable { int bestValue = Integer.MIN_VALUE; for (Move move : moves) { board.move(move); - int teamValue = board.evaluate(color); - int enemyValue = board.evaluate(color.opposite()); + int teamValue = evaluate(board, color); + int enemyValue = evaluate(board, color.opposite()); int valueChange = teamValue - enemyValue; if (depth < maxDepth && valueChange >= alphaBetaThreshold) @@ -59,4 +96,38 @@ public class MoveProcessor implements Callable { } 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; + } }