From 367f7a1709f2c4b9f1a8a1bdfbb26f9aef749784 Mon Sep 17 00:00:00 2001 From: LHY0125 <3364451258@qq.com> Date: Mon, 7 Jul 2025 18:24:02 +0800 Subject: [PATCH] Add files via upload --- game_mode.c | 32 +++++++--- game_mode.h | 11 ++-- gobang.h | 165 ++++++++++++++++++++-------------------------------- 五子棋.c | 48 ++++++++++++--- 4 files changed, 133 insertions(+), 123 deletions(-) diff --git a/game_mode.c b/game_mode.c index dc73c94..839c777 100644 --- a/game_mode.c +++ b/game_mode.c @@ -79,8 +79,7 @@ bool parse_player_input(int *x, int *y) if (*x == INPUT_UNDO) { int steps_to_undo; - printf("请输入要悔棋的步数(双方各退一步): "); - steps_to_undo = get_integer_input("", 1, step_count / 2); + steps_to_undo = get_integer_input("请输入要悔棋的步数(双方各退步数相同): ", 1, step_count / 2); if (return_move(steps_to_undo * 2)) { printf("成功悔棋,双方各退 %d 步!\n", steps_to_undo); @@ -110,12 +109,11 @@ bool parse_player_input(int *x, int *y) } else { - // sscanf失败,检查'r'或'R' + // sscanf失败,检查特殊命令 if (input[0] == 'r' || input[0] == 'R') { int steps_to_undo; - printf("请输入要悔棋的步数(双方各退一步): "); - steps_to_undo = get_integer_input("", 1, step_count / 2); + steps_to_undo = get_integer_input("请输入要悔棋的步数(双方各退步数相同): ", 1, step_count / 2); if (return_move(steps_to_undo * 2)) { printf("成功悔棋,双方各退 %d 步!\n", steps_to_undo); @@ -127,7 +125,22 @@ bool parse_player_input(int *x, int *y) } return false; // 特殊命令 } - printf("无效输入,请输入数字坐标或'r'悔棋。"); + else if (input[0] == 's' || input[0] == 'S') + { + *x = INPUT_SURRENDER; + int confirm = get_integer_input("确认认输?(1:是/0:否): ", 0, 1); + if (confirm) + { + printf("玩家选择认输!\n"); + return true; // 返回认输命令 + } + else + { + printf("取消认输!\n"); + return false; // 取消认输 + } + } + printf("无效输入,请输入数字坐标、'r'悔棋或's'认输。"); return false; // 无效输入 } return true; // 有效坐标 @@ -147,7 +160,7 @@ bool handle_player_turn(int current_player) time(&start_time); } - printf("\n玩家%d, 请输入落子坐标(行 列,1~%d),或输入R/r悔棋:", current_player, BOARD_SIZE); + printf("\n玩家%d, 请输入落子坐标(行 列,1~%d),或输入R/r悔棋,S/s认输:", current_player, BOARD_SIZE); while (1) { @@ -163,6 +176,11 @@ bool handle_player_turn(int current_player) if (parse_player_input(&x, &y)) { + if (x == INPUT_SURRENDER) + { + printf("\n玩家%d选择认输,对方获胜!\n", current_player); + return false; // 游戏结束,认输 + } break; // 收到有效输入 } else diff --git a/game_mode.h b/game_mode.h index 8c0467f..054a597 100644 --- a/game_mode.h +++ b/game_mode.h @@ -2,8 +2,8 @@ * @file game_mode.h * @author 刘航宇(3364451258@qq.com、15236416560@163.com、lhy3364451258@outlook.com) * @brief 五子棋游戏框架头文件 - * @version 4.1 - * @date 2025-07-07 + * @version 4.0 + * @date 2025-07-02 * * @copyright Copyright (c) 2025 * @@ -19,9 +19,10 @@ #include "gobang.h" // 特殊输入命令 -#define INPUT_UNDO -1 -#define INPUT_SAVE -2 -#define INPUT_EXIT -3 +#define INPUT_UNDO -1 // 悔棋 +#define INPUT_SAVE -2 // 保存 +#define INPUT_EXIT -3 // 退出 +#define INPUT_SURRENDER -4 // 认输 /** * @brief 从用户获取整数输入 diff --git a/gobang.h b/gobang.h index 550de06..3cdedb0 100644 --- a/gobang.h +++ b/gobang.h @@ -1,42 +1,3 @@ -/** - * @file gobang.h - * @brief Ϸ߼ͷļ - * @details Ϸĺݽṹȫֱ궨ͺԭ͡ - * @author (3364451258@qq.com15236416560@163.comlhy3364451258@outlook.com) - * @date 2025-07-02 - * @version 4.0 - * @note - * 1. ܣ - * - ˶Խֹֹ֧֣ҽ߷ - * - Ϸʱܣÿغϵ˼ʱ䡣 - * 2. Ż - * - Żܣ˲Ҫļ㡣 - * - Alpha-Beta ֦㷨 AI Чʡ - * 3. ûĽ - * - н棬ṩѺõĽ顣 - * - Զ̴СϷԡ - * 4. ṹŻ - * - Ϸ߼û룬ߴĿɶԺͿάԡ - * - Ż˴ṹ˴ĿɶԺͿάԡ - * 5. 쳣 - * - 쳣ƣȷϷȶԡ - * - ޸һЩ֪ bugϷȶԡ - * 6. ĵ£ - * - ˴עͣ˴Ŀɶԡ - * - ĵʹ÷עȡ - * 7. 汾ƣ - * - ʹ Git а汾ƣŶЭʹ - * 8. ԣ - * - ȫIJԣȷϷȶԺ͹ܵȷԡ - * 9. ԴЭ飺 - * - ѡ MIT ԴЭ飬ûʹá޸ĺͷַ롣 - * 10. ߣ - * - - * 11. ϵϢ - * - Ŀҳ[https://github.com/LHY0125/Gobang-Game] - * - ϵ䣺[3364451258@qq.com][15236416560@163.com][lhy3364451258@outlook.com] - */ - #ifndef GO_BANG_H #define GO_BANG_H @@ -47,112 +8,112 @@ #include #include -// 궨 -#define MAX_BOARD_SIZE 25 // ֵ֧̳ߴ -#define PLAYER 1 // ұʶ (˻սģʽ) -#define AI 2 // AIʶ (˻սģʽ) -#define PLAYER1 1 // 1ʶ (˫˶սģʽ) -#define PLAYER2 2 // 2ʶ (˫˶սģʽ) -#define EMPTY 0 // ̿λʶ -#define MAX_STEPS (MAX_BOARD_SIZE * MAX_BOARD_SIZE) // Ϸ +// 宏定义 +#define MAX_BOARD_SIZE 25 // 支持的最大棋盘尺寸 +#define PLAYER 1 // 玩家标识 (用于人机对战模式) +#define AI 2 // AI标识 (用于人机对战模式) +#define PLAYER1 1 // 玩家1标识 (用于双人对战模式) +#define PLAYER2 2 // 玩家2标识 (用于双人对战模式) +#define EMPTY 0 // 棋盘空位标识 +#define MAX_STEPS (MAX_BOARD_SIZE * MAX_BOARD_SIZE) // 游戏最大步数 -// ȫֱ -extern int BOARD_SIZE; // ǰʵʹõ̳ߴ -extern int board[MAX_BOARD_SIZE][MAX_BOARD_SIZE]; // 洢״̬Ķά -extern int step_count; // ǰϷܲ -extern bool use_forbidden_moves; // Ƿýֹı־ -extern int use_timer; // Ƿüʱı־ -extern int time_limit; // ÿغϵʱƣ룩 -extern const int direction[4][2]; // ĸˮƽֱбб +// 全局变量 +extern int BOARD_SIZE; // 当前实际使用的棋盘尺寸 +extern int board[MAX_BOARD_SIZE][MAX_BOARD_SIZE]; // 存储棋盘状态的二维数组 +extern int step_count; // 当前游戏的总步数 +extern bool use_forbidden_moves; // 是否启用禁手规则的标志 +extern int use_timer; // 是否启用计时器的标志 +extern int time_limit; // 每回合的时间限制(秒) +extern const int direction[4][2]; // 定义四个基本搜索方向:水平、垂直、左斜、右斜 -// ݽṹ +// 数据结构 /** - * @brief ¼һϸϢ + * @brief 记录一步棋的详细信息 */ typedef struct { - int player; // ִиòұʶ - int x; // ӵ (0-based) - int y; // ӵ (0-based) + int player; // 执行该步的玩家标识 + int x; // 落子的行坐标 (0-based) + int y; // 落子的列坐标 (0-based) } Step; -extern Step steps[MAX_STEPS]; // ڴ洢Ϸÿһ +extern Step steps[MAX_STEPS]; // 用于存储游戏中每一步棋的数组 /** - * @brief 洢ضԵϢ - * @details Σжϻĵȹؼ̬ + * @brief 存储在特定方向上棋子连续性的信息 + * @details 用于评估棋形,例如判断活三、冲四等关键形态。 */ typedef struct { - int continuous_chess; // ͬɫӵ - bool check_start; // еʼǷΪλǷ񿪷ţ - bool check_end; // еĩβǷΪλǷ񿪷ţ + int continuous_chess; // 连续同色棋子的数量 + bool check_start; // 棋子序列的起始端是否为空位(即是否开放) + bool check_end; // 棋子序列的末尾端是否为空位(即是否开放) } DirInfo; -// ԭ +// 函数原型 -// --- Ϸ߼ --- +// --- 游戏核心逻辑 --- /** - * @brief ָǷΪЧӵ㣨Ϊգ - * @param x (0-based) - * @param y (0-based) - * @return λЧΪ򷵻true򷵻false + * @brief 检查指定坐标是否为有效落子点(在棋盘内且为空) + * @param x 待检查的行坐标 (0-based) + * @param y 待检查的列坐标 (0-based) + * @return 若位置有效且为空则返回true,否则返回false */ bool have_space(int x, int y); /** - * @brief жһǷΪ - * @param x ӵ (0-based) - * @param y ӵ (0-based) - * @param player ǰҵıʶ - * @return ǽ򷵻true򷵻false + * @brief 判断一个落子是否为禁手 + * @param x 落子的行坐标 (0-based) + * @param y 落子的列坐标 (0-based) + * @param player 当前玩家的标识 + * @return 如果是禁手则返回true,否则返回false */ bool is_forbidden_move(int x, int y, int player); /** - * @brief ִһӲ - * @param x ӵ (0-based) - * @param y ӵ (0-based) - * @param player ǰҵıʶ - * @return ӳɹ򷵻trueλЧռãfalse + * @brief 执行一次玩家落子操作 + * @param x 落子的行坐标 (0-based) + * @param y 落子的列坐标 (0-based) + * @param player 当前玩家的标识 + * @return 若落子成功则返回true,否则(位置无效或被占用)返回false */ bool player_move(int x, int y, int player); /** - * @brief ضϵϢ - * @param x ʼ - * @param y ʼ - * @param dx x (-1, 0, or 1) - * @param dy y (-1, 0, or 1) - * @param player ұʶ - * @return һϢ DirInfo ṹ + * @brief 计算在特定方向上的棋子连续信息 + * @param x 起始点的行坐标 + * @param y 起始点的列坐标 + * @param dx x方向的增量 (-1, 0, or 1) + * @param dy y方向的增量 (-1, 0, or 1) + * @param player 玩家标识 + * @return 返回一个包含连续棋子信息的 DirInfo 结构体 */ DirInfo count_specific_direction(int x, int y, int dx, int dy, int player); /** - * @brief ijӺ󣬸Ƿʤ - * @param x ӵ (0-based) - * @param y ӵ (0-based) - * @param player ǰҵıʶ - * @return ʤ򷵻true򷵻false + * @brief 检查在某点落子后,该玩家是否获胜 + * @param x 落子的行坐标 (0-based) + * @param y 落子的列坐标 (0-based) + * @param player 当前玩家的标识 + * @return 如果获胜则返回true,否则返回false */ bool check_win(int x, int y, int player); /** - * @brief 幦ܣָ - * @param steps_to_undo ҪIJÿ˫һӣ - * @return ɹ򷵻true򷵻false + * @brief 悔棋功能,撤销指定步数 + * @param steps_to_undo 要撤销的步数(每步包含双方各一次落子) + * @return 若悔棋成功则返回true,否则返回false */ bool return_move(int steps_to_undo); /** - * @brief 㲢һĵ÷ - * @param x ӵ - * @param y ӵ - * @param player ұʶ - * @return òĵ÷ + * @brief 计算并返回一步棋的得分 + * @param x 落子的行坐标 + * @param y 落子的列坐标 + * @param player 玩家标识 + * @return 该步棋的得分 */ int calculate_step_score(int x, int y, int player); diff --git a/五子棋.c b/五子棋.c index cd1b3e0..d69aeae 100644 --- a/五子棋.c +++ b/五子棋.c @@ -1,3 +1,42 @@ +/** + * @file 五子棋.c + * @brief 五子棋游戏核心逻辑头文件 + * @details 游戏核心逻辑实现 + * @author 刘航宇(3364451258@qq.com、15236416560@163.com、lhy3364451258@outlook.com) + * @date 2025-07-02 + * @version 4.0 + * @note + * 1. 新增功能: + * - 增加了对禁手规则的支持,防止玩家进行无意义的走法。 + * - 新增了游戏计时器功能,限制每回合的思考时间。 + * 2. 性能优化: + * - 优化了评估函数的性能,减少了不必要的计算。 + * - 引入了 Alpha-Beta 剪枝算法,提高了 AI 搜索的效率。 + * 3. 用户界面改进: + * - 新增了命令行界面,提供更友好的交互体验。 + * - 可以自定义棋盘大小,增加游戏的灵活性。 + * 4. 代码结构优化: + * - 将游戏逻辑和用户界面分离,提高代码的可读性和可维护性。 + * - 优化了代码结构,提高了代码的可读性和可维护性。 + * 5. 异常处理: + * - 增加了输入错误的异常处理机制,确保游戏的稳定性。 + * - 修复了一些已知的 bug,提高游戏的稳定性。 + * 6. 文档更新: + * - 完善了代码注释,提高了代码的可读性。 + * - 更新了文档,包括功能描述、使用方法、注意事项等。 + * 7. 版本控制: + * - 使用 Git 进行版本控制,方便团队协作和代码管理。 + * 8. 测试: + * - 进行了全面的测试,确保游戏的稳定性和功能的正确性。 + * 9. 开源协议: + * - 选择了 MIT 开源协议,允许用户自由使用、修改和分发代码。 + * 10. 贡献者: + * - 刘航宇 + * 11. 联系信息: + * - 项目主页:[https://github.com/LHY0125/Gobang-Game] + * - 联系邮箱:[3364451258@qq.com][15236416560@163.com][lhy3364451258@outlook.com] + */ + #include "game_mode.h" #include #ifdef _WIN32 @@ -5,15 +44,6 @@ #include #endif -/** - * @file gobang.h - * @brief 五子棋游戏核心逻辑头文件 - * @details 定义了游戏的核心数据结构、全局变量、宏定义和函数原型。 - * @author 刘航宇(3364451258@qq.com、15236416560@163.com、lhy3364451258@outlook.com) - * @date 2025-07-07 - * @version 4.1 - */ - /** * @brief 将指令复制到powershell * gcc -o gobang.exe gobang.c ai.c game_mode.c init_board.c record.c 五子棋.c