remove all break
This commit is contained in:
parent
224bcfb60e
commit
2508a51ee0
|
|
@ -5,18 +5,10 @@ import java.util.Random;
|
|||
|
||||
public class AutoPlayer {
|
||||
|
||||
// Piece values used for evaluation and best move to do by calculating later the profit and losses (PnL)
|
||||
private final int PAWN_VALUE = 1;
|
||||
private final int KNIGHT_VALUE = 3;
|
||||
private final int BISHOP_VALUE = 3;
|
||||
private final int ROOK_VALUE = 5;
|
||||
private final int QUEEN_VALUE = 9;
|
||||
private final int KING_VALUE = 100; // High value to prioritize king safety
|
||||
|
||||
/// This chess AI uses a minimax algorithm with alpha-beta pruning to look 2 moves ahead so depth 4
|
||||
// it will evaluate the material value, the center control, and the pawn advancement (ELO 1400-1800)
|
||||
|
||||
private final int MAX_DEPTH = 4;
|
||||
private final int MAX_DEPTH = 5;
|
||||
|
||||
// Time limit for search in milliseconds to avoid bug or latence during the game
|
||||
private final long TIME_LIMIT_MS = 5000; // 5 seconds max
|
||||
|
|
@ -112,27 +104,33 @@ public class AutoPlayer {
|
|||
|
||||
if (isMaximizing) {//white turn (maximizing player)
|
||||
int maxEval = Integer.MIN_VALUE;//initialize with lowest value
|
||||
for (Move move : possibleMoves) {//try each move
|
||||
boolean shouldContinue = true;
|
||||
|
||||
for (int i = 0; i < possibleMoves.size() && shouldContinue; i++) {
|
||||
Move move = possibleMoves.get(i);//try each move
|
||||
Board boardCopy = new Board(board);//create a copy of the board
|
||||
applyMoveToBoard(boardCopy, move);//apply the move
|
||||
int eval = minimax(boardCopy, depth - 1, alpha, beta, false);//evaluate the resulting position
|
||||
maxEval = Math.max(maxEval, eval);//gives best evaluation
|
||||
alpha = Math.max(alpha, eval);//gives the alpha value
|
||||
if (beta <= alpha) {
|
||||
break; // Beta cutoff
|
||||
shouldContinue = false; // Beta cutoff - instead of break
|
||||
}
|
||||
}
|
||||
return maxEval;//best evaluation found
|
||||
} else {//black turn
|
||||
int minEval = Integer.MAX_VALUE;//initialize with highest value
|
||||
for (Move move : possibleMoves) {
|
||||
boolean shouldContinue = true;
|
||||
|
||||
for (int i = 0; i < possibleMoves.size() && shouldContinue; i++) {
|
||||
Move move = possibleMoves.get(i);
|
||||
Board boardCopy = new Board(board);
|
||||
applyMoveToBoard(boardCopy, move);
|
||||
int eval = minimax(boardCopy, depth - 1, alpha, beta, true);
|
||||
minEval = Math.min(minEval, eval);
|
||||
beta = Math.min(beta, eval);//gives beta value
|
||||
if (beta <= alpha) {
|
||||
break; // Alpha cutoff
|
||||
shouldContinue = false; // Alpha cutoff - instead of break
|
||||
}
|
||||
}
|
||||
return minEval;//best evaluation found
|
||||
|
|
@ -148,8 +146,8 @@ public class AutoPlayer {
|
|||
|
||||
// Prioritize captures based on a function of the Most Valuable Victim and the Least Valuable Attacker with the system of points
|
||||
if (move.getCapturedPiece() != null) {
|
||||
score += 10 * getPieceValue(move.getCapturedPiece().getType()) -
|
||||
getPieceValue(move.getMovedPiece().getType()) / 10; // Higher score for capturing valuable pieces with less valuable ones
|
||||
score += 10 * move.getCapturedPiece().getType().getValue() -
|
||||
move.getMovedPiece().getType().getValue() / 10; // Higher score for capturing valuable pieces with less valuable ones
|
||||
}
|
||||
|
||||
// Store the score with the move
|
||||
|
|
@ -169,7 +167,7 @@ public class AutoPlayer {
|
|||
|
||||
// Material evaluation
|
||||
for (Piece piece : board.getPieces()) {
|
||||
int pieceValue = getPieceValue(piece.getType());//get value of this piece
|
||||
int pieceValue = piece.getType().getValue();//get value of this piece using getValue()
|
||||
if (piece.isWhite()) {
|
||||
score += pieceValue;//add value for white
|
||||
} else {
|
||||
|
|
@ -210,20 +208,6 @@ public class AutoPlayer {
|
|||
return score;//return final score
|
||||
}
|
||||
|
||||
//Gets the value of a piece
|
||||
|
||||
private int getPieceValue(PieceType type) {
|
||||
switch (type) {
|
||||
case Pawn: return PAWN_VALUE;
|
||||
case Knight: return KNIGHT_VALUE;
|
||||
case Bishop: return BISHOP_VALUE;
|
||||
case Rook: return ROOK_VALUE;
|
||||
case Queen: return QUEEN_VALUE;
|
||||
case King: return KING_VALUE;
|
||||
default: return 0;// safety net to protect from bug
|
||||
}
|
||||
}
|
||||
|
||||
//Generates all possible moves for a player
|
||||
|
||||
private ArrayList<Move> generateAllPossibleMoves(Board board, boolean isWhite) {
|
||||
|
|
|
|||
|
|
@ -116,24 +116,16 @@ public class Board {
|
|||
} else {
|
||||
// convert each piece of both color into a character
|
||||
Piece piece = board[x][y];
|
||||
char pieceChar;
|
||||
|
||||
switch (piece.getType()) { // switch function avoids too many if-else
|
||||
case King: pieceChar = 'K'; break;
|
||||
case Queen: pieceChar = 'Q'; break;
|
||||
case Bishop: pieceChar = 'B'; break;
|
||||
case Knight: pieceChar = 'N'; break; // N because we already have King
|
||||
case Rook: pieceChar = 'R'; break;
|
||||
case Pawn: pieceChar = 'P'; break;
|
||||
default: pieceChar = '?'; break; // safety net
|
||||
}
|
||||
// associate piece to letter
|
||||
String pieceSymbol = piece.getType().getSummary();
|
||||
|
||||
// Make black pieces in lowercase
|
||||
if (!piece.isWhite()) {
|
||||
pieceChar = Character.toLowerCase(pieceChar);
|
||||
pieceSymbol = pieceSymbol.toLowerCase();
|
||||
}
|
||||
|
||||
str.append(pieceChar).append(" "); // gives structure to the output
|
||||
str.append(pieceSymbol).append(" "); // gives structure to the output
|
||||
}
|
||||
}
|
||||
str.append("\n"); // change of row
|
||||
|
|
@ -182,7 +174,7 @@ public class Board {
|
|||
for (int[] pos : highlightedPositions) {
|
||||
if (pos[0] == x && pos[1] == y) {
|
||||
valid = true;
|
||||
break;
|
||||
// Removed break statement
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -234,6 +226,7 @@ public class Board {
|
|||
for (int[] pos : highlightedPositions) {
|
||||
if (pos[0] == x && pos[1] == y) {
|
||||
return true;
|
||||
// Removed break statement (not actually needed here since return exits the method)
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
@ -382,3 +375,5 @@ public class Board {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -80,21 +80,24 @@ public class Piece {
|
|||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
// No break needed - end of case
|
||||
return moves;
|
||||
|
||||
case Rook:
|
||||
addLinearMoves(board, moves, x, y, 1, 0);
|
||||
addLinearMoves(board, moves, x, y, -1, 0);
|
||||
addLinearMoves(board, moves, x, y, 0, 1);
|
||||
addLinearMoves(board, moves, x, y, 0, -1);
|
||||
break;
|
||||
// No break needed - end of case
|
||||
return moves;
|
||||
|
||||
case Bishop:
|
||||
addLinearMoves(board, moves, x, y, 1, 1);
|
||||
addLinearMoves(board, moves, x, y, -1, 1);
|
||||
addLinearMoves(board, moves, x, y, 1, -1);
|
||||
addLinearMoves(board, moves, x, y, -1, -1);
|
||||
break;
|
||||
// No break needed - end of case
|
||||
return moves;
|
||||
|
||||
case Queen:
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
|
|
@ -104,7 +107,8 @@ public class Piece {
|
|||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
// No break needed - end of case
|
||||
return moves;
|
||||
|
||||
case King:
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
|
|
@ -131,7 +135,8 @@ public class Piece {
|
|||
}
|
||||
|
||||
}
|
||||
break;
|
||||
// No break needed - end of case
|
||||
return moves;
|
||||
|
||||
case Knight:
|
||||
int[][] jumps = {
|
||||
|
|
@ -148,9 +153,11 @@ public class Piece {
|
|||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
// No break needed - end of case
|
||||
return moves;
|
||||
}
|
||||
|
||||
// Default return if no case matched (shouldn't happen)
|
||||
return moves;
|
||||
}
|
||||
|
||||
|
|
@ -181,7 +188,9 @@ public class Piece {
|
|||
private void addLinearMoves(Board board, ArrayList<int[]> moves, int x, int y, int dx, int dy) {
|
||||
int nx = x + dx;
|
||||
int ny = y + dy;
|
||||
while (board.isInBounds(nx, ny)) {
|
||||
boolean shouldContinue = true;
|
||||
|
||||
while (board.isInBounds(nx, ny) && shouldContinue) {
|
||||
Piece target = board.getPiece(nx, ny);
|
||||
if (target == null) {
|
||||
moves.add(new int[]{nx, ny});
|
||||
|
|
@ -189,10 +198,13 @@ public class Piece {
|
|||
if (target.isWhite() != this.isWhite()) {
|
||||
moves.add(new int[]{nx, ny});
|
||||
}
|
||||
break;
|
||||
shouldContinue = false; // Instead of break, set a flag to exit the loop
|
||||
}
|
||||
|
||||
if (shouldContinue) {
|
||||
nx += dx;
|
||||
ny += dy;
|
||||
}
|
||||
nx += dx;
|
||||
ny += dy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -25,4 +25,14 @@ public enum PieceType {
|
|||
return PieceType.Queen;
|
||||
}
|
||||
|
||||
|
||||
//values of the pieces for the autoplayer
|
||||
public int getValue() {
|
||||
if(this == PieceType.Pawn) return 1;
|
||||
if(this == PieceType.Knight || this == PieceType.Bishop) return 3;
|
||||
if(this == PieceType.Rook) return 5;
|
||||
if(this == PieceType.Queen) return 9;
|
||||
if(this == PieceType.King) return 100;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue