我用华为云码道从0到1做出一款战棋游戏:一个周末的完整实战记录
一键开通华为云码道 CodeArts 代码智能体:https://developer.huaweicloud.com/codeartsco.html?source=dmzntgwatomgit1&sourcead=dmzntgwatomgithd
作品介绍: 本文记录了作者仅用6分37秒,通过华为云码道CodeArts代码智能体,从零开发出一款可玩的中世纪奇幻回合制战棋小游戏的全过程。借助AI精准需求澄清、分轮交付可运行版本、自动生成测试用例及代码修复能力,
作者以“产品经理+验收员”角色高效完成《战棋游戏-王国之战》核心功能开发:BFS寻路、兵种克制、地形加成、敌方智能评分与双人对战。项目最终实现完整交互逻辑与视觉呈现,形成了可以直接玩的游戏应用,验证了AI辅助编程在复杂游戏开发中的巨大潜力。
一、起因:一个还没想清楚就开干的想法
我是写 Java 和 Go 出身的,前端属于"能跑就行"水平。某个周末下午重温《火焰纹章》,突然就较上劲了:能不能用纯前端技术,从零搓一个能玩的回合制战棋?
冷静下来想了想,这活儿没那么简单。寻路要做移动范围计算,兵种克制和地形加成牵一发动全身,敌方 AI 得有个像样的决策逻辑,还有选中、移动、攻击、取消这一整套交互。纯手写,保守估计两三天,而且大概率写到一半就失去耐心。
正好手头在用华为云码道 CodeArts 代码智能体,我决定把整个开发过程交给它,自己只当"产品经理 + 验收员",顺便看看 AI 辅助编程到底能顶到什么程度。这篇文章就是那次实验的完整记录——包括踩的坑。
它使用起来非常简单,在Atomgit的工作台直接集成了,只需要登录就可以用了。

二、第一轮对话:它没急着写代码
我的需求就一句话:“帮我开发一个战棋小游戏,角色按回合制行动,发我可以玩的网页版。”

说实话,我本来做好了它直接糊一坨代码过来的心理准备。结果它先反问了我三个问题:
- 题材:中世纪奇幻、现代军事,还是科幻机甲?
- 玩法深度:休闲简化版、经典战棋(兵种克制 + 地形加成),还是带技能装备的深度策略版?
- 对战模式:单人打 AI,还是双人同屏?
这三个问题问得挺内行。战棋游戏 “做多重” 完全取决于这几个选择,选错了后面全是返工。我选了中世纪奇幻 + 经典战棋 + 单人打 AI——经典款规则完整又不过分复杂,适合当第一版。
需求敲定后它直接甩出一份游戏设计文档,两块内容我印象很深:
兵种克制闭环:剑士克枪兵、枪兵克骑士、骑士克剑士,弓手克法师,法师打骑士还几乎无视防御。有闭环就有博弈,这比"数值堆高就赢"有意思得多。
地形效果表:
| 地形 | 防御加成 | 移动消耗 | 特殊效果 |
|---|---|---|---|
| 平原 | 0 | 1 | 无 |
| 森林 | +2 | 2 | 适合驻守 |
| 山地 | +3 | 3 | 最佳防御地形 |
| 河流 | 0 | 4 | 行动艰难 |
| 村庄 | +1 | 1 | 每回合回血 |
核心操作循环也在这轮定死了:选中单位 → 移动 → 攻击/治疗 → 待机 → 结束回合。后面四轮迭代,全是在这个骨架上长肉。
三、三轮迭代,每个版本都拿得出手
这是我这次体验里最满意的一点:它不是一口气糊完,而是每轮交付一个能玩的版本。
v1 基础版:12×8 棋盘、六大近战远程兵种、BFS 寻路、战斗判定、敌方 AI,单文件 HTML,浏览器打开就能玩。
v2:加了治疗师(不能攻击、能奶人、AI 会优先治疗残血队友)、三档难度、三张地图(河谷对峙、幽暗密林、乱石峡谷)。
v3:六个主动技能 + 经验升级系统。剑士疾风连斩、骑士铁骑冲锋、法师炎爆术这些技能一一配齐,击杀和受击都攒经验,升级加攻防血——火焰纹章那个味儿一下就出来了。
v4:本地双人对战。蓝红双方轮流执军,右侧面板和战报跟着阵营切换。

最后 v4 交付时,我特意留意了一眼运行数据:整轮任务耗时 6 分 37 秒,输入 477.6K token,输出 2.6K token,5 个子任务全部完成。附带的验证结果里,JS 语法校验通过,无头浏览器实机截图确认双人模式 UI 正常。这个"自己验证完再交付"的习惯,比代码本身更让我安心。

四、关键代码拆解
单文件 HTML,3000 多行,挑三段核心逻辑说说。
4.1 BFS 寻路
战棋的灵魂。计算单位在移动力范围内可达的所有格子,地形不同耗的移动力不同,被占的格子直接跳过:
function bfsReach(unit) {
const res = new Map();
res.set(key(unit.c, unit.r), { cost: 0, prev: null });
const q = [{ c: unit.c, r: unit.r, cost: 0 }];
while (q.length) {
const cur = q.shift();
for (const [dc, dr] of DIRS) {
const nc = cur.c + dc, nr = cur.r + dr;
if (!inB(nc, nr)) continue;
if (unitAt(nc, nr)) continue; // 有单位占据
const k = key(nc, nr);
const cost = cur.cost + moveCost(unit.type, nc, nr);
if (cost > unit.mov) continue; // 超出移动力,剪枝
if (!res.has(k) || cost < res.get(k).cost) {
res.set(k, { cost, prev: [cur.c, cur.r] });
q.push({ c: nc, r: nr, cost });
}
}
}
return res;
}
值得一提的是骑士的 moveCost 特判——马进不了山地森林,这类"规则写在算法里"的细节,比界面华丽更能体现战棋的味道。
4.2 伤害计算
一条公式串起克制、暴击、地形、魔法四大要素:
function calcDamage(atk, def, opts) {
opts = opts || {};
const adv = atk.adv.includes(def.type);
const critChance = 0.08 + (atk.type === 'sword' || atk.type === 'knight' ? 0.04 : 0);
const crit = !opts.noCrit && Math.random() < critChance;
let defVal = def.def + (opts.ignoreTerrain ? 0 : TERRAIN[MAP[def.r][def.c]].def);
if (atk.magic) defVal = Math.floor(defVal * 0.3); // 魔法几乎无视防御
let dmg = atk.atk * (adv ? 1.5 : 1) * rand(0.85, 1.15) * (opts.mult || 1) - defVal;
if (atk.side === 'enemy') dmg *= DIFFICULTY[diffKey].aiDmg;
dmg = Math.max(1, Math.round(dmg));
if (crit) dmg = Math.round(dmg * 1.5);
return { dmg, crit, adv: adv && !atk.magic };
}
±15% 的随机波动是故意的。战棋如果每刀伤害都一样,玩家很快就算成 Excel 了;留一点运气成分,"残血反杀"的戏码才有登场机会。
4.3 敌方 AI:评分 + 阈值
AI 每回合遍历所有可达格子和可攻击目标,按"伤害 + 击杀奖励 + 暴击加成"打分,挑分最高的下手:
const kills = (t.hp <= d.dmg ? diff.killBonus : 0);
const score = d.dmg + kills + (d.crit ? 8 : 0);
困难难度下还有个小心机:只有当技能评分超过普通攻击评分的 85% 时才放技能。不然 AI 会无脑开大,打着像挂机。这条阈值是我在测试里被 AI 连续三回合放技能磨死后,让它自己调的——调完确实像个人了。
五、跑起来的样子

开始菜单把规则讲得很清楚:兵种克制、地形效果、治疗师定位,新玩家不用翻文档。模式、难度、地图三组选择一目了然。

进入战斗就是经典的战棋布局:左侧 12×8 棋盘,森林、河流、村庄都有独立手绘风格的贴图;右侧是部队列表、血条、经验条和战报日志。蓝方六人守左,红方压右,中间一条河把战场劈成两半——想过河,就得付出每格 4 点移动力代价。
选中单位是第一个要舒服的交互。点一下剑士,可达格子全部染蓝,一目了然:

技能瞄准也有独立状态。点「技能」按钮后,面板会给出技能说明和操作提示,右键随时反悔:

这套"选中 → 高亮 → 确认 → 可取消"的交互节奏,是我玩过所有战棋游戏里最花时间打磨的部分,码道一次就给对了。
六、实测数据:AI 辅助到底省了多少
按我自己手动开发同规模项目的经验,做了个对照估算:
| 环节 | 纯手动开发 | 华为云码道辅助 | 我的感受 |
|---|---|---|---|
| 需求澄清 | 自己脑补,写一半推翻重来 | 1 轮对话三个问题定清楚 | 省的不是时间,是心态 |
| 架构设计 | 2~3 小时画图写文档 | 10 分钟出 GDD | 文档质量够直接当博客素材 |
| 编码实现 | 800~1200 行,写一天 | 3000+ 行,单轮 6 分 37 秒 | 量级差距,代码还能跑 |
| 测试验证 | 手写用例 2~3 小时 | 22 项断言自动生成,100% 通过 | 覆盖度比我自己写的高 |
| Bug 修复 | 逐行排查 | 描述现象,AI 定位修复 | 它自己犯的错它自己改最快 |
| 总计 | 约 8~10 小时 | 约 3 小时(含人工验收) | 一半以上的时间省下来了 |
要说最大的变化,不是"代码写得快了",而是注意力不再被打断。以前写前端是写两行代码、查一次文档、调一次样式,来回横跳;现在这些全压缩在一个对话流里,我只负责想清楚"要什么"和验收"拿到什么"。
当然,那 3 小时里我并不闲着。每个版本我都会真的打开玩几局——AI 说测试通过是一回事,你自己被敌方 AI 堵在河谷里打是另一回事。
七、真人实测:我替你们先打了一局
为了写这篇博客,我特意用普通难度完整跑了一局,把过程截了下来。以下都是真实对局画面,不含摆拍。
开局双方隔河对峙。我按教科书打法推进:剑士顶前面,弓手和法师跟在后排,治疗师缩在最后。红方则不紧不慢地压过来:

先看一眼右上角:蓝 5,红 6。是的,我的法师已经在第一回合的交换里没了——它贪了一格输出位,被红方弓手和法师集火,两轮齐射送走,连技能都没来得及放。AI 懂得抓脆皮,这给我敲了第一记警钟。
第二回合,我方弓手摸到 (6,1),红方枪兵近在咫尺。选中、进射程、开火——

这一箭打掉了红方枪兵一小截血。有意思的是下一回合:红方治疗师居然摸上来,把枪兵的血奶了回去。战报里那条「红方治疗师为「枪兵」恢复了生命」,让我盯着屏幕愣了两秒——我根本没告诉过它"残血单位要优先保护"这种策略,它自己会。
而我的弓手没这么好命,被红方追着打到剩 2/20,蜷在河边动弹不得:


打到第三回合我就停手了——再打下去是给 AI 送人头。但短短三回合已经足够说明问题:普通难度的 AI 会抢地形、集火脆皮、奶残血,你能在它的走位里读出"意图"两个字。这就是前面那个 85% 技能阈值和评分模型在实际对局里的样子。
八、主要BUG解决
顺利的部分说得够多了,说说翻车的。
一:截图里藏着原始 HTML 标签。 写这篇博客重玩截图时,我在开局截图的角落发现一行奇怪的文字:第 1 回合 · <b class=''>蓝方</b>行动——回合开始的 toast 提示用了 textContent 渲染,代码里却塞了 HTML 标签,标签原样糊在了玩家脸上。这个问题之前所有自动化测试都没报错,因为语法没错、逻辑没错,纯粹是"人和机器对这段文字的理解不一致"。修复只要一行:把标签从 toast 文案里去掉。教训:视觉回归测试测不出"文案不该有标签"这种事,人类的眼睛仍是最后一道工序。
二:沙盒测试里的 await 不可全信。 22 项断言在 Node.js vm 沙盒里全绿,但循环内的异步行为和真实浏览器有细微差异。最后的解法很朴素:每个测试跑之前重置一遍游戏状态。教训:沙盒全绿只是及格线,真机才是考场。
三:Git 凭据过期。 往 AtomGit 推代码时,之前保存的个人 Token 失效了,折腾了一会儿才推上去。教训:正经项目老老实实用部署密钥,别拿个人 Token 凑合。
九、想自己改?速查手册
代码全部表驱动,二次开发门槛不高:
加新兵种:在 TYPES 里加属性定义,SKILLS 里加技能,ICONS 里配个图标就行,核心逻辑一行不用动。
加新地图:往 MAPS 数组里塞一个对象,地形用数字表示——0 平原、1 森林、2 山地、3 河流、4 村庄、5 岩石。
调难度:DIFFICULTY 里三个参数管到底:敌方人数(5/6/7)、AI 伤害系数(0.78/1.0/1.18)、治疗概率(40%/80%/100%)。
再往后,我打算加音效开关和关卡编辑器,远程联机(WebSocket)也在清单上,做完再写一篇。
总结
一个周末,一句话需求,四轮迭代,一款有兵种克制、地形博弈、技能、养成和双人模式的战棋游戏。搁去年,我不敢想这事能在一个周末内以"可玩"的完成度交付。
用下来我对 AI 辅助编程的理解是:它不是替你写代码的打字员,而是把"想"和"做"之间的距离压短了。需求澄清阶段它会逼你把模糊的想法说清楚,实现阶段它把重复劳动全包了,验收阶段它还自带测试和截图。人真正要做的,只剩两件事——想清楚要什么,以及保持怀疑。
对了,如果你也做了什么,别只让它躺在本地。传上 AtomGit,写篇博客,哪怕被人指出十个 bug,也比无人问津强。
开源仓库:https://atomgit.com/wdracky/walkchess
在线体验:浏览器直接打开 games/tactics/index.html,零依赖,即开即玩。
华为云码道:https://developer.huaweicloud.com/codeartsco.html?source=dmzntgwatomgit1&sourcead=dmzntgwatomgithd
本文为原创内容,首发 CSDN。转载请注明出处。
更多推荐


所有评论(0)