# 井字棋 **Repository Path**: yjj5/tic-tac-toe ## Basic Information - **Project Name**: 井字棋 - **Description**: 井字棋游戏 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-10-16 - **Last Updated**: 2025-10-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 井字棋游戏 (Tic-Tac-Toe) 一个使用C语言实现的智能井字棋游戏,支持双人对战和玩家vs电脑模式。 ## 🎮 游戏特性 - ✅ 经典3x3井字棋棋盘 - ✅ **双人对战模式**(玩家 vs 玩家) - ✅ **单人游戏模式**(玩家 vs 智能电脑) - ✅ **智能AI对手** - 使用Minimax算法,几乎不可战胜 - ✅ 完整的胜利检测(行、列、对角线) - ✅ 平局检测 - ✅ 用户友好的界面显示 - ✅ 严格的输入验证和错误处理 - ✅ 直观的位置编号系统 ## 🎯 游戏规则 1. 游戏在3x3的棋盘上进行 2. 玩家轮流放置自己的符号(X和O) 3. 玩家X总是先开始 4. 率先在水平、垂直或对角线方向连成一线的玩家获胜 5. 如果棋盘填满且无人获胜则为平局 ## 🤖 AI实现难点 ### 1. 判断胜负 - 检查8种获胜组合:3行 + 3列 + 2条对角线 - 实时胜负状态检测 - 平局判断(棋盘满且无胜者) ### 2. 玩家输入合法性 - 输入范围验证(1-9) - 位置占用检测 - 非法字符输入处理 - 输入缓冲区清理 ## 🚀 快速开始 ### 编译要求 - GCC编译器 - 支持C99标准 - 类Unix系统(Linux、macOS)或Windows with MinGW ### 编译和运行 使用Makefile(推荐): ```bash # 编译游戏 make # 编译并运行 make run # 清理编译文件 make clean # 重新编译 make rebuild ``` 手动编译: ```bash gcc -Wall -Wextra -std=c99 -o tic_tac_toe tic_tac_toe.c ./tic_tac_toe ``` ## 🎲 游戏界面 ### 启动界面 ``` ===================================== 🎮 井字棋游戏 🎮 ===================================== 游戏规则: • 在3x3棋盘上轮流下棋 • 率先在横向、纵向或对角线连成一线者获胜 • 支持玩家对战电脑或双人对战 • 输入1-9选择位置 ===================================== 请选择游戏模式: 1. 双人对战 (玩家 vs 玩家) 2. 单人游戏 (玩家 vs 电脑) 请输入选择 (1-2): ``` ### 棋盘显示 ``` 1 2 3 1 X | | O ----------- 2 | X | ----------- 3 O | | X 位置对应图: 1 2 3 1 1 | 2 | 3 ----------- 2 4 | 5 | 6 ----------- 3 7 | 8 | 9 ``` ### 游戏模式 #### 单人模式(玩家 vs 电脑) ``` 游戏开始!您是 X,电脑是 O 玩家 X 先手 当前玩家: X 请输入位置 (行-列格式如2-2): 2-2 ✅ 您选择了第2行第2列(位置5) 电脑正在思考... 电脑选择了一个位置 ``` #### 双人模式(玩家 vs 玩家) ``` 游戏开始!双人对战模式 玩家 X 先手 当前玩家: X 请输入位置 (行-列格式如2-2): 5 ✅ 您选择了位置5(第2行第2列) 当前玩家: O 请输入位置 (行-列格式如2-2): 1-1 ✅ 您选择了第1行第1列(位置1) ``` ## 📝 输入格式说明 支持两种输入格式: ### 方式1:位置编号(1-9) 根据位置对应图直接输入数字: - 输入 `5` = 中心位置(第2行第2列) - 输入 `1` = 左上角(第1行第1列) - 输入 `9` = 右下角(第3行第3列) ### 方式2:行-列格式(如2-2) 按行列坐标输入: - 输入 `2-2` = 第2行第2列(中心位置) - 输入 `1-1` = 第1行第1列(左上角) - 输入 `3-3` = 第3行第3列(右下角) 程序会自动识别输入格式并显示确认信息。 ## 🔧 技术实现 ### 文件结构 ``` 井字棋/ ├── tic_tac_toe.c # 主程序文件 ├── Makefile # 编译配置 └── README.md # 项目文档 ``` ### 核心算法 #### Minimax算法实现 ```c int minimax(char board[3][3], int depth, bool is_maximizing) { int score = evaluate_board(); // 终止条件 if (score == 10) return score - depth; // AI胜利 if (score == -10) return score + depth; // 玩家胜利 if (is_board_full()) return 0; // 平局 if (is_maximizing) { // AI回合:寻找最大值 int best = -1000; for (每个空位置) { 尝试AI移动; best = max(best, minimax(board, depth+1, false)); 撤销移动; } return best; } else { // 玩家回合:寻找最小值 int best = 1000; for (每个空位置) { 尝试玩家移动; best = min(best, minimax(board, depth+1, true)); 撤销移动; } return best; } } ``` ### 核心函数 | 函数名 | 功能描述 | 实现难点 | |--------|----------|----------| | `select_game_mode()` | 选择游戏模式 | 输入验证 | | `ai_move()` | AI智能移动 | Minimax算法 | | `minimax()` | 博弈树搜索 | 递归剪枝 | | `evaluate_board()` | 局面评估 | 胜负判断 | | `check_winner()` | 检查胜利条件 | 8种组合检测 | | `make_move()` | 执行移动 | 合法性验证 | | `get_player_move()` | 获取玩家输入 | 输入验证 | ### 数据结构 - `board[3][3]`: 3x3字符数组存储棋盘状态 - `current_player`: 当前玩家符号('X'或'O') - `GameMode`: 枚举类型定义游戏模式 - `is_ai_turn`: 布尔值标识AI回合 ### AI策略分析 1. **完美博弈**:AI使用Minimax算法,理论上不可战胜 2. **优先获胜**:深度越小的获胜路径得分越高 3. **阻止失败**:优先阻止玩家获胜 4. **中心优势**:在相同评分下倾向选择中心位置 ## 🐛 错误处理 - ✅ 无效模式选择(非1-2) - ✅ 无效位置输入(超出1-9范围) - ✅ 选择已被占用的位置 - ✅ 非数字字符输入 - ✅ 自动清理输入缓冲区防止错误累积 ## 📈 算法复杂度 - **时间复杂度**:O(9!) ≈ O(362,880) - 最坏情况 - **空间复杂度**:O(9) - 递归深度 - **实际性能**:由于剪枝优化,实际运行非常快速