mirror of
https://github.com/LHY0125/Gobang-Game.git
synced 2026-05-09 18:09:46 +08:00
重构项目结构:将源文件和头文件分别移动到src和include目录
This commit is contained in:
+105
-463
@@ -1,463 +1,105 @@
|
|||||||
# 🚀 五子棋AI增强指南 (v8.0)
|
## 🎯 项目优势
|
||||||
|
### ✅ 已经做得很好的方面
|
||||||
## 📋 概述
|
- 📚 代码质量优秀 :注释覆盖率30.1%,使用Doxygen格式文档
|
||||||
|
- 🏗️ 架构设计合理 :模块化设计,职责分离清晰
|
||||||
本文档详细介绍了提升五子棋AI水平的各种方法和实现策略,基于当前项目的代码架构(v8.0),提供从简单参数调优到复杂算法改进的完整方案。v8.0版本新增了GUI界面支持,为AI可视化分析和用户交互提供了更好的平台。
|
- 🎮 功能完整丰富 :支持人机对战、双人对战、网络对战、GUI界面
|
||||||
|
- 🔧 技术栈现代化 :SDL3图形库、双版本架构、专业安装包
|
||||||
## 🎯 当前AI分析
|
- 📋 文档完善 :详细的README、AI增强指南、架构重构指南
|
||||||
|
- 🌐 跨平台考虑 :已有条件编译支持Windows/Linux
|
||||||
### 现有优势
|
## 🚀 改进建议
|
||||||
- ✅ 模块化设计良好
|
### 1. 🧪 测试体系建设(高优先级)
|
||||||
- ✅ 基础Minimax + α-β剪枝算法
|
当前状况 :项目缺乏自动化测试
|
||||||
- ✅ 完整的棋型评估系统
|
|
||||||
- ✅ 威胁检测机制
|
建议改进 :
|
||||||
- ✅ 防御优先策略
|
|
||||||
- ✅ SDL3图形化界面支持AI可视化分析
|
- 添加单元测试框架(如Unity或自制简单测试框架)
|
||||||
- ✅ 双版本架构(控制台+GUI)提供更好的调试环境
|
- 为核心模块编写测试用例:AI算法、棋盘逻辑、网络通信
|
||||||
|
- 添加集成测试验证各模块协作
|
||||||
### 改进空间
|
- 创建性能基准测试
|
||||||
- 🔄 搜索深度有限(当前3层)
|
### 2. 🛡️ 错误处理和安全性增强(高优先级)
|
||||||
- 🔄 评估函数相对简单
|
当前状况 :基础错误处理存在,但可以更完善
|
||||||
- 🔄 缺乏开局库和残局库
|
|
||||||
- 🔄 没有学习机制
|
建议改进 :
|
||||||
- 🔄 搜索效率可优化
|
|
||||||
|
- 增强输入验证,防止缓冲区溢出
|
||||||
## 🛠️ 改进方案
|
- 添加网络通信的安全验证机制
|
||||||
|
- 完善内存管理,添加内存泄漏检测
|
||||||
### 1. 立即可实施的改进(难度:⭐)
|
- 增加异常恢复机制
|
||||||
|
### 3. 🎯 AI算法优化(中优先级)
|
||||||
#### 1.1 参数调优
|
当前状况 :基础Minimax+α-β剪枝,搜索深度3层
|
||||||
|
|
||||||
**修改 `config.h` 中的关键参数:**
|
建议改进 :
|
||||||
|
|
||||||
```c
|
- 实现置换表缓存系统
|
||||||
// 增加搜索深度
|
- 添加开局库和残局库
|
||||||
#define DEFAULT_AI_DEPTH 5 // 从3提升到5
|
- 实现迭代加深搜索
|
||||||
|
- 增加威胁检测优化
|
||||||
// 优化防守系数
|
- 支持多线程并行搜索
|
||||||
#define DEFAULT_DEFENSE_COEFFICIENT 1.5 // 从1.2提升到1.5
|
### 4. 🔧 构建和部署优化(中优先级)
|
||||||
|
当前状况 :编译脚本功能完善,但可以更自动化
|
||||||
// 扩大搜索范围
|
|
||||||
#define AI_NEARBY_RANGE 3 // 从2扩大到3
|
建议改进 :
|
||||||
|
|
||||||
// 降低搜索范围限制阈值
|
- 添加CMake构建系统支持
|
||||||
#define AI_SEARCH_RANGE_THRESHOLD 8 // 从10降低到8
|
- 实现持续集成/持续部署(CI/CD)
|
||||||
```
|
- 添加依赖管理和版本控制
|
||||||
|
- 完善跨平台构建脚本
|
||||||
#### 1.2 评分系统优化
|
### 5. 📊 性能监控和分析(中优先级)
|
||||||
|
建议添加 :
|
||||||
**在 `config.h` 中添加新的评分项:**
|
|
||||||
|
- AI决策时间统计
|
||||||
```c
|
- 内存使用监控
|
||||||
// 组合棋型评分
|
- 网络延迟分析
|
||||||
#define AI_SCORE_DOUBLE_THREE 50000 // 双三
|
- 性能瓶颈识别工具
|
||||||
#define AI_SCORE_FOUR_THREE 200000 // 四三
|
### 6. 🎮 用户体验提升(低优先级)
|
||||||
#define AI_SCORE_THREAT_SEQUENCE 80000 // 威胁序列
|
建议改进 :
|
||||||
#define AI_SCORE_POTENTIAL_FIVE 300000 // 潜在五连
|
|
||||||
```
|
- 添加音效和动画效果
|
||||||
|
- 实现主题和皮肤系统
|
||||||
### 2. 短期改进(1-2周,难度:⭐⭐)
|
- 增加游戏统计和成就系统
|
||||||
|
- 支持自定义快捷键
|
||||||
#### 2.1 移动排序优化
|
### 7. 🌐 网络功能增强(低优先级)
|
||||||
|
建议改进 :
|
||||||
**在 `ai.c` 中添加移动排序函数:**
|
|
||||||
|
- 实现房间系统和匹配机制
|
||||||
```c
|
- 添加观战功能
|
||||||
// 移动排序结构
|
- 支持断线重连
|
||||||
typedef struct {
|
- 实现聊天系统
|
||||||
int x, y;
|
## 📋 具体实施建议
|
||||||
int score;
|
### 立即可实施(1-2周)
|
||||||
} ScoredMove;
|
1. 1.
|
||||||
|
创建基础测试框架
|
||||||
// 移动排序函数
|
2. 2.
|
||||||
int compare_moves(const void *a, const void *b) {
|
添加输入验证和边界检查
|
||||||
ScoredMove *moveA = (ScoredMove*)a;
|
3. 3.
|
||||||
ScoredMove *moveB = (ScoredMove*)b;
|
完善错误日志记录
|
||||||
return moveB->score - moveA->score;
|
4. 4.
|
||||||
}
|
优化编译警告处理
|
||||||
|
### 短期目标(1-2月)
|
||||||
// 生成并排序候选移动
|
1. 1.
|
||||||
int generate_candidate_moves(ScoredMove *moves, int player) {
|
完善单元测试覆盖
|
||||||
int count = 0;
|
2. 2.
|
||||||
for (int i = 0; i < BOARD_SIZE; i++) {
|
实现置换表和开局库
|
||||||
for (int j = 0; j < BOARD_SIZE; j++) {
|
3. 3.
|
||||||
if (board[i][j] == EMPTY && is_near_stones(i, j)) {
|
添加性能监控
|
||||||
moves[count].x = i;
|
4. 4.
|
||||||
moves[count].y = j;
|
增强网络安全性
|
||||||
moves[count].score = evaluate_move(i, j);
|
### 长期规划(3-6月)
|
||||||
count++;
|
1. 1.
|
||||||
}
|
实现神经网络AI
|
||||||
}
|
2. 2.
|
||||||
}
|
完整跨平台支持
|
||||||
qsort(moves, count, sizeof(ScoredMove), compare_moves);
|
3. 3.
|
||||||
return count;
|
添加数据库支持
|
||||||
}
|
4. 4.
|
||||||
```
|
实现云端对战
|
||||||
|
## 🏆 总体评价
|
||||||
#### 2.2 威胁检测增强
|
你的项目已经达到了 专业级别的开源项目标准 !代码架构清晰、功能完整、文档详尽。主要的改进空间在于测试覆盖和一些高级特性的添加。
|
||||||
|
|
||||||
**添加多层次威胁检测:**
|
项目亮点 :
|
||||||
|
|
||||||
```c
|
- 从v7.0的架构重构到v8.2的编译优化,版本迭代思路清晰
|
||||||
// 威胁类型枚举
|
- SDL3图形化界面实现现代化
|
||||||
typedef enum {
|
- 网络对战功能完整
|
||||||
THREAT_NONE = 0,
|
- 代码注释和文档非常专业
|
||||||
THREAT_WIN = 5, // 直接获胜
|
这是一个非常值得继续完善和推广的优秀项目!🎉
|
||||||
THREAT_FOUR = 4, // 活四/冲四
|
|
||||||
THREAT_THREE = 3, // 活三
|
|
||||||
THREAT_DOUBLE = 2, // 双威胁
|
|
||||||
THREAT_POTENTIAL = 1 // 潜在威胁
|
|
||||||
} ThreatLevel;
|
|
||||||
|
|
||||||
// 威胁检测函数
|
|
||||||
ThreatLevel detect_threat(int x, int y, int player) {
|
|
||||||
// 实现威胁检测逻辑
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 中期改进(1-2月,难度:⭐⭐⭐)
|
|
||||||
|
|
||||||
#### 3.1 置换表实现
|
|
||||||
|
|
||||||
**添加置换表缓存系统:**
|
|
||||||
|
|
||||||
```c
|
|
||||||
// 置换表项
|
|
||||||
typedef struct {
|
|
||||||
uint64_t hash_key; // 棋盘哈希值
|
|
||||||
int score; // 评估分数
|
|
||||||
int depth; // 搜索深度
|
|
||||||
int best_x, best_y; // 最佳移动
|
|
||||||
int flag; // 节点类型(精确值/上界/下界)
|
|
||||||
} TranspositionEntry;
|
|
||||||
|
|
||||||
// 置换表
|
|
||||||
#define TT_SIZE 1048576 // 2^20
|
|
||||||
TranspositionEntry transposition_table[TT_SIZE];
|
|
||||||
|
|
||||||
// 棋盘哈希函数
|
|
||||||
uint64_t zobrist_hash() {
|
|
||||||
// 实现Zobrist哈希
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 3.2 开局库系统
|
|
||||||
|
|
||||||
**创建开局库数据结构:**
|
|
||||||
|
|
||||||
```c
|
|
||||||
// 开局库项
|
|
||||||
typedef struct {
|
|
||||||
int moves[20][2]; // 开局移动序列
|
|
||||||
int move_count; // 移动数量
|
|
||||||
int win_rate; // 胜率
|
|
||||||
char name[50]; // 开局名称
|
|
||||||
} OpeningEntry;
|
|
||||||
|
|
||||||
// 开局库
|
|
||||||
OpeningEntry opening_book[] = {
|
|
||||||
// 天元开局
|
|
||||||
{{{7,7}, {6,6}, {8,8}, {6,8}, {8,6}}, 5, 65, "天元开局"},
|
|
||||||
// 花月开局
|
|
||||||
{{{7,7}, {6,7}, {8,7}, {7,6}, {7,8}}, 5, 70, "花月开局"},
|
|
||||||
// 更多开局...
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 3.3 改进的评估函数
|
|
||||||
|
|
||||||
**实现更复杂的位置评估:**
|
|
||||||
|
|
||||||
```c
|
|
||||||
// 高级评估函数
|
|
||||||
int advanced_evaluate_pos(int x, int y, int player) {
|
|
||||||
int score = 0;
|
|
||||||
|
|
||||||
// 1. 基础棋型评分
|
|
||||||
score += basic_pattern_score(x, y, player);
|
|
||||||
|
|
||||||
// 2. 组合棋型评分
|
|
||||||
score += combination_pattern_score(x, y, player);
|
|
||||||
|
|
||||||
// 3. 位置价值评分
|
|
||||||
score += positional_value_score(x, y);
|
|
||||||
|
|
||||||
// 4. 威胁序列评分
|
|
||||||
score += threat_sequence_score(x, y, player);
|
|
||||||
|
|
||||||
// 5. 防守价值评分
|
|
||||||
score += defensive_value_score(x, y, player);
|
|
||||||
|
|
||||||
return score;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. 长期改进(3-6月,难度:⭐⭐⭐⭐)
|
|
||||||
|
|
||||||
#### 4.1 蒙特卡洛树搜索(MCTS)
|
|
||||||
|
|
||||||
**MCTS节点结构:**
|
|
||||||
|
|
||||||
```c
|
|
||||||
// MCTS节点
|
|
||||||
typedef struct MCTSNode {
|
|
||||||
int x, y; // 移动位置
|
|
||||||
int visits; // 访问次数
|
|
||||||
double wins; // 胜利次数
|
|
||||||
struct MCTSNode *parent; // 父节点
|
|
||||||
struct MCTSNode **children; // 子节点数组
|
|
||||||
int child_count; // 子节点数量
|
|
||||||
bool fully_expanded; // 是否完全展开
|
|
||||||
} MCTSNode;
|
|
||||||
|
|
||||||
// MCTS主函数
|
|
||||||
int mcts_search(int simulations) {
|
|
||||||
MCTSNode *root = create_node(-1, -1, NULL);
|
|
||||||
|
|
||||||
for (int i = 0; i < simulations; i++) {
|
|
||||||
MCTSNode *node = selection(root);
|
|
||||||
node = expansion(node);
|
|
||||||
double result = simulation(node);
|
|
||||||
backpropagation(node, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return best_child(root);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4.2 神经网络集成
|
|
||||||
|
|
||||||
**神经网络评估接口:**
|
|
||||||
|
|
||||||
```c
|
|
||||||
// 神经网络评估函数
|
|
||||||
float neural_network_evaluate(int board[BOARD_SIZE][BOARD_SIZE]) {
|
|
||||||
// 调用训练好的神经网络模型
|
|
||||||
// 返回位置评估值
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
|
|
||||||
// 混合评估函数
|
|
||||||
int hybrid_evaluate(int x, int y, int player) {
|
|
||||||
// 传统评估
|
|
||||||
int traditional_score = evaluate_pos(x, y, player);
|
|
||||||
|
|
||||||
// 神经网络评估
|
|
||||||
float nn_score = neural_network_evaluate(board);
|
|
||||||
|
|
||||||
// 加权组合
|
|
||||||
return (int)(0.7 * traditional_score + 0.3 * nn_score * 10000);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📊 性能优化策略
|
|
||||||
|
|
||||||
### 1. 搜索优化
|
|
||||||
|
|
||||||
#### 1.1 迭代加深搜索
|
|
||||||
```c
|
|
||||||
int iterative_deepening_search(int max_depth, int time_limit) {
|
|
||||||
int best_move = -1;
|
|
||||||
clock_t start_time = clock();
|
|
||||||
|
|
||||||
for (int depth = 1; depth <= max_depth; depth++) {
|
|
||||||
if ((clock() - start_time) * 1000 / CLOCKS_PER_SEC > time_limit) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
best_move = alpha_beta_search(depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
return best_move;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 1.2 空窗搜索
|
|
||||||
```c
|
|
||||||
int null_window_search(int depth, int beta) {
|
|
||||||
return alpha_beta_search(depth, beta - 1, beta);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 内存优化
|
|
||||||
|
|
||||||
#### 2.1 位棋盘表示
|
|
||||||
```c
|
|
||||||
// 使用位操作优化棋盘表示
|
|
||||||
typedef struct {
|
|
||||||
uint64_t player1_board[4]; // 玩家1的棋盘(4个64位整数)
|
|
||||||
uint64_t player2_board[4]; // 玩家2的棋盘
|
|
||||||
} BitBoard;
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🎮 实战策略
|
|
||||||
|
|
||||||
### 1. 自适应难度系统
|
|
||||||
|
|
||||||
```c
|
|
||||||
// 难度等级
|
|
||||||
typedef enum {
|
|
||||||
DIFFICULTY_EASY = 1,
|
|
||||||
DIFFICULTY_NORMAL = 2,
|
|
||||||
DIFFICULTY_HARD = 3,
|
|
||||||
DIFFICULTY_EXPERT = 4,
|
|
||||||
DIFFICULTY_MASTER = 5
|
|
||||||
} DifficultyLevel;
|
|
||||||
|
|
||||||
// 根据难度调整AI参数
|
|
||||||
void adjust_ai_parameters(DifficultyLevel level) {
|
|
||||||
switch (level) {
|
|
||||||
case DIFFICULTY_EASY:
|
|
||||||
ai_depth = 2;
|
|
||||||
defense_coefficient = 1.0;
|
|
||||||
break;
|
|
||||||
case DIFFICULTY_NORMAL:
|
|
||||||
ai_depth = 3;
|
|
||||||
defense_coefficient = 1.2;
|
|
||||||
break;
|
|
||||||
case DIFFICULTY_HARD:
|
|
||||||
ai_depth = 4;
|
|
||||||
defense_coefficient = 1.5;
|
|
||||||
break;
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 学习系统
|
|
||||||
|
|
||||||
```c
|
|
||||||
// 对局记录
|
|
||||||
typedef struct {
|
|
||||||
int moves[MAX_STEPS][2];
|
|
||||||
int move_count;
|
|
||||||
int winner;
|
|
||||||
int ai_mistakes;
|
|
||||||
float game_quality;
|
|
||||||
} GameRecord;
|
|
||||||
|
|
||||||
// 学习函数
|
|
||||||
void learn_from_game(GameRecord *record) {
|
|
||||||
// 分析对局,更新评估参数
|
|
||||||
// 识别AI的错误决策
|
|
||||||
// 调整相关参数
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📈 测试与评估
|
|
||||||
|
|
||||||
### 1. 性能测试
|
|
||||||
|
|
||||||
```c
|
|
||||||
// 性能测试函数
|
|
||||||
void performance_test() {
|
|
||||||
clock_t start = clock();
|
|
||||||
|
|
||||||
// 执行1000次AI决策
|
|
||||||
for (int i = 0; i < 1000; i++) {
|
|
||||||
ai_move(DEFAULT_AI_DEPTH);
|
|
||||||
// 重置棋盘
|
|
||||||
}
|
|
||||||
|
|
||||||
clock_t end = clock();
|
|
||||||
double time_taken = ((double)(end - start)) / CLOCKS_PER_SEC;
|
|
||||||
printf("平均决策时间: %.2f ms\n", time_taken);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 棋力测试
|
|
||||||
|
|
||||||
```c
|
|
||||||
// 自我对弈测试
|
|
||||||
int self_play_test(int games) {
|
|
||||||
int wins = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < games; i++) {
|
|
||||||
// AI vs AI(不同版本或参数)
|
|
||||||
int result = play_game();
|
|
||||||
if (result == 1) wins++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (wins * 100) / games; // 胜率
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🚀 实施路线图
|
|
||||||
|
|
||||||
### 阶段1:基础优化(1周)
|
|
||||||
- [ ] 调整搜索深度和评分参数
|
|
||||||
- [ ] 优化移动排序
|
|
||||||
- [ ] 增强威胁检测
|
|
||||||
|
|
||||||
### 阶段2:算法改进(2-4周)
|
|
||||||
- [ ] 实现置换表
|
|
||||||
- [ ] 添加开局库
|
|
||||||
- [ ] 改进评估函数
|
|
||||||
|
|
||||||
### 阶段3:高级功能(1-2月)
|
|
||||||
- [ ] 实现MCTS
|
|
||||||
- [ ] 添加学习机制
|
|
||||||
- [ ] 性能优化
|
|
||||||
|
|
||||||
### 阶段4:AI增强(2-3月)
|
|
||||||
- [ ] 神经网络集成
|
|
||||||
- [ ] 并行搜索
|
|
||||||
- [ ] 完整的自适应系统
|
|
||||||
|
|
||||||
## 📚 参考资源
|
|
||||||
|
|
||||||
### 算法资料
|
|
||||||
- 《人工智能:一种现代方法》- Stuart Russell
|
|
||||||
- 《游戏编程中的人工智能技术》- Mat Buckland
|
|
||||||
- AlphaGo论文系列
|
|
||||||
|
|
||||||
### 开源项目
|
|
||||||
- Stockfish(国际象棋引擎)
|
|
||||||
- Leela Zero(围棋AI)
|
|
||||||
- Gomoku AI项目
|
|
||||||
|
|
||||||
### 在线资源
|
|
||||||
- Chess Programming Wiki
|
|
||||||
- Computer Olympiad
|
|
||||||
- AI游戏编程社区
|
|
||||||
|
|
||||||
## 🏗️ 代码架构优化 (v7.0新增)
|
|
||||||
|
|
||||||
### 配置管理统一化
|
|
||||||
|
|
||||||
在v7.0版本中,我们完成了重要的代码架构重构:
|
|
||||||
|
|
||||||
#### 配置参数集中管理
|
|
||||||
- **统一配置文件**:所有AI相关参数现在集中在`config.h`中定义
|
|
||||||
- **参数分类管理**:AI参数按功能分组(搜索深度、评分权重、时间限制等)
|
|
||||||
- **配置文件支持**:AI参数可通过`gobang_config.ini`文件动态调整
|
|
||||||
- **运行时修改**:支持游戏过程中实时调整AI难度和参数
|
|
||||||
|
|
||||||
#### 代码模块化优化
|
|
||||||
- **清晰的模块分离**:AI逻辑与游戏逻辑完全分离
|
|
||||||
- **接口标准化**:统一的AI接口设计,便于算法替换和升级
|
|
||||||
- **全局变量管理**:AI相关全局变量集中在`globals`模块中
|
|
||||||
- **类型定义统一**:所有数据结构定义集中在`type.h`中
|
|
||||||
|
|
||||||
#### 维护性提升
|
|
||||||
- **宏定义优化**:消除重复定义,提高代码一致性
|
|
||||||
- **注释规范化**:完善的代码注释和文档
|
|
||||||
- **错误处理统一**:标准化的错误处理机制
|
|
||||||
- **调试支持增强**:更好的调试信息和日志记录
|
|
||||||
|
|
||||||
这些架构优化为后续的AI算法改进奠定了坚实的基础,使得实施复杂的AI增强方案变得更加容易和可靠。
|
|
||||||
|
|
||||||
## 💡 总结
|
|
||||||
|
|
||||||
通过系统性的改进,可以将当前的五子棋AI从业余水平提升到接近专业水平。关键是要循序渐进,先实施简单的改进,再逐步引入复杂的算法。每个阶段都要进行充分的测试和评估,确保改进的有效性。
|
|
||||||
|
|
||||||
建议按照优先级顺序实施:
|
|
||||||
|
|
||||||
1. **短期目标**:参数调优 + 开局库 + 棋型优化
|
|
||||||
2. **中期目标**:搜索算法优化 + 评估函数改进
|
|
||||||
3. **长期目标**:机器学习集成 + MCTS实现
|
|
||||||
|
|
||||||
v7.0的架构重构为所有这些改进提供了更好的代码基础。
|
|
||||||
|
|
||||||
记住:**好的AI不仅要算得深,更要算得准!**
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
# 编译器设置
|
# 编译器设置
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -Wall -Wextra -std=c17 -O2
|
CFLAGS = -Wall -Wextra -std=c17 -O2 -Iinclude
|
||||||
LDFLAGS = -lws2_32
|
LDFLAGS = -lws2_32
|
||||||
|
|
||||||
# SDL3路径设置
|
# SDL3路径设置
|
||||||
@@ -12,14 +12,14 @@ SDL3_INCLUDE = -I$(SDL3_PATH)/include
|
|||||||
SDL3_LIBS = -L$(SDL3_PATH)/lib -lSDL3 -lmingw32
|
SDL3_LIBS = -L$(SDL3_PATH)/lib -lSDL3 -lmingw32
|
||||||
|
|
||||||
# 源文件
|
# 源文件
|
||||||
COMMON_SOURCES = main.c gobang.c ai.c config.c game_mode.c globals.c \
|
COMMON_SOURCES = src/main.c src/gobang.c src/ai.c src/config.c src/game_mode.c src/globals.c \
|
||||||
init_board.c network.c record.c ui.c gui.c type.h
|
src/init_board.c src/network.c src/record.c src/ui.c src/gui.c
|
||||||
|
|
||||||
GUI_SOURCES = $(COMMON_SOURCES)
|
GUI_SOURCES = $(COMMON_SOURCES)
|
||||||
CONSOLE_SOURCES = $(COMMON_SOURCES)
|
CONSOLE_SOURCES = $(COMMON_SOURCES)
|
||||||
|
|
||||||
# 目标文件
|
# 目标文件
|
||||||
COMMON_OBJECTS = $(patsubst %.c,%.o,$(filter %.c,$(COMMON_SOURCES)))
|
COMMON_OBJECTS = $(patsubst src/%.c,src/%.o,$(filter %.c,$(COMMON_SOURCES)))
|
||||||
|
|
||||||
# 可执行文件
|
# 可执行文件
|
||||||
CONSOLE_TARGET = gobang_console.exe
|
CONSOLE_TARGET = gobang_console.exe
|
||||||
@@ -37,12 +37,12 @@ $(GUI_TARGET): $(COMMON_OBJECTS)
|
|||||||
$(CC) $(CFLAGS) $(SDL3_INCLUDE) -o $@ $^ $(SDL3_LIBS) $(LDFLAGS)
|
$(CC) $(CFLAGS) $(SDL3_INCLUDE) -o $@ $^ $(SDL3_LIBS) $(LDFLAGS)
|
||||||
|
|
||||||
# 通用目标文件编译规则(包含SDL3头文件路径,因为多个文件包含gui.h)
|
# 通用目标文件编译规则(包含SDL3头文件路径,因为多个文件包含gui.h)
|
||||||
%.o: %.c
|
src/%.o: src/%.c
|
||||||
$(CC) $(CFLAGS) $(SDL3_INCLUDE) -c -o $@ $<
|
$(CC) $(CFLAGS) $(SDL3_INCLUDE) -c -o $@ $<
|
||||||
|
|
||||||
# 清理规则
|
# 清理规则
|
||||||
clean:
|
clean:
|
||||||
del /Q *.o *.exe 2>nul || true
|
del /Q src\*.o *.exe 2>nul || true
|
||||||
|
|
||||||
# 只编译控制台版本
|
# 只编译控制台版本
|
||||||
console: $(CONSOLE_TARGET)
|
console: $(CONSOLE_TARGET)
|
||||||
|
|||||||
+4
-4
@@ -21,7 +21,7 @@ exit /b 1
|
|||||||
echo.
|
echo.
|
||||||
echo Compiling console version...
|
echo Compiling console version...
|
||||||
echo.
|
echo.
|
||||||
gcc -std=c17 -o gobang_console.exe *.c -ID:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\include -LD:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\lib -lSDL3 -lws2_32
|
gcc -std=c17 -o gobang_console.exe src/*.c -Iinclude -ID:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\include -LD:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\lib -lSDL3 -lws2_32
|
||||||
if %ERRORLEVEL% EQU 0 (
|
if %ERRORLEVEL% EQU 0 (
|
||||||
echo.
|
echo.
|
||||||
echo Compilation successful! Generated: gobang_console.exe
|
echo Compilation successful! Generated: gobang_console.exe
|
||||||
@@ -44,7 +44,7 @@ if not exist "D:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\include" (
|
|||||||
echo Please ensure SDL3 is extracted to: D:\settings\SDL\SDL3-3.2.22\
|
echo Please ensure SDL3 is extracted to: D:\settings\SDL\SDL3-3.2.22\
|
||||||
goto :end
|
goto :end
|
||||||
)
|
)
|
||||||
gcc -std=c17 -o gobang_gui.exe *.c -ID:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\include -LD:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\lib -lSDL3 -lws2_32
|
gcc -std=c17 -o gobang_gui.exe src/*.c -Iinclude -ID:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\include -LD:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\lib -lSDL3 -lws2_32
|
||||||
if %ERRORLEVEL% EQU 0 (
|
if %ERRORLEVEL% EQU 0 (
|
||||||
echo.
|
echo.
|
||||||
echo Compilation successful! Generated: gobang_gui.exe
|
echo Compilation successful! Generated: gobang_gui.exe
|
||||||
@@ -68,7 +68,7 @@ echo.
|
|||||||
echo Compiling all versions...
|
echo Compiling all versions...
|
||||||
echo.
|
echo.
|
||||||
echo [1/2] Compiling console version...
|
echo [1/2] Compiling console version...
|
||||||
gcc -std=c17 -o gobang_console.exe *.c -ID:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\include -LD:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\lib -lSDL3 -lws2_32
|
gcc -std=c17 -o gobang_console.exe src/*.c -Iinclude -ID:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\include -LD:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\lib -lSDL3 -lws2_32
|
||||||
if %ERRORLEVEL% EQU 0 (
|
if %ERRORLEVEL% EQU 0 (
|
||||||
echo Console version compilation successful!
|
echo Console version compilation successful!
|
||||||
) else (
|
) else (
|
||||||
@@ -80,7 +80,7 @@ if not exist "D:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\include" (
|
|||||||
echo Error: SDL3 library not found! Skipping GUI version compilation
|
echo Error: SDL3 library not found! Skipping GUI version compilation
|
||||||
goto :end
|
goto :end
|
||||||
)
|
)
|
||||||
gcc -std=c17 -o gobang_gui.exe *.c -ID:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\include -LD:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\lib -lSDL3 -lws2_32
|
gcc -std=c17 -o gobang_gui.exe src/*.c -Iinclude -ID:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\include -LD:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\lib -lSDL3 -lws2_32
|
||||||
if %ERRORLEVEL% EQU 0 (
|
if %ERRORLEVEL% EQU 0 (
|
||||||
echo GUI version compilation successful!
|
echo GUI version compilation successful!
|
||||||
copy "D:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\bin\SDL3.dll" . >nul 2>&1
|
copy "D:\settings\SDL\SDL3-3.2.22\x86_64-w64-mingw32\bin\SDL3.dll" . >nul 2>&1
|
||||||
|
|||||||
@@ -86,8 +86,23 @@ bool handle_network_player_turn(int current_player, bool is_local_turn);
|
|||||||
/**
|
/**
|
||||||
* @brief 网络游戏主循环
|
* @brief 网络游戏主循环
|
||||||
* @return true 游戏正常结束
|
* @return true 游戏正常结束
|
||||||
* @return false 网络错误或异常退出
|
* @return false 网络错误
|
||||||
*/
|
*/
|
||||||
bool network_game_loop();
|
bool network_game_loop();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 显示游戏规则
|
||||||
|
*/
|
||||||
|
void show_game_rules();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 显示关于游戏信息
|
||||||
|
*/
|
||||||
|
void show_about_game();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 启动图形化界面
|
||||||
|
*/
|
||||||
|
void run_gui_mode();
|
||||||
|
|
||||||
#endif // GAME_MODE_H
|
#endif // GAME_MODE_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
#include "gui.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@@ -706,6 +707,51 @@ void run_network_game()
|
|||||||
pause_for_input("按任意键返回主菜单...");
|
pause_for_input("按任意键返回主菜单...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 显示游戏规则
|
||||||
|
*/
|
||||||
|
void show_game_rules()
|
||||||
|
{
|
||||||
|
clear_screen();
|
||||||
|
display_game_rules();
|
||||||
|
pause_for_input("\n按任意键返回主菜单...");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 显示关于游戏信息
|
||||||
|
*/
|
||||||
|
void show_about_game()
|
||||||
|
{
|
||||||
|
clear_screen();
|
||||||
|
display_about();
|
||||||
|
pause_for_input("\n按任意键返回主菜单...");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 启动图形化界面
|
||||||
|
*/
|
||||||
|
void run_gui_mode()
|
||||||
|
{
|
||||||
|
if (init_gui() == 0)
|
||||||
|
{
|
||||||
|
printf("启动图形化界面...\n");
|
||||||
|
printf("图形化界面已启动,窗口应该可见\n");
|
||||||
|
printf("如果看不到窗口,请检查任务栏或按Alt+Tab切换\n");
|
||||||
|
while (gui_running && handle_events())
|
||||||
|
{
|
||||||
|
render_game();
|
||||||
|
SDL_Delay(16); // 约60FPS
|
||||||
|
}
|
||||||
|
printf("退出图形化界面\n");
|
||||||
|
cleanup_gui();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("图形化界面启动失败!请检查SDL3库是否正确安装。\n");
|
||||||
|
pause_for_input("按任意键返回主菜单...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 处理网络玩家回合
|
* @brief 处理网络玩家回合
|
||||||
*/
|
*/
|
||||||
@@ -31,14 +31,14 @@ NetworkGameState network_state = {0}; // 网络游戏
|
|||||||
|
|
||||||
// ==================== GUI相关变量定义 ====================
|
// ==================== GUI相关变量定义 ====================
|
||||||
SDL_Window* window = NULL; // SDL窗口指针
|
SDL_Window* window = NULL; // SDL窗口指针
|
||||||
SDL_Renderer* renderer = NULL; // SDL渲染器指针
|
SDL_Renderer* renderer = NULL; // SDL渲染器指针
|
||||||
int gui_running = 1; // GUI运行状态标志
|
int gui_running = 1; // GUI运行状态标志
|
||||||
int current_player_gui = PLAYER; // GUI当前玩家
|
int current_player_gui = PLAYER; // GUI当前玩家
|
||||||
int game_over = 0; // 游戏结束标志
|
int game_over = 0; // 游戏结束标志
|
||||||
char status_message[256] = "五子棋游戏 - 黑子先行"; // 状态消息
|
char status_message[256] = "五子棋游戏 - 黑子先行"; // 状态消息
|
||||||
|
|
||||||
// ==================== 记录相关变量定义 ====================
|
// ==================== 记录相关变量定义 ====================
|
||||||
int player1_final_score = 0; // 玩家1最终得分
|
int player1_final_score = 0; // 玩家1最终得分
|
||||||
int player2_final_score = 0; // 玩家2最终得分
|
int player2_final_score = 0; // 玩家2最终得分
|
||||||
int scores_calculated = 0; // 评分计算标志
|
int scores_calculated = 0; // 评分计算标志
|
||||||
char winner_info[50] = "平局或未完成"; // 存储胜负信息
|
char winner_info[50] = "平局或未完成"; // 存储胜负信息
|
||||||
+3
-25
@@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
#include "game_mode.h"
|
#include "game_mode.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "gui.h"
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -73,36 +72,15 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
// 6. 游戏规则
|
// 6. 游戏规则
|
||||||
case 6:
|
case 6:
|
||||||
clear_screen();
|
show_game_rules();
|
||||||
display_game_rules();
|
|
||||||
pause_for_input("\n按任意键返回主菜单...");
|
|
||||||
break;
|
break;
|
||||||
// 7. 关于游戏
|
// 7. 关于游戏
|
||||||
case 7:
|
case 7:
|
||||||
clear_screen();
|
show_about_game();
|
||||||
display_about();
|
|
||||||
pause_for_input("\n按任意键返回主菜单...");
|
|
||||||
break;
|
break;
|
||||||
// 8. 图形化界面
|
// 8. 图形化界面
|
||||||
case 8:
|
case 8:
|
||||||
if (init_gui() == 0)
|
run_gui_mode();
|
||||||
{
|
|
||||||
printf("启动图形化界面...\n");
|
|
||||||
printf("图形化界面已启动,窗口应该可见\n");
|
|
||||||
printf("如果看不到窗口,请检查任务栏或按Alt+Tab切换\n");
|
|
||||||
while (gui_running && handle_events())
|
|
||||||
{
|
|
||||||
render_game();
|
|
||||||
SDL_Delay(16); // 约60FPS
|
|
||||||
}
|
|
||||||
printf("退出图形化界面\n");
|
|
||||||
cleanup_gui();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("图形化界面启动失败!请检查SDL3库是否正确安装。\n");
|
|
||||||
pause_for_input("按任意键返回主菜单...");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
// 0. 退出游戏
|
// 0. 退出游戏
|
||||||
case 0:
|
case 0:
|
||||||
Reference in New Issue
Block a user