上一篇
html象棋游戏
- 行业动态
- 2025-04-26
- 3041
基于HTML/CSS/JS构建,棋盘布局与棋子交互,规则逻辑实现,支持拖拽操作与响应式
技术栈与工具
- HTML:构建棋盘结构与棋子元素。
- CSS:定义棋盘样式、棋子外观及交互状态(如选中高亮)。
- JavaScript:实现棋子移动逻辑、规则校验、胜负判定及交互功能。
游戏结构设计
棋盘布局
象棋棋盘为10×9的格子,实际可用区域为中间8×9(含楚河汉界),HTML中可通过<table>
模拟棋盘:
<table id="chessboard"> <tr><!-第1行(无棋子) --></tr> <tr><!-红方棋子 --></tr> <!-中间省略行 --> <tr><!-黑方棋子 --></tr> <tr><!-第10行(无棋子) --></tr> </table>
棋子表示
每个棋子可封装为<div>
,包含以下属性:
data-side
:所属方(红/黑)。data-type
:棋子类型(车/马/炮等)。data-id
:唯一标识(如“红车一”)。class
:控制样式(如.piece-red
、.piece-black
)。
核心功能实现
棋盘渲染
通过JavaScript动态生成棋盘与棋子:
const boardData = [ ['', '', '黑车一', '黑马一', '黑象一', '黑士', '黑将', '黑士', '黑象二', '黑马二', '黑车二', ''], // 中间省略行数据 ['', '', '红车一', '红马一', '红象一', '红士', '红帅', '红士', '红象二', '红马二', '红车二', ''] ]; function initBoard() { const board = document.getElementById('chessboard'); boardData.forEach(row => { const tr = document.createElement('tr'); row.forEach(cell => { const td = document.createElement('td'); if (cell) { const piece = document.createElement('div'); piece.className = `piece ${cell.startsWith('红') ? 'piece-red' : 'piece-black'}`; piece.innerText = cell.slice(1); // 提取棋子类型(如“车一”) piece.dataset.side = cell[0]; piece.dataset.type = cell.slice(1, 2); // 简化类型(如“车”) td.appendChild(piece); } tr.appendChild(td); }); board.appendChild(tr); }); }
棋子移动逻辑
- 选中棋子:监听
click
事件,记录当前选中的棋子。 - 移动验证:根据棋子类型与象棋规则校验目标位置合法性。
- 吃子与将军:检测目标位置是否有敌方棋子,并触发“将军”提示。
规则校验示例(车为例)
棋子类型 | 移动规则 | 代码实现 |
---|---|---|
车 | 直线无限格,不能跳过其他棋子 | “`javascript |
function checkMove(piece, target) {
const { row, col } = piece.position;
const { row: tRow, col: tCol } = target.position;
if (row === tRow) { // 横向移动
return checkPathClear(row, col, tCol); // 检查路径是否无阻挡
} else if (col === tCol) { // 纵向移动
return checkPathClear(col, row, tRow);
}
return false;
}
---
常见问题与解答
# 问题1:如何判断棋子移动是否合法?
解答:
1. 路径检查:对于车、炮等直线棋子,需验证路径上是否有其他棋子阻挡。
2. 目标位置检查:
普通移动:目标位置必须为空或己方棋子(如将/帅移动)。
吃子操作:目标位置需为敌方棋子。
3. 特殊规则:如“蹩马腿”(马的移动)、“将帅不见面”等需单独处理。
# 问题2:如何实现胜负判定?
解答:
1. 将死判定:当一方的“将/帅”被敌方棋子攻击且无法逃脱时,判定失败。
2. 困毙判定:若一方无合法移动且未被将死,则判负(较少见)。
3. 代码示例:
```javascript
function checkWin(side) {
const king = getKingPosition(side); // 获取将/帅位置
const enemyPieces = getEnemyPieces(side); // 获取敌方所有棋子
for (const piece of enemyPieces) {
if (canAttack(piece, king)) { // 检查是否被攻击
// 检查是否有逃脱路径
const escapePaths = getEscapePaths(king);
if (escapePaths.length === 0) {
alert(`${side}方被将死,${oppSide(side)}方获胜!`);
return true;
}
}
}
return false;