# 五子棋人机对战AI项目 ## 项目简介 这是一个基于C语言实现的高级五子棋人机对战系统,采用α-β剪枝的极小极大算法实现AI决策,支持自定义棋盘大小和完整的游戏复盘功能。 ## 核心功能 - 支持5x5到25x25的棋盘尺寸 - 玩家(X)与AI(○)对战模式 - AI采用α-β剪枝优化的极小极大算法 - 详细的棋型评估系统(活四、冲四、活三等) - 完整的游戏复盘功能 - 清晰的棋盘界面显示 ## 技术特点 1. **AI算法**: - 使用α-β剪枝优化的极小极大算法 - 搜索深度可调(当前设置为3层) - 优先处理威胁位置(如阻止玩家形成活四) 2. **评估系统**: - 考虑四个方向的棋型评估 - 区分活棋、眠棋和死棋 - 位置奖励(中心位置价值更高) 3. **游戏流程**: - 完整的胜负判定 - 平局检测 - 详细的复盘系统 ## 编译运行 1. 编译程序: ```bash gcc "C语言代码/课上代码练习/五子棋/五子棋 copy 3.c" -o gomoku -lm ``` 2. 运行游戏: ```bash ./gomoku ``` ## 使用说明 1. 启动后输入棋盘尺寸(5-25,默认15) 2. 游戏进行: - 玩家输入坐标格式:行 列(如"8 8") - AI会自动计算最佳落子位置 3. 游戏结束: - 显示胜负结果 - 可选择查看完整复盘 ## 核心函数说明 ### 1. ai_move() - AI决策函数 **功能**:决定AI的最佳落子位置 **算法**: 1. 优先检查是否需要阻止玩家形成活四/冲四 2. 使用α-β剪枝优化的极小极大算法搜索最佳位置 3. 考虑已有棋子附近2格范围内的位置 **参数**:无 **返回值**:无(直接修改棋盘状态) ### 2. evaluate_pos() - 棋型评估函数 **功能**:评估特定位置对当前玩家的价值 **评分标准**: - 活四: 100000分 - 冲四: 10000分 - 活三: 5000分 - 眠三: 1000分 - 活二: 500分 - 眠二: 100分 - **参数**: - x,y: 待评估位置坐标 - player: 当前玩家标识 **返回值**:评估分数(越高越好) ### 3. dfs() - 深度优先搜索 **功能**:实现带α-β剪枝的极小极大算法 **特点**: - 搜索深度:3层 - 使用α-β剪枝优化搜索效率 - 评估函数差值作为叶节点值 **参数**: - x,y: 当前落子位置 - player: 当前玩家 - depth: 剩余搜索深度 - alpha,beta: 剪枝参数 - is_maximizing: 是否最大化玩家 ### 4. count_specific_direction() - 方向分析 **功能**:计算特定方向上的连续棋子情况 **返回结构**: - continuous_chess: 连续棋子数 - check_start/check_end: 两端是否开放 **应用**:用于判断棋型(活棋/眠棋) ### 5. check_win() - 胜负判断 **功能**:检查落子后是否形成五连珠 **逻辑**:检查四个方向是否存在≥5的连续同色棋子 ## 程序流程图 ``` 开始 │ ├─> 初始化棋盘 │ │ │ └─> 设置默认大小(15x15) │ ├─> 游戏主循环 │ │ │ ├─> [玩家回合] │ │ ├─> 显示棋盘 │ │ ├─> 获取玩家输入坐标 │ │ └─> 落子并检查胜负 │ │ │ ├─> [AI回合] │ │ ├─> AI计算最佳落子(α-β剪枝) │ │ └─> 落子并检查胜负 │ │ │ └─> 检查平局条件 │ ├─> 游戏结束处理 │ ├─> 显示胜负结果 │ └─> 询问是否复盘 │ ├─> 是: 显示完整复盘 │ └─> 否: 退出游戏 │ └─> 程序结束 ``` ## 关键代码实现 ### 1. AI决策核心算法 ```c // α-β剪枝极小极大算法实现 int dfs(int x, int y, int player, int depth, int alpha, int beta, int is_maximizing) { if (depth == 0 || check_win(x, y)) { return evaluate_pos(x, y, player) - evaluate_pos(x, y, 3 - player); } if (is_maximizing) { int max_eval = INT_MIN; for (每个可能位置) { int eval = dfs(x, y, player, depth-1, alpha, beta, 0); max_eval = max(max_eval, eval); alpha = max(alpha, eval); // α剪枝 if (beta <= alpha) { break; } } return max_eval; } else { int min_eval = INT_MAX; for (每个可能位置) { int eval = dfs(x, y, player, depth-1, alpha, beta, 1); min_eval = min(min_eval, eval); beta = min(beta, eval); // β剪枝 if (beta <= alpha) { break; } } return min_eval; } } ``` ### 2. 棋型评估函数 ```c // 评估特定位置的棋型价值 int evaluate_pos(int x, int y, int player) { int score = 0; for (四个方向) { ChessPattern pattern =count_specific_direction(x, y, dir); if (pattern.continuous_chess >= 5) { return 1000000; // 五连珠 } // 活棋 if (pattern.check_start && pattern.check_end) { if (pattern.continuous_chess == 4) score += 100000; // 活四 else if (pattern.continuous_chess == 3) score += 5000; // 活三 else if (pattern.continuous_chess == 2) score += 500; // 活二 } // 眠棋 else if (pattern.check_start || pattern.check_end) { if (pattern.continuous_chess == 4) score += 10000; // 冲四 else if (pattern.continuous_chess == 3) score += 1000; // 眠三 else if (pattern.continuous_chess == 2) score += 100; // 眠二 } } return score; } ``` ### 3. 胜负判断逻辑 ```c // 检查是否形成五连珠 int check_win(int x, int y) { for (四个方向) { int count = 1; // 正向检查 for (int i = 1; i < 5; i++) { if (棋盘边界检查 || 棋子不连续) { break; } count++; } // 反向检查 for (int i = 1; i < 5; i++) { if (棋盘边界检查 || 棋子不连续) { break; } count++; } // 五连珠 if (count >= 5) { return 1; } } return 0; } ``` ## 项目结构 - `五子棋 copy 3.c` - 主程序文件(当前使用版本) - 其他`五子棋 copy*.c`文件为开发过程中的不同版本 ## 注意事项 1. 编译时需要链接数学库(-lm) 2. 确保输入坐标在棋盘范围内 3. AI思考时间随棋盘大小和搜索深度增加 ## 详细技术实现说明 ### 1. 主函数(main)执行流程 1. **初始化阶段**: - 提示用户输入棋盘尺寸(5-25),默认15x15 - 初始化棋盘状态(全空) - 打印初始空棋盘 2. **游戏主循环**: - **玩家回合**: * 提示玩家输入坐标(行列格式) * 验证坐标有效性(是否在棋盘范围内且为空位) * 在棋盘放置玩家棋子(X) * 检查是否形成五连珠(玩家胜利) - **AI回合**: * 调用ai_move()计算最佳落子位置 * 在棋盘放置AI棋子(○) * 检查是否形成五连珠(AI胜利) - **平局检查**: * 当棋盘已满且无胜负时判定平局 3. **游戏结束处理**: - 显示最终胜负结果 - 提供复盘功能(逐步展示整个对局过程) ### 2. AI决策系统(ai_move) **防御策略**: 1. 优先检查玩家可能形成的威胁棋型: - 活四(必须立即阻挡) - 冲四(一端被堵的四连珠) - 活三(两端开放的三连珠) **进攻策略**: 1. 使用α-β剪枝优化的极小极大算法: - 搜索深度:3层 - 评估函数:evaluate_pos()差值 - 剪枝条件:alpha ≥ beta时终止搜索 2. 搜索优化: - 仅考虑已有棋子周围2格范围内的空位 - 中心位置奖励(棋盘中心区域价值更高) - 对称位置剪枝(减少重复计算) ### 3. 棋型评估系统(evaluate_pos) **评分标准详细说明**: 1. **活棋(两端开放)**: - 活四:100000分(必胜) - 活三:5000分(高威胁) - 活二:500分(潜在威胁) 2. **眠棋(一端开放)**: - 冲四:10000分(次高威胁) - 眠三:1000分(中等威胁) - 眠二:100分(低威胁) 3. **死棋(两端封闭)**: - 无威胁价值,仅基础分 4. **位置奖励**: - 中心区域:额外加分(50*(BOARD_SIZE-距离)) - 边角区域:基础分 **评估过程**: 1. 四个方向(水平、垂直、对角线)分别评估 2. 综合最高分方向和所有方向加权分 3. 考虑当前玩家和对手的分数差值 ### 4. 胜负判断(check_win) **实现细节**: 1. 四个方向检查: - 水平(→) - 垂直(↓) - 主对角线(↘) - 副对角线(↙) 2. 检查逻辑: - 从当前位置向两个方向延伸 - 统计连续同色棋子数 - 任一方向≥5即判定胜利 3. 优化措施: - 边界检查避免数组越界 - 提前终止(发现5连立即返回) ### 5. 复盘系统(review_process) **实现机制**: 1. 数据结构: - 使用steps数组记录每一步落子 - 包含玩家类型、坐标信息 2. 回放过程: - 逐步重建棋盘状态 - 显示每一步的落子位置 - 支持暂停/继续控制 3. 可视化: - 清晰的棋盘显示 - 回合计数和玩家标识 - 坐标转换(0-base转1-base) ### 6. 方向分析(count_specific_direction) **算法细节**: 1. 输入参数: - 起始坐标(x,y) - 方向向量(dx,dy) - 玩家标识 2. 分析过程: - 正向延伸(统计连续棋子) - 反向延伸(统计连续棋子) - 检查两端开放状态 3. 输出结构: - 连续棋子数 - 起点开放状态 - 终点开放状态 **应用场景**: 1. 胜负判断 2. 棋型评估 3. 威胁检测