Untitled

 avatar
unknown
plain_text
6 months ago
4.7 kB
3
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