传统风格的中国象棋网页游戏
# 传统风格的中国象棋网页游戏
> 楚河汉界,将帅相争。本文记录了一款纯前端中国象棋网页版游戏的完整开发过程——从需求分析、技术选型、走棋规则实现,到传统中国风界面设计、部署预览与发布上架的全流程。

## 一、项目背景
中国象棋是中华文化的瑰宝,规则严谨、变化万千。作为一名象棋爱好者,我一直想要一个简洁优雅、开箱即用的网页版象棋——不需要安装 App,不需要注册登录,打开浏览器就能对弈。
于是,我决定自己写一个。
### 需求定义
| 维度 | 要求 |
|------|------|
| 用途 | 网页版中国象棋对弈 |
| 用户 | 象棋玩家 |
| 功能 | 完整走棋规则、悔棋、重开、棋谱记录 |
| 风格 | 传统中国风——木纹棋盘、书法字体、楚河汉界 |
| 技术 | 纯 HTML + CSS + JavaScript,无框架依赖 |
## 二、技术选型
### 为什么不用框架?
中国象棋的核心逻辑是**规则引擎**——给定棋盘状态和一步棋,判断是否合法。这部分逻辑与 UI 无关,纯 JavaScript 就能清晰表达。引入 React/Vue 反而增加了构建复杂度,对于一个两人对弈的棋盘游戏来说属于过度工程。
最终选型:
- **HTML**:页面骨架,一个 Canvas 画棋盘,一个 DOM 层放棋子
- **CSS**:全部样式,包括木纹背景、棋子圆形、古风面板
- **JavaScript**:游戏核心——棋盘状态、走棋规则、交互逻辑
- **部署**:Python `http.server` 一行命令启动
### 文件结构
```
chinese-chess/
├── index.html # 页面结构(60 行)
├── style.css # 传统风格样式(525 行)
├── game.js # 游戏逻辑(679 行)
└── README.md # 项目说明
```
总共约 1260 行代码,没有一行依赖 `npm install`。
## 三、棋盘坐标系设计
中国象棋的棋盘是 **9 列 × 10 行**,这是所有规则的根基。
```
0 1 2 3 4 5 6 7 8 ← x(列)
0 车 马 象 士 将 士 象 马 车
1 . . . . . . . . .
2 . 炮 . . . . . 炮 .
3 卒 . 卒 . 卒 . 卒 . 卒
4 . . . . . . . . . ← 楚河
5 . . . . . . . . . ← 汉界
6 兵 . 兵 . 兵 . 兵 . 兵
7 . 炮 . . . . . 炮 .
8 . . . . . . . . .
9 车 马 相 仕 帅 仕 相 马 车
↑ y(行)
```
坐标系约定:
- `x`:列号,0\~8,从左到右
- `y`:行号,0\~9,从上到下
- **黑方在上**(y: 0\~4),**红方在下**(y: 5\~9)
- **楚河汉界**在 y=4 和 y=5 之间
每个棋子用一个对象表示:
```javascript
{
type: 'king', // 棋种:king/advisor/elephant/chariot/horse/cannon/pawn
side: 'red', // 阵营:red/black
x: 4, // 列坐标
y: 9, // 行坐标
char: '帅' // 显示文字
}
```
棋盘状态就是一个 10×9 的二维数组,每个格子要么是 `null`(空),要么是一个棋子对象。
## 四、走棋规则引擎
这是整个项目的核心,也是最容易出错的部分。中国象棋的规则看似简单,细节却很多。
### 4.1 帅/将——九宫格内直走一步
```javascript
function isValidKingMove(piece, fromX, fromY, toX, toY) {
const palaceXMin = 3, palaceXMax = 5;
const palaceYMin = piece.side === 'red' ? 7 : 0;
const palaceYMax = piece.side === 'red' ? 9 : 2;
if (toX < palaceXMin || toX > palaceXMax || toY < palaceYMin || toY > palaceYMax)
return false;
const dx = Math.abs(toX - fromX);
const dy = Math.abs(toY - fromY);
return (dx + dy === 1);
}
```
### 4.2 马——日字格走,检测蹩马腿
马的走法是"日"字,但如果有棋子挡在马腿位置,就不能走。这是新手最容易忽略的规则。
```javascript
function isValidHorseMove(board, fromX, fromY, toX, toY) {
const dx = toX - fromX;
const dy = toY - fromY;
if (!((Math.abs(dx) === 1 && Math.abs(dy) === 2) ||
(Math.abs(dx) === 2 && Math.abs(dy) === 1)))
return false;
// 蹩马腿检测
let legX, legY;
if (Math.abs(dx) === 2) {
legX = fromX + dx / 2;
legY = fromY;
} else {
legX = fromX;
legY = fromY + dy / 2;
}
return board[legY][legX] === null;
}
```
### 4.3 炮——直线移动同车,吃子需炮架
炮是最有特色的棋子。不吃子时走法同车(直线无阻挡),吃子时中间必须**恰好有一个棋子**作为炮架。
```javascript
function isValidCannonMove(board, fromX, fromY, toX, toY) {
if (fromX !== toX && fromY !== toY) return false;
const target = board[toY][toX];
const count = countPiecesBetween(board, fromX, fromY, toX, toY);
if (target === null) {
return count === 0; // 不吃子:路径无阻挡
} else {
return count === 1; // 吃子:中间恰好一个炮架
}
}
```
### 4.4 相/象——田字格走,不能过河,检测塞象眼
象走"田"字,不能过河,且田字中心(象眼)不能有棋子。
```javascript
function isValidElephantMove(board, piece, fromX, fromY, toX, toY) {
const dx = Math.abs(toX - fromX);
const dy = Math.abs(toY - fromY);
if (dx !== 2 || dy !== 2) return false;
if (piece.side === 'red' && toY < 5) return false;
if (piece.side === 'black' && toY > 4) return false;
const eyeX = (fromX + toX) / 2;
const eyeY = (fromY + toY) / 2;
return board[eyeY][eyeX] === null;
}
```
### 4.5 飞将检测——帅将不能照面
这是一个全局规则:如果走完一步后,帅和将在同一列且中间无遮挡,这步棋不合法。
```javascript
function isFlyingGeneral(board) {
let kingRed = null, kingBlack = null;
for (let y = 0; y < 10; y++) {
for (let x = 0; x < 9; x++) {
const p = board[y][x];
if (p && p.type === 'king') {
if (p.side === 'red') kingRed = {x, y};
else kingBlack = {x, y};
}
}
}
if (!kingRed || !kingBlack) return false;
if (kingRed.x !== kingBlack.x) return false;
const minY = Math.min(kingRed.y, kingBlack.y);
const maxY = Math.max(kingRed.y, kingBlack.y);
for (let y = minY + 1; y < maxY; y++) {
if (board[y][kingRed.x] !== null) return false;
}
return true;
}
```
### 4.6 将军与将死
- **将军**:走完一步后,检查对方的将/帅是否在己方任意棋子的可吃范围内
- **将死**:对方无论走哪一步都无法解除将军状态
将死判定需要对所有可能的走法进行搜索,是整个规则引擎中计算量最大的部分。
## 五、传统中国风界面设计
### 5.1 配色方案
| 角色 | 颜色 | 用途 |
|------|------|------|
| 中国红 | `#C0392B` | 红方棋子、标题强调 |
| 墨黑 | `#2C3E50` | 黑方棋子、正文文字 |
| 宣纸黄 | `#F5F0E6` | 页面背景 |
| 木纹棕 | `#DEB887` | 棋盘背景、面板装饰 |
| 深棕 | `#8B4513` | 边框、分割线 |
### 5.2 棋盘渲染
棋盘用 **Canvas** 绘制,因为网格线、九宫格斜线、楚河汉界文字都是纯几何图形,Canvas 比 DOM 更高效。
```javascript
function drawBoard(ctx) {
ctx.fillStyle = '#DEB887';
ctx.fillRect(0, 0, boardWidth, boardHeight);
ctx.strokeStyle = '#8B4513';
for (let x = 0; x < 9; x++) {
if (x === 0 || x === 8) {
drawVerticalLine(ctx, x, 0, 9);
} else {
drawVerticalLine(ctx, x, 0, 4);
drawVerticalLine(ctx, x, 5, 9);
}
}
for (let y = 0; y < 10; y++) {
drawHorizontalLine(ctx, 0, 8, y);
}
// 九宫格斜线 + 楚河汉界文字...
}
```
### 5.3 棋子渲染
棋子用 **DOM 元素**(而非 Canvas),因为棋子需要响应点击事件,DOM 的事件处理比 Canvas 的坐标计算更直观。
```css
.piece {
width: 52px;
height: 52px;
border-radius: 50%;
font-family: "KaiTi", "STKaiti", serif;
font-size: 28px;
font-weight: bold;
cursor: pointer;
transition: transform 0.15s;
}
.piece.red {
color: #C0392B;
border: 2px solid #2C3E50;
background: #F9F5EB;
}
.piece.black {
color: #2C3E50;
border: 2px solid #C0392B;
background: #F9F5EB;
}
.piece.selected {
transform: scale(1.15);
box-shadow: 0 0 12px #D4AC0D;
}
```
### 5.4 交互设计
- **选中棋子**:点击己方棋子,高亮显示(放大 + 金色光晕)
- **显示可走位置**:选中后,所有合法目标位置显示绿色圆点标记
- **移动棋子**:点击目标位置,棋子移动,轮次切换
- **吃子**:点击对方棋子位置,对方棋子消失,己方棋子移入
- **非法操作**:点击不合法的目标位置,无反应或提示
### 5.5 侧边面板
侧边面板包含四个区域:
1. **轮次提示**:大字显示"红方走棋"或"黑方走棋",颜色对应
2. **状态消息**:将军、将死等提示信息
3. **控制按钮**:悔棋、重新开始
4. **棋谱记录**:有序列表,每步记录走法
## 六、开发过程
### 6.1 使用 CodeArts 辅助编码
本项目通过华为云 CodeArts 的 ACP(Agent Coding Protocol)服务辅助生成代码。流程如下:
1. **连接 ACP 服务**:通过 `acpx` 客户端连接到 CodeArts 沙箱中的 ACP 服务
2. **发送需求描述**:将完整的需求文档(功能要求 + 界面风格 + 技术要求)发送给 CodeArts
3. **自动生成代码**:CodeArts 自动创建 `index.html`、`style.css`、`game.js` 三个文件
4. **语法验证**:用 `node -c game.js` 检查 JavaScript 语法
5. **启动预览**:`python3 -m http.server 8080` 启动服务
整个代码生成过程约 10 分钟,生成的代码结构清晰、规则实现完整。
### 6.2 代码规模
| 文件 | 行数 | 大小 | 职责 |
|------|------|------|------|
| `index.html` | 60 行 | 2 KB | 页面结构 |
| `style.css` | 525 行 | 11 KB | 传统风格样式 |
| `game.js` | 679 行 | 20 KB | 游戏逻辑 |
| **合计** | **1264 行** | **33 KB** | — |
## 七、部署与预览
### 7.1 本地预览
```bash
python3 -m http.server 8080 --bind 0.0.0.0
```
浏览器访问 `http://localhost:8080` 即可开始对弈。
### 7.2 DevBridge 隧道分享
通过华为云 DevBridge 开发隧道服务,将本地端口暴露为公网可访问地址:
```
https://futity4w-8081.devbridge-s2.hwtunnel.com
```
这样任何人都可以通过这个链接直接访问象棋游戏,无需部署到服务器。隧道默认有效期 72 小时。
## 八、发布到开发者作品展览馆
### 8.1 代码推送
将代码推送到 GitCode 仓库:
```bash
git init
git add -A
git commit -m "中国象棋网页版 - 传统风格界面"
git remote add origin https://gitcode.com/gcw_nfhkuMAb/chinese-chess.git
git push -u origin master
```
### 8.2 发布流程
通过华为云开发者作品展览馆的发布工具,完成以下步骤:
1. **IAM 域信息解析**:获取华为云账号 Domain ID
2. **STS 临时凭证**:生成 900 秒有效的临时凭证,永久 AK/SK 不上传
3. **GitCode OAuth 授权**:扫码登录获取 GitCode access token
4. **创建仓库**:通过 GitCode API 创建 `chinese-chess` 仓库并推送代码
5. **封面图生成**:使用 Playwright 对运行中的应用截图,自动合成 16:9 封面
6. **详情包打包**:将项目说明文档 + 系统架构图打包为 zip
7. **选择活动**:选择"布道师通用产品体验"作为投稿目标
8. **发布上架**:上传封面 + 详情包,完成发布
### 8.3 发布结果
| 项目 | 详情 |
|------|------|
| 作品名称 | 中国象棋 |
| 作品 ID | `0061746d05000000` |
| 展览馆地址 | https://gallery.developer.huaweicloud.com/gallery/0061746d05000000 |
| GitCode 仓库 | https://gitcode.com/gcw_nfhkuMAb/chinese-chess.git |
| 投稿活动 | 布道师通用产品体验 |
| 积分奖励 | 200 积分 |
## 九、系统架构
```
┌─────────────────────────────────────────┐
│ 中国象棋网页应用 │
├─────────────────────────────────────────┤
│ 表现层 (Presentation Layer) │
│ ├── index.html — 页面结构 │
│ └── style.css — 传统风格样式 │
├─────────────────────────────────────────┤
│ 逻辑层 (Logic Layer) — game.js │
│ ├── 棋盘渲染 (Canvas 绘制) │
│ ├── 棋子管理 (DOM 渲染) │
│ ├── 规则引擎 (走法验证) │
│ └── 游戏状态 (轮次/胜负) │
├─────────────────────────────────────────┤
│ 规则引擎详情 │
│ ├── 帅/将 — 九宫格直走 │
│ ├── 仕/士 — 九宫格斜走 │
│ ├── 相/象 — 田字+塞象眼 │
│ ├── 车 — 直线无阻挡 │
│ ├── 马 — 日字+蹩马腿 │
│ ├── 炮 — 直线+炮架 │
│ └── 兵/卒 — 前进+过河 │
├─────────────────────────────────────────┤
│ 服务层 (Service Layer) │
│ ├── Python http.server — 静态文件服务 │
│ └── 端口 8080 — 本地预览 │
└─────────────────────────────────────────┘
```
## 十、总结与反思
### 做对了什么
1. **纯前端方案**:零依赖、零构建,一个 `http.server` 就能跑,部署门槛极低
2. **Canvas + DOM 混合渲染**:棋盘网格用 Canvas(几何图形高效),棋子用 DOM(事件处理直观),各取所长
3. **规则引擎与 UI 分离**:走棋验证函数纯逻辑、无副作用,易于测试和复用
4. **传统风格设计**:木纹、楷书、楚河汉界,视觉上一眼就能认出是中国象棋
### 可以改进的地方
1. **AI 对手**:目前只支持两人对弈,可以加入简单的 AI(如 minimax 搜索)
2. **棋谱导出**:支持导出为标准 PGN 格式,方便复盘
3. **在线对战**:加入 WebSocket 实现远程对弈
4. **移动端适配**:虽然已做响应式,但小屏幕上棋子点击精度可以优化
### 开发感受
中国象棋的规则看似简单,但要完整实现每一个细节——蹩马腿、塞象眼、炮架、飞将、将军、将死——需要非常仔细的逻辑设计。尤其是将死判定,需要搜索所有可能的走法,是整个项目中计算量最大的部分。
传统中国风的界面设计也很有意思。木纹质感、楷书字体、楚河汉界,这些元素不是简单堆砌,而是要和谐统一。配色上用了中国红、墨黑、宣纸黄、木纹棕四色,既古韵盎然,又不失清晰可读。
最后,通过华为云 CodeArts 辅助编码、DevBridge 隧道分享、开发者作品展览馆发布,整个从开发到上架的流程一气呵成,体验顺畅。
---
*项目地址:[GitCode](https://gitcode.com/gcw_nfhkuMAb/chinese-chess.git) | [展览馆](https://gallery.developer.huaweicloud.com/gallery/0061746d05000000)*
- 点赞
- 收藏
- 关注作者
评论(0)