game/.zcode/plans/plan-sess_15c8eda4-d9a9-450...

3.9 KiB
Raw Blame History

五子棋网页版 · 最小可玩版本计划

目标

15×15 棋盘网页五子棋:双人对战 + 打分法人机对战,双击 index.html 即可游玩,零依赖零构建。架构上为后续增强(Minimax、悔棋、难度分级)预留接口。

文件结构

D:\五子棋\
├── index.html          # 页面结构,普通 <script> 标签按序引入(file:// 直开兼容)
├── css\style.css       # 布局与控件样式(左侧棋盘 + 右侧控制面板)
├── js\
│   ├── engine.js       # 规则引擎:棋盘状态、落子校验、五连判定、历史记录(纯逻辑,无 DOM)
│   ├── ai.js           # 打分法 AI(纯逻辑)
│   ├── renderer.js     # Canvas 绘制:棋盘、棋子、落子预览、最后一手标记、获胜连线
│   ├── ui.js           # 交互控制:点击落子、模式切换、状态栏
│   └── main.js         # 入口,组装各模块
└── tests\
    ├── engine.test.js  # 规则引擎测试
    └── ai.test.js      # AI 行为测试

跨环境模块写法:engine.js / ai.js 采用轻量 UMD 模式——浏览器中挂到 window.GomokuEngine / window.GomokuAI,Node 中走 module.exports,同一份代码两处可用。

模块设计

1. 规则引擎 engine.js

  • createGame() 返回游戏对象:board(15×15,0空/1黑/2白)、currentPlayer、moveHistory、winner、gameOver
  • place(x, y):校验(界内、空位、未结束)→ 落子 → 从该点向 4 个方向数连子(≥5 即胜,无禁手自由规则,长连也算胜)→ 切换行棋方
  • checkWinAt(x, y) 返回获胜五连的坐标数组(供 UI 高亮)
  • 棋盘下满为平局
  • 内部保留 moveHistory 栈,为后续悔棋功能预留

2. 打分法 AI ai.js

  • nextMove(game) 返回 {x, y}
  • 候选点生成:仅取已有棋子周围 2 格内的空位(空盘则直接下天元)
  • 对每个候选点,沿 4 个方向计算「AI 落此处的进攻分」与「对手落此处的防守分」,按棋形打分表计分:连五 1000000 / 活四 100000 / 冲四 10000 / 活三 8000 / 眠三 500 / 活二 400 / 眠二 50
  • 总分 = 进攻分 + 防守分 × 0.9(自动实现"能赢先赢 > 挡对方活四 > 自己做活三"的优先级),取最高分点,并列时随机取一

3. 渲染 renderer.js

  • Canvas 绘制:木纹色底、网格线、5 个星位点、径向渐变立体棋子、最后一手红点标记
  • 鼠标悬停显示半透明落子预览
  • 获胜时在五连棋子上绘制高亮连线
  • 按 devicePixelRatio 缩放保证清晰度

4. 交互 ui.js / main.js

  • 模式选择:双人对战 / 人机对战;人机模式下可选执黑(先手)或执白(后手)
  • 状态栏:轮到黑方/白方 → 获胜方/平局宣告
  • 「新对局」按钮;AI 落子加约 300ms 延迟(观感自然且让界面先渲染)
  • 对局结束或轮到 AI 时禁止点击
  • 界面文案为中文

实施步骤

  1. 搭建 index.html + style.css 骨架(布局与控件)
  2. 实现 engine.js + 编写并跑通 engine.test.js
  3. 实现 renderer.js + 点击落子,双人模式完整可玩
  4. 实现 ai.js + 接入人机模式,跑通 ai.test.js
  5. 状态栏、新对局、悬停预览等细节打磨,浏览器里实际对弈验证两条路径(双人五连胜负判定、人机 AI 应手)

测试与验证

  • node --test tests/(Node ≥18 自带 runner,零依赖):4 方向五连、长连、边界、非法落子、平局、行棋交替;AI 能一手取胜时会取胜、对方冲四时会防守、首着落天元附近
  • 浏览器端实际点击对弈做端到端验证

暂不做(后续迭代)

悔棋按钮、Minimax + Alpha-Beta(难度分级)、Web Worker、音效动画、对局保存复盘、禁手规则、联机对战。引擎的历史栈与 AI 的 nextMove(game) 接口已为这些预留。