From 798d77259cbb5cd023778d08bb59a1faa46cbea8 Mon Sep 17 00:00:00 2001 From: LHY0125 <3364451258@qq.com> Date: Thu, 10 Jul 2025 18:32:57 +0800 Subject: [PATCH] Add files via upload --- ai.h | 8 + config.h | 11 +- game_mode.c | 462 +++++++++++++++++++++++++++++++++++++++------------ game_mode.h | 15 +- globals.h | 3 - gobang.h | 6 + init_board.h | 6 + main.c | 8 + network.h | 6 - record.c | 48 ++++-- record.h | 6 + ui.h | 6 + 简介.txt | 2 +- 13 files changed, 451 insertions(+), 136 deletions(-) diff --git a/ai.h b/ai.h index 87f9fe8..77e787c 100644 --- a/ai.h +++ b/ai.h @@ -1,3 +1,11 @@ +/** + * @file ai.h + * @note 本文件定义了AI模块的函数和变量 + * @note 包括: + * 1. 评估一个落子位置的综合得分(结合进攻和防守) + * 2. 评估指定位置的价值 + * 3. 评估棋盘价值 + */ #ifndef AI_H #define AI_H diff --git a/config.h b/config.h index bcd92e2..17cad0e 100644 --- a/config.h +++ b/config.h @@ -1,12 +1,6 @@ /** * @file config.h - * @author 刘航宇(3364451258@qq.com、15236416560@163.com、lhy3364451258@outlook.com) * @brief 五子棋游戏参数配置头文件 - * @version 6.0 - * @date 2025-07-10 - * - * @copyright Copyright (c) 2025 - * * @note 本文件集中定义了五子棋游戏的所有参数配置,便于统一管理和修改 */ @@ -19,6 +13,11 @@ #define DEFAULT_BOARD_SIZE 15 // 默认棋盘尺寸 #define MAX_STEPS (MAX_BOARD_SIZE * MAX_BOARD_SIZE) // 游戏最大步数 +//---------- 游戏模式参数 ----------// +#define GAME_MODE_AI 1 // 人机对战模式 +#define GAME_MODE_PVP 2 // 双人对战模式 +#define GAME_MODE_NETWORK 3 // 网络对战模式 + //---------- 玩家标识参数 ----------// #define EMPTY 0 // 棋盘空位标识 #define PLAYER 1 // 玩家标识 (用于人机对战模式) diff --git a/game_mode.c b/game_mode.c index 665d456..5d61197 100644 --- a/game_mode.c +++ b/game_mode.c @@ -11,6 +11,7 @@ #include #include #include +#include // 全局变量现在在globals.c中定义 #ifdef _WIN32 @@ -95,7 +96,7 @@ bool parse_player_input(int *x, int *y) { printf("无法悔棋!\n"); } - return false; // 特殊命令 + return 0; // 特殊命令已处理 } else if (*x == INPUT_SAVE) { @@ -107,10 +108,10 @@ bool parse_player_input(int *x, int *y) // ... 处理退出 ... return false; // 特殊命令 } - printf("无效输入,请输入两个数字坐标。"); + printf("无效输入,请输入两个数字坐标。\n"); while (getchar() != '\n') ; - return false; // 无效输入 + return 0; // 无效输入 } } else @@ -138,7 +139,7 @@ bool parse_player_input(int *x, int *y) if (confirm) { printf("玩家选择认输!\n"); - return true; // 返回认输命令 + return 1; // 正常回合完成 // 返回认输命令 } else { @@ -146,7 +147,121 @@ bool parse_player_input(int *x, int *y) return false; // 取消认输 } } - printf("无效输入,请输入数字坐标、'r'悔棋或's'认输。"); + printf("无效输入,请输入数字坐标、'r'悔棋或's'认输。\n"); + return 0; // 无效输入 + } + return 1; // 有效坐标 +} + +/** + * @brief 解析网络对战模式下的玩家输入 + * @param x 行坐标指针 + * @param y 列坐标指针 + * @return true 有效坐标输入 + * @return false 特殊命令或无效输入 + */ +bool parse_network_player_input(int *x, int *y) +{ + char input[10]; + + while (1) + { + if (_kbhit()) + { + scanf("%s", input); + break; + } + Sleep(100); // 短暂延迟以防止CPU占用过高 + } + + if (sscanf(input, "%d", x) == 1) + { + // 成功解析第一个数字,现在解析第二个 + if (scanf("%d", y) != 1) + { + printf("无效输入,请输入两个数字坐标。\n"); + while (getchar() != '\n') + ; + return false; // 无效输入 + } + } + else + { + // sscanf失败,检查特殊命令 + if (input[0] == 'r' || input[0] == 'R') + { + int steps_to_undo; + steps_to_undo = get_integer_input("请输入要悔棋的步数(双方各退步数相同): ", 1, step_count / 2); + + printf("发送悔棋请求给对方...\n"); + if (send_undo_request(steps_to_undo)) + { + printf("悔棋请求已发送,等待对方回应...\n"); + + // 等待对方回应 + NetworkMessage msg; + time_t start_time = time(NULL); + + while (difftime(time(NULL), start_time) < 30) // 30秒超时 + { + if (receive_network_message(&msg, 1000)) + { + if (msg.type == MSG_UNDO_RESPONSE && msg.x == steps_to_undo) + { + if (msg.y == 1) // 对方同意 + { + if (return_move(steps_to_undo * 2)) + { + printf("对方同意悔棋,双方各退 %d 步!\n", steps_to_undo); + print_board(); + return 2; // 悔棋成功,需要重新开始回合 + } + else + { + printf("悔棋失败!\n"); + return 0; // 悔棋失败,继续当前回合 + } + } + else // 对方拒绝 + { + printf("对方拒绝了悔棋请求。\n"); + return 0; // 悔棋被拒绝,继续当前回合 + } + } + } + + if (!is_network_connected()) + { + printf("网络连接断开\n"); + return 0; + } + } + + printf("悔棋请求超时,对方未回应。\n"); + } + else + { + printf("发送悔棋请求失败!\n"); + } + return 0; // 特殊命令已处理 + } + else if (input[0] == 's' || input[0] == 'S') + { + *x = INPUT_SURRENDER; + int confirm = get_integer_input("确认认输?(1:是/0:否): ", 0, 1); + if (confirm) + { + printf("你选择认输!\n"); + *x = INPUT_SURRENDER; + return -1; // 返回认输命令 + } + else + { + printf("取消认输!\n"); + return 0; // 取消认输 + } + } + printf("无效输入,请输入数字坐标、'r'悔棋或's'认输。\n"); return false; // 无效输入 } return true; // 有效坐标 @@ -166,44 +281,52 @@ bool handle_player_turn(int current_player) time(&start_time); } - printf("\n玩家%d, 请输入落子坐标(行 列,1~%d),或输入R/r悔棋,S/s认输:", current_player, BOARD_SIZE); - while (1) { - if (use_timer) + printf("\n玩家%d, 请输入落子坐标(行 列,1~%d),或输入R/r悔棋,S/s认输:", current_player, BOARD_SIZE); + + bool input_received = false; + while (!input_received) { - time(&end_time); - if (difftime(end_time, start_time) > time_limit) + if (use_timer) { - printf("\n玩家%d超时, 对方获胜!\n", current_player); - return false; // Timeout + time(&end_time); + if (difftime(end_time, start_time) > time_limit) + { + printf("\n玩家%d超时, 对方获胜!\n", current_player); + return false; // Timeout + } + } + + if (parse_player_input(&x, &y)) + { + if (x == INPUT_SURRENDER) + { + printf("\n玩家%d选择认输,对方获胜!\n", current_player); + return false; // 游戏结束,认输 + } + input_received = true; + } + else + { + // 已处理特殊命令或无效输入,继续循环 + return true; } } - if (parse_player_input(&x, &y)) + x--; + y--; + + if (player_move(x, y, current_player)) { - if (x == INPUT_SURRENDER) - { - printf("\n玩家%d选择认输,对方获胜!\n", current_player); - return false; // 游戏结束,认输 - } - break; // 收到有效输入 + break; // 成功落子,跳出循环 } else { - // 已处理特殊命令或无效输入,继续循环 - return true; + printf("坐标无效!请重新输入。\n"); + // 继续循环,重新输入坐标 } } - - x--; - y--; - - if (!player_move(x, y, current_player)) - { - printf("坐标无效!请重新输入。\n"); - return true; // 坐标无效,但回合继续 - } print_board(); if (check_win(x, y, current_player)) @@ -301,8 +424,8 @@ void run_ai_game() } } printf("===== 游戏结束 =====\n"); - review_process(1); // 1 for AI mode - handle_save_record(1); // 1 for AI mode + review_process(GAME_MODE_AI); // AI对战模式 + handle_save_record(GAME_MODE_AI); // AI对战模式 } /** @@ -339,8 +462,8 @@ void run_pvp_game() } } printf("===== 游戏结束 =====\n"); - review_process(2); // 2 for PvP mode - handle_save_record(2); // 2 for PvP mode + review_process(GAME_MODE_PVP); // 双人对战模式 + handle_save_record(GAME_MODE_PVP); // 双人对战模式 } /** @@ -437,7 +560,8 @@ void run_network_game() scores_calculated = 0; // 初始化网络模块 - if (!init_network()) { + if (!init_network()) + { printf("网络初始化失败!\n"); pause_for_input("按任意键返回主菜单..."); return; @@ -451,27 +575,96 @@ void run_network_game() bool connection_success = false; - if (choice == 1) { + if (choice == 1) + { // 服务器模式 int port = get_integer_input("请输入监听端口(默认8888): ", MIN_NETWORK_PORT, MAX_NETWORK_PORT); if (port == 0) port = network_port; printf("\n正在创建房间...\n"); connection_success = create_server(port); - } else { + } + else + { // 客户端模式 char ip[MAX_IP_LENGTH]; - printf("请输入服务器IP地址: "); - scanf("%s", ip); + + // 循环直到输入有效的IP地址或用户选择退出 + while (1) + { + printf("请输入服务器IP地址 (输入'exit'退出): "); + if (scanf("%s", ip) != 1) + { + printf("输入错误,请重新输入。\n"); + // 清除输入缓冲区 + while (getchar() != '\n'); + continue; + } + + // 检查是否要退出 + if (strcmp(ip, "exit") == 0 || strcmp(ip, "EXIT") == 0) + { + printf("取消连接,返回主菜单。\n"); + cleanup_network(); + pause_for_input("按任意键返回主菜单..."); + return; + } + + // 简单的IP地址格式验证 + if (strlen(ip) < 7 || strlen(ip) > 15) + { + printf("IP地址格式错误!请输入有效的IP地址(如:192.168.1.100)\n"); + continue; + } + + // 检查IP地址是否包含有效字符 + bool valid_ip = true; + for (int i = 0; i < strlen(ip); i++) + { + if (!(isdigit(ip[i]) || ip[i] == '.')) + { + valid_ip = false; + break; + } + } + + if (!valid_ip) + { + printf("IP地址格式错误!只能包含数字和点号。\n"); + continue; + } + + // 检查点号数量 + int dot_count = 0; + for (int i = 0; i < strlen(ip); i++) + { + if (ip[i] == '.') dot_count++; + } + + if (dot_count != 3) + { + printf("IP地址格式错误!应包含3个点号(如:192.168.1.100)\n"); + continue; + } + + printf("输入的IP地址: %s\n", ip); + int confirm = get_integer_input("确认连接到此IP?(1:是/0:否,重新输入): ", 0, 1); + if (confirm) + { + break; // 确认IP地址,跳出循环 + } + // 如果选择否,继续循环重新输入 + } int port = get_integer_input("请输入服务器端口(默认8888): ", MIN_NETWORK_PORT, MAX_NETWORK_PORT); if (port == 0) port = network_port; - printf("\n正在连接到服务器...\n"); + printf("\n正在连接到服务器 %s:%d...\n", ip, port); connection_success = connect_to_server(ip, port); } - if (!connection_success) { + if (!connection_success) + { printf("网络连接失败!\n"); cleanup_network(); pause_for_input("按任意键返回主菜单..."); @@ -487,11 +680,14 @@ void run_network_game() empty_board(); print_board(); - if (network_game_loop()) { + if (network_game_loop()) + { printf("===== 游戏结束 =====\n"); - review_process(2); // 使用PvP模式的复盘 - handle_save_record(2); // 保存为PvP模式记录 - } else { + review_process(GAME_MODE_NETWORK); // 网络对战模式的复盘 + handle_save_record(GAME_MODE_NETWORK); // 保存为网络对战模式记录 + } + else + { printf("游戏因网络错误而结束\n"); } @@ -505,128 +701,177 @@ void run_network_game() */ bool handle_network_player_turn(int current_player, bool is_local_turn) { - if (is_local_turn) { + if (is_local_turn) + { // 本地玩家回合 int x, y; time_t start_time, end_time; - if (use_timer) { + if (use_timer) + { time(&start_time); } + - printf("\n轮到你了,请输入落子坐标(行 列,1~%d),或输入R/r悔棋,S/s认输: ", BOARD_SIZE); - - while (1) { - if (use_timer) { - time(&end_time); - if (difftime(end_time, start_time) > time_limit) { - printf("\n你超时了,对方获胜!\n"); - send_surrender(); // 发送认输消息 - return false; + while (1) + { + printf("\n轮到你了,请输入落子坐标(行 列,1~%d),或输入R/r悔棋,S/s认输: ", BOARD_SIZE); + + bool input_received = false; + while (!input_received) + { + if (use_timer) + { + time(&end_time); + if (difftime(end_time, start_time) > time_limit) + { + printf("\n你超时了,对方获胜!\n"); + send_surrender(); // 发送认输消息 + return 0; // 游戏结束 + } + } + + int parse_result = parse_network_player_input(&x, &y); + if (parse_result == 1) // 有效坐标输入 + { + input_received = true; + } + else if (parse_result == -1) // 认输命令 + { + printf("\n你选择认输,对方获胜!\n"); + send_surrender(); + return 0; // 游戏结束 + } + else if (parse_result == 2) // 悔棋成功 + { + return 2; // 悔棋发生,需要重新开始回合 + } + else // parse_result == 0, 特殊命令已处理或无效输入 + { + // 继续等待输入 + continue; } } - if (parse_player_input(&x, &y)) { - if (x == INPUT_SURRENDER) { - printf("\n你选择认输,对方获胜!\n"); - send_surrender(); - return false; - } - break; - } else { - // 处理特殊命令或继续等待输入 - continue; + x--; y--; // 转换为0-based坐标 + + if (player_move(x, y, current_player)) + { + break; // 成功落子,跳出循环 + } + else + { + printf("坐标无效!请重新输入。\n"); + // 继续循环,重新输入坐标 } } - x--; y--; // 转换为0-based坐标 - - if (!player_move(x, y, current_player)) { - printf("坐标无效!请重新输入。\n"); - return true; // 继续当前回合 - } - // 发送落子消息 - if (!send_move(x, y, current_player)) { + if (!send_move(x, y, current_player)) + { printf("发送落子消息失败!\n"); - return false; + return 0; // 游戏结束 } print_board(); - if (check_win(x, y, current_player)) { + if (check_win(x, y, current_player)) + { printf("\n你获胜了!\n"); - return false; + return 0; // 游戏结束 } - } else { + } + else + { // 等待对方落子 printf("\n等待对方落子...\n"); NetworkMessage msg; time_t start_time = time(NULL); - while (1) { - if (receive_network_message(&msg, 1000)) { // 1秒超时 - if (msg.type == MSG_MOVE && msg.player_id == current_player) { + while (1) + { + if (receive_network_message(&msg, 1000)) + { + // 1秒超时 + if (msg.type == MSG_MOVE && msg.player_id == current_player) + { // 收到落子消息 - if (!player_move(msg.x, msg.y, current_player)) { + if (!player_move(msg.x, msg.y, current_player)) + { printf("收到无效的落子坐标!\n"); - return false; + return 0; // 游戏结束 } printf("对方落子: (%d, %d)\n", msg.x + 1, msg.y + 1); print_board(); - if (check_win(msg.x, msg.y, current_player)) { + if (check_win(msg.x, msg.y, current_player)) + { printf("\n对方获胜!\n"); - return false; + return 0; // 游戏结束 } break; - } else if (msg.type == MSG_SURRENDER) { + } + else if (msg.type == MSG_SURRENDER) + { printf("\n对方认输,你获胜了!\n"); - return false; + return 0; // 游戏结束 - } else if (msg.type == MSG_DISCONNECT) { + } + else if (msg.type == MSG_DISCONNECT) + { printf("\n对方已断开连接\n"); - return false; + return 0; // 游戏结束 - } else if (msg.type == MSG_CHAT) { + } + else if (msg.type == MSG_CHAT) + { printf("[对方]: %s\n", msg.message); - } else if (msg.type == MSG_UNDO_REQUEST) { + } + else if (msg.type == MSG_UNDO_REQUEST) + { int steps = msg.x; printf("\n对方请求悔棋 %d 步,是否同意?(1:同意/0:拒绝): ", steps); int response = get_integer_input("", 0, 1); - if (response && return_move(steps * 2)) { + if (response && return_move(steps * 2)) + { printf("同意悔棋,双方各退 %d 步\n", steps); send_undo_response(true, steps); print_board(); - return true; // 继续游戏 - } else { + // 悔棋后需要重新开始当前回合,不改变current_player + return 2; // 悔棋发生,需要重新开始回合 + } + else + { printf("拒绝悔棋\n"); send_undo_response(false, steps); + // 继续等待对方落子 } } } // 检查超时 - if (use_timer && difftime(time(NULL), start_time) > time_limit) { + if (use_timer && difftime(time(NULL), start_time) > time_limit) + { printf("\n对方超时,你获胜!\n"); - return false; + return 0; // 游戏结束 } // 检查网络连接 - if (!is_network_connected()) { + if (!is_network_connected()) + { printf("\n网络连接断开\n"); - return false; + return 0; // 游戏结束 } } } - return true; + return 1; // 正常回合完成 } /** @@ -636,15 +881,23 @@ bool network_game_loop() { int current_player = PLAYER1; // 总是从玩家1开始 - while (1) { + while (1) + { bool is_local_turn = (current_player == network_state.local_player_id); - if (!handle_network_player_turn(current_player, is_local_turn)) { - return true; // 游戏结束 + int turn_result = handle_network_player_turn(current_player, is_local_turn); + if (turn_result == 0) // 游戏结束 + { + return true; + } + else if (turn_result == 2) // 悔棋发生,重新开始当前回合 + { + continue; // 不切换玩家,重新开始当前回合 } // 检查平局 - if (step_count == BOARD_SIZE * BOARD_SIZE) { + if (step_count == BOARD_SIZE * BOARD_SIZE) + { printf("\n平局!\n"); return true; } @@ -653,7 +906,8 @@ bool network_game_loop() current_player = (current_player == PLAYER1) ? PLAYER2 : PLAYER1; // 检查网络连接 - if (!is_network_connected()) { + if (!is_network_connected()) + { printf("\n网络连接断开\n"); return false; } diff --git a/game_mode.h b/game_mode.h index bcc606c..3f2ef7b 100644 --- a/game_mode.h +++ b/game_mode.h @@ -1,12 +1,6 @@ /** * @file game_mode.h - * @author 刘航宇(3364451258@qq.com、15236416560@163.com、lhy3364451258@outlook.com) * @brief 五子棋游戏框架头文件 - * @version 4.0 - * @date 2025-07-02 - * - * @copyright Copyright (c) 2025 - * * @note 本文件定义了五子棋游戏的四种主要模式: * 1. AI对战模式 * 2. 双人对战模式 @@ -40,6 +34,15 @@ int get_integer_input(const char *prompt, int min, int max); */ bool parse_player_input(int *x, int *y); +/** + * @brief 解析网络对战模式下的玩家输入 + * @param x 行坐标指针 + * @param y 列坐标指针 + * @return true 有效坐标输入 + * @return false 特殊命令或无效输入 + */ +bool parse_network_player_input(int *x, int *y); + /** * @brief 处理AI回合 * diff --git a/globals.h b/globals.h index c9fd502..86bd510 100644 --- a/globals.h +++ b/globals.h @@ -1,9 +1,6 @@ /** * @file globals.h - * @author 刘航宇(3364451258@qq.com、15236416560@163.com、lhy3364451258@outlook.com) * @brief 全局变量声明头文件 - * @version 6.0 - * @date 2025-07-10 * @note 集中管理所有全局变量的声明,提高代码可维护性 */ diff --git a/gobang.h b/gobang.h index 48ca98d..3b1e8ab 100644 --- a/gobang.h +++ b/gobang.h @@ -1,3 +1,9 @@ +/** + * @file gobang.h + * @brief 五子棋游戏头文件 + * @note 本文件定义了五子棋游戏的主要数据结构、函数和全局变量。 + * 它包含了游戏棋盘的表示、玩家操作、规则检查以及AI决策等功能。 + */ #ifndef GO_BANG_H #define GO_BANG_H diff --git a/init_board.h b/init_board.h index 253bf41..0030578 100644 --- a/init_board.h +++ b/init_board.h @@ -1,3 +1,9 @@ +/** + * @file init_board.h + * @brief 初始化游戏棋盘头文件 + * @note 本文件定义了初始化游戏棋盘的相关函数和全局变量。 + * 它负责设置游戏的初始状态,包括棋盘大小、玩家标识、游戏规则等。 + */ #ifndef INIT_BOARD_H #define INIT_BOARD_H diff --git a/main.c b/main.c index 7864e1b..c7d144f 100644 --- a/main.c +++ b/main.c @@ -37,31 +37,39 @@ int main(int argc, char *argv[]) switch (mode) { + // 1. 人机对战 case 1: run_ai_game(); break; + // 2. 玩家对战 case 2: run_pvp_game(); break; + // 3. 网络对战 case 3: run_network_game(); break; + // 4. 复盘模式 case 4: run_review_mode(); break; + // 5. 配置管理 case 5: config_management_menu(); break; + // 6. 游戏规则 case 6: clear_screen(); display_game_rules(); pause_for_input("\n按任意键返回主菜单..."); break; + // 7. 关于 case 7: clear_screen(); display_about(); pause_for_input("\n按任意键返回主菜单..."); break; + // 8. 退出游戏 case 8: save_game_config(); printf("感谢使用五子棋游戏!\n"); diff --git a/network.h b/network.h index 2086cb7..5f84113 100644 --- a/network.h +++ b/network.h @@ -1,12 +1,6 @@ /** * @file network.h - * @author 刘航宇(3364451258@qq.com、15236416560@163.com、lhy3364451258@outlook.com) * @brief 五子棋网络对战模块头文件 - * @version 1.0 - * @date 2025-01-15 - * - * @copyright Copyright (c) 2025 - * * @note 本文件定义了五子棋游戏的网络对战功能: * 1. 服务器模式(主机) * 2. 客户端模式(加入游戏) diff --git a/record.c b/record.c index fa30784..468f337 100644 --- a/record.c +++ b/record.c @@ -75,7 +75,7 @@ void review_process(int game_mode) // 打印当前步骤信息 // 根据游戏模式显示不同的标题和玩家信息 - if (game_mode == 1) + if (game_mode == GAME_MODE_AI) { // 人机对战 printf("\n===== 五子棋人机对战(%dX%d棋盘) =====", BOARD_SIZE, BOARD_SIZE); @@ -84,7 +84,7 @@ void review_process(int game_mode) (s.player == PLAYER) ? "玩家" : "AI", s.x + 1, s.y + 1); } - else + else if (game_mode == GAME_MODE_PVP) { // 双人对战 printf("\n===== 五子棋双人对战(%dX%d棋盘) =====", BOARD_SIZE, BOARD_SIZE); @@ -93,6 +93,15 @@ void review_process(int game_mode) (s.player == PLAYER1) ? "玩家1(黑棋)" : "玩家2(白棋)", s.x + 1, s.y + 1); } + else if (game_mode == GAME_MODE_NETWORK) + { + // 网络对战 + printf("\n===== 五子棋网络对战(%dX%d棋盘) =====", BOARD_SIZE, BOARD_SIZE); + printf("\n 第%d步/%d步: %s 落子于(%d, %d)\n", + i + 1, step_count, + (s.player == PLAYER1) ? "玩家1(黑棋)" : "玩家2(白棋)", + s.x + 1, s.y + 1); + } // 打印当前复盘棋盘 printf(" "); @@ -222,14 +231,21 @@ void display_game_scores(int game_mode) if (sum_score > 0) { - if (game_mode == 1) + if (game_mode == GAME_MODE_AI) { printf("玩家得分: %d, 占比: %.2f%%\n", player1_final_score, (double)player1_final_score * 100.0 / sum_score); printf("AI得分: %d, 占比: %.2f%%\n", player2_final_score, (double)player2_final_score * 100.0 / sum_score); } - else + else if (game_mode == GAME_MODE_PVP) + { + printf("玩家1(黑棋)得分: %d, 占比: %.2f%%\n", + player1_final_score, (double)player1_final_score * 100.0 / sum_score); + printf("玩家2(白棋)得分: %d, 占比: %.2f%%\n", + player2_final_score, (double)player2_final_score * 100.0 / sum_score); + } + else if (game_mode == GAME_MODE_NETWORK) { printf("玩家1(黑棋)得分: %d, 占比: %.2f%%\n", player1_final_score, (double)player1_final_score * 100.0 / sum_score); @@ -239,7 +255,7 @@ void display_game_scores(int game_mode) } else { - if (game_mode == 1) + if (game_mode == GAME_MODE_AI) { printf("玩家得分: %d\n", player1_final_score); printf("AI得分: %d\n", player2_final_score); @@ -255,11 +271,11 @@ void display_game_scores(int game_mode) // 评选MVP if (player1_final_score > player2_final_score) { - printf("\nMVP: %s (领先 %d 分)\n", (game_mode == 1) ? "玩家" : "玩家1(黑棋)", player1_final_score - player2_final_score); + printf("\nMVP: %s (领先 %d 分)\n", (game_mode == GAME_MODE_AI) ? "玩家" : "玩家1(黑棋)", player1_final_score - player2_final_score); } else if (player2_final_score > player1_final_score) { - printf("\nMVP: %s (领先 %d 分)\n", (game_mode == 1) ? "AI" : "玩家2(白棋)", player2_final_score - player1_final_score); + printf("\nMVP: %s (领先 %d 分)\n", (game_mode == GAME_MODE_AI) ? "AI" : "玩家2(白棋)", player2_final_score - player1_final_score); } else { @@ -362,7 +378,7 @@ int save_game_to_file(const char *filename, int game_mode) Step last_step = steps[step_count - 1]; if (check_win(last_step.x, last_step.y, last_step.player)) { - if (game_mode == 1) + if (game_mode == GAME_MODE_AI) { // 人机对战 if (last_step.player == PLAYER) @@ -374,7 +390,7 @@ int save_game_to_file(const char *filename, int game_mode) strcpy(winner_info, "AI获胜"); } } - else + else if (game_mode == GAME_MODE_PVP) { // 双人对战 if (last_step.player == PLAYER1) @@ -386,6 +402,18 @@ int save_game_to_file(const char *filename, int game_mode) strcpy(winner_info, "玩家2获胜"); } } + else if (game_mode == GAME_MODE_NETWORK) + { + // 网络对战 + if (last_step.player == PLAYER1) + { + strcpy(winner_info, "玩家1获胜"); + } + else + { + strcpy(winner_info, "玩家2获胜"); + } + } } } @@ -464,7 +492,7 @@ int load_game_from_file(const char *filename) return 0; } - if (game_mode != 1 && game_mode != 2) + if (game_mode != GAME_MODE_AI && game_mode != GAME_MODE_PVP && game_mode != GAME_MODE_NETWORK) { fclose(file); return 0; // 无效的游戏模式 diff --git a/record.h b/record.h index 8b29a08..a5452ef 100644 --- a/record.h +++ b/record.h @@ -1,3 +1,9 @@ +/** + * @file record.h + * @brief 游戏复盘与记录头文件 + * @note 本文件定义了游戏复盘与记录相关的函数和数据结构。 + * 它负责管理游戏的历史记录、加载和保存游戏文件、计算游戏评分等功能。 + */ #ifndef RECORD_H #define RECORD_H diff --git a/ui.h b/ui.h index 159b016..d0581c7 100644 --- a/ui.h +++ b/ui.h @@ -1,3 +1,9 @@ +/** + * @file ui.h + * @brief + * @note 本文件定义了用户界面相关的函数和数据结构。 + * 它负责处理用户输入、显示游戏界面、提示信息等与用户交互的功能。 + */ #ifndef UI_H #define UI_H diff --git a/简介.txt b/简介.txt index a0ebb23..28363ea 100644 --- a/简介.txt +++ b/简介.txt @@ -4,7 +4,7 @@ * @details 支持人机对战、双人对战、网络对战的完整五子棋游戏系统 * @author 刘航宇(3364451258@qq.com、15236416560@163.com、lhy3364451258@outlook.com) * @date 2025-07-10 - * @version 6.0 + * @version 6.1 * @note * 1. v6.0新增功能: * - 🌐 完整的网络对战模式,支持服务器/客户端架构