pretty convincing

This commit is contained in:
2025-04-18 23:51:42 +02:00
parent dd6e033528
commit 031d3d94ec
6 changed files with 146 additions and 12 deletions

View File

@@ -1,5 +1,6 @@
package chess; package chess;
import chess.ai.AI;
import chess.ai.AlphaBetaAI; import chess.ai.AlphaBetaAI;
import chess.ai.DumbAI; import chess.ai.DumbAI;
import chess.ai.HungryAI; import chess.ai.HungryAI;
@@ -19,10 +20,10 @@ public class SwingMain {
Window window = new Window(commandExecutor, false); Window window = new Window(commandExecutor, false);
commandExecutor.addListener(window); commandExecutor.addListener(window);
DumbAI ai = new DumbAI(commandExecutor, Color.White); AI ai = new AlphaBetaAI(commandExecutor, Color.White, 3);
commandExecutor.addListener(ai); commandExecutor.addListener(ai);
AlphaBetaAI ai2 = new AlphaBetaAI(commandExecutor, Color.Black, 3); AI ai2 = new AlphaBetaAI(commandExecutor, Color.Black, 3);
commandExecutor.addListener(ai2); commandExecutor.addListener(ai2);
// Window window2 = new Window(ai2.getSimulation(), false); // Window window2 = new Window(ai2.getSimulation(), false);

View File

@@ -17,11 +17,13 @@ import chess.model.Color;
import chess.model.Coordinate; import chess.model.Coordinate;
import chess.model.Game; import chess.model.Game;
import chess.model.Move; import chess.model.Move;
import chess.model.Piece;
public class AlphaBetaAI extends AI { public class AlphaBetaAI extends AI {
private final int searchDepth; private final int searchDepth;
private final PieceCost pieceCost; private final PieceCost pieceCost;
private final PiecePosCost piecePosCost;
private final CommandExecutor simulation; private final CommandExecutor simulation;
private final Game gameSimulation; private final Game gameSimulation;
@@ -32,6 +34,7 @@ public class AlphaBetaAI extends AI {
super(commandExecutor, color); super(commandExecutor, color);
this.searchDepth = searchDepth; this.searchDepth = searchDepth;
this.pieceCost = new PieceCost(color); this.pieceCost = new PieceCost(color);
this.piecePosCost = new PiecePosCost(color);
this.gameSimulation = new Game(); this.gameSimulation = new Game();
this.simulation = new CommandExecutor(this.gameSimulation, new EmptyGameDispatcher()); this.simulation = new CommandExecutor(this.gameSimulation, new EmptyGameDispatcher());
} }
@@ -45,7 +48,9 @@ public class AlphaBetaAI extends AI {
int result = 0; int result = 0;
for (int i = 0; i < Coordinate.VALUE_MAX; i++) { for (int i = 0; i < Coordinate.VALUE_MAX; i++) {
for (int j = 0; j < Coordinate.VALUE_MAX; j++) { for (int j = 0; j < Coordinate.VALUE_MAX; j++) {
result += pieceCost.getCost(board.pieceAt(new Coordinate(i, j))); Coordinate coordinate = new Coordinate(i, j);
Piece piece = board.pieceAt(coordinate);
result += pieceCost.getCost(piece) + piecePosCost.getEvaluation(piece, coordinate);
} }
} }
if (this.gameSimulation.getPlayerTurn() != color) if (this.gameSimulation.getPlayerTurn() != color)
@@ -60,7 +65,7 @@ public class AlphaBetaAI extends AI {
} else { } else {
if (this.gameSimulation.getBoard().isKingInCheck(currentTurn)) if (this.gameSimulation.getBoard().isKingInCheck(currentTurn))
return GREAT_MOVE; return GREAT_MOVE;
return getBoardEvaluation() - PieceCost.PAWN; return getBoardEvaluation() + PieceCost.PAWN;
} }
} }

View File

