返回

纵横博弈,智慧对决——Java实现五子棋

后端

五子棋:起源、算法和 Java 实现

五子棋,又称连珠,是一种起源于中国的传统棋类游戏,因其简单易学、变化无穷而受到广泛喜爱。随着技术的进步,利用人工智能算法来实现五子棋游戏成为可能,本文将深入探讨五子棋背后的算法以及如何使用 Java 来实现它。

五子棋的起源和玩法

五子棋起源于古代中国,是一种两人对弈的棋类游戏。棋盘通常为 15×15 的方格,玩家轮流在空位落子,目标是使自己颜色的棋子在横、竖或斜线上连成一线,即五子相连。落子后,如果一方棋子满足五子连线的条件,则该方获胜。

极大极小算法

五子棋的智能化实现需要一个算法来指导计算机做出决策。极大极小算法 是一种广泛用于博弈游戏的算法,它通过搜索所有可能的走法,选择对己方最有利、对对方最不利的走法来实现计算机的决策。

极大极小算法的核心思想是:

  • 对于最大值玩家,它会选择所有可能走法中得分最高的走法。
  • 对于最小值玩家,它会选择所有可能走法中得分最低的走法。

通过反复应用极大极小算法,计算机可以找到当前局面下最优的走法。

Java 实现

使用 Java 实现五子棋游戏需要创建一个棋盘类、玩家类和游戏逻辑类。

  • 棋盘类 :存储棋盘上的棋子分布情况。
  • 玩家类 :表示游戏中的玩家,包括玩家的名称、棋子颜色等信息。
  • 游戏逻辑类 :实现游戏的核心逻辑,包括判断胜负、生成 AI 走法等。

代码示例

// 棋盘类
public class Board {

    private int[][] board;

    public Board() {
        this.board = new int[15][15];
    }

    // 获取棋盘上的棋子分布情况
    public int[][] getBoard() {
        return board;
    }

    // 落子
    public void makeMove(int x, int y, int player) {
        board[x][y] = player;
    }

    // 判断胜负
    public int checkWinner() {
        // 横向检查
        for (int i = 0; i < 15; i++) {
            for (int j = 0; j < 11; j++) {
                if (board[i][j] != 0 && board[i][j] == board[i][j + 1] && board[i][j] == board[i][j + 2] && board[i][j] == board[i][j + 3] && board[i][j] == board[i][j + 4]) {
                    return board[i][j];
                }
            }
        }

        // 纵向检查
        for (int i = 0; i < 11; i++) {
            for (int j = 0; j < 15; j++) {
                if (board[i][j] != 0 && board[i][j] == board[i + 1][j] && board[i][j] == board[i + 2][j] && board[i][j] == board[i + 3][j] && board[i][j] == board[i + 4][j]) {
                    return board[i][j];
                }
            }
        }

        // 斜向检查
        for (int i = 0; i < 11; i++) {
            for (int j = 0; j < 11; j++) {
                if (board[i][j] != 0 && board[i][j] == board[i + 1][j + 1] && board[i][j] == board[i + 2][j + 2] && board[i][j] == board[i + 3][j + 3] && board[i][j] == board[i + 4][j + 4]) {
                    return board[i][j];
                }
            }
        }

        // 反斜向检查
        for (int i = 0; i < 11; i++) {
            for (int j = 14; j > 3; j--) {
                if (board[i][j] != 0 && board[i][j] == board[i + 1][j - 1] && board[i][j] == board[i + 2][j - 2] && board[i][j] == board[i + 3][j - 3] && board[i][j] == board[i + 4][j - 4]) {
                    return board[i][j];
                }
            }
        }

        // 无胜负
        return 0;
    }
}

// 玩家类
public class Player {

    private String name;
    private int color;

    public Player(String name, int color) {
        this.name = name;
        this.color = color;
    }

    // 获取玩家名称
    public String getName() {
        return name;
    }

    // 获取玩家棋子颜色
    public int getColor() {
        return color;
    }
}

// 游戏逻辑类
public class GameLogic {

    private Board board;
    private Player player1;
    private Player player2;
    private int currentPlayer;

    public GameLogic(Board board, Player player1, Player player2) {
        this.board = board;
        this.player1 = player1;
        this.player2 = player2;
        this.currentPlayer = player1.getColor();
    }

    // 获取当前玩家
    public int getCurrentPlayer() {
        return currentPlayer;
    }

    // 判断胜负
    public int checkWinner() {
        return board.checkWinner();
    }

    // 生成 AI 走法
    public int[] generateAIMove() {
        // 搜索所有可能的走法
        List<int[]> possibleMoves = new ArrayList<>();
        for (int i = 0; i < 15; i++) {
            for (int j = 0; j < 15; j++) {
                if (board.getBoard()[i][j] == 0) {
                    possibleMoves.add(new int[]{i, j});
                }
            }
        }

        // 评估每个走法的得分
        int[] bestMove = null;
        int bestScore = Integer.MIN_VALUE;
        for (int[] move : possibleMoves) {
            int score = minimax(move, 2, Integer.MIN_VALUE, Integer.MAX_VALUE);
            if (score > bestScore) {
                bestScore = score;
                bestMove = move;
            }
        }

        return bestMove;
    }

    // 极大极小算法
    private int minimax(int[] move, int depth, int alpha, int beta) {
        // 判断游戏是否结束
        int winner = board.checkWinner();
        if (winner != 0) {
            return winner == currentPlayer ? 100 : -100;
        }

        // 判断深度是否达到最大深度
        if (depth == 0) {
            return evaluateBoard();
        }

        // 最大值玩家
        if (currentPlayer == player1.getColor()) {
            int bestScore = Integer.MIN_VALUE;
            for (int i = 0; i < 15; i++) {
                for (int j = 0; j < 15; j++) {
                    if (board.getBoard()[i][j] == 0) {
                        board.makeMove(i, j, currentPlayer);
                        int score = minimax(new int[]{i, j}, depth - 1, alpha, beta);
                        board.makeMove(i, j, 0);
                        bestScore = Math.max(bestScore, score);
                        alpha = Math.max(alpha, bestScore);
                        if (beta <= alpha) {
                            break;
                        }
                    }
                }
            }
            return bestScore;
        }

        // 最小值玩家
        else {
            int bestScore = Integer.MAX_VALUE;
            for (int i = 0; i < 15; i++) {
                for (int j = 0; j < 15; j++) {
                    if (board.getBoard()[i][j] == 0) {
                        board.makeMove(i, j, currentPlayer);
                        int score = minimax(new int[]{i, j}, depth - 1, alpha, beta);
                        board.makeMove(i