两人小游戏,玩家轮流在 3x3 棋盘上放置标记(X 或 O),先连成三子者获胜。如果棋盘填满且无人获胜,则为平局。
示例图
思考:x和y轴,可以用二维数组表示
在这里插入图片描述


一、核心代码

package com.mantis.micor;

public class TicTacToe {

    String[][] board = new String[3][3]; // 棋盘
    int count = 1;                       // 已下步数

    // 游戏结果枚举
    public enum Result {
        /**
         * 玩家获胜
         */
        WIN,
        /**
         * 游戏继续
         */
        CONTINUE,
        /**
         * 棋盘已满,平局
         */
        DRAW,
        /**
         * 错误,坐标越界或格子已被占用
         */
        ERROR
    }

    public Result placeMark(int x, int y, String player) {
        // 越界检查
        if (x < 0 || x > 2 || y < 0 || y > 2) {
            return Result.ERROR;
        }
        // 棋盘是否已满
        if (count > 9) {
            return Result.DRAW;
        }
        // 格子是否已被占用
        if (board[x][y] != null) {
            return Result.ERROR;
        }

        // 放置玩家标记
        board[x][y] = player;
        count++;

        // 判断胜利条件(行、列、主对角线、副对角线)
        if ((board[x][0] != null && board[x][0].equals(board[x][1]) && board[x][1].equals(board[x][2])) ||
            (board[0][y] != null && board[0][y].equals(board[1][y]) && board[1][y].equals(board[2][y])) ||
            (board[0][0] != null && board[0][0].equals(board[1][1]) && board[1][1].equals(board[2][2])) ||
            (board[0][2] != null && board[0][2].equals(board[1][1]) && board[1][1].equals(board[2][0]))) {
            return Result.WIN;
        }

        return Result.CONTINUE; // 游戏继续
    }

    public static void main(String[] args) {
        TicTacToe ticTacToe = new TicTacToe();

        // 测试落子
        System.out.println(ticTacToe.placeMark(0, 0, "X")); // CONTINUE
        System.out.println(ticTacToe.placeMark(0, 1, "X")); // CONTINUE
        System.out.println(ticTacToe.placeMark(0, 2, "X")); // WIN
        System.out.println(ticTacToe.placeMark(0, 2, "X")); // ERROR,重复落子
        System.out.println(ticTacToe.placeMark(3, 0, "X")); // ERROR,越界
    }
}

二、代码解析

1. 棋盘表示

  • 使用二维数组 String[3][3] 表示棋盘
  • 空格为 null,落子后存储 "X""O"
  • count 用于记录已经下的步数,用于平局判断

2. 枚举类型 Result

public enum Result {
    WIN,       // 玩家获胜
    CONTINUE,  // 游戏继续
    DRAW,      // 棋盘已满,平局
    ERROR      // 错误,坐标越界或格子已被占用
}
  • 注释清楚说明每个状态的含义
  • 防止空指针或错误输入

3. 核心方法 placeMark

  1. 越界检查:保证行列在 0~2 范围内

  2. 棋盘满检查:超过 9 步返回平局

  3. 格子占用检查:已落子返回错误

  4. 落子并计数

  5. 胜负判断:检查行、列、主对角线、副对角线

    • 空指针安全判断:!= null

三、特点

  • 安全:防止空指针异常
  • 胜负判断清晰:行、列、对角线直观
  • 易扩展:如需轮流玩家、棋盘打印可在此基础上拓展

四、技巧

  1. 空指针处理:在调用 equals 前判断非空

  2. 逻辑条理清楚:行、列、对角线分开判断容易讲解

  3. 单步测试main 演示关键场景即可

    • 连续三子获胜
    • 重复落子报错
    • 越界报错

✅ 这样就是一个完整、安全、可用的井字棋实现,逻辑清晰、枚举注释完整。

更多推荐