@@ -26,7 +26,7 @@ public class HungryAI extends AI {
private int getMoveCost(Move move) { private int getMoveCost(Move move) {
Piece piece = pieceAt(move.getDeadPieceCoords()); Piece piece = pieceAt(move.getDeadPieceCoords());
return pieceCost.getCost(piece); return -pieceCost.getCost(piece);
} }
private List<Move> getBestMoves() { private List<Move> getBestMoves() {

View File

@@ -14,12 +14,12 @@ public class PieceCost implements PieceVisitor<Integer> {
private final Color player; private final Color player;
public static final int BISHOP = 3; public static final int BISHOP = 30;
public static final int KING = 90; public static final int KING = 900;
public static final int KNIGHT = 3; public static final int KNIGHT = 30;
public static final int PAWN = 1; public static final int PAWN = 10;
public static final int QUEEN = 9; public static final int QUEEN = 90;
public static final int ROOK = 5; public static final int ROOK = 50;
public PieceCost(Color color) { public PieceCost(Color color) {
this.player = color; this.player = color;

View File

@@ -0,0 +1,128 @@
package chess.ai;
import java.util.Arrays;
import java.util.List;
import chess.model.Color;
import chess.model.Coordinate;
import chess.model.Piece;
import chess.model.PieceVisitor;
import chess.model.pieces.Bishop;
import chess.model.pieces.King;
import chess.model.pieces.Knight;
import chess.model.pieces.Pawn;
import chess.model.pieces.Queen;
import chess.model.pieces.Rook;
public class PiecePosCost implements PieceVisitor<List<Integer>> {
private final Color color;
private static final List<Integer> BISHOP = Arrays.asList(
-2, -1, -1, -1, -1, -1, -1, -2, -1,
0, 0, 0, 0, 0, 0, -1,
-1, 0, 0, 1, 1, 0, 0, -1,
-1, 0, 0, 1, 1, 0, 0, -1,
-1, 0, 0, 1, 1, 0, 0, -1,
-1, 1, 1, 1, 1, 1, 1, -1,
-1, 0, 0, 0, 0, 0, 0, -1,
-2, -1, -1, -1, -1, -1, -1, -2);
private static final List<Integer> KING = Arrays.asList(
-3, -4, -4, -5, -5, -4, -4, -3,
-3, -4, -4, -5, -5, -4, -4, -3,
-3, -4, -4, -5, -5, -4, -4, -3,
-3, -4, -4, -5, -5, -4, -4, -3,
-2, -3, -3, -4, -4, -3, -3, -2,
-1, -2, -2, -2, -2, -2, -2, -1,
2, 2, 0, 0, 0, 0, 2, 2,
2, 3, 1, 0, 0, 1, 3, 2);
private static final List<Integer> KNIGHT = Arrays.asList(
-5, -4, -3, -3, -3, -3, -4, -5, -4,
-2, 0, 0, 0, 0, -2, -4,
-3, 0, 1, 1, 1, 1, 0, -3,
-3, 0, 1, 2, 2, 1, 0, -3,
-3, 0, 1, 2, 2, 1, 0, -3,
-3, 0, 1, 1, 1, 1, 0, -3,
-4, -2, 0, 0, 0, 0, -2, -4,
-5, -4, -3, -3, -3, -3, -4, -5);
private static final List<Integer> PAWN = Arrays.asList(
0, 0, 0, 0, 0, 0, 0, 0,
5, 5, 5, 5, 5, 5, 5, 5,
1, 1, 2, 3, 3, 2, 1, 1,
0, 0, 1, 2, 2, 1, 0, 0,
0, 0, 1, 2, 2, 1, 0, 0,
0, 0, -1, 0, 0, -1, 0, 0,
0, 1, 1, -2, -2, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0);
private static final List<Integer> QUEEN = Arrays.asList(
-2, -1, -1, 0, 0, -1, -1, -2,
-1, 0, 0, 0, 0, 0, 0, -1,
-1, 0, 0, 0, 0, 0, 0, -1,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
-1, 0, 0, 0, 0, 0, 0, -1,
-1, 0, 0, 0, 0, 0, 0, -1,
-2, -1, -1, 0, 0, -1, -1, -2);
private static final List<Integer> ROOK = Arrays.asList(
0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 0,
-1, 0, 0, 0, 0, 0, 0, 0, -1,
-1, 0, 0, 0, 0, 0, 0, 0, -1,
-1, 0, 0, 0, 0, 0, 0, 0, -1,
-1, 0, 0, 0, 0, 0, 0, 0, -1,
-1, 0, 0, 0, 0, 0, 0, 0, -1,
0, 0, 0, 0, 1, 1, 0, 0, 0);
public PiecePosCost(Color color) {
this.color = color;
}
public int getEvaluation(Piece piece, Coordinate coordinate) {
if (piece == null)
return 0;
List<Integer> positions = visit(piece);
int y = piece.getColor() == Color.Black ? (Coordinate.VALUE_MAX - 1 - coordinate.getY()) : coordinate.getY();
Coordinate newCoords = new Coordinate(coordinate.getX(), y);
assert newCoords.isValid();
int result = positions.get(newCoords.toIndex());
if (piece.getColor() != color)
return -result;
return result;
}
@Override
public List<Integer> visitPiece(Bishop bishop) {
return BISHOP;
}
@Override
public List<Integer> visitPiece(King king) {
return KING;
}
@Override
public List<Integer> visitPiece(Knight knight) {
return KNIGHT;
}
@Override
public List<Integer> visitPiece(Pawn pawn) {
return PAWN;
}
@Override
public List<Integer> visitPiece(Queen queen) {
return QUEEN;
}
@Override
public List<Integer> visitPiece(Rook rook) {
return ROOK;
}
}

View File

@@ -56,7 +56,7 @@ public class PgnExport {
} }
private static String gameEnd(Game game) { private static String gameEnd(Game game) {
switch (game.checkGameStatus()) { switch (game.checkGameStatus(game.getPlayerTurn())) {
case Draw: case Draw:
case Pat: case Pat:
return "1/2-1/2"; return "1/2-1/2";