返回

编程高手教你用Java轻松实现五子棋人机对战,赶快学起来

后端

五子棋:简单规则,深邃策略

前言

五子棋,一种源自中国的古老棋盘游戏,以其简单易懂的规则和错综复杂的策略,风靡全球。本文将深入探索五子棋的世界,从基本规则到AI算法,带您领略这款游戏的魅力。

一、五子棋的基本规则

五子棋的规则简单明了:

  • 在19×19的棋盘上进行,棋子下在棋盘的交点处。
  • 两名玩家轮流下棋,一人执黑棋,一人执白棋。
  • 先手将五颗己方棋子连成一条直线(水平、垂直或对角线)即可获胜。
  • 棋盘上下满,则游戏平局。

二、AI算法在五子棋中的应用

随着人工智能技术的不断发展,五子棋的AI算法也日益完善。从简单的贪心算法到复杂的搜索算法,AI算法已经能够与人类顶尖棋手分庭抗礼。

一种常见的贪心算法思路是:在每次落子时,评估所有可能的落子点,选择能够最大程度地阻止对手获胜的落子点。

三、Java代码示例

下面是一个用Java实现的五子棋人机对战代码示例:

import java.util.Scanner;

public class Gomoku {

    // 棋盘大小
    private static final int BOARD_SIZE = 19;

    // 方向数组
    private static final int[][] DIRECTIONS = {{0, 1}, {1, 0}, {1, 1}, {-1, 1}};

    // 棋盘
    private static int[][] board = new int[BOARD_SIZE][BOARD_SIZE];

    // 当前玩家
    private static int currentPlayer = 1; // 1为人类,2为电脑

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 初始化棋盘
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                board[i][j] = 0;
            }
        }

        // 游戏循环
        while (true) {
            // 人类玩家回合
            if (currentPlayer == 1) {
                System.out.println("人类玩家回合");
                System.out.print("输入行号(1-19):");
                int row = scanner.nextInt();
                System.out.print("输入列号(1-19):");
                int column = scanner.nextInt();

                // 检查落子是否合法
                if (row < 1 || row > BOARD_SIZE || column < 1 || column > BOARD_SIZE || board[row - 1][column - 1] != 0) {
                    System.out.println("非法落子");
                    continue;
                }

                // 落子
                board[row - 1][column - 1] = 1;

                // 检查是否获胜
                if (hasWon(1)) {
                    System.out.println("人类玩家获胜!");
                    break;
                }

                // 电脑玩家回合
            } else {
                System.out.println("电脑玩家回合");

                // 寻找最优落子点
                int bestMoveRow = -1;
                int bestMoveColumn = -1;
                int bestMoveScore = Integer.MIN_VALUE;
                for (int i = 0; i < BOARD_SIZE; i++) {
                    for (int j = 0; j < BOARD_SIZE; j++) {
                        // 检查落子是否合法
                        if (board[i][j] != 0) {
                            continue;
                        }

                        // 落子
                        board[i][j] = 2;

                        // 评估落子
                        int score = evaluateMove(2);

                        // 撤销落子
                        board[i][j] = 0;

                        // 更新最优落子点
                        if (score > bestMoveScore) {
                            bestMoveRow = i;
                            bestMoveColumn = j;
                            bestMoveScore = score;
                        }
                    }
                }

                // 落子
                board[bestMoveRow][bestMoveColumn] = 2;

                // 检查是否获胜
                if (hasWon(2)) {
                    System.out.println("电脑玩家获胜!");
                    break;
                }
            }

            // 切换玩家
            currentPlayer = 3 - currentPlayer;

            // 绘制棋盘
            for (int i = 0; i < BOARD_SIZE; i++) {
                for (int j = 0; j < BOARD_SIZE; j++) {
                    if (board[i][j] == 0) {
                        System.out.print("-");
                    } else if (board[i][j] == 1) {
                        System.out.print("O");
                    } else {
                        System.out.print("X");
                    }
                }
                System.out.println();
            }
        }

        // 关闭扫描器
        scanner.close();
    }

    // 判断是否获胜
    private static boolean hasWon(int player) {
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                if (board[i][j] == player) {
                    // 检查所有方向是否存在连五
                    for (int[] direction : DIRECTIONS) {
                        int count = 0;
                        for (int k = 0; k < 5; k++) {
                            int row = i + k * direction[0];
                            int column = j + k * direction[1];
                            if (row >= 0 && row < BOARD_SIZE && column >= 0 && column < BOARD_SIZE && board[row][column] == player) {
                                count++;
                            }
                        }
                        if (count == 5) {
                            return true;
                        }
                    }
                }
            }
        }

        return false;
    }

    // 评估落子
    private static int evaluateMove(int player) {
        // 统计己方连五的个数
        int score = 0;
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                if (board[i][j] == player) {
                    // 检查所有方向是否存在连五
                    for (int[] direction : DIRECTIONS) {
                        int count = 0;
                        for (int k = 0; k < 5; k++) {
                            int row = i + k * direction[0];
                            int column = j + k * direction[1];
                            if (row >= 0 && row < BOARD_SIZE && column >= 0 && column < BOARD_SIZE && board[row][column] == player) {
                                count++;
                            }
                        }
                        if (count == 5) {
                            score += 10000;
                            break;
                        }
                    }
                }
            }
        }

        // 统计对方连五的个数
        int opponent = 3 - player;
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                if (board[i][j] == opponent) {
                    // 检查所有方向是否存在连五
                    for (int[] direction : DIRECTIONS) {
                        int count = 0;
                        for (int k = 0; k < 5; k++) {
                            int row = i + k * direction[0];
                            int column = j + k * direction[1];
                            if (row >= 0 && row < BOARD_SIZE && column >= 0 && column < BOARD_SIZE && board[row][column] == opponent) {
                                count++;
                            }
                        }
                        if (count == 5) {
                            score -= 10000;
                            break;
                        }
                    }
                }
            }
        }

        return score;
    }
}

四、常见问题解答

  1. 什么是五子棋?

五子棋是一种中国传统棋类游戏,玩法简单,目标是将五颗棋子连成一条直线(水平、垂直或对角线)。

  1. 五子棋有哪些规则?

五子棋的规则非常简单:

  • 在19×19的棋盘上进行。
  • 两名玩家轮流下棋。
  • 先手将五颗己方棋子连成一条直线即可获胜。
  • 棋盘上下满,则游戏平局。
  1. **五