From 6e8b61a9587c80e18cb6fdab46aa8e73928d647d Mon Sep 17 00:00:00 2001 From: LHY0125 <3364451258@qq.com> Date: Mon, 30 Jun 2025 22:27:15 +0800 Subject: [PATCH] Add files via upload --- README.md | 201 +++++++++++----------- ai.c | 216 ++++++++++++------------ ai.h | 32 ++-- game_mode.c | 128 +++++++------- game_mode.h | 50 +++--- gobang.c | 474 ++++++++++++++++++++++++++-------------------------- gobang.h | 232 ++++++++++++------------- 7 files changed, 670 insertions(+), 663 deletions(-) diff --git a/README.md b/README.md index ae413a2..c0e2c1f 100644 --- a/README.md +++ b/README.md @@ -1,146 +1,159 @@ -# ? 五子棋人机对战AI +# ? 浜斿瓙妫嬩汉鏈哄鎴楢I ![Build Status](https://img.shields.io/badge/build-passing-brightgreen) ![License](https://img.shields.io/badge/license-MIT-blue) ![Code Lines](https://img.shields.io/tokei/lines/github/your-username/your-repo) -## 目录 -- [? 五子棋人机对战AI](#-五子棋人机对战ai) - - [目录](#目录) - - [项目简介](#项目简介) - - [? 功能特性](#-功能特性) - - [? 快速开始](#-快速开始) - - [编译程序](#编译程序) - - [运行游戏](#运行游戏) - - [? 游戏玩法](#-游戏玩法) - - [? 开发环境](#-开发环境) - - [?? 常见问题](#?-常见问题) - - [权限问题](#权限问题) - - [中文显示问题](#中文显示问题) - - [?? 技术实现](#?-技术实现) - - [核心决策算法](#核心决策算法) - - [启发式评估函数](#启发式评估函数) - - [? 代码结构](#-代码结构) - - [? 许可证](#-许可证) - - [? 反馈与贡献](#-反馈与贡献) - - [? 未来计划](#-未来计划) +## 鐩綍 +- [? 浜斿瓙妫嬩汉鏈哄鎴楢I](#-浜斿瓙妫嬩汉鏈哄鎴榓i) + - [鐩綍](#鐩綍) + - [椤圭洰绠浠媇(#椤圭洰绠浠) + - [鍔熻兘鐗规(#鍔熻兘鐗规) + - [蹇熷紑濮媇(#蹇熷紑濮) + - [缂栬瘧绋嬪簭](#缂栬瘧绋嬪簭) + - [杩愯娓告垙](#杩愯娓告垙) + - [娓告垙鐜╂硶](#娓告垙鐜╂硶) + - [寮鍙戠幆澧僝(#寮鍙戠幆澧) + - [甯歌闂](#甯歌闂) + - [鏉冮檺闂](#鏉冮檺闂) + - [涓枃鏄剧ず闂](#涓枃鏄剧ず闂) + - [鎶鏈疄鐜癩(#鎶鏈疄鐜) + - [鏍稿績鍐崇瓥绠楁硶](#鏍稿績鍐崇瓥绠楁硶) + - [鍚彂寮忚瘎浼板嚱鏁癩(#鍚彂寮忚瘎浼板嚱鏁) + - [浠g爜缁撴瀯](#浠g爜缁撴瀯) + - [璁稿彲璇乚(#璁稿彲璇) + - [鍙嶉涓庤础鐚甝(#鍙嶉涓庤础鐚) + - [鏈潵璁″垝](#鏈潵璁″垝) -## 项目简介 -基于C语言实现的五子棋人机对战系统,采用α-β剪枝优化的极小极大算法,支持自定义棋盘大小、游戏复盘和实时评分。 +## 椤圭洰绠浠 +鍩轰簬C璇█瀹炵幇鐨勪簲瀛愭浜烘満瀵规垬绯荤粺锛岄噰鐢ㄎ-尾鍓灊浼樺寲鐨勬瀬灏忔瀬澶х畻娉曪紝鏀寔鑷畾涔夋鐩樺ぇ灏忋佹父鎴忓鐩樺拰瀹炴椂璇勫垎銆 -## ? 功能特性 -- ? 人机对战模式 -- ?? 可调棋盘尺寸(5x5到25x25) -- ? 智能AI决策(1-5级难度) -- ? 完整游戏复盘功能 -- ? 实时对局评分系统 -- ?? 悔棋功能(可撤销上一步) -- ?? 清晰的终端界面显示 -- ?? 健壮的输入验证(确保所有数字输入都在有效范围内) -- ?? 可选的回合计时器 -- ? 自动游戏记录保存 +## 鍔熻兘鐗规 +- 浜烘満瀵规垬妯″紡 +- 鍙皟妫嬬洏灏哄(5x5鍒25x25) +- 鏅鸿兘AI鍐崇瓥(1-5绾ч毦搴) +- 瀹屾暣娓告垙澶嶇洏鍔熻兘 +- 瀹炴椂瀵瑰眬璇勫垎绯荤粺 +- 鎮旀鍔熻兘(鍙挙閿涓婁竴姝) +- 娓呮櫚鐨勭粓绔晫闈㈡樉绀 +- 鍋ュ.鐨勮緭鍏ラ獙璇(纭繚鎵鏈夋暟瀛楄緭鍏ラ兘鍦ㄦ湁鏁堣寖鍥村唴) +- 鍙夌殑鍥炲悎璁℃椂鍣 +- 鑷姩娓告垙璁板綍淇濆瓨 -## ? 快速开始 +## 蹇熷紑濮 -![游戏演示](https://your-gif-url.com/demo.gif) +![娓告垙婕旂ず](https://your-gif-url.com/demo.gif) -### 编译程序 +### 缂栬瘧绋嬪簭 ```bash -gcc 五子棋.c gobang.c game_mode.c -o output/五子棋.exe +gcc 浜斿瓙妫.c gobang.c game_mode.c ai.c -o gobang.exe ``` -### 运行游戏 +### 杩愯娓告垙 ```bash -.\output\五子棋.exe +.\gobang.exe ``` -## ? 游戏玩法 -1. 启动后设置棋盘大小(默认15x15) -2. 选择AI难度级别(1-5) -3. 输入坐标进行游戏(格式:行 列) - - 输入R/r可悔棋 -4. 游戏结束可查看完整复盘和评分 +## 娓告垙鐜╂硶 +1. 鍚姩鍚庤缃鐩樺ぇ灏(榛樿15x15) +2. 閫夋嫨AI闅惧害绾у埆(1-5) +3. 杈撳叆鍧愭爣杩涜娓告垙(鏍煎紡:琛 鍒) + - 杈撳叆R/r鍙倲妫 +4. 娓告垙缁撴潫鍙煡鐪嬪畬鏁村鐩樺拰璇勫垎 -## ? 开发环境 -- 操作系统: Windows (当前版本使用了Windows特有的 `_kbhit()` 和 `Sleep()` 函数,因此仅限Windows平台) -- 编译器: GCC (MinGW(gcc为14.2.0) on Windows) -- 终端: 支持UTF-8编码的终端 +## 寮鍙戠幆澧 +- 鎿嶄綔绯荤粺: Windows (褰撳墠鐗堟湰浣跨敤浜哤indows鐗规湁鐨 `_kbhit()` 鍜 `Sleep()` 鍑芥暟锛屽洜姝や粎闄怶indows骞冲彴) +- 缂栬瘧鍣: GCC (MinGW(gcc涓14.2.0) on Windows) +- 缁堢: 鏀寔UTF-8缂栫爜鐨勭粓绔 -> **跨平台兼容性说明:** +> **璺ㄥ钩鍙板吋瀹规ц鏄:** > -> 为了未来能在Linux或macOS等其他操作系统上运行,需要将平台特定的代码(如 `_kbhit()`)替换为跨平台的实现,或使用条件编译(`#ifdef _WIN32`)进行隔离。 +> 涓轰簡鏈潵鑳藉湪Linux鎴杕acOS绛夊叾浠栨搷浣滅郴缁熶笂杩愯锛岄渶瑕佸皢骞冲彴鐗瑰畾鐨勪唬鐮侊紙濡 `_kbhit()`锛夋浛鎹负璺ㄥ钩鍙扮殑瀹炵幇锛屾垨浣跨敤鏉′欢缂栬瘧锛坄#ifdef _WIN32`锛夎繘琛岄殧绂汇 -## ?? 常见问题 +## 甯歌闂 -### 权限问题 -如果程序在保存游戏记录时提示“无法创建文件”或类似错误,通常是由于缺少写入权限。请尝试以下解决方案: +### 鏉冮檺闂 +濡傛灉绋嬪簭鍦ㄤ繚瀛樻父鎴忚褰曟椂鎻愮ず鈥滄棤娉曞垱寤烘枃浠垛濇垨绫讳技閿欒锛岄氬父鏄敱浜庣己灏戝啓鍏ユ潈闄愩傝灏濊瘯浠ヤ笅瑙e喅鏂规锛 -1. **以管理员身份运行**:右键点击 `五子棋.exe` 或在管理员权限的终端中运行程序。 -2. **检查目录权限**:确保程序所在目录不是系统保护目录(如 `C:\Program Files`)。建议将项目放在用户目录下(如 `D:\Code`)。 -3. **手动创建 `records` 目录**:如果 `records` 目录不存在,请在 `output` 目录下手动创建一个。 +1. **浠ョ鐞嗗憳韬唤杩愯**锛氬彸閿偣鍑 `浜斿瓙妫.exe` 鎴栧湪绠$悊鍛樻潈闄愮殑缁堢涓繍琛岀▼搴忋 +2. **妫鏌ョ洰褰曟潈闄**锛氱‘淇濈▼搴忔墍鍦ㄧ洰褰曚笉鏄郴缁熶繚鎶ょ洰褰曪紙濡 `C:\Program Files`锛夈傚缓璁皢椤圭洰鏀惧湪鐢ㄦ埛鐩綍涓嬶紙濡 `D:\Code`锛夈 +3. **鎵嬪姩鍒涘缓 `records` 鐩綍**锛氬鏋 `records` 鐩綍涓嶅瓨鍦紝璇峰湪 `output` 鐩綍涓嬫墜鍔ㄥ垱寤轰竴涓 -### 中文显示问题 -如果在Windows终端中遇到中文字符显示为乱码,是由于终端编码页不匹配导致的。请在运行程序前执行以下命令: +### 涓枃鏄剧ず闂 +濡傛灉鍦╓indows缁堢涓亣鍒颁腑鏂囧瓧绗︽樉绀轰负涔辩爜锛屾槸鐢变簬缁堢缂栫爜椤典笉鍖归厤瀵艰嚧鐨勩傝鍦ㄨ繍琛岀▼搴忓墠鎵ц浠ヤ笅鍛戒护锛 ```bash chcp 65001 ``` -该命令会将当前终端的编码页切换到UTF-8,从而正确显示中文字符。为方便起见,你可以创建一个启动脚本(`.bat` 文件)来自动执行此操作: +璇ュ懡浠や細灏嗗綋鍓嶇粓绔殑缂栫爜椤靛垏鎹㈠埌UTF-8锛屼粠鑰屾纭樉绀轰腑鏂囧瓧绗︺備负鏂逛究璧疯锛屼綘鍙互鍒涘缓涓涓惎鍔ㄨ剼鏈紙`.bat` 鏂囦欢锛夋潵鑷姩鎵ц姝ゆ搷浣滐細 **start_game.bat** ```batch @echo off chcp 65001 -.\output\五子棋.exe +.\output\浜斿瓙妫.exe ``` -## ?? 技术实现 +## 鎶鏈疄鐜 -项目的AI主要基于以下技术实现: +椤圭洰鐨凙I涓昏鍩轰簬浠ヤ笅鎶鏈疄鐜帮細 -### 核心决策算法 +### 鏍稿績鍐崇瓥绠楁硶 -- **极小极大算法 (Minimax)**:作为决策的基础,模拟对弈双方的每一步,选择对我方最有利的走法。 -- **α-β 剪枝 (Alpha-Beta Pruning)**:对极小极大算法的關鍵優化,通过剪掉不可能影响最终决策的搜索分支,大幅提升AI的计算效率,使其能够在有限时间内达到更深的搜索深度。 -- **搜索深度**:AI的思考深度,默认为3层,并可根据难度设置进行调整。搜索深度越深,AI的棋力越强,但计算耗时也越长。 +- **鏋佸皬鏋佸ぇ绠楁硶 (Minimax)**锛氫綔涓哄喅绛栫殑鍩虹锛屾ā鎷熷寮堝弻鏂圭殑姣忎竴姝ワ紝閫夋嫨瀵规垜鏂规渶鏈夊埄鐨勮蛋娉曘 +- **伪-尾 鍓灊 (Alpha-Beta Pruning)**锛氬鏋佸皬鏋佸ぇ绠楁硶鐨勯棞閸靛劒鍖栵紝閫氳繃鍓帀涓嶅彲鑳藉奖鍝嶆渶缁堝喅绛栫殑鎼滅储鍒嗘敮锛屽ぇ骞呮彁鍗嘇I鐨勮绠楁晥鐜囷紝浣垮叾鑳藉鍦ㄦ湁闄愭椂闂村唴杈惧埌鏇存繁鐨勬悳绱㈡繁搴︺ +- **鎼滅储娣卞害**锛欰I鐨勬濊冩繁搴︼紝榛樿涓3灞傦紝骞跺彲鏍规嵁闅惧害璁剧疆杩涜璋冩暣銆傛悳绱㈡繁搴﹁秺娣憋紝AI鐨勬鍔涜秺寮猴紝浣嗚绠楄楁椂涔熻秺闀裤 -### 启发式评估函数 +### 鍚彂寮忚瘎浼板嚱鏁 -为了判断棋局的优劣,AI使用了一套复杂的启发式评估函数,主要包括: +涓轰簡鍒ゆ柇妫嬪眬鐨勪紭鍔o紝AI浣跨敤浜嗕竴濂楀鏉傜殑鍚彂寮忚瘎浼板嚱鏁帮紝涓昏鍖呮嫭锛 -- **棋型识别 (Pattern Recognition)**:能够识别并评估多种关键棋型,如“活四”、“冲四”、“活三”、“眠三”等,并为每种棋型赋予不同权重。 -- **位置权重 (Positional Value)**:棋盘上不同位置的战略价值不同,中心位置通常比边缘位置更有优势。评估函数会为中心区域的落子给予额外加分。 -- **威胁检测 (Threat Detection)**:优先搜索能够直接形成制胜威胁的棋步,如“连五”或“活四”,从而快速响应对手的进攻或抓住制胜机会。 -- **双向延伸评估**:评估一个棋子在特定方向上是否有足够的空间形成连续棋型,避免在被封堵的位置浪费棋步。 +- **妫嬪瀷璇嗗埆 (Pattern Recognition)**锛氳兘澶熻瘑鍒苟璇勪及澶氱鍏抽敭妫嬪瀷锛屽鈥滄椿鍥涒濄佲滃啿鍥涒濄佲滄椿涓夆濄佲滅湢涓夆濈瓑锛屽苟涓烘瘡绉嶆鍨嬭祴浜堜笉鍚屾潈閲嶃 +- **浣嶇疆鏉冮噸 (Positional Value)**锛氭鐩樹笂涓嶅悓浣嶇疆鐨勬垬鐣ヤ环鍊间笉鍚岋紝涓績浣嶇疆閫氬父姣旇竟缂樹綅缃洿鏈変紭鍔裤傝瘎浼板嚱鏁颁細涓轰腑蹇冨尯鍩熺殑钀藉瓙缁欎簣棰濆鍔犲垎銆 +- **濞佽儊妫娴 (Threat Detection)**锛氫紭鍏堟悳绱㈣兘澶熺洿鎺ュ舰鎴愬埗鑳滃▉鑳佺殑妫嬫锛屽鈥滆繛浜斺濇垨鈥滄椿鍥涒濓紝浠庤屽揩閫熷搷搴斿鎵嬬殑杩涙敾鎴栨姄浣忓埗鑳滄満浼氥 +- **鍙屽悜寤朵几璇勪及**锛氳瘎浼颁竴涓瀛愬湪鐗瑰畾鏂瑰悜涓婃槸鍚︽湁瓒冲鐨勭┖闂村舰鎴愯繛缁鍨嬶紝閬垮厤鍦ㄨ灏佸牭鐨勪綅缃氮璐规姝ャ -## ? 代码结构 -- `五子棋.c` - 主程序入口,负责初始化和模式选择 -- `gobang.c` - 核心游戏逻辑,包括棋盘操作、胜负判断、AI算法等 -- `gobang.h` - `gobang.c` 的头文件,定义核心数据结构和函数原型 -- `game_mode.c` - 各种游戏模式的实现,如人机对战、双人对战和复盘模式 -- `game_mode.h` - `game_mode.c` 的头文件,定义游戏模式相关函数原型 +## 浠g爜缁撴瀯 -## ? 许可证 +椤圭洰閲囩敤妯″潡鍖栬璁★紝鍚勪釜鏂囦欢鐨勮亴璐e涓嬶細 -该项目采用 [MIT 许可证](https://opensource.org/licenses/MIT)进行授权。 +- `浜斿瓙妫.c` - 涓荤▼搴忓叆鍙o紝璐熻矗鍒濆鍖栧拰妯″紡閫夋嫨 +- `gobang.h` - 瀹氫箟鏍稿績鏁版嵁缁撴瀯锛堝妫嬬洏銆佹楠よ褰曠瓑锛夊拰鍩虹鍑芥暟鍘熷瀷 +- `gobang.c` - 瀹炵幇鍩虹鐨勬鐩樻搷浣滐紙濡傝惤瀛愩佹樉绀烘鐩樼瓑锛夊拰鑳滆礋鍒ゆ柇 +- `ai.h` - 瀹氫箟 AI 鐩稿叧鐨勫嚱鏁板師鍨 +- `ai.c` - 瀹炵幇 AI 鐨勬牳蹇冪畻娉曪紝鍖呮嫭锛 + - `evaluate_pos`: 鍚彂寮忚瘎浼板嚱鏁帮紝涓烘瘡涓彲鑳界殑钀藉瓙浣嶇疆鎵撳垎 + - `dfs`: 甯 伪-尾 鍓灊鐨勬瀬灏忔瀬澶ф悳绱㈢畻娉 + - `ai_move`: AI 鍐崇瓥鐨勪富鍑芥暟锛屽疄鐜伴槻瀹堝拰杩涙敾鐨勪袱闃舵鍐崇瓥 +- `game_mode.c` - 瀹炵幇鍚勭娓告垙妯″紡锛堝浜烘満瀵规垬銆佸鐩樼瓑锛夊拰鐢ㄦ埛浜や簰 +- `game_mode.h` - 瀹氫箟娓告垙妯″紡鐩稿叧鐨勫嚱鏁板師鍨 -简单来说,你可以自由地使用、复制、修改、合并、出版、分发、再授权和/或销售本软件的副本,只需在你的项目中包含原始的版权和许可声明即可。 +杩欑妯″潡鍖栫殑缁撴瀯浣垮緱锛 +1. 浠g爜鑱岃矗鍒掑垎鏇村姞娓呮櫚 +2. AI 绠楁硶鐩稿叧浠g爜琚嫭绔嬪嚭鏉ワ紝渚夸簬缁存姢鍜屼紭鍖 +3. 娓告垙閫昏緫鍜 AI 閫昏緫瑙h︼紝鏈夊埄浜庡悗缁墿灞曪紙濡傛坊鍔犳柊鐨 AI 绠楁硶鎴栨父鎴忔ā寮忥級 -## ? 反馈与贡献 +## 璁稿彲璇 -我们非常欢迎任何形式的反馈和贡献!如果你发现了Bug、有功能建议,或者希望改进代码,请随时通过以下方式参与: +璇ラ」鐩噰鐢 [MIT 璁稿彲璇乚(https://opensource.org/licenses/MIT)杩涜鎺堟潈銆 -- **提交 Issue**:如果你遇到问题或有新的想法,请在 [GitHub Issues](https://github.com/LHY0125/Gobang-Game/issues) 页面提交详细描述。 -- **发起 Pull Request**:如果你对代码进行了改进,欢迎提交 Pull Request。请确保你的代码风格与项目保持一致,并附上清晰的改动说明。 +绠鍗曟潵璇达紝浣犲彲浠ヨ嚜鐢卞湴浣跨敤銆佸鍒躲佷慨鏀广佸悎骞躲佸嚭鐗堛佸垎鍙戙佸啀鎺堟潈鍜/鎴栭攢鍞湰杞欢鐨勫壇鏈紝鍙渶鍦ㄤ綘鐨勯」鐩腑鍖呭惈鍘熷鐨勭増鏉冨拰璁稿彲澹版槑鍗冲彲銆 -你的每一次贡献都将使这个项目变得更好! +## 鍙嶉涓庤础鐚 -## ? 未来计划 +鎴戜滑闈炲父娆㈣繋浠讳綍褰㈠紡鐨勫弽棣堝拰璐$尞锛佸鏋滀綘鍙戠幇浜咮ug銆佹湁鍔熻兘寤鸿锛屾垨鑰呭笇鏈涙敼杩涗唬鐮侊紝璇烽殢鏃堕氳繃浠ヤ笅鏂瑰紡鍙備笌锛 -为了让这个项目变得更完善,我们计划在未来实现以下功能: +- **鎻愪氦 Issue**锛氬鏋滀綘閬囧埌闂鎴栨湁鏂扮殑鎯虫硶锛岃鍦 [GitHub Issues](https://github.com/LHY0125/Gobang-Game/issues) 椤甸潰鎻愪氦璇︾粏鎻忚堪銆 +- **鍙戣捣 Pull Request**锛氬鏋滀綘瀵逛唬鐮佽繘琛屼簡鏀硅繘锛屾杩庢彁浜 Pull Request銆傝纭繚浣犵殑浠g爜椋庢牸涓庨」鐩繚鎸佷竴鑷达紝骞堕檮涓婃竻鏅扮殑鏀瑰姩璇存槑銆 -- [ ] **图形用户界面 (GUI)**:使用 `SDL2` 或 `Qt` 等库,将当前的终端界面升级为图形化界面,提升用户体验。 -- [ ] **网络对战功能**:增加一个在线对战模式,允许两名玩家通过网络进行对战。 -- [ ] **棋谱库集成**:引入开局库,使AI在游戏初期能够选择更优的开局走法。 -- [ ] **代码重构与优化**:持续优化现有代码,提高模块化程度和运行效率,并实现完全的跨平台兼容性。 \ No newline at end of file +浣犵殑姣忎竴娆¤础鐚兘灏嗕娇杩欎釜椤圭洰鍙樺緱鏇村ソ锛 + +## 鏈潵璁″垝 + +涓轰簡璁╄繖涓」鐩彉寰楁洿瀹屽杽锛屾垜浠鍒掑湪鏈潵瀹炵幇浠ヤ笅鍔熻兘锛 + +- [ ] **鍥惧舰鐢ㄦ埛鐣岄潰 (GUI)**锛氫娇鐢 `SDL2` 鎴 `Qt` 绛夊簱锛屽皢褰撳墠鐨勭粓绔晫闈㈠崌绾т负鍥惧舰鍖栫晫闈紝鎻愬崌鐢ㄦ埛浣撻獙銆 +- [ ] **缃戠粶瀵规垬鍔熻兘**锛氬鍔犱竴涓湪绾垮鎴樻ā寮忥紝鍏佽涓ゅ悕鐜╁閫氳繃缃戠粶杩涜瀵规垬銆 +- [ ] **妫嬭氨搴撻泦鎴**锛氬紩鍏ュ紑灞搴擄紝浣緼I鍦ㄦ父鎴忓垵鏈熻兘澶熼夋嫨鏇翠紭鐨勫紑灞璧版硶銆 +- [ ] **浠g爜閲嶆瀯涓庝紭鍖**锛氭寔缁紭鍖栫幇鏈変唬鐮侊紝鎻愰珮妯″潡鍖栫▼搴﹀拰杩愯鏁堢巼锛屽苟瀹炵幇瀹屽叏鐨勮法骞冲彴鍏煎鎬с \ No newline at end of file diff --git a/ai.c b/ai.c index 062472c..a062205 100644 --- a/ai.c +++ b/ai.c @@ -10,94 +10,94 @@ extern const int direction[4][2]; extern Step steps[MAX_STEPS]; /** - * @brief 璇勪及鐗瑰畾浣嶇疆瀵瑰綋鍓嶇帺瀹剁殑鎴樼暐浠峰笺 - * 姝ゅ嚱鏁伴氳繃妯℃嫙鍦ㄨ浣嶇疆钀藉瓙锛岀劧鍚庡垎鏋愬舰鎴愮殑妫嬪瀷鏉ヤ负璇ヤ綅缃墦鍒嗐 - * 鍒嗘暟瓒婇珮锛屼唬琛ㄨ浣嶇疆瀵规寚瀹氱帺瀹惰秺鏈夊埄銆 - * @param x 瑕佽瘎浼扮殑琛屽潗鏍 (0-based)銆 - * @param y 瑕佽瘎浼扮殑鍒楀潗鏍 (0-based)銆 - * @param player 鐜╁鏍囪瘑 (PLAYER 鎴 AI)锛屼唬琛ㄤ负鍝竴鏂硅繘琛岃瘎浼般 - * @return int 杩斿洖璇ヤ綅缃殑缁煎悎璇勪及鍒嗘暟銆 - * @note 璇勫垎绯荤粺璁捐锛 - * - 鏍稿績鎬濇兂鏄负涓嶅悓鐨勬鍨嬭祴浜堜笉鍚岀殑鏉冮噸锛屾鍨嬭秺鎺ヨ繎鑳滃埄锛屾潈閲嶈秺楂樸 - * - 鈥滄椿鈥濇鍨嬶紙涓ょ鏃犻樆鎸★級姣斺滅湢鈥濇鍨嬶紙涓绔湁闃绘尅锛夋垨鈥滄鈥濇鍨嬶紙涓ょ琚樆鎸★級寰楀垎楂樺緱澶氾紝 - * 鍥犱负瀹冧滑鏈夋洿澶х殑鍙戝睍娼滃姏銆 - * - 璇勫垎鏍囧噯 (浠呬负绀轰緥锛屽彲璋冩暣浠ヤ紭鍖朅I琛屼负): - * - 杩炰簲: 1,000,000 (鑳滃埄) - * - 娲诲洓: 100,000 (涓嬩竴姝ヨ儨鍒) - * - 鍐插洓: 10,000 (涓嬩竴姝ュ彲鑳借儨鍒) - * - 娲讳笁: 5,000 (娼滃姏宸ㄥぇ) - * - 鐪犱笁: 1,000 - * - 娲讳簩: 500 - * - 鐪犱簩: 100 - * - 鍏朵粬: 鏇翠綆鐨勫垎鏁 - * - 浣嶇疆濂栧姳锛氭鐩樹腑蹇冨尯鍩熼氬父鍏锋湁鏇撮珮鐨勬垬鐣ヤ环鍊硷紝鍥犳浼氱粰浜堥澶栧姞鍒嗭紝榧撳姳AI鍗犳嵁涓績銆 + * @brief ????????????????????????? + * ?????????????????????????????????????????????????? + * ???????????????????????????????? + * @param x ????????????? (0-based)?? + * @param y ????????????? (0-based)?? + * @param player ????? (PLAYER ?? AI)?????????????????????? + * @return int ??????????????????????? + * @note ?????????? + * - ??????????????????????M??????????????????????????? + * - ?????????????????\????????????????????\????????????????????\????????? + * ????????????????????? + * - ?????? (??????????????????AI???): + * - ????: 1,000,000 (???) + * - ????: 100,000 (????????) + * - ????: 10,000 (????????????) + * - ????: 5,000 (??????) + * - ????: 1,000 + * - ???: 500 + * - ???: 100 + * - ????: ???????? + * - ?????????????????????????????????????????????????????????AI???????? */ int evaluate_pos(int x, int y, int player) { - // 淇濆瓨鍘熷鍊肩敤浜庤繕鍘 + // ????????????? int original = board[x][y]; - // 妯℃嫙鍦ㄨ浣嶇疆钀藉瓙 + // ?????????????? board[x][y] = player; - int total_score = 0; // 鎬诲垎 - int line_scores[4] = {0}; // 鍥涗釜鏂瑰悜鐨勫緱鍒 + int total_score = 0; // ??? + int line_scores[4] = {0}; // ??????????? - // 閬嶅巻鍥涗釜鏂瑰悜杩涜璇勪及 + // ?????????????????? for (int i = 0; i < 4; i++) { int dx = direction[i][0], dy = direction[i][1]; - // 鑾峰彇褰撳墠鏂瑰悜涓婄殑妫嬪瀷淇℃伅 + // ???????????????????? DirInfo info = count_specific_direction(x, y, dx, dy, player); - // 鐩存帴褰㈡垚浜旇繛鐝犱负蹇呰儨 + // ????????????????? if (info.continuous_chess >= 5) { - board[x][y] = original; // 杩樺師妫嬬洏 - return 1000000; // 杩斿洖鏈澶у垎 + board[x][y] = original; // ??????? + return 1000000; // ???????? } - // 鏍规嵁杩炵画妫嬪瓙鏁拌瘎鍒 + // ?????????????????? switch (info.continuous_chess) { - case 4: // 鍥涜繛鐝 - if (info.check_start && info.check_end) // 娲诲洓(涓ょ寮鏀) + case 4: // ?????? + if (info.check_start && info.check_end) // ????(???????) line_scores[i] = 100000; - else if (info.check_start || info.check_end) // 鍐插洓(涓绔紑鏀) + else if (info.check_start || info.check_end) // ????(??????) line_scores[i] = 10000; - else // 姝诲洓(涓ょ灏侀棴) + else // ????(??????) line_scores[i] = 500; break; - case 3: // 涓夎繛鐝 - if (info.check_start && info.check_end) // 娲讳笁 + case 3: // ?????? + if (info.check_start && info.check_end) // ???? line_scores[i] = 5000; - else if (info.check_start || info.check_end) // 鐪犱笁 + else if (info.check_start || info.check_end) // ???? line_scores[i] = 1000; - else // 姝讳笁 + else // ???? line_scores[i] = 50; break; - case 2: // 浜岃繛鐝 - if (info.check_start && info.check_end) // 娲讳簩 + case 2: // ?????? + if (info.check_start && info.check_end) // ??? line_scores[i] = 500; - else if (info.check_start || info.check_end) // 鐪犱簩 + else if (info.check_start || info.check_end) // ??? line_scores[i] = 100; - else // 姝讳簩 + else // ???? line_scores[i] = 10; break; - case 1: // 鍗曞瓙 - if (info.check_start && info.check_end) // 寮鏀句綅缃 + case 1: // ???? + if (info.check_start && info.check_end) // ???????? line_scores[i] = 50; - else if (info.check_start || info.check_end) // 鍗婂紑鏀句綅缃 + else if (info.check_start || info.check_end) // ???????? line_scores[i] = 10; - else // 灏侀棴浣嶇疆 + else // ??????? line_scores[i] = 1; break; } } - // 璁$畻鎬诲垎锛堟渶楂樻柟鍚戝垎+鍏朵粬鏂瑰悜鍒嗗姞鏉冿級 + // ???????????????+????????????? int max_score = 0; int sum_score = 0; for (int i = 0; i < 4; i++) @@ -106,49 +106,49 @@ int evaluate_pos(int x, int y, int player) max_score = line_scores[i]; sum_score += line_scores[i]; } - total_score = max_score * 10 + sum_score; // 涓绘柟鍚戞潈閲嶆洿楂 + total_score = max_score * 10 + sum_score; // ???????????? - // 浣嶇疆濂栧姳锛氳秺闈犺繎涓績鍒嗘暟瓒婇珮 + // ???????????????????????? int center_x = BOARD_SIZE / 2; int center_y = BOARD_SIZE / 2; - int distance = abs(x - center_x) + abs(y - center_y); // 鏇煎搱椤胯窛绂 - int position_bonus = 50 * (BOARD_SIZE - distance); // 璺濈涓績瓒婅繎濂栧姳瓒婇珮 + int distance = abs(x - center_x) + abs(y - center_y); // ????????? + int position_bonus = 50 * (BOARD_SIZE - distance); // ?????????????????? - board[x][y] = original; // 杩樺師妫嬬洏鐘舵 - return total_score + position_bonus; // 杩斿洖鎬昏瘎浼板垎 + board[x][y] = original; // ????????? + return total_score + position_bonus; // ???????????? } /** - * @brief 浣跨敤甯ξ-尾鍓灊鐨勬繁搴︿紭鍏堟悳绱紙Minimax绠楁硶锛夋潵瀵绘壘鏈浣宠惤瀛愮偣銆 - * 璇ュ嚱鏁伴掑綊鍦版帰绱㈡湭鏉ョ殑鍑犳妫嬶紝璇勪及涓嶅悓閫夋嫨鐨勪紭鍔o紝骞堕夋嫨鏈浼樼瓥鐣ャ - * @param x 涓婁竴姝ヨ惤瀛愮殑琛屽潗鏍囥 - * @param y 涓婁竴姝ヨ惤瀛愮殑鍒楀潗鏍囥 - * @param player 褰撳墠杞埌鐨勭帺瀹 (PLAYER 鎴 AI)銆 - * @param depth 鍓╀綑鐨勬悳绱㈡繁搴︺傛繁搴﹁秺澶э紝AI鐪嬪緱瓒婅繙锛屼絾璁$畻閲忎篃瓒婂ぇ銆 - * @param alpha 伪鍊硷紝鏋佸ぇ鍖栫帺瀹讹紙AI锛夊綋鍓嶈兘纭繚鐨勬渶濂界粨鏋滐紙涓嬬晫锛夈 - * @param beta 尾鍊硷紝鏋佸皬鍖栫帺瀹讹紙瀵规墜锛夊綋鍓嶈兘纭繚鐨勬渶濂界粨鏋滐紙涓婄晫锛夈 - * @param is_maximizing 甯冨皵鍊硷紝true琛ㄧず褰撳墠鏄瀬澶у寲鐜╁锛圓I锛夌殑鍥炲悎锛宖alse琛ㄧず鏄瀬灏忓寲鐜╁锛堝鎵嬶級鐨勫洖鍚堛 - * @return int 杩斿洖鍦ㄥ綋鍓嶅垎鏀笅鐨勬渶浣宠瘎浼板垎鏁般 - * @note 绠楁硶鏍稿績鎬濇兂: - * 1. **閫掑綊缁堟鏉′欢**: 褰撴父鎴忓嚭鐜拌儨璐熴佸钩灞锛屾垨杈惧埌棰勮鐨勬悳绱㈡繁搴︽椂锛屽仠姝㈤掑綊锛屽苟杩斿洖褰撳墠灞闈㈢殑闈欐佽瘎浼板垎鏁般 - * 2. **鏋佸ぇ鍖栫帺瀹 (AI)**: 灏濊瘯鎵鏈夊彲鑳界殑钀藉瓙锛屽苟閫夋嫨鑳戒娇鍏跺緱鍒嗘渶澶у寲鐨勯偅涓姝ャ傛杩囩▼涓紝浼氫笉鏂洿鏂癮lpha鍊笺 - * 3. **鏋佸皬鍖栫帺瀹 (瀵规墜)**: 妯℃嫙瀵规墜鐨勮蛋娉曪紝骞跺亣璁惧鎵嬩細閫夋嫨鑳戒娇AI寰楀垎鏈灏忓寲鐨勯偅涓姝ャ傛杩囩▼涓紝浼氫笉鏂洿鏂癰eta鍊笺 - * 4. **伪-尾鍓灊**: 杩欐槸瀵筂inimax绠楁硶鐨勫叧閿紭鍖栥 - * - **伪鍓灊**: 鍦ㄦ瀬灏忓寲鐜╁鐨勫洖鍚堜腑锛屽鏋滃彂鐜颁竴涓蛋娉曞緱鍒扮殑鍒嗘暟姣攁lpha杩樹綆锛岄偅涔堣繖涓垎鏀彲浠ヨ鍓帀锛 - * 鍥犱负鏋佸ぇ鍖栫帺瀹剁粷涓嶄細閫夋嫨杩涘叆杩欎釜鍒嗘敮锛堜粬鏈夋洿濂界殑閫夋嫨锛夈(if beta <= alpha) - * - **尾鍓灊**: 鍦ㄦ瀬澶у寲鐜╁鐨勫洖ah鍚堜腑锛屽鏋滃彂鐜颁竴涓蛋娉曞緱鍒扮殑鍒嗘暟姣攂eta杩橀珮锛岄偅涔堣繖涓垎鏀篃鍙互琚壀鎺夛紝 - * 鍥犱负鏋佸皬鍖栫帺瀹剁粷涓嶄細璁╂父鎴忚繘鍏ヨ繖涓垎鏀紙浠栨湁鏇村ソ鐨勯夋嫨鏉ラ樆姝級銆(if beta <= alpha) - * 閫氳繃鍓灊锛屽彲浠ラ伩鍏嶅澶ч噺鏃犳晥鍒嗘敮鐨勬悳绱紝鏋佸ぇ鍦版彁楂樹簡AI鐨勫喅绛栨晥鐜囥 + * @brief ??????-???????????????????Minimax????????????????? + * ?????????????????????????????????????????????????????? + * @param x ???????????????? + * @param y ???????????????? + * @param player ??????????? (PLAYER ?? AI)?? + * @param depth ??????????????????AI???????????????????? + * @param alpha ?????????????AI????????????????????????? + * @param beta ??????????????????????????????????????????? + * @param is_maximizing ???????true???????????????AI???????false???????????????????????? + * @return int ??????????????????????????? + * @note ?????????: + * 1. **??????????**: ????????????????????????????????????????????????????????????????? + * 2. **??????? (AI)**: ??????????????????????????????????????????????????????????alpha??? + * 3. **????????? (????)**: ????????????????????????????AI???????????????????????????????????beta??? + * 4. **??-????**: ?????Minimax??????????? + * - **?????**: ????????????????????????????????????????alpha????????????????????????? + * ??????????????????????????????????????????(if beta <= alpha) + * - **????**: ??????????ah?????????????????????????????beta?????????????????????????? + * ???????????????????????????????????????????????????????(if beta <= alpha) + * ????????????????????????????????????????????AI?????????? */ int dfs(int x, int y, int player, int depth, int alpha, int beta, bool is_maximizing) { - // 妫鏌ュ綋鍓嶈惤瀛愭槸鍚﹁幏鑳 + // ???n?????????? if (check_win(x, y, player)) { return (player == AI) ? 1000000 + depth : -1000000 - depth; } - // 杈惧埌鎼滅储娣卞害鎴栧钩灞 + // ????????????? if (depth == 0 || step_count >= BOARD_SIZE * BOARD_SIZE) { return evaluate_pos(x, y, AI) - evaluate_pos(x, y, PLAYER); @@ -156,7 +156,7 @@ int dfs(int x, int y, int player, int depth, int alpha, int beta, bool is_maximi int best_score = is_maximizing ? -1000000 : 1000000; - // 閬嶅巻鎵鏈夊彲鑳借惤瀛愪綅缃 + // ???????????????????? for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) @@ -164,34 +164,34 @@ int dfs(int x, int y, int player, int depth, int alpha, int beta, bool is_maximi if (board[i][j] != EMPTY) continue; - // 妯℃嫙褰撳墠鐜╁钀藉瓙 + // ??????????? board[i][j] = player; step_count++; - // 閫掑綊鎼滅储(鍒囨崲鐜╁鍜屾悳绱㈡繁搴) + // ???????(???????????????) int current_score = dfs(i, j, (player == AI) ? PLAYER : AI, depth - 1, alpha, beta, !is_maximizing); - // 鎾ら攢钀藉瓙 + // ???????? board[i][j] = EMPTY; step_count--; - // 鏋佸ぇ鍊肩帺瀹(AI)閫昏緫 + // ????????(AI)??? if (is_maximizing) { best_score = (current_score > best_score) ? current_score : best_score; alpha = (best_score > alpha) ? best_score : alpha; - // 伪鍓灊 + // ????? if (beta <= alpha) { break; } } - // 鏋佸皬鍊肩帺瀹(浜虹被)閫昏緫 + // ????????(????)??? else { best_score = (current_score < best_score) ? current_score : best_score; beta = (best_score < beta) ? best_score : beta; - // 尾鍓灊 + // ???? if (beta <= alpha) { break; @@ -200,7 +200,7 @@ int dfs(int x, int y, int player, int depth, int alpha, int beta, bool is_maximi } if ((is_maximizing && best_score >= beta) || (!is_maximizing && best_score <= alpha)) { - break; // 鎻愬墠閫鍑哄灞傚惊鐜 + break; // ???????????? } } @@ -208,18 +208,18 @@ int dfs(int x, int y, int player, int depth, int alpha, int beta, bool is_maximi } /** - * @brief AI鍐崇瓥涓诲嚱鏁帮紝浣跨敤璇勪及鍑芥暟鍜屾悳绱㈢畻娉曢夋嫨鏈浣宠惤瀛愪綅缃 - * @note 閲囩敤涓ら樁娈靛喅绛栭昏緫锛 - * 1. 闃插尽闃舵锛氭鏌ュ苟闃绘鐜╁鍗冲皢鑾疯儨鐨勪綅缃紙娲诲洓銆佸啿鍥涖佹椿涓夛級 - * 2. 杩涙敾闃舵锛氳嫢鏃犵揣鎬ラ槻寰¢渶姹傦紝浣跨敤DFS璇勪及閫夋嫨鏈浣宠繘鏀讳綅缃 - * @note 瀹炵幇缁嗚妭锛 - * - 浼樺厛澶勭悊鐜╁娲诲洓銆佸啿鍥涚瓑鍗遍櫓灞闈 - * - 姝ユ暟>10鏃剁缉灏忔悳绱㈣寖鍥村埌宸叉湁妫嬪瓙闄勮繎2鏍 - * - 浣跨敤涓績浣嶇疆浼樺厛绛栫暐 + * @brief AI????????????????????????????????????????????? + * @note ?????????????????? + * 1. ???????????????????????????????????????????????? + * 2. ???????????????????????????DFS????????????????? + * @note ??????? + * - ?????????????????????????? + * - ????>10??????????????????????????2?? + * - ?????????????????? */ void ai_move(int depth) { - // 1. 棣栧厛妫鏌ユ槸鍚﹂渶瑕侀樆姝㈢帺瀹剁殑鍥涘瓙杩炴鎴栦笁瀛愭椿妫 + // 1. ??????????????????????????????????? for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) @@ -227,23 +227,23 @@ void ai_move(int depth) if (board[i][j] != EMPTY) continue; - // 妯℃嫙鐜╁鍦ㄦ浣嶇疆钀藉瓙 + // ????????????????? board[i][j] = PLAYER; bool need_block = false; - // 妫鏌ュ洓涓柟鍚 + // ?????????? for (int k = 0; k < 4; k++) { DirInfo info = count_specific_direction(i, j, direction[k][0], direction[k][1], PLAYER); - // 濡傛灉鐜╁鑳藉舰鎴愬洓瀛愯繛妫嬩笖鑷冲皯涓绔紑鏀 + // ???????????????????????????????? if (info.continuous_chess >= 4 && (info.check_start || info.check_end)) { need_block = true; break; } - // 濡傛灉鐜╁鑳藉舰鎴愪笁瀛愭椿妫嬩笖涓ょ寮鏀 + // ???????????????????????????? if (info.continuous_chess == 3 && info.check_start && info.check_end) { need_block = true; @@ -251,24 +251,24 @@ void ai_move(int depth) } } - board[i][j] = EMPTY; // 鎭㈠妫嬬洏 + board[i][j] = EMPTY; // ??????? if (need_block) { - // 蹇呴』鍦ㄦ浣嶇疆钀藉瓙闃绘 + // ?????????????????? board[i][j] = AI; steps[step_count++] = (Step){AI, i, j}; - printf("AI钀藉瓙(%d, %d)\n", i + 1, j + 1); + printf("AI????(%d, %d)\n", i + 1, j + 1); return; } } } - // 2. 濡傛灉娌℃湁闇瑕佺珛鍗抽樆姝㈢殑鎯呭喌锛屽垯姝e父璇勪及 + // 2. ????????????????????????????????? int best_score = -1000000; int best_x = -1, best_y = -1; - // 閬嶅巻妫嬬洏鎵鏈夌┖浣 + // ???????????????? for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) @@ -276,7 +276,7 @@ void ai_move(int depth) if (board[i][j] != EMPTY) continue; - // 鍙冭檻宸叉湁妫嬪瓙闄勮繎(2鏍艰寖鍥村唴) + // ????????????????(2??????) bool has_nearby_stone = false; for (int di = -2; di <= 2; di++) { @@ -300,12 +300,12 @@ void ai_move(int depth) if (!has_nearby_stone && step_count > 10) continue; - // 妯℃嫙AI钀藉瓙 + // ???AI???? board[i][j] = AI; int current_score = dfs(i, j, PLAYER, depth, -1000000, 1000000, false); board[i][j] = EMPTY; - // 鏇存柊鏈浣充綅缃 + // ??????????? if (current_score > best_score) { best_score = current_score; @@ -315,11 +315,11 @@ void ai_move(int depth) } } - // 鎵ц鏈浣宠惤瀛 + // ?????????? if (best_x != -1 && best_y != -1) { board[best_x][best_y] = AI; steps[step_count++] = (Step){AI, best_x, best_y}; - printf("AI钀藉瓙(%d, %d)\n", best_x + 1, best_y + 1); + printf("AI????(%d, %d)\n", best_x + 1, best_y + 1); } } \ No newline at end of file diff --git a/ai.h b/ai.h index 318a9cb..6fde53c 100644 --- a/ai.h +++ b/ai.h @@ -4,30 +4,30 @@ #include "gobang.h" /** - * @brief 璇勪及鐗瑰畾浣嶇疆瀵瑰綋鍓嶇帺瀹剁殑浠峰 - * @param x 琛屽潗鏍(0-base) - * @param y 鍒楀潗鏍(0-base) - * @param player 鐜╁鏍囪瘑(PLAYER/AI) - * @return int 浣嶇疆璇勪及鍒嗘暟(瓒婇珮瓒婂ソ) + * @brief ???????????????????? + * @param x ??????(0-base) + * @param y ??????(0-base) + * @param player ?????(PLAYER/AI) + * @return int ????????????(??????) */ int evaluate_pos(int x, int y, int player); /** - * @brief 甯ξ-尾鍓灊鐨勬繁搴︿紭鍏堟悳绱(鏋佸皬鏋佸ぇ绠楁硶) - * @param x 褰撳墠琛屽潗鏍 - * @param y 褰撳墠鍒楀潗鏍 - * @param player 褰撳墠鐜╁ - * @param depth 鎼滅储娣卞害 - * @param alpha 伪鍊(褰撳墠鏈澶у) - * @param beta 尾鍊(褰撳墠鏈灏忓) - * @param is_maximizing 鏄惁涓烘瀬澶у寲鐜╁ - * @return int 鏈浣宠瘎浼板垎鏁 + * @brief ????-?????????????????(??????????) + * @param x ????????? + * @param y ????????? + * @param player ?????? + * @param depth ??????? + * @param alpha ???(???????) + * @param beta ???(????????) + * @param is_maximizing ??????????? + * @return int ??????????? */ int dfs(int x, int y, int player, int depth, int alpha, int beta, bool is_maximizing); /** - * @brief AI钀藉瓙鍐崇瓥鍑芥暟 - * 浣跨敤璇勪及鍑芥暟鍜屾悳绱㈢畻娉曢夋嫨鏈浣宠惤瀛愪綅缃 + * @brief AI?????????? + * ????????????????????????????????? */ void ai_move(int depth); diff --git a/game_mode.c b/game_mode.c index ab1caac..cfc1e5e 100644 --- a/game_mode.c +++ b/game_mode.c @@ -12,12 +12,12 @@ #endif /** - * @brief 浠庣敤鎴疯幏鍙栨暣鏁拌緭鍏 + * @brief ???????????????? * - * @param prompt 鎻愮ず淇℃伅 - * @param min 鏈灏忓 - * @param max 鏈澶у - * @return int 鐢ㄦ埛杈撳叆鐨勬暣鏁 + * @param prompt ?????? + * @param min ????? + * @param max ???? + * @return int ???????????? */ int get_integer_input(const char *prompt, int min, int max) { @@ -32,23 +32,23 @@ int get_integer_input(const char *prompt, int min, int max) if (result == 1 && value >= min && value <= max) { - // 娓呴櫎杈撳叆缂撳啿鍖轰腑鍓╀綑鐨勫瓧绗 + // ???????????????????? while ((ch = getchar()) != '\n' && ch != EOF) ; return value; } else { - // 娓呴櫎鏃犳晥杈撳叆 + // ??????????? while ((ch = getchar()) != '\n' && ch != EOF) ; - printf("杈撳叆鏃犳晥锛岃杈撳叆涓涓粙浜 %d 鍜 %d 涔嬮棿鐨勬暣鏁般俓n", min, max); + printf("??????????????????????? %d ?? %d ??????????\n", min, max); } } } /** - * @brief 澶勭悊鐜╁鍥炲悎 + * @brief ????????? * * @param current_player * @return true @@ -65,70 +65,65 @@ bool parse_player_input(int *x, int *y) scanf("%s", input); break; } - Sleep(100); // a small delay to prevent high CPU usage + Sleep(100); } if (sscanf(input, "%d", x) == 1) { - // Successfully parsed the first number, now parse the second if (scanf("%d", y) != 1) { - // Check for special commands if second number is not available if (*x == INPUT_UNDO) { int steps_to_undo; - printf("璇疯緭鍏ヨ鎮旀鐨勬鏁(鍙屾柟鍚勯涓姝): "); + printf("???????????????(??????????): "); steps_to_undo = get_integer_input("", 1, step_count / 2); if (return_move(steps_to_undo * 2)) { - printf("鎴愬姛鎮旀锛屽弻鏂瑰悇閫 %d 姝ワ紒\n", steps_to_undo); + printf("??????????????? %d ????\n", steps_to_undo); print_board(); } else { - printf("鏃犳硶鎮旀锛乗n"); + printf("????????\n"); } - return false; // Special command + return false; } else if (*x == INPUT_SAVE) { - // ... handle save ... - return false; // Special command + return false; } else if (*x == INPUT_EXIT) { - // ... handle exit ... - return false; // Special command + return false; } - printf("鏃犳晥杈撳叆锛岃杈撳叆涓や釜鏁板瓧鍧愭爣銆"); + printf("??????????????????????????"); while (getchar() != '\n') ; - return false; // Invalid input + return false; } } else { - // sscanf failed, check for 'r' or 'R' if (input[0] == 'r' || input[0] == 'R') { int steps_to_undo; - printf("璇疯緭鍏ヨ鎮旀鐨勬鏁(鍙屾柟鍚勯涓姝): "); + printf("???????????????(??????????): "); steps_to_undo = get_integer_input("", 1, step_count / 2); if (return_move(steps_to_undo * 2)) { - printf("鎴愬姛鎮旀锛屽弻鏂瑰悇閫 %d 姝ワ紒\n", steps_to_undo); + printf("??????????????? %d ????\n", steps_to_undo); print_board(); } else { - printf("鏃犳硶鎮旀锛乗n"); + printf("????????\n"); } - return false; // Special command + return false; } - printf("鏃犳晥杈撳叆锛岃杈撳叆鏁板瓧鍧愭爣鎴'r'鎮旀銆"); - return false; // Invalid input + printf("???????????????????????'r'????^"); + return false; } - return true; // Valid coordinates + return true; } bool handle_player_turn(int current_player) @@ -140,7 +135,7 @@ bool handle_player_turn(int current_player) time(&start_time); } - printf("\n鐜╁%d, 璇疯緭鍏ヨ惤瀛愬潗鏍(琛 鍒楋紝1~%d)锛屾垨杈撳叆R/r鎮旀:", current_player, BOARD_SIZE); + printf("\n???%d, ??????????????(?? ????1~%d)????????R/r????:", current_player, BOARD_SIZE); while (1) { @@ -149,18 +144,17 @@ bool handle_player_turn(int current_player) time(&end_time); if (difftime(end_time, start_time) > time_limit) { - printf("\n鐜╁%d瓒呮椂, 瀵规柟鑾疯儨锛乗n", current_player); - return false; // Timeout + printf("\n???%d???, ????????\n", current_player); + return false; } } if (parse_player_input(&x, &y)) { - break; // Valid input received + break; } else { - // Special command or invalid input handled, just continue the loop return true; } } @@ -170,33 +164,33 @@ bool handle_player_turn(int current_player) if (!player_move(x, y, current_player)) { - printf("鍧愭爣鏃犳晥锛佽閲嶆柊杈撳叆銆俓n"); - return true; // 鍧愭爣鏃犳晥锛屼絾鍥炲悎缁х画 + printf("????????????????????\n"); + return true; // ?????????????????? } print_board(); if (check_win(x, y, current_player)) { - printf("\n鐜╁%d鑾疯儨锛乗n", current_player); - return false; // 娓告垙缁撴潫 + printf("\n???%d?????\n", current_player); + return false; // ??????? } - return true; // 鎴愬姛钀藉瓙 + return true; // ??????? } /** - * @brief 杩愯AI娓告垙 - * @note 浠庢枃浠朵腑鍔犺浇鍘嗗彶璁板綍骞惰繘琛屽鐩 - * @param AI_DEPTH AI鐨勬悳绱㈡繁搴 + * @brief ????AI??? + * @note ??????????????????????????? + * @param AI_DEPTH AI????????? */ void run_ai_game() { setup_game_options(); - // AI瀵规垬妯″紡 + // AI????? setup_board_size(); int AI_DEPTH = 3; - AI_DEPTH = get_integer_input("璇烽夋嫨AI闅惧害(1~5), 鏁板瓧瓒婂ぇ瓒婂己锛屾敞鎰忔暟瀛楄秺澶I鎬濊冩椂闂磋秺闀匡紒):", 1, 5); + AI_DEPTH = get_integer_input("?????AI???(1~5), ?????????????????????AI???????????):", 1, 5); empty_board(); int current_player = determine_first_player(PLAYER, AI); @@ -209,7 +203,7 @@ void run_ai_game() int old_step_count = step_count; if (!handle_player_turn(current_player)) { - break; // 娓告垙缁撴潫鎴栬秴鏃 + break; // ?????????? } if (step_count > old_step_count) { @@ -218,7 +212,7 @@ void run_ai_game() } else { - printf("\nAI鎬濊冧腑...\n"); + printf("\nAI?????...\n"); time_t start_time, end_time; if (use_timer) { @@ -232,7 +226,7 @@ void run_ai_game() time(&end_time); if (difftime(end_time, start_time) > time_limit) { - printf("\nAI瓒呮椂, 鐜╁鑾疯儨锛乗n"); + printf("\nAI???, ???????\n"); break; } } @@ -240,7 +234,7 @@ void run_ai_game() Step last_step = steps[step_count - 1]; if (check_win(last_step.x, last_step.y, AI)) { - printf("\nAI鑾疯儨锛乗n"); + printf("\nAI?????\n"); break; } current_player = PLAYER; @@ -248,13 +242,13 @@ void run_ai_game() if (step_count == BOARD_SIZE * BOARD_SIZE) { - printf("\n骞冲眬锛乗n"); + printf("\n????\n"); break; } } - printf("===== 娓告垙缁撴潫 =====\n"); + printf("===== ??????? =====\n"); int review_choice; - review_choice = get_integer_input("鏄惁瑕佸鐩樻湰灞姣旇禌? (1-鏄, 0-鍚): ", 0, 1); + review_choice = get_integer_input("??????????????? (1-??, 0-??): ", 0, 1); if (review_choice == 1) { review_process(1); // 1 for AI mode @@ -263,14 +257,14 @@ void run_ai_game() } /** - * @brief 杩愯鍙屼汉瀵规垬妯″紡 - * @note 浠庢枃浠朵腑鍔犺浇鍘嗗彶璁板綍骞惰繘琛屽鐩 + * @brief ??????????? + * @note ??????????????????????????? */ void run_pvp_game() { setup_game_options(); - // 鍙屼汉瀵规垬妯″紡 + // ??????? setup_board_size(); empty_board(); int current_player = determine_first_player(PLAYER1, PLAYER2); @@ -281,12 +275,12 @@ void run_pvp_game() int old_step_count = step_count; if (!handle_player_turn(current_player)) { - break; // 娓告垙缁撴潫鎴栬秴鏃 + break; // ?????????? } if (step_count == BOARD_SIZE * BOARD_SIZE) { - printf("\n骞冲眬锛乗n"); + printf("\n????\n"); break; } @@ -295,9 +289,9 @@ void run_pvp_game() current_player = (current_player == PLAYER1) ? PLAYER2 : PLAYER1; } } - printf("===== 娓告垙缁撴潫 =====\n"); + printf("===== ??????? =====\n"); int review_choice; - review_choice = get_integer_input("鏄惁瑕佸鐩樻湰灞姣旇禌? (1-鏄, 0-鍚): ", 0, 1); + review_choice = get_integer_input("??????????????? (1-??, 0-??): ", 0, 1); if (review_choice == 1) { review_process(2); // 2 for PvP mode @@ -306,8 +300,8 @@ void run_pvp_game() } /** - * @brief 杩愯澶嶇洏妯″紡 - * @note 浠庢枃浠朵腑鍔犺浇鍘嗗彶璁板綍骞惰繘琛屽鐩 + * @brief ?????????? + * @note ??????????????????????????? */ void run_review_mode() { @@ -333,14 +327,14 @@ void run_review_mode() if (file_count > 0) { - printf("鍙戠幇浠ヤ笅澶嶇洏鏂囦欢:\n"); + printf("??????????????:\n"); for (int i = 0; i < file_count; i++) { printf("%d. %s\n", i + 1, record_files[i]); } char prompt[150]; - sprintf(prompt, "璇疯緭鍏ュ鐩樻枃浠剁紪鍙(1-%d)锛屾垨杈撳叆0浠ユ墜鍔ㄨ緭鍏ユ枃浠跺悕: ", file_count); + sprintf(prompt, "??????????????(1-%d)????????0??????????????: ", file_count); int choice = get_integer_input(prompt, 0, file_count); if (choice > 0) @@ -349,7 +343,7 @@ void run_review_mode() } else { - printf("璇疯緭鍏ュ畬鏁存枃浠跺悕: "); + printf("???????????????: "); scanf("%s", filename); int c; while ((c = getchar()) != '\n' && c != EOF) @@ -364,7 +358,7 @@ void run_review_mode() } else { - printf("鏈壘鍒颁换浣曞鐩樻枃浠讹紝璇疯緭鍏ュ鐩樻枃浠跺湴鍧: "); + printf("???????????????????????????????: "); scanf("%s", filename); int c; while ((c = getchar()) != '\n' && c != EOF) @@ -376,11 +370,11 @@ void run_review_mode() { if (game_mode == 1) { - printf("鍔犺浇AI瀵规垬妯″紡澶嶇洏鏂囦欢鎴愬姛锛乗n"); + printf("????AI?????????????????\n"); } else if (game_mode == 2) { - printf("鍔犺浇鍙屼汉瀵规垬妯″紡澶嶇洏鏂囦欢鎴愬姛锛乗n"); + printf("???????????????????????\n"); } review_process(game_mode); } diff --git a/game_mode.h b/game_mode.h index c83d665..fb32ba6 100644 --- a/game_mode.h +++ b/game_mode.h @@ -1,16 +1,16 @@ /** * @file game_mode.h - * @author 鍒樿埅瀹(3364451258@qq.com銆15236416560@163.com銆乴hy3364451258@outlook.com) - * @brief 浜斿瓙妫嬫父鎴忔鏋跺ご鏂囦欢 + * @author ??????(3364451258@qq.com??15236416560@163.com??lhy3364451258@outlook.com) + * @brief ???????????????? * @version 3.0 * @date 2025-06-30 * * @copyright Copyright (c) 2025 * - * @note 鏈枃浠跺畾涔変簡浜斿瓙妫嬫父鎴忕殑涓夌涓昏妯″紡锛 - * 1. AI瀵规垬妯″紡 - * 2. 鍙屼汉瀵规垬妯″紡 - * 3. 澶嶇洏妯″紡 + * @note ????????????????????????????????? + * 1. AI????? + * 2. ??????? + * 3. ?????? */ #ifndef GAME_MODE_H @@ -18,53 +18,53 @@ #include "gobang.h" -// 鐗规畩杈撳叆鍛戒护 +// ???????????? #define INPUT_UNDO -1 #define INPUT_SAVE -2 #define INPUT_EXIT -3 /** - * @brief 浠庣敤鎴疯幏鍙栨暣鏁拌緭鍏 + * @brief ???????????????? * - * @param prompt 鎻愮ず淇℃伅 - * @param min 鏈灏忓 - * @param max 鏈澶у - * @return int 杈撳叆鐨勬暣鏁 + * @param prompt ?????? + * @param min ????? + * @param max ???? + * @return int ????????? */ int get_integer_input(const char *prompt, int min, int max); /** - * @brief 澶勭悊鐜╁鍥炲悎 + * @brief ????????? * - * @param x 鐜╁杈撳叆鐨勬í鍧愭爣 - * @param y 鐜╁杈撳叆鐨勭旱鍧愭爣 - * @return true 杈撳叆鏈夋晥 - * @return false 杈撳叆鏃犳晥 + * @param x ????????????? + * @param y ?????????????? + * @return true ???????? + * @return false ???????? */ bool parse_player_input(int *x, int *y); /** - * @brief 澶勭悊AI鍥炲悎 + * @brief ????AI??? * - * @param current_player 褰撳墠鐜╁ + * @param current_player ?????? */ bool handle_player_turn(int current_player); /** - * @brief AI瀵规垬妯″紡 - * 瀹炵幇鐜╁涓嶢I鐨勫鎴橀昏緫 + * @brief AI????? + * ????????AI??????? */ void run_ai_game(); /** - * @brief 鍙屼汉瀵规垬妯″紡 - * 瀹炵幇涓や釜鐜╁涔嬮棿鐨勫鎴橀昏緫 + * @brief ??????? + * ??????????????????? */ void run_pvp_game(); /** - * @brief 澶嶇洏妯″紡 - * 鍔犺浇骞堕噸鐜板巻鍙插灞 + * @brief ?????? + * ??????????????? */ void run_review_mode(); diff --git a/gobang.c b/gobang.c index 999609d..3fcdb16 100644 --- a/gobang.c +++ b/gobang.c @@ -5,24 +5,24 @@ #include #include -// 鍏ㄥ眬鍙橀噺瀹氫箟 -int BOARD_SIZE = 15; // 瀹為檯浣跨敤鐨勬鐩樺昂瀵(榛樿15) -int board[MAX_BOARD_SIZE][MAX_BOARD_SIZE] = {0}; // 妫嬬洏鐘舵佸瓨鍌ㄦ暟缁(榛樿妫嬬洏鍏ㄧ┖涓0) +// ?????????? +int BOARD_SIZE = 15; // ?????????????(???15) +int board[MAX_BOARD_SIZE][MAX_BOARD_SIZE] = {0}; // ?????????????(???????????0) -Step steps[MAX_STEPS]; // 瀛樺偍鎵鏈夎惤瀛愭楠ょ殑鏁扮粍 -const int direction[4][2] = {{1, 0}, {0, 1}, {1, 1}, {1, -1}}; // 鍥涗釜鏂瑰悜锛氬悜涓嬨佸悜鍙炽佸彸涓嬨佸乏涓 -int step_count = 0; // 褰撳墠姝ユ暟璁℃暟鍣 -bool use_forbidden_moves = false; // 榛樿涓嶅惎鐢ㄧ鎵嬭鍒 -int use_timer = 0; // 榛樿涓嶅惎鐢ㄨ鏃跺櫒 -int time_limit = 30; // 榛樿鏃堕棿闄愬埗涓30绉 +Step steps[MAX_STEPS]; // ??????????????????? +const int direction[4][2] = {{1, 0}, {0, 1}, {1, 1}, {1, -1}}; // ?????????????????????????? +int step_count = 0; // ????????????? +bool use_forbidden_moves = false; // ?????????????? +int use_timer = 0; // ????????????? +int time_limit = 30; // ???????????30?? /** - * @brief 鍒濆鍖栨鐩樹负鍏ㄧ┖鐘舵佸苟閲嶇疆姝ユ暟璁℃暟鍣 - * 娓呯┖妫嬬洏鏁扮粍骞跺皢鎵鏈変綅缃涓篍MPTY锛屽悓鏃跺皢step_count閲嶇疆涓0 + * @brief ??????????????????????????????? + * ?????????????????????????EMPTY??????step_count?????0 */ void empty_board() { - // 鍒濆鍖栨鐩樼姸鎬佷负鍏ㄧ┖ + // ??????????????? for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) @@ -30,87 +30,87 @@ void empty_board() board[i][j] = EMPTY; } } - step_count = 0; // 閲嶇疆姝ユ暟璁℃暟鍣 + step_count = 0; // ?????????????? } /** - * @brief 鎵撳嵃褰撳墠妫嬬洏鐘舵 - * 浠ュ彲璇绘牸寮忚緭鍑烘鐩橈紝鍖呮嫭琛屽垪鍙峰拰妫嬪瓙鐘舵 - * 鐜╁妫嬪瓙鏄剧ず涓'x'锛孉I妫嬪瓙鏄剧ず涓'鈼'锛岀┖浣嶆樉绀轰负'路' + * @brief ???????????? + * ???????????????????????????????? + * ???????????'x'??AI????????'??'??????????'??' */ void print_board() { - // 鎵撳嵃鍒楀彿锛1-BOARD_SIZE鏄剧ず锛 + // ????????1-BOARD_SIZE????? printf("\n "); for (int i = 0; i < BOARD_SIZE; i++) { printf("%2d", i + 1); - if (i + 1 == 9) // 澶勭悊鍒楀彿9鍜10+鐨勫榻 + if (i + 1 == 9) // ????????9??10+????? printf(" "); } printf("\n"); - // 閫愯鎵撳嵃妫嬬洏鍐呭 + // ??????????????? for (int i = 0; i < BOARD_SIZE; i++) { - printf("%2d ", i + 1); // 鎵撳嵃琛屽彿锛1-BOARD_SIZE锛 + printf("%2d ", i + 1); // ????????1-BOARD_SIZE?? for (int j = 0; j < BOARD_SIZE; j++) { if (board[i][j] == PLAYER) - printf("x "); // 鐜╁妫嬪瓙 + printf("x "); // ??????? else if (board[i][j] == AI) - printf("鈼 "); // AI妫嬪瓙(浣跨敤鈼嬫樉绀) + printf("?? "); // AI????(????????) else - printf("路 "); // 绌轰綅 + printf("?? "); // ???? } - printf("\n"); // 姣忚缁撴潫鎹㈣ + printf("\n"); // ??????????? } } /** - * @brief 妫鏌ユ寚瀹氫綅缃槸鍚︽湁鏁堜笖涓虹┖ - * @param x 琛屽潗鏍(0-base) - * @param y 鍒楀潗鏍(0-base) - * @return true 浣嶇疆鏈夋晥涓斾负绌 - * @return false 浣嶇疆鏃犳晥鎴栧凡琚崰鐢 + * @brief ?????????????????????? + * @param x ??????(0-base) + * @param y ??????(0-base) + * @return true ????????????? + * @return false ???????????????? */ bool have_space(int x, int y) { - // 鏍¢獙鍧愭爣鏄惁鍦ㄨ寖鍥村唴涓旇浣嶇疆涓虹┖ + // ???????????????????????????? return (x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE && board[x][y] == EMPTY); } /** - * @brief 閰嶇疆妫嬬洏澶у皬 + * @brief ??????????? * - * @param player1 鐜╁1 - * @param player2 鐜╁2 + * @param player1 ???1 + * @param player2 ???2 */ void setup_board_size() { - printf("閫氬父妫嬬洏澶у皬鍒嗕负浼戦棽妫嬬洏(13X13)銆佹爣鍑嗘鐩(15X15)鍜岀壒娈婃鐩(19X19)\n"); + printf("?????????????????????(13X13)?????????(15X15)??????????(19X19)\n"); char prompt[100]; - sprintf(prompt, "璇疯緭鍏ユ鐩樺ぇ灏(5~%d)(榛樿涓烘爣鍑嗘鐩):\n", MAX_BOARD_SIZE); + sprintf(prompt, "?????????????(5~%d)(???????????):\n", MAX_BOARD_SIZE); BOARD_SIZE = get_integer_input(prompt, 5, MAX_BOARD_SIZE); } /** * @brief Set the up game options object - * 閰嶇疆娓告垙閫夐」锛屽寘鎷鎵嬭鍒欍佽鏃跺櫒鍜屾椂闂撮檺鍒 + * ?????????????????????????????????? */ void setup_game_options() { - use_forbidden_moves = get_integer_input("鏄惁鍚敤绂佹墜瑙勫垯 (1-鏄, 0-鍚): ", 0, 1); + use_forbidden_moves = get_integer_input("????????????? (1-??, 0-??): ", 0, 1); - use_timer = get_integer_input("鏄惁鍚敤璁℃椂鍣 (1-鏄, 0-鍚): ", 0, 1); + use_timer = get_integer_input("???????????? (1-??, 0-??): ", 0, 1); if (use_timer) { - time_limit = get_integer_input("璇疯緭鍏ユ瘡鍥炲悎鐨勬椂闂撮檺鍒 (1~60鍒嗛挓): ", 1, 60) * 60; + time_limit = get_integer_input("?????????????????? (1~60????): ", 1, 60) * 60; } } /** - * @brief 纭畾鍏堟墜鐜╁ + * @brief ?????????? * * @param player1 * @param player2 @@ -119,7 +119,7 @@ void setup_game_options() int determine_first_player(int player1, int player2) { char prompt[100]; - sprintf(prompt, "璇烽夋嫨鍏堟墜鏂 (1 for Player %d, 2 for Player %d): ", player1, player2); + sprintf(prompt, "?????????? (1 for Player %d, 2 for Player %d): ", player1, player2); int first_player_choice = get_integer_input(prompt, 1, 2); if (first_player_choice == 1) { @@ -132,7 +132,7 @@ int determine_first_player(int player1, int player2) } /** - * @brief 妫鏌ユ槸鍚︿负绂佹墜 + * @brief ??????????? * * @param x * @param y @@ -163,7 +163,7 @@ bool is_forbidden_move(int x, int y, int player) if (info.continuous_chess > 5) { board[x][y] = EMPTY; - return true; // 闀胯繛绂佹墜 + return true; // ???????? } if (info.continuous_chess == 3 && info.check_start && info.check_end) { @@ -179,77 +179,77 @@ bool is_forbidden_move(int x, int y, int player) if (three_count >= 2 || four_count >= 2) { - return true; // 涓変笁鎴栧洓鍥涚鎵 + return true; // ????????????? } return false; } /** - * @brief 鎵ц鐜╁钀藉瓙鎿嶄綔 - * @param x 琛屽潗鏍(0-base) - * @param y 鍒楀潗鏍(0-base) - * @return true 钀藉瓙鎴愬姛 - * @return false 钀藉瓙澶辫触(浣嶇疆鏃犳晥) + * @brief ????????????? + * @param x ??????(0-base) + * @param y ??????(0-base) + * @return true ?????? + * @return false ???????(????????) */ bool player_move(int x, int y, int player) { - // 浣嶇疆鏃犳晥鍒欒繑鍥瀎alse + // ???????????false if (!have_space(x, y)) return false; if (is_forbidden_move(x, y, player)) { - printf("绂佹墜锛佽閫夋嫨鍏朵粬浣嶇疆銆俓n"); + printf("????????????????????\n"); return false; } - // 鏇存柊妫嬬洏鐘舵 + // ?????????? board[x][y] = player; - // 璁板綍钀藉瓙姝ラ锛氱帺瀹舵爣璇嗗拰鍧愭爣 + // ??????????s??????????? steps[step_count++] = (Step){player, x, y}; return true; } /** - * @brief 璁$畻鐗瑰畾鏂瑰悜涓婅繛缁悓鑹叉瀛愭暟閲 - * @param x 璧峰琛屽潗鏍 - * @param y 璧峰鍒楀潗鏍 - * @param dx 琛屾柟鍚戝閲(-1,0,1) - * @param dy 鍒楁柟鍚戝閲(-1,0,1) - * @param player 鐜╁鏍囪瘑(PLAYER/AI) - * @return DirInfo 鍖呭惈杩炵画妫嬪瓙鏁板拰鏂瑰悜寮鏀剧姸鎬佺殑缁撴瀯浣 - * @note 妫鏌ユ鍙嶄袱涓柟鍚戯紝缁熻杩炵画妫嬪瓙鏁板苟鍒ゆ柇绔偣鏄惁寮鏀 + * @brief ??????????????????????????? + * @param x ????????? + * @param y ????????? + * @param dx ??????????(-1,0,1) + * @param dy ??????????(-1,0,1) + * @param player ?????(PLAYER/AI) + * @return DirInfo ??????????????????????????? + * @note ???????????????????????????????????????? */ DirInfo count_specific_direction(int x, int y, int dx, int dy, int player) { DirInfo info; - info.continuous_chess = 1; // 璧峰浣嶇疆宸茬粡鏈変竴涓瀛 - info.check_start = false; // 璧风偣鏂瑰悜鏄惁寮鏀 - info.check_end = false; // 缁堢偣鏂瑰悜鏄惁寮鏀 + info.continuous_chess = 1; // ??????????????????? + info.check_start = false; // ????????? + info.check_end = false; // ????????? - // 妫鏌ユ鏂瑰悜锛坉x, dy锛 + // ?????????dx, dy?? int nx = x + dx, ny = y + dy; while (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE && board[nx][ny] == player) { - info.continuous_chess++; // 杩炵画妫嬪瓙璁℃暟澧炲姞 - nx += dx; // 娌垮綋鍓嶆柟鍚戝墠杩 + info.continuous_chess++; // ??????????????? + nx += dx; // ??????????? ny += dy; } - // 鍒ゆ柇姝f柟鍚戠鐐规槸鍚﹀紑鏀撅紙閬囧埌绌轰綅锛 + // ??????????????????????????? if (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE) if (board[nx][ny] == EMPTY) info.check_end = true; - // 妫鏌ュ弽鏂瑰悜锛-dx, -dy锛 + // ????????-dx, -dy?? nx = x - dx, ny = y - dy; while (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE && board[nx][ny] == player) { - info.continuous_chess++; // 杩炵画妫嬪瓙璁℃暟澧炲姞 - nx -= dx; // 娌跨浉鍙嶆柟鍚戝墠杩 + info.continuous_chess++; // ??????????????? + nx -= dx; // ??????????? ny -= dy; } - // 鍒ゆ柇鍙嶆柟鍚戠鐐规槸鍚﹀紑鏀撅紙閬囧埌绌轰綅锛 + // ?????????????????????????? if (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE) if (board[nx][ny] == EMPTY) info.check_start = true; @@ -259,115 +259,115 @@ DirInfo count_specific_direction(int x, int y, int dx, int dy, int player) bool check_win(int x, int y, int player) { - // 妫鏌ュ洓涓柟鍚戞槸鍚﹀瓨鍦ㄤ簲杩炵彔 + // ?????????????????????? for (int i = 0; i < 4; i++) { DirInfo info = count_specific_direction(x, y, direction[i][0], direction[i][1], player); - if (info.continuous_chess >= 5) // 杩炵画妫嬪瓙>=5鍗宠幏鑳 + if (info.continuous_chess >= 5) // ????????>=5????? { return true; } } - return false; // 鍥涗釜鏂瑰悜閮芥病鏈変簲杩炵彔 + return false; // ???????????????? } /** - * @brief 澶嶇洏娓告垙鍏ㄨ繃绋嬪苟灞曠ず璇勫垎 - * @note 瀹炵幇娴佺▼: - * 1. 鍒濆鍖栦复鏃跺鐩樻鐩 - * 2. 鎸夋鏁伴『搴忛愭閲嶇幇姣忎釜钀藉瓙 - * 3. 姣忔鏄剧ず: - * - 褰撳墠姝ユ暟/鎬绘鏁 - * - 钀藉瓙鏂(鐜╁/AI) - * - 钀藉瓙浣嶇疆(1-based鍧愭爣) - * - 褰撳墠妫嬬洏鐘舵 - * 4. 閫氳繃鐢ㄦ埛鎸塃nter閿帶鍒舵楠ゅ墠杩 - * 5. 澶嶇洏缁撴潫鍚庤嚜鍔ㄨ繘鍏ヨ瘎鍒嗙幆鑺: - * - 璇勪及鍙屾柟琛ㄧ幇 - * - 鏄剧ず寰楀垎 - * - 璇勯塎VP - * @note 鎶鏈粏鑺: - * - 浣跨敤鐙珛涓存椂妫嬬洏閬垮厤褰卞搷涓绘父鎴忕姸鎬 - * - 鍧愭爣鏄剧ず杞崲涓1-based鏂逛究鐢ㄦ埛鐞嗚В - * - 鍖呭惈杈撳叆缂撳啿鍖烘竻鐞嗛槻姝㈡剰澶栬緭鍏 - * - 璇勫垎鐜妭璋冪敤evaluate_performance()鍑芥暟 + * @brief ??????????????????? + * @note ???????: + * 1. ???????????????? + * 2. ?????????????????????? + * 3. ??????: + * - ???????/????? + * - ?????(???/AI) + * - ????????(1-based????) + * - ????????? + * 4. ????????Enter???????????? + * 5. ???????????????????????: + * - ??????????? + * - ??????? + * - ???MVP + * @note ???????: + * - ?????????????????????????? + * - ???????????1-based??????????? + * - ??????????????????????????? + * - ??????????evaluate_performance()???? */ void review_process(int game_mode) { - printf("\n===== 澶嶇洏璁板綍(鎬绘鏁帮細%d) =====\n", step_count); - // 娓呯┖杈撳叆缂撳啿鍖 + printf("\n===== ??????(???????%d) =====\n", step_count); + // ??????????? int c; while ((c = getchar()) != '\n' && c != EOF) ; - // 鍒涘缓涓存椂澶嶇洏妫嬬洏 + // ??????????????? int temp_board[MAX_BOARD_SIZE][MAX_BOARD_SIZE]; - memset(temp_board, EMPTY, sizeof(temp_board)); // 鍒濆鍖栦负绌烘鐩 + memset(temp_board, EMPTY, sizeof(temp_board)); // ???????????? - // 閫愭閲嶇幇娓告垙杩囩▼ + // ????????????? for (int i = 0; i < step_count; i++) { - Step s = steps[i]; // 鑾峰彇褰撳墠姝ラ - temp_board[s.x][s.y] = s.player; // 鍦ㄤ复鏃舵鐩樹笂钀藉瓙 + Step s = steps[i]; // ?????????? + temp_board[s.x][s.y] = s.player; // ??????????????? - // 鎵撳嵃褰撳墠姝ラ淇℃伅 - // 鏍规嵁娓告垙妯″紡鏄剧ず涓嶅悓鐨勬爣棰樺拰鐜╁淇℃伅 + // ????????????? + // ??????????????????????????? if (game_mode == 1) { - // 浜烘満瀵规垬 - printf("\n===== 浜斿瓙妫嬩汉鏈哄鎴(%dX%d妫嬬洏) =====", BOARD_SIZE, BOARD_SIZE); - printf("\n 绗%d姝/%d姝: %s 钀藉瓙浜(%d, %d)\n", + // ?????? + printf("\n===== ????????????(%dX%d????) =====", BOARD_SIZE, BOARD_SIZE); + printf("\n ??%d??/%d??: %s ??????(%d, %d)\n", i + 1, step_count, - (s.player == PLAYER) ? "鐜╁" : "AI", + (s.player == PLAYER) ? "???" : "AI", s.x + 1, s.y + 1); } else { - // 鍙屼汉瀵规垬 - printf("\n===== 浜斿瓙妫嬪弻浜哄鎴(%dX%d妫嬬洏) =====", BOARD_SIZE, BOARD_SIZE); - printf("\n 绗%d姝/%d姝: %s 钀藉瓙浜(%d, %d)\n", + // ????? + 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.player == PLAYER1) ? "???1(????)" : "???2(????)", s.x + 1, s.y + 1); } - // 鎵撳嵃褰撳墠澶嶇洏妫嬬洏 + // ?????????????? printf(" "); for (int col = 0; col < BOARD_SIZE; col++) - printf("%2d", col + 1); // 鍒楀彿 + printf("%2d", col + 1); // ???? printf("\n"); for (int row = 0; row < BOARD_SIZE; row++) { - printf("%2d ", row + 1); // 琛屽彿 + printf("%2d ", row + 1); // ???? for (int col = 0; col < BOARD_SIZE; col++) { if (temp_board[row][col] == PLAYER || temp_board[row][col] == PLAYER1) printf("x "); else if (temp_board[row][col] == AI || temp_board[row][col] == PLAYER2) - printf("鈼 "); + printf("?? "); else - printf("路 "); + printf("?? "); } - printf("\n"); // 琛岀粨鏉熸崲琛 + printf("\n"); // ?????????? } - // 濡傛灉涓嶆槸鏈鍚庝竴姝ワ紝绛夊緟鐢ㄦ埛鎸夐敭缁х画 + // ????????????????????????????? if (i < step_count - 1) { - printf("\n鎸塃nter缁х画涓嬩竴姝..."); + printf("\n??Enter?????????..."); while (getchar() != '\n') - ; // 绛夊緟鍥炶溅 + ; // ?????? } } - printf("\n澶嶇洏缁撴潫锛佹寜Enter鏌ョ湅璇勫垎..."); - getchar(); // 绛夊緟鐢ㄦ埛鎸夐敭 + printf("\n???????????Enter??????..."); + getchar(); // ?????????? - // 璇勪及鍙屾柟琛ㄧ幇 - printf("\n===== 瀵瑰眬璇勫垎 =====\n"); + // ??????????? + printf("\n===== ??????? =====\n"); int player1_score = 0, player2_score = 0; - // 閬嶅巻鎵鏈夋鏁帮紝绱Н姣忎竴姝ョ殑寰楀垎 + // ?????????????????????????? for (int i = 0; i < step_count; i++) { if (steps[i].player == PLAYER || steps[i].player == PLAYER1) @@ -386,16 +386,16 @@ void review_process(int game_mode) { if (game_mode == 1) { - printf("鐜╁寰楀垎: %d, 鍗犳瘮: %.2f%%\n", + printf("??????: %d, ???: %.2f%%\n", player1_score, (double)player1_score * 100.0 / sum_score); - printf("AI寰楀垎: %d, 鍗犳瘮: %.2f%%\n", + printf("AI????: %d, ???: %.2f%%\n", player2_score, (double)player2_score * 100.0 / sum_score); } else { - printf("鐜╁1(榛戞)寰楀垎: %d, 鍗犳瘮: %.2f%%\n", + printf("???1(????)????: %d, ???: %.2f%%\n", player1_score, (double)player1_score * 100.0 / sum_score); - printf("鐜╁2(鐧芥)寰楀垎: %d, 鍗犳瘮: %.2f%%\n", + printf("???2(????)????: %d, ???: %.2f%%\n", player2_score, (double)player2_score * 100.0 / sum_score); } } @@ -403,43 +403,43 @@ void review_process(int game_mode) { if (game_mode == 1) { - printf("鐜╁寰楀垎: %d\n", player1_score); - printf("AI寰楀垎: %d\n", player2_score); + printf("??????: %d\n", player1_score); + printf("AI????: %d\n", player2_score); } else { - printf("鐜╁1(榛戞)寰楀垎: %d\n", player1_score); - printf("鐜╁2(鐧芥)寰楀垎: %d\n", player2_score); + printf("???1(????)????: %d\n", player1_score); + printf("???2(????)????: %d\n", player2_score); } - printf("娉: 鍙屾柟寰楀垎鍧囦负0锛屾棤娉曡绠楀崰姣擻n"); + printf("?: ?????????0????????????\n"); } - // 璇勯塎VP + // ???MVP if (player1_score > player2_score) { - printf("\nMVP: %s (棰嗗厛 %d 鍒)\n", (game_mode == 1) ? "鐜╁" : "鐜╁1(榛戞)", player1_score - player2_score); + printf("\nMVP: %s (???? %d ??)\n", (game_mode == 1) ? "???" : "???1(????)", player1_score - player2_score); } else if (player2_score > player1_score) { - printf("\nMVP: %s (棰嗗厛 %d 鍒)\n", (game_mode == 1) ? "AI" : "鐜╁2(鐧芥)", player2_score - player1_score); + printf("\nMVP: %s (???? %d ??)\n", (game_mode == 1) ? "AI" : "???2(????)", player2_score - player1_score); } else { - printf("\n鍙屾柟鍔垮潎鍔涙晫锛乗n"); + printf("\n????????????\n"); } getchar(); } /** - * @brief 澶勭悊娓告垙缁撴潫鍚庣殑璁板綍淇濆瓨 - * @return int 淇濆瓨鐘舵佺爜(0-鎴愬姛, 1-鐩綍鍒涘缓澶辫触, 2-鏂囦欢鎵撳紑澶辫触, 3-鏂囦欢鍐欏叆澶辫触) + * @brief ???????????????????? + * @return int ????????(0-???, 1-?????????, 2-????????, 3-??????????) */ void handle_save_record(int game_mode) { int save_choice = 0; - printf("===== 娓告垙缁撴潫 =====\n"); - printf("鏄惁淇濆瓨娓告垙璁板綍? (1-鏄, 0-鍚): "); + printf("===== ??????? =====\n"); + printf("??????????? (1-??, 0-??): "); scanf("%d", &save_choice); if (save_choice == 1) @@ -452,35 +452,35 @@ void handle_save_record(int game_mode) int save_status = save_game_to_file(filename, game_mode); switch (save_status) { - case 0: // 鎴愬姛 - printf("\n娓告垙璁板綍宸叉垚鍔熶繚瀛樿嚦: %s\n", filename); - printf("鎮ㄥ彲浠ヤ娇鐢ㄤ互涓嬪懡浠よ繘琛屽鐩: .\\gobang.exe -l %s\n", filename); + case 0: // ??? + printf("\n????????????????: %s\n", filename); + printf("????????????????????????: .\\gobang.exe -l %s\n", filename); break; - case 1: // 鐩綍鍒涘缓澶辫触 - printf("\n娓告垙璁板綍淇濆瓨澶辫触: 鏃犳硶鍒涘缓 'records' 鐩綍銆俓n"); - printf("璇锋鏌ョ▼搴忔槸鍚﹀叿鏈夎冻澶熺殑鍐欏叆鏉冮檺鎴栫鐩樼┖闂存槸鍚﹀厖瓒炽俓n"); + case 1: // ????????? + printf("\n?????????????: ??????? 'records' ????\n"); + printf("????????????????????????????????????\n"); break; - case 2: // 鏂囦欢鎵撳紑澶辫触 - printf("\n娓告垙璁板綍淇濆瓨澶辫触: 鏃犳硶鍦ㄨ矾寰 '%s' 鍒涘缓鏂囦欢銆俓n", filename); - printf("璇锋鏌ヨ矾寰勬槸鍚︽湁鏁堜互鍙婄▼搴忔槸鍚﹀叿鏈夊啓鍏ユ潈闄愩俓n"); + case 2: // ???????? + printf("\n?????????????: ????????? '%s' ?????????\n", filename); + printf("????????????????????????????????????\n"); break; - case 3: // 鏂囦欢鍐欏叆澶辫触 - printf("\n娓告垙璁板綍淇濆瓨澶辫触: 鍐欏叆鏂囦欢鏃跺彂鐢熼敊璇俓n"); - printf("璇锋鏌ョ鐩樼┖闂存槸鍚﹀凡婊°俓n"); + case 3: // ?????????? + printf("\n?????????????: ????????????????\n"); + printf("??????????????????\n"); break; default: - printf("\n娓告垙璁板綍淇濆瓨澶辫触: 鍙戠敓鏈煡閿欒銆俓n"); + printf("\n?????????????: ???????????\n"); break; } } } /** - * @brief 鎮旀鍔熻兘瀹炵幇 + * @brief ?????????? * - * @param steps_to_undo 瑕佹倲妫嬬殑姝ユ暟 - * @return true 鎮旀鎴愬姛 - * @return false 鎮旀澶辫触(姝ユ暟涓嶈冻) + * @param steps_to_undo ????????? + * @return true ?????? + * @return false ???????(????????) */ bool return_move(int steps_to_undo) { @@ -502,65 +502,65 @@ bool return_move(int steps_to_undo) } /** - * @brief 璇勪及鐜╁鍦ㄦ暣鐩樻灞涓殑琛ㄧ幇 - * @param player 瑕佽瘎浼扮殑鐜╁(PLAYER/AI) - * @return int 鎬诲垎(宸茶冭檻鏂瑰悜閲嶅璁$畻) - * @note 璇勫垎鏍囧噯: - * - 浜旇繛:2500 - * - 娲诲洓:1000 鍐插洓:500 姝诲洓:250 - * - 娲讳笁:250 鐪犱笁:100 姝讳笁:50 - * - 娲讳簩:50 鐪犱簩:20 姝讳簩:10 - * - 寮鏀惧崟瀛:10 鍗婂紑鏀惧崟瀛:5 灏侀棴鍗曞瓙:1 - * @note 瀹炵幇缁嗚妭: - * 1. 閬嶅巻妫嬬洏鎵鏈変綅缃 - * 2. 瀵规瘡涓瀛愭鏌ュ洓涓柟鍚 - * 3. 缁熻鎵鏈夎繛瀛愭儏鍐靛苟璇勫垎 - * 4. 鏈缁堝垎鏁伴櫎浠4(娑堥櫎鏂瑰悜閲嶅璁$畻褰卞搷) + * @brief ??????????????????????? + * @param player ??????????(PLAYER/AI) + * @return int ???(???????????????) + * @note ??????: + * - ????:2500 + * - ????:1000 ????:500 ????:250 + * - ????:250 ????:100 ????:50 + * - ???:50 ???:20 ????:10 + * - ???????:10 ???????:5 ??????:1 + * @note ??????: + * 1. ???????????????? + * 2. ?????????????????? + * 3. ???????????????????? + * 4. ???????????4(??????????????????) */ int calculate_step_score(int x, int y, int player) { int step_score = 0; - // 妫鏌ュ洓涓柟鍚 + // ?????????? for (int k = 0; k < 4; k++) { DirInfo info = count_specific_direction(x, y, direction[k][0], direction[k][1], player); - // 鏍规嵁杩炲瓙鏁拌瘎鍒 + // ?????????????? switch (info.continuous_chess) { case 5: step_score += 2500; - break; // 浜旇繛 + break; // ???? case 4: if (info.check_start && info.check_end) - step_score += 1000; // 娲诲洓 + step_score += 1000; // ???? else if (info.check_start || info.check_end) - step_score += 500; // 鍐插洓 + step_score += 500; // ???? else - step_score += 250; // 姝诲洓 + step_score += 250; // ???? break; case 3: if (info.check_start && info.check_end) - step_score += 250; // 娲讳笁 + step_score += 250; // ???? else if (info.check_start || info.check_end) - step_score += 100; // 鐪犱笁 + step_score += 100; // ???? else - step_score += 50; // 姝讳笁 + step_score += 50; // ???? break; case 2: if (info.check_start && info.check_end) - step_score += 50; // 娲讳簩 + step_score += 50; // ??? else if (info.check_start || info.check_end) - step_score += 20; // 鐪犱簩 + step_score += 20; // ??? else - step_score += 10; // 姝讳簩 + step_score += 10; // ???? break; case 1: if (info.check_start && info.check_end) - step_score += 10; // 寮鏀惧崟瀛 + step_score += 10; // ??????? else if (info.check_start || info.check_end) - step_score += 5; // 鍗婂紑鏀惧崟瀛 + step_score += 5; // ??????? else - step_score += 1; // 灏侀棴鍗曞瓙 + step_score += 1; // ?????? break; } } @@ -568,26 +568,26 @@ int calculate_step_score(int x, int y, int player) } /** - * @brief 璇勪及鐜╁鍦ㄦ暣鐩樻灞涓殑琛ㄧ幇 - * @param player 瑕佽瘎浼扮殑鐜╁(PLAYER/AI) - * @return int 鎬诲垎(宸茶冭檻鏂瑰悜閲嶅璁$畻) - * @note 璇勫垎鏍囧噯: - * - 浜旇繛:2500 - * - 娲诲洓:1000 鍐插洓:500 姝诲洓:250 - * - 娲讳笁:250 鐪犱笁:100 姝讳笁:50 - * - 娲讳簩:50 鐪犱簩:20 姝讳簩:10 - * - 寮鏀惧崟瀛:10 鍗婂紑鏀惧崟瀛:5 灏侀棴鍗曞瓙:1 - * @note 瀹炵幇缁嗚妭: - * 1. 閬嶅巻妫嬬洏鎵鏈変綅缃 - * 2. 瀵规瘡涓瀛愭鏌ュ洓涓柟鍚 - * 3. 缁熻鎵鏈夎繛瀛愭儏鍐靛苟璇勫垎 - * 4. 鏈缁堝垎鏁伴櫎浠4(娑堥櫎鏂瑰悜閲嶅璁$畻褰卞搷) + * @brief ??????????????????????? + * @param player ??????????(PLAYER/AI) + * @return int ???(???????????????) + * @note ??????: + * - ????:2500 + * - ????:1000 ????:500 ????:250 + * - ????:250 ????:100 ????:50 + * - ???:50 ???:20 ????:10 + * - ???????:10 ???????:5 ??????:1 + * @note ??????: + * 1. ???????????????? + * 2. ?????????????????? + * 3. ???????????????????? + * 4. ???????????4(??????????????????) */ int evaluate_performance(int player) { int total_score = 0; - // 閬嶅巻妫嬬洏鎵鏈変綅缃 + // ???????????????? for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) @@ -598,86 +598,86 @@ int evaluate_performance(int player) } } } - return total_score / 4; // 姣忎釜鏂瑰悜閮借绠椾簡锛岄渶瑕侀櫎浠4 + return total_score / 4; // ????????????????????4 } /** - * @brief 灏嗗綋鍓嶆父鎴忚褰曚繚瀛樺埌鏂囦欢 - * @param filename 瑕佷繚瀛樼殑鏂囦欢鍚 - * @return int 閿欒鐮: - * 0: 鎴愬姛 - * 1: 鐩綍鍒涘缓澶辫触 - * 2: 鏂囦欢鎵撳紑澶辫触 - * 3: 鏂囦欢鍐欏叆澶辫触 + * @brief ??????????????????? + * @param filename ??????????? + * @return int ??????: + * 0: ??? + * 1: ????????? + * 2: ???????? + * 3: ?????????? */ int save_game_to_file(const char *filename, int game_mode) { - // 鍒涘缓records鐩綍(濡傛灉涓嶅瓨鍦) + // ????records??(?????????) struct stat st = {0}; if (stat("records", &st) == -1) { if (mkdir("records") != 0) { - // 妫鏌ユ槸鍚︾洰褰曞凡瀛樺湪(澶氱嚎绋嬫儏鍐典笅鍙兘琚叾浠栫嚎绋嬪垱寤) + // ?????????????(????????????????????????) if (stat("records", &st) == -1) { #ifdef _WIN32 - printf("閿欒锛氭棤娉曞垱寤簉ecords鐩綍\n"); - printf("鍙兘鍘熷洜锛歕n"); - printf("1. 娌℃湁鍐欏叆鏉冮檺 - 璇峰皾璇曚互绠$悊鍛樿韩浠借繍琛孿n"); - printf("2. 闃茬梾姣掕蒋浠堕樆姝 - 璇锋鏌ュ畨鍏ㄨ蒋浠惰缃甛n"); - printf("3. 璺緞鏃犳晥 - 璇锋鏌ュ伐浣滅洰褰昞n"); + printf("???????????records??\n"); + printf("???????\n"); + printf("1. ?????????? - ??????????????????\n"); + printf("2. ????????????? - ??????????????\n"); + printf("3. ???????? - ?????????\n"); #else - perror("鍒涘缓鐩綍澶辫触"); + perror("?????????"); #endif - return 1; // 鐩綍鍒涘缓澶辫触 + return 1; // ????????? } } } - // 鎵撳紑鏂囦欢 + // ????? char fullpath[256]; snprintf(fullpath, sizeof(fullpath), "records/%s", filename); FILE *file = fopen(fullpath, "w"); if (!file) { - return 2; // 鏂囦欢鎵撳紑澶辫触 + return 2; // ???????? } - // 鍐欏叆娓告垙妯″紡鍜屾鐩樺ぇ灏 + // ?????????????????? if (fprintf(file, "%d\n%d\n", game_mode, BOARD_SIZE) < 0) { fclose(file); - return 3; // 鏂囦欢鍐欏叆澶辫触 + return 3; // ?????????? } - // 鍐欏叆鎵鏈夎惤瀛愭楠 + // ??????????????? for (int i = 0; i < step_count; i++) { if (fprintf(file, "%d %d %d\n", steps[i].player, steps[i].x, steps[i].y) < 0) { fclose(file); - return 3; // 鏂囦欢鍐欏叆澶辫触 + return 3; // ?????????? } } if (fclose(file) != 0) { - return 3; // 鏂囦欢鍏抽棴/鍐欏叆澶辫触 + return 3; // ??????/??????? } - return 0; // 鎴愬姛 + return 0; // ??? } /** - * @brief 浠庢枃浠跺姞杞芥父鎴忚褰 - * @param filename 瑕佸姞杞界殑鏂囦欢鍚 - * @return true 鍔犺浇鎴愬姛 - * @return false 鍔犺浇澶辫触 + * @brief ??????????????? + * @param filename ??????????? + * @return true ?????? + * @return false ??????? */ int load_game_from_file(const char *filename) { - // 鎵撳紑鏂囦欢 + // ????? char fullpath[256]; snprintf(fullpath, sizeof(fullpath), "records/%s", filename); FILE *file = fopen(fullpath, "r"); @@ -686,12 +686,12 @@ int load_game_from_file(const char *filename) return false; } - // 璇诲彇娓告垙妯″紡鍜屾鐩樺ぇ灏 + // ????????????????? int game_mode, size; if (fscanf(file, "%d", &game_mode) != 1 || (game_mode != 1 && game_mode != 2)) { fclose(file); - return 0; // 鏃犳晥鐨勬父鎴忔ā寮 + return 0; // ??????????? } if (fscanf(file, "%d", &size) != 1 || size < 5 || size > MAX_BOARD_SIZE) { @@ -699,11 +699,11 @@ int load_game_from_file(const char *filename) return false; } - // 鍒濆鍖栨鐩 + // ????????? BOARD_SIZE = size; empty_board(); - // 璇诲彇鎵鏈夎惤瀛愭楠 + // ?????????????? step_count = 0; while (fscanf(file, "%d %d %d", &steps[step_count].player, &steps[step_count].x, &steps[step_count].y) == 3) { diff --git a/gobang.h b/gobang.h index 4482189..e116f8a 100644 --- a/gobang.h +++ b/gobang.h @@ -1,21 +1,21 @@ /** * @file gobang.h - * @author 鍒樿埅瀹(3364451258@qq.com銆15236416560@163.com銆乴hy3364451258@outlook.com) - * @brief 浜斿瓙妫嬫父鎴忓ご鏂囦欢 + * @author ??????(3364451258@qq.com??15236416560@163.com??lhy3364451258@outlook.com) + * @brief ????????????? * @version 3.0 * @date 2025-06-30 * * @copyright Copyright (c) 2025 * - * @note 鏈枃浠朵负gobang.c鐨勬帴鍙f枃浠讹紝鎻愪緵娓告垙鎵闇鐨勬墍鏈夊嚱鏁板0鏄 - * @note 璁捐瑕佺偣锛 - * 1. 鏀寔5x5鍒25x25鐨勫彲鍙樻鐩樺昂瀵 - * 2. 浣跨敤鏋佸皬鏋佸ぇ绠楁硶瀹炵幇AI鍐崇瓥 - * 3. 鎻愪緵瀹屾暣鐨勬父鎴忚繃绋嬪鐩樺姛鑳 - * 4. 鎵鏈夊潗鏍囬噰鐢0-base绱㈠紩 - * 5. 浣跨敤鍏ㄥ眬鍙橀噺绠鍖栫姸鎬佺鐞 - * 6. 瀹炵幇浜嗛潪闃诲鐨勮秴鏃舵娴嬶紝瓒呮椂鍚庤兘绔嬪埢缁撴潫鍥炲悎 - * 7. 璁℃椂鍗曚綅涓哄垎閽燂紝鏂逛究鐢ㄦ埛璁剧疆 + * @note ??????gobang.c??????????????????????????????? + * @note ?????? + * 1. ???5x5??25x25?????????? + * 2. ????????????????AI???? + * 3. ????????????????????? + * 4. ???????????0-base???? + * 5. ????????????????? + * 6. ?????????????????????????????????? + * 7. ???????????????????????? */ #ifndef GO_BANG_H @@ -28,205 +28,205 @@ #include #include -// 瀹忓畾涔 +// ???? /** - * @brief 鏈澶ф敮鎸佹鐩樺昂瀵 - * @note 25x25鏄ц兘涓庡疄鐢ㄦх殑骞宠 鐐癸紝鏇村ぇ鐨勬鐩樹細鏄捐憲闄嶄綆AI鍝嶅簲閫熷害 + * @brief ???????????? + * @note 25x25????????????????????????????????????AI?????? */ -#define MAX_BOARD_SIZE 25 // 鏈澶ф敮鎸佹鐩樺昂瀵(5x5鍒25x25) +#define MAX_BOARD_SIZE 25 // ????????????(5x5??25x25) /** - * @brief 鐜╁鏍囪瘑绗 - * @note 浣跨敤1/2鑰岄潪瀛楃鏍囪瘑锛屼究浜庢墿灞曚负澶氱帺瀹舵父鎴 + * @brief ??????? + * @note ???1/2???????????????????????????? */ -#define PLAYER 1 // 鐜╁妫嬪瓙鏍囪瘑绗 -#define AI 2 // AI妫嬪瓙鏍囪瘑绗 -#define PLAYER1 1 // 鐜╁1妫嬪瓙鏍囪瘑绗 -#define PLAYER2 2 // 鐜╁2妫嬪瓙鏍囪瘑绗 +#define PLAYER 1 // ??????????? +#define AI 2 // AI???????? +#define PLAYER1 1 // ???1???????? +#define PLAYER2 2 // ???2???????? /** - * @brief 绌轰綅缃爣璇嗙 - * @note 蹇呴』涓嶱LAYER/AI鐨勫间笉鍚 + * @brief ?????????? + * @note ??????PLAYER/AI?????? */ -#define EMPTY 0 // 绌轰綅缃爣璇嗙 +#define EMPTY 0 // ?????????? /** - * @brief 鏈澶ф鏁伴檺鍒 - * @note 绛変簬妫嬬洏鎬绘牸鏁帮紝纭繚涓嶄細鏁扮粍瓒婄晫 + * @brief ????????? + * @note ????????????????????????????? */ -#define MAX_STEPS (MAX_BOARD_SIZE * MAX_BOARD_SIZE) // 鏈澶ф鏁帮紙妫嬬洏鎬绘牸鏁帮級 +#define MAX_STEPS (MAX_BOARD_SIZE * MAX_BOARD_SIZE) // ?????????????????? -// 鍏ㄥ眬鍙橀噺澹版槑 -extern int BOARD_SIZE; // 瀹為檯浣跨敤鐨勬鐩樺昂瀵(榛樿15) -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 BOARD_SIZE; // ?????????????(???15) +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 const int direction[4][2]; /** - * @brief 钀藉瓙姝ラ璁板綍缁撴瀯浣 - * @note 鐢ㄤ簬瀛樺偍娓告垙鍘嗗彶璁板綍鍜孉I鍐崇瓥鏍 - * @note 瀛楁璇存槑: - * - player: 鏍囪瘑钀藉瓙鏂(PLAYER/AI) - * - x/y: 0-based鍧愭爣浣嶇疆 + * @brief ????????????? + * @note ?????????????????AI?????? + * @note ??????: + * - player: ????????(PLAYER/AI) + * - x/y: 0-based???????? */ typedef struct { - int player; // 钀藉瓙鏂规爣璇 - int x, y; // 鍧愭爣浣嶇疆 + int player; // ???????? + int x, y; // ???????? } Step; -extern Step steps[MAX_STEPS]; // 瀛樺偍鎵鏈夎惤瀛愭楠ょ殑鏁扮粍 +extern Step steps[MAX_STEPS]; // ??????????????????? bool handle_player_turn(int current_player); /** - * @brief 杩炲瓙妫娴嬩俊鎭粨鏋勪綋 - * @note 鐢ㄤ簬浜斿瓙杩炵彔鍒ゆ柇鍜屾灞璇勪及 - * @note 瀛楁璇存槑: - * - continuous_chess: 杩炵画鍚岃壊妫嬪瓙鏁伴噺 - * - check_start: 搴忓垪璧风偣鏂瑰悜鏄惁鏈夌┖浣(鍙彂灞曟) - * - check_end: 搴忓垪缁堢偣鏂瑰悜鏄惁鏈夌┖浣(鍙彂灞曟) + * @brief ????????????? + * @note ???????????????????????? + * @note ??????: + * - continuous_chess: ?????????????? + * - check_start: ??????????????????(??????) + * - check_end: ??????????????????(??????) */ typedef struct { - int continuous_chess; // 杩炵画妫嬪瓙鏁伴噺 - bool check_start; // 搴忓垪璧风偣鏂瑰悜鏄惁寮鏀撅紙绌轰綅锛 - bool check_end; // 搴忓垪缁堢偣鏂瑰悜鏄惁寮鏀撅紙绌轰綅锛 + int continuous_chess; // ???????????? + bool check_start; // ???????????????????? + bool check_end; // ???????????????????? } DirInfo; -// 鍑芥暟澹版槑 +// ???????? /** - * @brief 鍒濆鍖栨鐩樹负鍏ㄧ┖鐘舵 + * @brief ??????????????? */ void empty_board(); /** - * @brief 鎵撳嵃褰撳墠妫嬬洏鐘舵 + * @brief ???????????? */ void print_board(); /** - * @brief 妫鏌ユ寚瀹氫綅缃槸鍚︿负绌轰笖鏈夋晥 - * @param x 琛屽潗鏍(0-base) - * @param y 鍒楀潗鏍(0-base) - * @return true 浣嶇疆鏈夋晥涓斾负绌 - * @return false 浣嶇疆鏃犳晥鎴栧凡琚崰鐢 + * @brief ?????????????????????? + * @param x ??????(0-base) + * @param y ??????(0-base) + * @return true ????????????? + * @return false ???????????????? */ bool have_space(int x, int y); /** - * @brief 璁剧疆妫嬬洏澶у皬 + * @brief ??????????? */ void setup_board_size(); /** - * @brief 璁剧疆娓告垙閫夐」 - * @note 鍖呮嫭绂佹墜瑙勫垯銆佽鏃跺櫒鍜屾椂闂撮檺鍒 + * @brief ?????????? + * @note ???????????????????????? */ void setup_game_options(); /** - * @brief 鍐冲畾鍏堟墜鐜╁ - * @param player1 鐜╁1鐨勬爣璇 - * @param player2 鐜╁2鐨勬爣璇 - * @return int 鍏堟墜鐜╁鐨勬爣璇 + * @brief ??????????? + * @param player1 ???1???? + * @param player2 ???2???? + * @return int ?????????? */ int determine_first_player(int player1, int player2); /** - * @brief 妫鏌ユ槸鍚︿负绂佹墜 - * @param x 琛屽潗鏍(0-base) - * @param y 鍒楀潗鏍(0-base) - * @param player 鐜╁鏍囪瘑 - * @return true 鏄鎵 - * @return false 涓嶆槸绂佹墜 + * @brief ??????????? + * @param x ??????(0-base) + * @param y ??????(0-base) + * @param player ????? + * @return true ????? + * @return false ??????? */ bool is_forbidden_move(int x, int y, int player); /** - * @brief 鐜╁钀藉瓙鎿嶄綔 - * @param x 琛屽潗鏍(0-base) - * @param y 鍒楀潗鏍(0-base) - * @return true 钀藉瓙鎴愬姛 - * @return false 钀藉瓙澶辫触(浣嶇疆鏃犳晥) + * @brief ?????????? + * @param x ??????(0-base) + * @param y ??????(0-base) + * @return true ?????? + * @return false ???????(????????) */ bool player_move(int x, int y, int player); /** - * @brief 璁$畻鐗瑰畾鏂瑰悜涓婅繛缁悓鑹叉瀛愭暟閲 - * @param x 璧峰琛屽潗鏍 - * @param y 璧峰鍒楀潗鏍 - * @param dx 琛屾柟鍚戝閲(-1,0,1) - * @param dy 鍒楁柟鍚戝閲(-1,0,1) - * @param player 鐜╁鏍囪瘑(PLAYER/AI) - * @return DirInfo 鍖呭惈杩炵画妫嬪瓙鏁板拰鏂瑰悜寮鏀剧姸鎬佺殑缁撴瀯浣 + * @brief ??????????????????????????? + * @param x ????????? + * @param y ????????? + * @param dx ??????????(-1,0,1) + * @param dy ??????????(-1,0,1) + * @param player ?????(PLAYER/AI) + * @return DirInfo ??????????????????????????? */ DirInfo count_specific_direction(int x, int y, int dx, int dy, int player); /** - * @brief 妫鏌ョ壒瀹氫綅缃惤瀛愬悗鏄惁褰㈡垚浜旇繛鐝 - * @param x 琛屽潗鏍(0-base) - * @param y 鍒楀潗鏍(0-base) - * @param player 鐜╁鏍囪瘑(PLAYER/AI) - * @return true 褰㈡垚浜旇繛鐝 - * @return false 鏈舰鎴愪簲杩炵彔 + * @brief ???????????????????????????? + * @param x ??????(0-base) + * @param y ??????(0-base) + * @param player ?????(PLAYER/AI) + * @return true ?????????? + * @return false ???????????? */ bool check_win(int x, int y, int player); /** - * @brief 鎮旀鍔熻兘瀹炵幇 - * @return true 鎮旀鎴愬姛 - * @return false 鎮旀澶辫触(姝ユ暟涓嶈冻) - * @note 浼氭挙閿鐜╁鍜孉I鐨勬渶鍚庝竴姝ユ搷浣 + * @brief ?????????? + * @return true ?????? + * @return false ???????(????????) + * @note ????????AI???????????? */ bool return_move(int steps_to_undo); /** - * @brief 澶嶇洏娓告垙杩囩▼ - * 閫愭閲嶇幇娓告垙涓殑鎵鏈夎惤瀛愭楠 + * @brief ??????????? + * ???????????????????????? */ void review_process(int game_mode); /** - * @brief 璇勪及鐜╁鍦ㄦ暣鐩樻灞涓殑琛ㄧ幇 - * @param player 瑕佽瘎浼扮殑鐜╁(PLAYER/AI) - * @return int 鎬诲垎(宸茶冭檻鏂瑰悜閲嶅璁$畻) + * @brief ??????????????????????? + * @param player ??????????(PLAYER/AI) + * @return int ???(???????????????) */ int evaluate_performance(int player); /** - * @brief 璁$畻涓姝ユ鐨勫緱鍒 - * @param x 琛屽潗鏍 - * @param y 鍒楀潗鏍 - * @param player 鐜╁鏍囪瘑 - * @return int 涓姝ユ鐨勫緱鍒 + * @brief ????????????? + * @param x ?????? + * @param y ?????? + * @param player ????? + * @return int ????????? */ int calculate_step_score(int x, int y, int player); /** - * @brief 灏嗗綋鍓嶆父鎴忚褰曚繚瀛樺埌鏂囦欢 - * @param filename 瑕佷繚瀛樼殑鏂囦欢鍚 - * @return int 閿欒鐮: - * 0: 鎴愬姛 - * 1: 鐩綍鍒涘缓澶辫触 - * 2: 鏂囦欢鎵撳紑澶辫触 - * 3: 鏂囦欢鍐欏叆澶辫触 + * @brief ??????????????????? + * @param filename ??????????? + * @return int ??????: + * 0: ??? + * 1: ????????? + * 2: ???????? + * 3: ?????????? */ int save_game_to_file(const char *filename, int game_mode); /** - * @brief 澶勭悊娓告垙缁撴潫鍚庣殑璁板綍淇濆瓨 + * @brief ???????????????????? */ void handle_save_record(int game_mode); /** - * @brief 浠庢枃浠跺姞杞芥父鎴忚褰 - * @param filename 瑕佸姞杞界殑鏂囦欢鍚 - * @return true 鍔犺浇鎴愬姛 - * @return false 鍔犺浇澶辫触 + * @brief ??????????????? + * @param filename ??????????? + * @return true ?????? + * @return false ??????? */ int load_game_from_file(const char *filename);