Add files via upload

This commit is contained in:
2025-07-10 10:07:34 +08:00
committed by GitHub
parent 3663352e5f
commit aae7990cfd
11 changed files with 871 additions and 77 deletions
+255
View File
@@ -0,0 +1,255 @@
#include "config.h"
#include "ui.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 配置文件路径
#define CONFIG_FILE "gobang_config.ini"
/**
* @brief 加载游戏配置
*/
void load_game_config()
{
FILE *file = fopen(CONFIG_FILE, "r");
if (file == NULL)
{
// 配置文件不存在,使用默认配置
printf("配置文件不存在,使用默认配置\n");
return;
}
char line[256];
while (fgets(line, sizeof(line), file))
{
// 去除换行符
line[strcspn(line, "\n")] = 0;
// 解析配置项
if (strncmp(line, "BOARD_SIZE=", 11) == 0)
{
int size = atoi(line + 11);
if (size >= MIN_BOARD_SIZE && size <= MAX_BOARD_SIZE)
{
BOARD_SIZE = size;
}
}
else if (strncmp(line, "USE_FORBIDDEN_MOVES=", 20) == 0)
{
use_forbidden_moves = (atoi(line + 20) != 0);
}
else if (strncmp(line, "USE_TIMER=", 10) == 0)
{
use_timer = atoi(line + 10);
}
else if (strncmp(line, "TIME_LIMIT=", 11) == 0)
{
time_limit = atoi(line + 11);
}
else if (strncmp(line, "AI_DIFFICULTY=", 14) == 0)
{
int difficulty = atoi(line + 14);
if (difficulty >= 1 && difficulty <= 5)
{
// 根据难度设置AI搜索深度
// 这里可以添加AI难度相关的配置
}
}
}
fclose(file);
printf("配置加载完成\n");
}
/**
* @brief 保存游戏配置
*/
void save_game_config()
{
FILE *file = fopen(CONFIG_FILE, "w");
if (file == NULL)
{
printf("无法保存配置文件\n");
return;
}
fprintf(file, "# 五子棋游戏配置文件\n");
fprintf(file, "# 棋盘大小 (范围: %d-%d)\n", MIN_BOARD_SIZE, MAX_BOARD_SIZE);
fprintf(file, "BOARD_SIZE=%d\n", BOARD_SIZE);
fprintf(file, "\n# 禁手规则 (0=关闭, 1=开启)\n");
fprintf(file, "USE_FORBIDDEN_MOVES=%d\n", use_forbidden_moves ? 1 : 0);
fprintf(file, "\n# 计时器 (0=关闭, 1=开启)\n");
fprintf(file, "USE_TIMER=%d\n", use_timer);
fprintf(file, "\n# 时间限制 (分钟)\n");
fprintf(file, "TIME_LIMIT=%d\n", time_limit);
fclose(file);
printf("配置保存完成\n");
}
/**
* @brief 重置为默认配置
*/
void reset_to_default_config()
{
BOARD_SIZE = DEFAULT_BOARD_SIZE;
use_forbidden_moves = DEFAULT_USE_FORBIDDEN_MOVES;
use_timer = DEFAULT_USE_TIMER;
time_limit = DEFAULT_TIME_LIMIT;
printf("已重置为默认配置\n");
}
/**
* @brief 显示当前配置
*/
void display_current_config()
{
printf("\n===== 当前游戏配置 =====\n");
printf("棋盘大小: %d x %d\n", BOARD_SIZE, BOARD_SIZE);
printf("禁手规则: %s\n", use_forbidden_moves ? "开启" : "关闭");
printf("计时器: %s\n", use_timer ? "开启" : "关闭");
if (use_timer)
{
printf("时间限制: %d 分钟\n", time_limit / 60);
}
printf("=====================\n");
}
/**
* @brief 配置棋盘大小
*/
void config_board_size()
{
printf("\n当前棋盘大小: %d x %d\n", BOARD_SIZE, BOARD_SIZE);
printf("请输入新的棋盘大小 (%d-%d): ", MIN_BOARD_SIZE, MAX_BOARD_SIZE);
int new_size;
if (scanf("%d", &new_size) == 1)
{
if (new_size >= MIN_BOARD_SIZE && new_size <= MAX_BOARD_SIZE)
{
BOARD_SIZE = new_size;
printf("棋盘大小已设置为: %d x %d\n", BOARD_SIZE, BOARD_SIZE);
}
else
{
printf("无效的棋盘大小!\n");
}
}
else
{
printf("输入格式错误!\n");
// 清除输入缓冲区
while (getchar() != '\n');
}
}
/**
* @brief 配置禁手规则
*/
void config_forbidden_moves()
{
printf("\n当前禁手规则: %s\n", use_forbidden_moves ? "开启" : "关闭");
printf("是否启用禁手规则?(1=开启, 0=关闭): ");
int choice;
if (scanf("%d", &choice) == 1)
{
use_forbidden_moves = (choice != 0);
printf("禁手规则已%s\n", use_forbidden_moves ? "开启" : "关闭");
}
else
{
printf("输入格式错误!\n");
while (getchar() != '\n');
}
}
/**
* @brief 配置计时器
*/
void config_timer()
{
printf("\n当前计时器: %s\n", use_timer ? "开启" : "关闭");
printf("是否启用计时器?(1=开启, 0=关闭): ");
int choice;
if (scanf("%d", &choice) == 1)
{
use_timer = choice;
if (use_timer)
{
printf("请输入时间限制(分钟): ");
int new_limit;
if (scanf("%d", &new_limit) == 1 && new_limit > 0)
{
time_limit = new_limit * 60; // 转换为秒数存储
printf("计时器已开启,时间限制: %d 分钟\n", time_limit / 60);
}
else
{
printf("无效的时间限制!\n");
while (getchar() != '\n');
}
}
else
{
printf("计时器已关闭\n");
}
}
else
{
printf("输入格式错误!\n");
while (getchar() != '\n');
}
}
/**
* @brief 配置管理主菜单
*/
void config_management_menu()
{
int choice;
while (1)
{
clear_screen();
display_settings_menu();
display_current_config();
printf("请选择操作: ");
if (scanf("%d", &choice) != 1)
{
printf("输入格式错误!\n");
while (getchar() != '\n');
pause_for_input("按任意键继续...");
continue;
}
switch (choice)
{
case 1:
config_board_size();
break;
case 2:
config_forbidden_moves();
break;
case 3:
config_timer();
break;
case 4:
printf("AI难度设置功能开发中...\n");
break;
case 5:
save_game_config();
return;
default:
printf("无效的选择!\n");
break;
}
pause_for_input("按任意键继续...");
}
}
+43 -1
View File
@@ -15,6 +15,7 @@
//---------- 棋盘相关参数 ----------//
#define MAX_BOARD_SIZE 25 // 支持的最大棋盘尺寸
#define MIN_BOARD_SIZE 5 // 支持的最小棋盘尺寸
#define DEFAULT_BOARD_SIZE 15 // 默认棋盘尺寸
#define MAX_STEPS (MAX_BOARD_SIZE * MAX_BOARD_SIZE) // 游戏最大步数
@@ -34,7 +35,7 @@
//---------- 游戏设置默认值 ----------//
#define DEFAULT_USE_FORBIDDEN_MOVES false // 默认不启用禁手规则
#define DEFAULT_USE_TIMER 0 // 默认不启用计时器
#define DEFAULT_TIME_LIMIT 30 // 默认时间限制为30秒
#define DEFAULT_TIME_LIMIT 30 // 默认时间限制为30秒(内部存储)
//---------- AI参数 ----------//
#define DEFAULT_AI_DEPTH 3 // 默认AI搜索深度
@@ -91,4 +92,45 @@
#define RECORDS_DIR "records" // 记录文件目录
#define MAX_PATH_LENGTH 256 // 最大路径长度
//---------- 配置管理函数声明 ----------//
/**
* @brief 加载游戏配置
*/
void load_game_config();
/**
* @brief 保存游戏配置
*/
void save_game_config();
/**
* @brief 重置为默认配置
*/
void reset_to_default_config();
/**
* @brief 显示当前配置
*/
void display_current_config();
/**
* @brief 配置棋盘大小
*/
void config_board_size();
/**
* @brief 配置禁手规则
*/
void config_forbidden_moves();
/**
* @brief 配置计时器
*/
void config_timer();
/**
* @brief 配置管理主菜单
*/
void config_management_menu();
#endif // CONFIG_H
+7 -6
View File
@@ -222,11 +222,8 @@ void run_ai_game()
{
// 重置评分计算标志,确保每局游戏都会重新计算评分
scores_calculated = 0;
setup_game_options();
// AI对战模式
setup_board_size();
int AI_DEPTH = 3;
AI_DEPTH = get_integer_input("请选择AI难度(1~5), 数字越大越强,注意数字越大AI思考时间越长!):", 1, 5);
@@ -255,6 +252,13 @@ void run_ai_game()
}
if (step_count > old_step_count)
{
// 检查玩家是否获胜
Step last_step = steps[step_count - 1];
if (check_win(last_step.x, last_step.y, PLAYER))
{
printf("\n玩家获胜!\n");
break;
}
current_player = AI;
}
}
@@ -307,11 +311,8 @@ void run_pvp_game()
{
// 重置评分计算标志,确保每局游戏都会重新计算评分
scores_calculated = 0;
setup_game_options();
// 双人对战模式
setup_board_size();
empty_board();
int current_player = determine_first_player(PLAYER1, PLAYER2);
print_board();
+1 -1
View File
@@ -23,7 +23,7 @@ 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 int time_limit; // 每回合的时间限制(秒,内部存储
extern const int direction[4][2]; // 定义四个基本搜索方向:水平、垂直、左斜、右斜
// 数据结构
+12
View File
@@ -0,0 +1,12 @@
# 五子棋游戏配置文件
# 棋盘大小 (范围: 5-25)
BOARD_SIZE=15
# 禁手规则 (0=关闭, 1=开启)
USE_FORBIDDEN_MOVES=1
# 计时器 (0=关闭, 1=开启)
USE_TIMER=1
# 时间限制 (分钟)
TIME_LIMIT=60
+9 -9
View File
@@ -3,32 +3,32 @@
#include "gobang.h"
// --- 游戏初始化 ---
// --- 游戏初始化 ---
/**
* @brief 初始化棋盘,将所有位置设置为空(EMPTY)
* @brief 初始化棋盘,将所有位置设置为空(EMPTY)
*/
void empty_board();
/**
* @brief 将当前棋盘状态打印到控制台
* @brief 将当前棋盘状态打印到控制台
*/
void print_board();
/**
* @brief 设置当前游戏的棋盘大小
* @brief 设置当前游戏的棋盘大小
*/
void setup_board_size();
/**
* @brief 设置游戏选项,如是否启用禁手、计时器等
* @brief 设置游戏选项,如是否启用禁手、计时器等
*/
void setup_game_options();
/**
* @brief 决定先手玩家
* @param player1 玩家1的标识
* @param player2 玩家2的标识
* @return 返回先手玩家的标识
* @brief 决定先手玩家
* @param player1 玩家1的标识
* @param player2 玩家2的标识
* @return 返回先手玩家的标识
*/
int determine_first_player(int player1, int player2);
+119
View File
@@ -0,0 +1,119 @@
/**
* @file 五子棋.c
* @brief 五子棋游戏核心逻辑头文件
* @details 游戏核心逻辑实现
* @author 刘航宇(3364451258@qq.com、15236416560@163.com、lhy3364451258@outlook.com)
* @date 2025-07-07
* @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 "ui.h"
#include "config.h"
#include <stdio.h>
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#endif
/**
* @brief 将指令复制到powershell
* gcc -o gobang.exe main.c gobang.c game_mode.c ai.c record.c init_board.c ui.c config.c
* gcc 为编译器,五子棋.c gobang.c game_mode.c 为源文件,output/为输出目录
* @brief 将指令复制到powershell
* .\gobang.exe
*/
int main(int argc, char *argv[])
{
// 设置控制台编码为UTF-8
#ifdef _WIN32
system("chcp 65001 > nul"); // 设置控制台编码为UTF-8
SetConsoleOutputCP(65001); // 设置控制台输出编码
SetConsoleCP(65001); // 设置控制台输入编码
_mkdir("records");
#endif
// 加载游戏配置
load_game_config();
// 选择模式
while(1)
{
clear_screen();
display_main_menu();
int mode = get_integer_input("请输入模式(1-7): ", 1, 7);
switch (mode)
{
case 1:
run_ai_game();
break;
case 2:
run_pvp_game();
break;
case 3:
run_review_mode();
break;
case 4:
config_management_menu();
break;
case 5:
clear_screen();
display_game_rules();
pause_for_input("\n按任意键返回主菜单...");
break;
case 6:
clear_screen();
display_about();
pause_for_input("\n按任意键返回主菜单...");
break;
case 7:
save_game_config();
printf("感谢使用五子棋游戏!\n");
return 0;
default:
printf("无效的选择!\n");
pause_for_input("按任意键继续...");
break;
}
}
return 0;
}
+136 -44
View File
@@ -34,6 +34,7 @@
int player1_final_score = 0;
int player2_final_score = 0;
int scores_calculated = 0;
char winner_info[50] = "平局或未完成"; // 存储胜负信息
void review_process(int game_mode)
{
@@ -42,45 +43,7 @@ void review_process(int game_mode)
// 如果评分尚未计算,则计算评分
if (!scores_calculated)
{
// 评估双方表现
player1_final_score = 0;
player2_final_score = 0;
// 遍历所有步数,累积每一步的得分,后期步骤权重更高
for (int i = 0; i < step_count; i++)
{
// 计算时间权重因子:步数越靠后,权重越大
double time_weight = 1.0 + (double)i / step_count * TIME_WEIGHT_FACTOR; // 最后的步骤权重是开始步骤的(1+TIME_WEIGHT_FACTOR)倍
if (steps[i].player == PLAYER || steps[i].player == PLAYER1)
{
player1_final_score += (int)(calculate_step_score(steps[i].x, steps[i].y, steps[i].player) * time_weight);
}
else
{
player2_final_score += (int)(calculate_step_score(steps[i].x, steps[i].y, steps[i].player) * time_weight);
}
}
// 胜负加权:获胜方获得额外的评分奖励
if (step_count > 0)
{
Step last_step = steps[step_count - 1];
if (check_win(last_step.x, last_step.y, last_step.player))
{
// 获胜方获得额外奖励分数
if (last_step.player == PLAYER || last_step.player == PLAYER1)
{
player1_final_score += WIN_BONUS; // 获胜奖励
}
else
{
player2_final_score += WIN_BONUS; // 获胜奖励
}
}
}
scores_calculated = 1; // 标记评分已计算
calculate_game_scores();
}
else
{
@@ -164,11 +127,92 @@ void review_process(int game_mode)
; // 等待回车
}
}
// 显示胜负结果(直接使用文件中的信息)
printf("\n===== 对局结果 =====");
if (strcmp(winner_info, "玩家获胜") == 0)
{
printf("\n? 恭喜!玩家获胜!\n");
}
else if (strcmp(winner_info, "AI获胜") == 0)
{
printf("\n? AI获胜!\n");
}
else if (strcmp(winner_info, "玩家1获胜") == 0)
{
printf("\n? 恭喜!玩家1(黑棋)获胜!\n");
}
else if (strcmp(winner_info, "玩家2获胜") == 0)
{
printf("\n? 恭喜!玩家2(白棋)获胜!\n");
}
else
{
printf("\n?? 对局平局或未完成\n");
}
printf("\n复盘结束!按Enter查看评分...");
getchar(); // 等待用户按键
}
// 显示评分结果
display_game_scores(game_mode);
getchar();
}
/**
* @brief 计算游戏评分
*/
void calculate_game_scores()
{
// 评估双方表现
player1_final_score = 0;
player2_final_score = 0;
// 遍历所有步数,累积每一步的得分,后期步骤权重更高
for (int i = 0; i < step_count; i++)
{
// 计算时间权重因子:步数越靠后,权重越大
double time_weight = 1.0 + (double)i / step_count * TIME_WEIGHT_FACTOR; // 最后的步骤权重是开始步骤的(1+TIME_WEIGHT_FACTOR)倍
if (steps[i].player == PLAYER || steps[i].player == PLAYER1)
{
player1_final_score += (int)(calculate_step_score(steps[i].x, steps[i].y, steps[i].player) * time_weight);
}
else
{
player2_final_score += (int)(calculate_step_score(steps[i].x, steps[i].y, steps[i].player) * time_weight);
}
}
// 胜负加权:获胜方获得额外的评分奖励
if (step_count > 0)
{
Step last_step = steps[step_count - 1];
if (check_win(last_step.x, last_step.y, last_step.player))
{
// 获胜方获得额外奖励分数
if (last_step.player == PLAYER || last_step.player == PLAYER1)
{
player1_final_score += WIN_BONUS; // 获胜奖励
}
else
{
player2_final_score += WIN_BONUS; // 获胜奖励
}
}
}
scores_calculated = 1; // 标记评分已计算
}
/**
* @brief 显示游戏评分结果和MVP评选
* @param game_mode 游戏模式(1-人机对战, 2-双人对战)
*/
void display_game_scores(int game_mode)
{
printf("\n===== 对局评分 =====\n");
double sum_score = (long double)player1_final_score + (long double)player2_final_score;
@@ -217,8 +261,6 @@ void review_process(int game_mode)
{
printf("\n双方势均力敌!\n");
}
getchar();
}
/**
@@ -309,8 +351,42 @@ int save_game_to_file(const char *filename, int game_mode)
return 2; // 文件打开失败
}
// 判断胜负结果
strcpy(winner_info, "平局或未完成");
if (step_count > 0)
{
Step last_step = steps[step_count - 1];
if (check_win(last_step.x, last_step.y, last_step.player))
{
if (game_mode == 1)
{
// 人机对战
if (last_step.player == PLAYER)
{
strcpy(winner_info, "玩家获胜");
}
else
{
strcpy(winner_info, "AI获胜");
}
}
else
{
// 双人对战
if (last_step.player == PLAYER1)
{
strcpy(winner_info, "玩家1获胜");
}
else
{
strcpy(winner_info, "玩家2获胜");
}
}
}
}
// 写入CSV文件头部
if (fprintf(file, "游戏模式,棋盘大小,玩家1得分,玩家2得分\n%d,%d,%d,%d\n\n", game_mode, BOARD_SIZE, player1_final_score, player2_final_score) < 0)
if (fprintf(file, "游戏模式,棋盘大小,玩家1得分,玩家2得分,对局结果\n%d,%d,%d,%d,%s\n\n", game_mode, BOARD_SIZE, player1_final_score, player2_final_score, winner_info) < 0)
{
fclose(file);
return 3; // 文件写入失败
@@ -368,10 +444,26 @@ int load_game_from_file(const char *filename)
// 读取游戏模式、棋盘大小和评分结果
int game_mode, size;
if (fscanf(file, "%d,%d,%d,%d", &game_mode, &size, &player1_final_score, &player2_final_score) != 4 || (game_mode != 1 && game_mode != 2))
// 尝试读取新格式(包含胜负信息)
int read_count = fscanf(file, "%d,%d,%d,%d,%49s", &game_mode, &size, &player1_final_score, &player2_final_score, winner_info);
if (read_count == 4)
{
// 旧格式文件,没有胜负信息
strcpy(winner_info, "未知");
}
else if (read_count != 5)
{
// 文件格式错误
fclose(file);
return 0;
}
if (game_mode != 1 && game_mode != 2)
{
fclose(file);
return 0; // 无效的游戏模式或文件格式
return 0; // 无效的游戏模式
}
if (size < 5 || size > MAX_BOARD_SIZE)
{
+28 -16
View File
@@ -3,37 +3,49 @@
#include "gobang.h"
// 全局变量,用于存储对局评分,确保对战结束和复盘模式使用相同的评分
extern int player1_final_score;
extern int player2_final_score;
extern int scores_calculated;
// 全局变量,用于存储对局评分,确保对战结束和复盘模式使用相同的评分
extern int player1_final_score; // 玩家1最终得分
extern int player2_final_score; // 玩家2最终得分
extern int scores_calculated; // 评分计算标志
extern char winner_info[50]; // 存储胜负信息
// --- 复盘与记录 ---
// --- 复盘与记录功能 ---
/**
* @brief 进入复盘流程,回顾整局游戏
* @param game_mode 游戏模式(1为人机,2为双人)
* @brief 进入复盘流程,回顾整局游戏
* @param game_mode 游戏模式(1为人机对战2为双人对战
*/
void review_process(int game_mode);
/**
* @brief 将当前对局记录保存到文件
* @param filename 要保存到的文件名
* @param game_mode 游戏模式
* @return 0表示成功,非0表示失败
* @brief 将当前对局记录保存到文件
* @param filename 要保存到的文件名
* @param game_mode 游戏模式
* @return 0表示成功,非0表示失败
*/
int save_game_to_file(const char *filename, int game_mode);
/**
* @brief 处理保存游戏记录的逻辑
* @param game_mode 游戏模式
* @brief 处理保存游戏记录的逻辑
* @param game_mode 游戏模式
*/
void handle_save_record(int game_mode);
/**
* @brief 从文件加载游戏记录
* @param filename 要加载的文件名
* @return 0表示成功,非0表示失败
* @brief 从文件加载游戏记录
* @param filename 要加载的文件名
* @return 游戏模式(1或2),0表示失败
*/
int load_game_from_file(const char *filename);
/**
* @brief 计算游戏评分
*/
void calculate_game_scores();
/**
* @brief 显示游戏评分结果和MVP评选
* @param game_mode 游戏模式(1-人机对战,2-双人对战)
*/
void display_game_scores(int game_mode);
#endif // RECORD_H
+199
View File
@@ -0,0 +1,199 @@
#include "ui.h"
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#include <windows.h>
#include <conio.h>
#else
#include <unistd.h>
#endif
/**
* @brief 显示游戏主菜单
*/
void display_main_menu()
{
printf("===== 五子棋游戏 =====\n");
printf("1. AI模式\n");
printf("2. 玩家比赛\n");
printf("3. 复盘模式\n");
printf("4. 游戏设置\n");
printf("5. 游戏规则\n");
printf("6. 关于游戏\n");
printf("7. 退出游戏\n");
printf("=====================\n");
}
/**
* @brief 显示棋盘
*/
void display_board()
{
printf("\n ");
// 打印列号
for (int j = 0; j < BOARD_SIZE; j++)
{
printf("%2d", j);
}
printf("\n");
// 打印棋盘内容
for (int i = 0; i < BOARD_SIZE; i++)
{
printf("%2d", i); // 打印行号
for (int j = 0; j < BOARD_SIZE; j++)
{
if (board[i][j] == EMPTY)
{
printf(" ·"); // 空位用点表示
}
else if (board[i][j] == PLAYER || board[i][j] == PLAYER1)
{
printf(""); // 玩家1用实心圆表示
}
else
{
printf(""); // 玩家2/AI用空心圆表示
}
}
printf("\n");
}
printf("\n");
}
/**
* @brief 显示游戏状态信息
* @param current_player 当前玩家
* @param step_count 当前步数
*/
void display_game_status(int current_player, int step_count)
{
printf("当前步数: %d\n", step_count);
if (current_player == PLAYER || current_player == PLAYER1)
{
printf("当前玩家: ●\n");
}
else
{
printf("当前玩家: ○\n");
}
}
/**
* @brief 显示获胜信息
* @param winner 获胜者
*/
void display_winner(int winner)
{
printf("\n? 游戏结束!\n");
if (winner == PLAYER)
{
printf("? 玩家获胜!\n");
}
else if (winner == AI)
{
printf("? AI获胜!\n");
}
else if (winner == PLAYER1)
{
printf("? 玩家1获胜!\n");
}
else if (winner == PLAYER2)
{
printf("? 玩家2获胜!\n");
}
else
{
printf("? 平局!\n");
}
}
/**
* @brief 显示游戏设置菜单
*/
void display_settings_menu()
{
printf("\n===== 游戏设置 =====\n");
printf("1. 棋盘大小设置\n");
printf("2. 禁手规则设置\n");
printf("3. 计时器设置\n");
printf("4. AI难度设置\n");
printf("5. 返回主菜单\n");
printf("==================\n");
}
/**
* @brief 清屏函数
*/
void clear_screen()
{
#ifdef _WIN32
system("cls");
#else
system("clear");
#endif
}
/**
* @brief 暂停等待用户输入
* @param prompt 提示信息
*/
void pause_for_input(const char* prompt)
{
printf("%s", prompt);
#ifdef _WIN32
_getch();
#else
getchar();
#endif
}
/**
* @brief 显示游戏规则
*/
void display_game_rules()
{
printf("\n===== 五子棋游戏规则 =====\n");
printf("1. 游戏目标:\n");
printf(" 在棋盘上连成五个同色棋子(横、竖、斜均可)\n\n");
printf("2. 游戏流程:\n");
printf(" - 黑棋先行,双方轮流落子\n");
printf(" - 输入坐标格式:行号 列号(如:7 7)\n");
printf(" - 棋子落在棋盘交叉点上\n\n");
printf("3. 胜负判定:\n");
printf(" - 率先连成五子者获胜\n");
printf(" - 棋盘下满无人获胜则为平局\n\n");
printf("4. 禁手规则(可选):\n");
printf(" - 三三禁手:同时形成两个活三\n");
printf(" - 四四禁手:同时形成两个冲四\n");
printf(" - 长连禁手:连成六子或以上\n\n");
printf("5. 特殊功能:\n");
printf(" - 悔棋:输入 'R' 或 'r' 可悔棋\n");
printf(" - 保存:游戏结束后可保存对局记录\n");
printf(" - 复盘:可加载历史对局进行复盘\n");
printf("========================\n");
}
/**
* @brief 显示关于信息
*/
void display_about()
{
printf("\n===== 关于五子棋游戏 =====\n");
printf("🎮 游戏名称:五子棋人机对战\n");
printf("📦 版本:4.0\n");
printf("👨‍💻 开发者:刘航宇\n");
printf("📧 联系邮箱:3364451258@qq.com\n");
printf("🌐 项目主页:https://github.com/LHY0125/Gobang-Game\n\n");
printf("✨ 主要特性:\n");
printf(" 🤖 智能AI对战(支持多种难度)\n");
printf(" 👥 双人对战模式\n");
printf(" 📝 对局记录与复盘\n");
printf(" 🚫 禁手规则支持\n");
printf(" ⏱️ 计时器功能\n");
printf(" 📏 自定义棋盘大小\n");
printf(" 📊 评分系统\n\n");
printf("🙏 感谢使用!\n");
printf("========================\n");
}
+62
View File
@@ -0,0 +1,62 @@
#ifndef UI_H
#define UI_H
#include "gobang.h"
/**
* @brief UI模块 - 用户界面相关功能
* @author 刘航宇
* @date 2025-01-15
* @version 1.0
*/
/**
* @brief 显示游戏主菜单
*/
void display_main_menu();
/**
* @brief 显示棋盘
*/
void display_board();
/**
* @brief 显示游戏状态信息
* @param current_player 当前玩家
* @param step_count 当前步数
*/
void display_game_status(int current_player, int step_count);
/**
* @brief 显示获胜信息
* @param winner 获胜者
*/
void display_winner(int winner);
/**
* @brief 显示游戏设置菜单
*/
void display_settings_menu();
/**
* @brief 清屏函数
*/
void clear_screen();
/**
* @brief 暂停等待用户输入
* @param prompt 提示信息
*/
void pause_for_input(const char* prompt);
/**
* @brief 显示游戏规则
*/
void display_game_rules();
/**
* @brief 显示关于信息
*/
void display_about();
#endif // UI_H