mirror of
https://github.com/LHY0125/Gobang-Game.git
synced 2026-05-09 18:09:46 +08:00
feat(gui): 迁移图形界面库从SDL3到IUP
- 移除SDL3依赖,引入IUP图形界面库 - 更新Makefile以支持IUP编译配置 - 重构GUI模块,移除SDL相关代码 - 更新全局变量和类型定义,移除SDL依赖 - 添加IUP头文件到项目库目录 - 删除手动帧率控制(SDL_Delay),依赖IUP事件循环 - 更新编译脚本和文档说明
This commit is contained in:
+21
-24
@@ -9,42 +9,39 @@
|
||||
|
||||
#include "type.h"
|
||||
#include "gobang.h"
|
||||
#include "network.h"
|
||||
#include <stdbool.h>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
// ==================== 游戏核心变量 ====================
|
||||
extern int BOARD_SIZE; // 当前实际使用的棋盘尺寸
|
||||
extern int board[MAX_BOARD_SIZE][MAX_BOARD_SIZE]; // 棋盘状态存储数组
|
||||
extern Step steps[MAX_STEPS]; // 存储所有落子步骤的数组
|
||||
extern const int direction[4][2]; // 四个方向:向下、向右、右下、左下
|
||||
extern int step_count; // 当前步数计数器
|
||||
extern int BOARD_SIZE; // 当前实际使用的棋盘尺寸
|
||||
extern int board[MAX_BOARD_SIZE][MAX_BOARD_SIZE]; // 棋盘状态存储数组
|
||||
extern Step steps[MAX_STEPS]; // 存储所有落子步骤的数组
|
||||
extern const int direction[4][2]; // 四个方向:向下、向右、右下、左下
|
||||
extern int step_count; // 当前步数计数器
|
||||
|
||||
// ==================== 游戏配置变量 ====================
|
||||
extern bool use_forbidden_moves; // 是否启用禁手规则的标志
|
||||
extern int use_timer; // 是否启用计时器的标志
|
||||
extern int time_limit; // 每回合的时间限制(秒,内部存储)
|
||||
extern int network_port; // 网络端口
|
||||
extern int network_timeout; // 网络超时时间
|
||||
extern bool use_forbidden_moves; // 是否启用禁手规则的标志
|
||||
extern int use_timer; // 是否启用计时器的标志
|
||||
extern int time_limit; // 每回合的时间限制(秒,内部存储)
|
||||
extern int network_port; // 网络端口
|
||||
extern int network_timeout; // 网络超时时间
|
||||
|
||||
// ==================== AI相关变量 ====================
|
||||
extern double defense_coefficient; // 防守系数
|
||||
extern double defense_coefficient; // 防守系数
|
||||
|
||||
// ==================== 网络相关变量 ====================
|
||||
extern NetworkGameState network_state; // 网络游戏状态
|
||||
extern NetworkGameState network_state; // 网络游戏状态
|
||||
|
||||
// ==================== GUI相关变量 ====================
|
||||
extern SDL_Window* window; // SDL窗口指针
|
||||
extern SDL_Renderer* renderer; // SDL渲染器指针
|
||||
extern int gui_running; // GUI运行状态标志
|
||||
extern int current_player_gui; // GUI当前玩家
|
||||
extern int game_over; // 游戏结束标志
|
||||
extern char status_message[256]; // 状态消息
|
||||
// Raylib 不需要暴露窗口和渲染器指针
|
||||
extern int gui_running; // GUI运行状态标志
|
||||
extern int current_player_gui; // GUI当前玩家
|
||||
extern int game_over; // 游戏结束标志
|
||||
extern char status_message[256]; // 状态消息
|
||||
|
||||
// ==================== 记录相关变量 ====================
|
||||
extern int player1_final_score; // 玩家1最终得分
|
||||
extern int player2_final_score; // 玩家2最终得分
|
||||
extern int scores_calculated; // 评分计算标志
|
||||
extern char winner_info[50]; // 存储胜负信息
|
||||
extern int player1_final_score; // 玩家1最终得分
|
||||
extern int player2_final_score; // 玩家2最终得分
|
||||
extern int scores_calculated; // 评分计算标志
|
||||
extern char winner_info[50]; // 存储胜负信息
|
||||
|
||||
#endif // GLOBALS_H
|
||||
+5
-90
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file gui.h
|
||||
* @brief 图形化用户界面头文件
|
||||
* @note 使用SDL3库实现五子棋的图形化界面
|
||||
* @note 使用Raylib库实现五子棋的图形化界面
|
||||
* @author 刘航宇
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
@@ -9,7 +9,6 @@
|
||||
#ifndef GUI_H
|
||||
#define GUI_H
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include "gobang.h"
|
||||
#include "config.h"
|
||||
#include "globals.h"
|
||||
@@ -18,136 +17,52 @@
|
||||
|
||||
/**
|
||||
* @brief 初始化GUI
|
||||
* @details 初始化SDL3图形库和游戏界面组件:
|
||||
* - 初始化SDL视频子系统
|
||||
* - 创建游戏窗口(可调整大小)
|
||||
* - 创建SDL渲染器
|
||||
* - 初始化游戏状态和棋盘数据
|
||||
* @details 初始化Raylib图形库和游戏界面组件
|
||||
* @return 成功返回0,失败返回-1
|
||||
* @note 窗口标题为"五子棋游戏 - SDL3版本"
|
||||
* 窗口尺寸由WINDOW_WIDTH和WINDOW_HEIGHT定义
|
||||
* 失败时会自动清理已创建的资源
|
||||
*/
|
||||
int init_gui();
|
||||
|
||||
/**
|
||||
* @brief 清理GUI资源
|
||||
* @details 按顺序释放所有SDL相关资源:
|
||||
* - 销毁SDL渲染器
|
||||
* - 销毁SDL窗口
|
||||
* - 退出SDL子系统
|
||||
* @note 函数会检查资源是否存在再进行释放
|
||||
* 释放后将指针设置为NULL防止重复释放
|
||||
* 程序退出时必须调用此函数避免内存泄漏
|
||||
* @details 关闭窗口
|
||||
*/
|
||||
void cleanup_gui();
|
||||
|
||||
/**
|
||||
* @brief 渲染游戏画面
|
||||
* @details 完整的游戏画面渲染流程:
|
||||
* - 清空屏幕并设置背景色
|
||||
* - 绘制棋盘网格和标记点
|
||||
* - 绘制所有棋子
|
||||
* - 绘制UI界面元素
|
||||
* - 将渲染结果显示到屏幕
|
||||
* @note 使用双缓冲技术,通过SDL_RenderPresent显示最终结果
|
||||
* 背景色由GUI_COLOR_BACKGROUND定义
|
||||
* 每帧都会完全重绘整个画面
|
||||
* @details 完整的游戏画面渲染流程
|
||||
*/
|
||||
void render_game();
|
||||
|
||||
/**
|
||||
* @brief 处理事件
|
||||
* @details 处理所有SDL事件并执行相应操作:
|
||||
* - SDL_EVENT_QUIT:用户关闭窗口
|
||||
* - SDL_EVENT_KEY_DOWN:键盘按键(ESC退出)
|
||||
* - SDL_EVENT_MOUSE_BUTTON_DOWN:鼠标点击落子
|
||||
* @details 处理所有Raylib事件并执行相应操作
|
||||
* @return 继续运行返回1,退出返回0
|
||||
* @note 鼠标左键点击会转换为棋盘坐标并尝试落子
|
||||
* 落子后会检查胜负并切换玩家
|
||||
* 游戏结束后不再响应落子操作
|
||||
*/
|
||||
int handle_events();
|
||||
|
||||
/**
|
||||
* @brief 绘制棋盘
|
||||
* @details 绘制15x15的五子棋棋盘,包括:
|
||||
* - 横竖交叉的网格线
|
||||
* - 天元点(棋盘中心的标记点)
|
||||
* - 四个星位(棋盘上的定位点)
|
||||
* @note 使用SDL3渲染器绘制线条和填充矩形
|
||||
* 棋盘线条颜色由GUI_COLOR_BOARD_LINE定义
|
||||
* 天元点和星位用黑色小矩形标记
|
||||
*/
|
||||
void draw_board();
|
||||
|
||||
/**
|
||||
* @brief 绘制棋子
|
||||
* @details 遍历整个棋盘数组,绘制所有已落下的棋子:
|
||||
* - 黑子:使用GUI_COLOR_BLACK_STONE颜色
|
||||
* - 白子:使用GUI_COLOR_WHITE_STONE颜色
|
||||
* - 每个棋子都有边框:使用GUI_COLOR_STONE_BORDER颜色
|
||||
* @note 棋子绘制为圆形,半径由STONE_RADIUS定义
|
||||
* 通过draw_circle函数实现圆形绘制
|
||||
* 棋子位置根据棋盘坐标和CELL_SIZE计算屏幕坐标
|
||||
*/
|
||||
void draw_stones();
|
||||
|
||||
/**
|
||||
* @brief 绘制UI元素
|
||||
* @details 绘制游戏界面的用户交互元素:
|
||||
* - 状态信息区域背景和边框
|
||||
* - 当前玩家指示器(黑子或白子圆形)
|
||||
* - 游戏状态显示区域
|
||||
* @note 暂时使用简单图形代替文字显示
|
||||
* 需要额外字体库支持文字渲染
|
||||
* 指示器位置在棋盘右侧固定区域
|
||||
*/
|
||||
void draw_ui_elements();
|
||||
|
||||
/**
|
||||
* @brief 绘制圆形
|
||||
* @param center_x 圆心X坐标
|
||||
* @param center_y 圆心Y坐标
|
||||
* @param radius 半径
|
||||
* @param color 颜色
|
||||
* @details 使用像素级绘制实现圆形:
|
||||
* - 遍历圆形外接矩形内的所有像素点
|
||||
* - 计算每个像素到圆心的距离
|
||||
* - 距离小于等于半径的像素点进行着色
|
||||
* @note 采用暴力算法,性能较低但实现简单
|
||||
* 适用于绘制棋子等小尺寸圆形
|
||||
* SDL3没有内置圆形绘制函数,需要自实现
|
||||
*/
|
||||
void draw_circle(int center_x, int center_y, int radius, SDL_Color color);
|
||||
|
||||
/**
|
||||
* @brief 屏幕坐标转棋盘坐标
|
||||
* @param screen_x 屏幕X坐标
|
||||
* @param screen_y 屏幕Y坐标
|
||||
* @param board_x 输出棋盘X坐标
|
||||
* @param board_y 输出棋盘Y坐标
|
||||
* @return 转换成功返回1,失败返回0
|
||||
* @details 坐标转换算法:
|
||||
* - 减去棋盘偏移量得到相对坐标
|
||||
* - 加上半个格子尺寸实现就近取整
|
||||
* - 除以格子尺寸得到棋盘坐标
|
||||
* - 检查坐标是否在有效范围内
|
||||
* @note 使用就近取整算法,点击格子中心附近都会定位到该格子
|
||||
* 坐标范围检查确保不会越界访问棋盘数组
|
||||
*/
|
||||
int screen_to_board(int screen_x, int screen_y, int *board_x, int *board_y);
|
||||
|
||||
/**
|
||||
* @brief 显示消息
|
||||
* @param message 要显示的消息
|
||||
* @details 消息显示功能:
|
||||
* - 将消息复制到全局状态消息缓冲区
|
||||
* - 同时在控制台输出消息内容
|
||||
* - 确保字符串安全复制,防止缓冲区溢出
|
||||
* @note 消息会存储在status_message全局变量中
|
||||
* 字符串长度限制为缓冲区大小减1
|
||||
* 消息可用于游戏状态提示和错误信息显示
|
||||
*/
|
||||
void show_message(const char *message);
|
||||
|
||||
|
||||
+39
-38
@@ -10,32 +10,29 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#define SOCKET int
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
|
||||
// ==================== 游戏核心数据结构 ====================
|
||||
|
||||
/**
|
||||
* @brief 记录一步棋的详细信息
|
||||
*/
|
||||
typedef struct {
|
||||
int player; // 执行该步的玩家标识
|
||||
int x; // 落子的行坐标 (0-based)
|
||||
int y; // 落子的列坐标 (0-based)
|
||||
typedef struct
|
||||
{
|
||||
int player; // 执行该步的玩家标识
|
||||
int x; // 落子的行坐标 (0-based)
|
||||
int y; // 落子的列坐标 (0-based)
|
||||
} Step;
|
||||
|
||||
/**
|
||||
* @brief 存储在特定方向上棋子连续性的信息
|
||||
* @details 用于评估棋形,例如判断活三、冲四等关键形态
|
||||
*/
|
||||
typedef struct {
|
||||
int continuous_chess; // 连续同色棋子的数量
|
||||
bool check_start; // 棋子序列的起始端是否为空位(即是否开放)
|
||||
bool check_end; // 棋子序列的末尾端是否为空位(即是否开放)
|
||||
typedef struct
|
||||
{
|
||||
int continuous_chess; // 连续同色棋子的数量
|
||||
bool check_start; // 棋子序列的起始端是否为空位(即是否开放)
|
||||
bool check_end; // 棋子序列的末尾端是否为空位(即是否开放)
|
||||
} DirInfo;
|
||||
|
||||
// ==================== AI相关数据结构 ====================
|
||||
@@ -44,22 +41,24 @@ typedef struct {
|
||||
* @brief 移动排序结构体
|
||||
* @details 用于AI移动排序,存储候选移动及其评估分数
|
||||
*/
|
||||
typedef struct {
|
||||
int x, y; // 位置坐标
|
||||
int score; // 评估分数
|
||||
typedef struct
|
||||
{
|
||||
int x, y; // 位置坐标
|
||||
int score; // 评估分数
|
||||
} ScoredMove;
|
||||
|
||||
/**
|
||||
* @brief 威胁类型枚举
|
||||
* @details 用于AI威胁检测系统
|
||||
*/
|
||||
typedef enum {
|
||||
THREAT_NONE = 0, // 无威胁
|
||||
THREAT_WIN = 5, // 直接获胜
|
||||
THREAT_FOUR = 4, // 活四/冲四
|
||||
THREAT_THREE = 3, // 活三
|
||||
THREAT_DOUBLE = 2, // 双威胁
|
||||
THREAT_POTENTIAL = 1 // 潜在威胁
|
||||
typedef enum
|
||||
{
|
||||
THREAT_NONE = 0, // 无威胁
|
||||
THREAT_WIN = 5, // 直接获胜
|
||||
THREAT_FOUR = 4, // 活四/冲四
|
||||
THREAT_THREE = 3, // 活三
|
||||
THREAT_DOUBLE = 2, // 双威胁
|
||||
THREAT_POTENTIAL = 1 // 潜在威胁
|
||||
} ThreatLevel;
|
||||
|
||||
// ==================== 网络相关数据结构 ====================
|
||||
@@ -68,26 +67,28 @@ typedef enum {
|
||||
* @brief 网络消息结构
|
||||
* @details 用于网络对战中的消息传输
|
||||
*/
|
||||
typedef struct {
|
||||
int type; // 消息类型
|
||||
int player_id; // 玩家ID
|
||||
int x, y; // 坐标(用于落子)
|
||||
char message[256]; // 消息内容(用于聊天等)
|
||||
time_t timestamp; // 时间戳
|
||||
typedef struct
|
||||
{
|
||||
int type; // 消息类型
|
||||
int player_id; // 玩家ID
|
||||
int x, y; // 坐标(用于落子)
|
||||
char message[256]; // 消息内容(用于聊天等)
|
||||
time_t timestamp; // 时间戳
|
||||
} NetworkMessage;
|
||||
|
||||
/**
|
||||
* @brief 网络游戏状态结构
|
||||
* @details 用于管理网络游戏状态
|
||||
*/
|
||||
typedef struct {
|
||||
SOCKET socket; // 套接字
|
||||
bool is_server; // 是否为服务器
|
||||
bool is_connected; // 是否已连接
|
||||
int local_player_id; // 本地玩家ID
|
||||
int remote_player_id; // 远程玩家ID
|
||||
char remote_ip[16]; // 远程IP地址(MAX_IP_LENGTH = 16)
|
||||
int port; // 端口号
|
||||
typedef struct
|
||||
{
|
||||
uintptr_t socket; // 套接字 (使用uintptr_t代替SOCKET以避免引入winsock2.h)
|
||||
bool is_server; // 是否为服务器
|
||||
bool is_connected; // 是否已连接
|
||||
int local_player_id; // 本地玩家ID
|
||||
int remote_player_id; // 远程玩家ID
|
||||
char remote_ip[16]; // 远程IP地址(MAX_IP_LENGTH = 16)
|
||||
int port; // 端口号
|
||||
} NetworkGameState;
|
||||
|
||||
#endif // TYPE_H
|
||||
Reference in New Issue
Block a user