mirror of
https://github.com/LHY0125/Gobang-Game.git
synced 2026-05-10 02:19:46 +08:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f897536a45 |
+2
-4
@@ -34,7 +34,7 @@
|
||||
//---------- 游戏设置默认值 ----------//
|
||||
#define DEFAULT_USE_FORBIDDEN_MOVES false // 默认不启用禁手规则
|
||||
#define DEFAULT_USE_TIMER 0 // 默认不启用计时器
|
||||
#define DEFAULT_TIME_LIMIT 30 // 默认时间限制为30秒(内部存储)
|
||||
#define DEFAULT_TIME_LIMIT 1800 // 默认时间限制为30分钟(内部以秒存储: 30*60)
|
||||
|
||||
//---------- AI参数 ----------//
|
||||
#define DEFAULT_AI_DEPTH 5 // 默认AI搜索深度
|
||||
@@ -48,8 +48,6 @@
|
||||
#define NETWORK_BUFFER_SIZE 1024 // 网络缓冲区大小
|
||||
|
||||
// 网络配置
|
||||
#define DEFAULT_PORT 8888 // 默认端口(与DEFAULT_NETWORK_PORT保持一致)
|
||||
#define BUFFER_SIZE 1024 // 缓冲区大小(与NETWORK_BUFFER_SIZE保持一致)
|
||||
#define MAX_IP_LENGTH 16 // 最大IP地址长度
|
||||
|
||||
// 网络消息类型
|
||||
@@ -65,7 +63,7 @@
|
||||
|
||||
//---------- 评分参数 ----------//
|
||||
// 棋型评分 - 用于calculate_step_score函数
|
||||
#define SCORE_FIVE 0 // 五连
|
||||
#define SCORE_FIVE 5000 // 五连
|
||||
#define SCORE_LIVE_FOUR 2000 // 活四
|
||||
#define SCORE_RUSH_FOUR 1000 // 冲四
|
||||
#define SCORE_DEAD_FOUR 300 // 死四
|
||||
|
||||
@@ -33,8 +33,6 @@ extern int ai_difficulty; // AI难度 (1-5)
|
||||
extern NetworkGameState network_state; // 网络游戏状态
|
||||
|
||||
// ==================== GUI相关变量 ====================
|
||||
// Raylib 不需要暴露窗口和渲染器指针
|
||||
extern int gui_running; // GUI运行状态标志
|
||||
extern int current_player_gui; // GUI当前玩家
|
||||
extern int game_over; // 游戏结束标志
|
||||
extern char status_message[256]; // 状态消息
|
||||
|
||||
+3
-39
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* @file gui.h
|
||||
* @brief 图形化用户界面头文件
|
||||
* @note 使用Raylib库实现五子棋的图形化界面
|
||||
* @note 使用IUP库实现五子棋的图形化界面
|
||||
* @author 刘航宇
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
|
||||
#ifndef GUI_H
|
||||
@@ -17,45 +16,16 @@
|
||||
|
||||
/**
|
||||
* @brief 初始化GUI
|
||||
* @details 初始化Raylib图形库和游戏界面组件
|
||||
* @details 初始化IUP图形库和游戏界面组件
|
||||
* @return 成功返回0,失败返回-1
|
||||
*/
|
||||
int init_gui();
|
||||
|
||||
/**
|
||||
* @brief 清理GUI资源
|
||||
* @details 关闭窗口
|
||||
*/
|
||||
void cleanup_gui();
|
||||
|
||||
/**
|
||||
* @brief 渲染游戏画面
|
||||
* @details 完整的游戏画面渲染流程
|
||||
*/
|
||||
void render_game();
|
||||
|
||||
/**
|
||||
* @brief 处理事件
|
||||
* @details 处理所有Raylib事件并执行相应操作
|
||||
* @return 继续运行返回1,退出返回0
|
||||
*/
|
||||
int handle_events();
|
||||
|
||||
/**
|
||||
* @brief 绘制棋盘
|
||||
*/
|
||||
void draw_board();
|
||||
|
||||
/**
|
||||
* @brief 绘制棋子
|
||||
*/
|
||||
void draw_stones();
|
||||
|
||||
/**
|
||||
* @brief 绘制UI元素
|
||||
*/
|
||||
void draw_ui_elements();
|
||||
|
||||
/**
|
||||
* @brief 屏幕坐标转棋盘坐标
|
||||
*/
|
||||
@@ -81,16 +51,10 @@ void start_pve_game_gui();
|
||||
*/
|
||||
void start_replay_gui();
|
||||
|
||||
/**
|
||||
* @brief 启动图形化界面模式
|
||||
* @note 替代原来的 main 函数中的 GUI 分支逻辑
|
||||
*/
|
||||
int init_gui(); // Already declared
|
||||
|
||||
/**
|
||||
* @brief 运行图形化界面模式
|
||||
* @details 主循环处理事件、渲染画面和更新状态
|
||||
*/
|
||||
void run_gui_mode();
|
||||
|
||||
#endif // GUI_H
|
||||
#endif // GUI_H
|
||||
|
||||
@@ -8,7 +8,6 @@ extern Ihandle *dlg;
|
||||
extern Ihandle *board_canvas;
|
||||
extern Ihandle *lbl_player;
|
||||
extern Ihandle *lbl_status;
|
||||
extern int gui_loop_running;
|
||||
extern int gui_game_mode; // 0: PvP, 1: PvE, 2: Replay
|
||||
extern int replay_total_steps; // 复盘总步数
|
||||
|
||||
|
||||
@@ -532,8 +532,9 @@ ThreatLevel detect_threat(int x, int y, int player)
|
||||
// 恢复棋盘
|
||||
board[x][y] = EMPTY;
|
||||
|
||||
// 如果有多个威胁,提升威胁等级
|
||||
if (threat_count >= 2 && max_threat >= THREAT_THREE)
|
||||
// 如果有多个活三威胁,升级为双威胁(如双三、四三等组合)
|
||||
// 注意:不能把已经是活四的威胁降级为双威胁
|
||||
if (threat_count >= 2 && max_threat == THREAT_THREE)
|
||||
{
|
||||
max_threat = THREAT_DOUBLE;
|
||||
}
|
||||
|
||||
+6
-2
@@ -48,7 +48,11 @@ void load_game_config()
|
||||
}
|
||||
else if (strncmp(line, "TIME_LIMIT=", 11) == 0)
|
||||
{
|
||||
time_limit = atoi(line + 11);
|
||||
int minutes = atoi(line + 11);
|
||||
if (minutes > 0)
|
||||
{
|
||||
time_limit = minutes * 60; // 配置文件存分钟,内部转为秒
|
||||
}
|
||||
}
|
||||
else if (strncmp(line, "NETWORK_PORT=", 13) == 0)
|
||||
{
|
||||
@@ -101,7 +105,7 @@ void save_game_config()
|
||||
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);
|
||||
fprintf(file, "TIME_LIMIT=%d\n", time_limit / 60); // 内部存秒,配置文件存分钟
|
||||
fprintf(file, "\n# 网络端口 (范围: %d-%d)\n", MIN_NETWORK_PORT, MAX_NETWORK_PORT);
|
||||
fprintf(file, "NETWORK_PORT=%d\n", network_port);
|
||||
fprintf(file, "\n# 网络超时时间 (毫秒)\n");
|
||||
|
||||
@@ -30,7 +30,6 @@ int ai_difficulty = 3; // AI难度 (1-5)
|
||||
NetworkGameState network_state = {0}; // 网络游戏状态
|
||||
|
||||
// ==================== GUI相关变量定义 ====================
|
||||
int gui_running = 1; // GUI运行状态标志
|
||||
int current_player_gui = PLAYER; // GUI当前玩家
|
||||
int game_over = 0; // 游戏结束标志
|
||||
char status_message[256] = "五子棋游戏 - 黑子先行"; // 状态消息
|
||||
|
||||
@@ -11,7 +11,6 @@ Ihandle *dlg = NULL;
|
||||
Ihandle *board_canvas = NULL;
|
||||
Ihandle *lbl_player = NULL;
|
||||
Ihandle *lbl_status = NULL;
|
||||
int gui_loop_running = 0;
|
||||
int gui_game_mode = 0; // 0: PvP, 1: PvE, 2: Replay, 3: Network
|
||||
int replay_total_steps = 0; // 复盘总步数
|
||||
|
||||
@@ -32,8 +31,6 @@ int init_gui()
|
||||
create_main_menu();
|
||||
show_main_menu();
|
||||
|
||||
gui_loop_running = 1;
|
||||
|
||||
printf("图形化界面初始化成功!(IUP)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
+3
-3
@@ -37,7 +37,7 @@ static int btn_network_host_cb(Ihandle *ih)
|
||||
Ihandle *dlg = IupGetDialog(ih);
|
||||
Ihandle *txt_port = IupGetDialogChild(dlg, "NET_PORT");
|
||||
int port = IupGetInt(txt_port, "VALUE");
|
||||
if (port <= 0 || port > 65535) port = DEFAULT_PORT;
|
||||
if (port <= 0 || port > 65535) port = DEFAULT_NETWORK_PORT;
|
||||
|
||||
if (create_server(port))
|
||||
{
|
||||
@@ -61,7 +61,7 @@ static int btn_network_join_cb(Ihandle *ih)
|
||||
|
||||
char *ip = IupGetAttribute(txt_ip, "VALUE");
|
||||
int port = IupGetInt(txt_port, "VALUE");
|
||||
if (port <= 0 || port > 65535) port = DEFAULT_PORT;
|
||||
if (port <= 0 || port > 65535) port = DEFAULT_NETWORK_PORT;
|
||||
|
||||
if (connect_to_server(ip, port))
|
||||
{
|
||||
@@ -97,7 +97,7 @@ static int btn_network_cb(Ihandle *ih)
|
||||
Ihandle *txt_port = IupText(NULL);
|
||||
IupSetAttribute(txt_port, "NAME", "NET_PORT");
|
||||
char port_str[16];
|
||||
sprintf(port_str, "%d", DEFAULT_PORT);
|
||||
sprintf(port_str, "%d", DEFAULT_NETWORK_PORT);
|
||||
IupSetAttribute(txt_port, "VALUE", port_str);
|
||||
IupSetAttribute(txt_port, "SIZE", "50x");
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
// 设置控制台编码为UTF-8
|
||||
#ifdef _WIN32
|
||||
system("chcp 65001 > nul"); // 设置控制台编码为UTF-8
|
||||
SetConsoleOutputCP(65001); // 设置控制台输出编码
|
||||
SetConsoleCP(65001); // 设置控制台输入编码
|
||||
_mkdir("records");
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ bool init_network()
|
||||
}
|
||||
|
||||
memset(&network_state, 0, sizeof(NetworkGameState));
|
||||
network_state.port = DEFAULT_PORT;
|
||||
network_state.port = DEFAULT_NETWORK_PORT;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+11
-24
@@ -23,29 +23,6 @@
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief 复盘游戏全过程并展示评分
|
||||
* @note 实现流程:
|
||||
* 1. 初始化临时复盘棋盘
|
||||
* 2. 按步数顺序逐步重现每个落子
|
||||
* 3. 每步显示:
|
||||
* - 当前步数/总步数
|
||||
* - 落子方(玩家/AI)
|
||||
* - 落子位置(1-based坐标)
|
||||
* - 当前棋盘状态
|
||||
* 4. 通过用户按Enter键控制步骤前进
|
||||
* 5. 复盘结束后自动进入评分环节:
|
||||
* - 评估双方表现
|
||||
* - 显示得分
|
||||
* - 评选MVP
|
||||
* @note 技术细节:
|
||||
* - 使用独立临时棋盘避免影响主游戏状态
|
||||
* - 坐标显示转换为1-based方便用户理解
|
||||
* - 包含输入缓冲区清理防止意外输入
|
||||
* - 评分环节调用calculate_final_score()函数
|
||||
*/
|
||||
void calculate_game_scores();
|
||||
|
||||
/**
|
||||
* @brief 计算游戏评分
|
||||
*/
|
||||
@@ -99,7 +76,7 @@ void calculate_game_scores()
|
||||
void display_game_scores(int game_mode)
|
||||
{
|
||||
printf("\n===== 对局评分 =====\n");
|
||||
double sum_score = (long double)player1_final_score + (long double)player2_final_score;
|
||||
double sum_score = (double)player1_final_score + (double)player2_final_score;
|
||||
|
||||
if (sum_score > 0)
|
||||
{
|
||||
@@ -379,11 +356,21 @@ int load_game_from_file(const char *filename)
|
||||
|
||||
while (fgets(buffer, sizeof(buffer), file) != NULL)
|
||||
{
|
||||
if (step_count >= MAX_STEPS)
|
||||
{
|
||||
break; // 防止数组越界
|
||||
}
|
||||
if (sscanf(buffer, "%d,%d,%d,%d", &step_num, &steps[step_count].player, &steps[step_count].x, &steps[step_count].y) == 4)
|
||||
{
|
||||
// 将1-based坐标转换为0-based坐标
|
||||
steps[step_count].x--;
|
||||
steps[step_count].y--;
|
||||
// 验证坐标合法性
|
||||
if (steps[step_count].x < 0 || steps[step_count].x >= size ||
|
||||
steps[step_count].y < 0 || steps[step_count].y >= size)
|
||||
{
|
||||
continue; // 跳过非法坐标
|
||||
}
|
||||
step_count++;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user