掌握使用数组模拟 3×3 游戏棋盘
熟练运用条件判断与循环控制游戏流程
理解胜负判定逻辑的实现方式
能够处理用户输入验证与异常情况
构建完整的控制台交互式游戏程序
游戏规则
两名玩家轮流在 3×3 网格 上放置自己的标记(X 或 O)
X 先手,O 后手
目标:横、竖、斜任一方向连成三个相同标记
若所有格子填满仍未分胜负,则为平局
棋盘布局(编号 1~9)
|---|---|---|
| 1 | 2 | 3 |
|-----------|
| 4 | 5 | 6 |
|-----------|
| 7 | 8 | 9 |
|---|---|---|设计技巧:用 长度为 9 的一维字符串数组 表示棋盘
static String[] board = new String[9]; // 棋盘
static String turn = "X"; // 当前轮到谁初始化棋盘:
for (int i = 0; i < 9; i++) {
board[i] = String.valueOf(i + 1); // ["1", "2", ..., "9"]
}static void printBoard() {
System.out.println("|---|---|---|");
System.out.println("| " + board[0] + " | " + board[1] + " | " + board[2] + " |");
System.out.println("|-----------|");
System.out.println("| " + board[3] + " | " + board[4] + " | " + board[5] + " |");
System.out.println("|-----------|");
System.out.println("| " + board[6] + " | " + board[7] + " | " + board[8] + " |");
System.out.println("|---|---|---|");
}输出效果清晰直观,符合用户预期
胜利组合(共 8 种)
行:(0,1,2), (3,4,5), (6,7,8)
列:(0,3,6), (1,4,7), (2,5,8)
对角线:(0,4,8), (2,4,6)
实现逻辑
static String checkWinner() {
// 检查 8 种胜利情况
for (int i = 0; i < 8; i++) {
String line = switch (i) {
case 0 -> board[0] + board[1] + board[2];
case 1 -> board[3] + board[4] + board[5];
case 2 -> board[6] + board[7] + board[8];
case 3 -> board[0] + board[3] + board[6];
case 4 -> board[1] + board[4] + board[7];
case 5 -> board[2] + board[5] + board[8];
case 6 -> board[0] + board[4] + board[8];
case 7 -> board[2] + board[4] + board[6];
default -> "";
};
if (line.equals("XXX")) return "X";
if (line.equals("OOO")) return "O";
}
// 检查是否平局(所有格子都被占用)
boolean isDraw = true;
for (int i = 0; i < 9; i++) {
if (board[i].equals(String.valueOf(i + 1))) {
isDraw = false; // 还有空位
break;
}
}
if (isDraw) return "draw";
// 游戏继续
System.out.println(turn + "'s turn; enter a slot number to place " + turn + " in:");
return null;
}优化建议:可改用二维数组或常量数组存储胜利组合,提升可读性
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 初始化...
while (winner == null) {
try {
int numInput = in.nextInt();
// 1. 输入范围校验 (1~9)
if (numInput < 1 || numInput > 9) {
System.out.println("Invalid input; re-enter slot number:");
continue;
}
// 2. 检查格子是否已被占用
if (board[numInput - 1].equals(String.valueOf(numInput))) {
board[numInput - 1] = turn; // 放置标记
turn = turn.equals("X") ? "O" : "X"; // 切换回合
printBoard(); // 重绘棋盘
winner = checkWinner(); // 检查结果
} else {
System.out.println("Slot already taken; re-enter slot number:");
}
} catch (InputMismatchException e) {
System.out.println("Invalid input; please enter a number.");
in.nextLine(); // 清除无效输入,防止死循环
}
}
// 输出最终结果
if ("draw".equals(winner)) {
System.out.println("It's a draw! Thanks for playing.");
} else {
System.out.println("Congratulations! " + winner + "'s have won!");
}
}import java.util.InputMismatchException;
import java.util.Scanner;
public class TicTacToe {
static String[] board;
static String turn;
static String checkWinner() {
// 所有可能的胜利组合
int[][] winPatterns = {
{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, // 行
{0, 3, 6}, {1, 4, 7}, {2, 5, 8}, // 列
{0, 4, 8}, {2, 4, 6} // 对角线
};
for (int[] pattern : winPatterns) {
String a = board[pattern[0]];
String b = board[pattern[1]];
String c = board[pattern[2]];
if (a.equals(b) && b.equals(c)) {
return a; // 返回 "X" 或 "O"
}
}
// 检查平局
for (String cell : board) {
if (cell.matches("[1-9]")) {
System.out.println(turn + " 的回合;请输入一个位置数字放置 " + turn + ":");
return null; // 游戏继续
}
}
return "平局";
}
static void printBoard() {
System.out.println("|---|---|---|");
System.out.println("| " + board[0] + " | " + board[1] + " | " + board[2] + " |");
System.out.println("|-----------|");
System.out.println("| " + board[3] + " | " + board[4] + " | " + board[5] + " |");
System.out.println("|-----------|");
System.out.println("| " + board[6] + " | " + board[7] + " | " + board[8] + " |");
System.out.println("|---|---|---|");
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
board = new String[9];
turn = "X";
// 初始化棋盘
for (int i = 0; i < 9; i++) {
board[i] = String.valueOf(i + 1);
}
System.out.println("欢迎来到 3x3 井字棋游戏");
printBoard();
System.out.println("X 先行。请输入一个位置数字 (1-9):");
String winner = null;
while (winner == null) {
try {
int numInput = in.nextInt();
if (numInput < 1 || numInput > 9) {
System.out.println("请输入 1 到 9 之间的数字:");
continue;
}
int index = numInput - 1;
if (board[index].matches("[1-9]")) {
board[index] = turn;
turn = turn.equals("X") ? "O" : "X";
printBoard();
winner = checkWinner();
} else {
System.out.println("位置已被占用!请选择其他位置:");
}
} catch (InputMismatchException e) {
System.out.println("输入无效!请输入一个数字:");
in.nextLine();
}
}
if ("平局".equals(winner)) {
System.out.println("平局!感谢游玩");
} else {
System.out.println("恭喜! " + winner + " 获胜!");
}
in.close();
}
}改进点:
使用
winPatterns二维数组替代switch,逻辑更清晰用正则
matches("[1-9]")判断是否为空位提示信息更友好
欢迎来到 3x3 井字棋游戏
|---|---|---|
| 1 | 2 | 3 |
|-----------|
| 4 | 5 | 6 |
|-----------|
| 7 | 8 | 9 |
|---|---|---|
X 先行。请输入一个位置数字 (1-9):
3
|---|---|---|
| 1 | 2 | X |
|-----------|
| 4 | 5 | 6 |
|-----------|
| 7 | 8 | 9 |
|---|---|---|
O 的回合;请输入一个位置数字放置 O:
5
|---|---|---|
| 1 | 2 | X |
|-----------|
| 4 | O | 6 |
|-----------|
| 7 | 8 | 9 |
|---|---|---|
...
恭喜! X 获胜!人机对战:加入简单 AI(如随机走或优先占中心)
图形界面:使用 Swing 或 JavaFX 实现 GUI
记录战绩:统计胜 / 负 / 平局次数
重玩机制:游戏结束后询问是否再玩一局
输入高亮:显示合法可选位置
可引入 状态模式 管理游戏状态(进行中、X 胜、O 胜、平局)
使用 策略模式 支持不同难度的 AI 玩家
用 一维数组 高效表示 3×3 棋盘
8 种胜利组合 是判定核心,需全面覆盖
输入验证 是健壮性的关键(范围 + 占用检查)
final 不适用于此场景,因棋盘内容需动态更新
控制台游戏注重 清晰提示 与 友好交互
当前 checkWinner() 方法在每次调用时都遍历全部 8 种组合。能否优化为只检查刚落子位置相关的行 / 列 / 对角线?
如果将棋盘改为 4×4 或 5×5,需要修改哪些部分?如何让程序支持任意 N×N 井字棋?
如何防止两个玩家输入相同的符号(如都选 X)?请设计一个玩家选择标记的流程。