Untitled
unknown
plain_text
a year ago
4.7 kB
5
Indexable
public class ConnectFourAI {
private static final int AI_PLAYER = 1;
private static final int HUMAN_PLAYER = -1;
private static final int EMPTY = 0;
private static final int ROWS = 6;
private static final int COLUMNS = 7;
private static final int WINNING_SCORE = 1000;
private static final int MAX_DEPTH = 6; // Maksymalna głębokość przeszukiwania
// Główna funkcja, która wybiera najlepszy ruch
public int getBestMove(int[][] board) {
int bestScore = Integer.MIN_VALUE;
int bestMove = -1;
for (int col = 0; col < COLUMNS; col++) {
if (isValidMove(board, col)) {
int[][] newBoard = makeMove(board, col, AI_PLAYER);
int score = minimax(newBoard, MAX_DEPTH, Integer.MIN_VALUE, Integer.MAX_VALUE, false);
if (score > bestScore) {
bestScore = score;
bestMove = col;
}
}
}
return bestMove;
}
// Algorytm Minimax z Alpha-Beta Pruning
private int minimax(int[][] board, int depth, int alpha, int beta, boolean isMaximizingPlayer) {
int boardScore = evaluateBoard(board);
// Warunki końcowe: wygrana, przegrana, remis lub maksymalna głębokość
if (Math.abs(boardScore) == WINNING_SCORE || depth == 0 || isBoardFull(board)) {
return boardScore;
}
if (isMaximizingPlayer) {
int maxEval = Integer.MIN_VALUE;
for (int col = 0; col < COLUMNS; col++) {
if (isValidMove(board, col)) {
int[][] newBoard = makeMove(board, col, AI_PLAYER);
int eval = minimax(newBoard, depth - 1, alpha, beta, false);
maxEval = Math.max(maxEval, eval);
alpha = Math.max(alpha, eval);
if (beta <= alpha) {
break; // Alpha-Beta Pruning
}
}
}
return maxEval;
} else {
int minEval = Integer.MAX_VALUE;
for (int col = 0; col < COLUMNS; col++) {
if (isValidMove(board, col)) {
int[][] newBoard = makeMove(board, col, HUMAN_PLAYER);
int eval = minimax(newBoard, depth - 1, alpha, beta, true);
minEval = Math.min(minEval, eval);
beta = Math.min(beta, eval);
if (beta <= alpha) {
break; // Alpha-Beta Pruning
}
}
}
return minEval;
}
}
// Funkcja oceny planszy
private int evaluateBoard(int[][] board) {
// Logika oceny planszy: wykrywanie wygranej i ocenianie stanu gry
// To tutaj trzeba dodać np. ocenę za bliskie cztery w rzędzie, wygrane itp.
// W tej wersji uproszczonej po prostu zwracamy 1000 jeśli AI wygrał, -1000 jeśli gracz wygrał
if (checkWin(board, AI_PLAYER)) {
return WINNING_SCORE;
} else if (checkWin(board, HUMAN_PLAYER)) {
return -WINNING_SCORE;
}
return 0; // Neutralny wynik, jeśli nikt nie wygrał
}
// Sprawdza, czy dany ruch jest poprawny (czy kolumna nie jest pełna)
private boolean isValidMove(int[][] board, int col) {
return board[0][col] == EMPTY;
}
// Wykonuje ruch na planszy
private int[][] makeMove(int[][] board, int col, int player) {
int[][] newBoard = copyBoard(board);
for (int row = ROWS - 1; row >= 0; row--) {
if (newBoard[row][col] == EMPTY) {
newBoard[row][col] = player;
break;
}
}
return newBoard;
}
// Sprawdza, czy plansza jest pełna (remis)
private boolean isBoardFull(int[][] board) {
for (int col = 0; col < COLUMNS; col++) {
if (board[0][col] == EMPTY) {
return false;
}
}
return true;
}
// Sprawdza, czy którykolwiek gracz wygrał
private boolean checkWin(int[][] board, int player) {
// Logika do sprawdzania 4 w jednym rzędzie (pion, poziom, skośnie)
// To powinno obejmować sprawdzanie całej planszy dla danego gracza
return false; // To jest placeholder, tutaj wprowadź faktyczne sprawdzanie
}
// Tworzy kopię planszy
private int[][] copyBoard(int[][] board) {
int[][] newBoard = new int[ROWS][COLUMNS];
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLUMNS; j++) {
newBoard[i][j] = board[i][j];
}
}
return newBoard;Editor is loading...
Leave a Comment