1. 五子棋HTML版项目概述
五子棋作为中国传统棋类游戏,用纯HTML+CSS+JS实现是一个绝佳的前端练手项目。这个版本不需要任何后端支持,单HTML文件就能运行,适合初学者理解网页三剑客的协作原理。我在实现过程中发现,200行左右代码就能完成核心功能,但要做好用户体验需要处理不少细节。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心功能设计思路
2.1 棋盘渲染方案
采用15x15的table布局最直观:
html复制<table id="board">
<!-- 动态生成15行 -->
<tr>
<!-- 每行15个单元格 -->
<td></td>
</tr>
</table>
用CSS美化棋盘线:
css复制#board {
border: 2px solid #333;
margin: 0 auto;
}
#board td {
width: 30px;
height: 30px;
border: 1px solid #aaa;
text-align: center;
cursor: pointer;
}
2.2 落子逻辑实现
通过事件委托监听点击:
javascript复制document.getElementById('board').addEventListener('click', (e) => {
if (e.target.tagName === 'TD' && !e.target.textContent) {
e.target.textContent = currentPlayer; // '●'或'○'
checkWin();
switchPlayer();
}
});
3. 胜负判定算法
3.1 四方向检测法
从最后落子点向四个方向延伸检测:
javascript复制function checkWin(x, y) {
const directions = [
[1,0], [0,1], [1,1], [1,-1] // 横竖斜方向
];
return directions.some(([dx, dy]) => {
let count = 1;
// 正向检测
count += countSame(x, y, dx, dy);
// 反向检测
count += countSame(x, y, -dx, -dy);
return count >= 5;
});
}
3.2 边界处理技巧
在countSame函数中需要处理棋盘边界:
javascript复制function countSame(x, y, dx, dy) {
let i = 1, count = 0;
while (
x + i*dx >= 0 && x + i*dx < 15 &&
y + i*dy >= 0 && y + i*dy < 15
) {
if (board[y + i*dy][x + i*dx] === currentPlayer) {
count++;
i++;
} else break;
}
return count;
}
4. 完整实现步骤
4.1 初始化棋盘
javascript复制const board = Array(15).fill().map(() => Array(15).fill(''));
let currentPlayer = '●';
function initBoard() {
const table = document.createElement('table');
for (let y = 0; y < 15; y++) {
const tr = document.createElement('tr');
for (let x = 0; x < 15; x++) {
const td = document.createElement('td');
td.dataset.x = x;
td.dataset.y = y;
tr.appendChild(td);
}
table.appendChild(tr);
}
document.body.appendChild(table);
}
4.2 游戏状态管理
javascript复制function resetGame() {
document.querySelectorAll('#board td').forEach(td => {
td.textContent = '';
td.style.backgroundColor = '';
});
board.forEach(row => row.fill(''));
currentPlayer = '●';
document.getElementById('status').textContent = `${currentPlayer}回合`;
}
5. 进阶优化方案
5.1 落子动画效果
使用CSS过渡增强体验:
css复制#board td {
transition: all 0.3s;
}
#board td:hover {
background-color: rgba(0,0,0,0.1);
}
5.2 本地存储存档
javascript复制function saveGame() {
localStorage.setItem('gomoku', JSON.stringify({
board,
currentPlayer
}));
}
function loadGame() {
const saved = localStorage.getItem('gomoku');
if (saved) {
const {board: savedBoard, currentPlayer: savedPlayer} = JSON.parse(saved);
// 恢复棋盘状态...
}
}
6. 常见问题解决
6.1 移动端适配方案
添加viewport meta并调整触摸事件:
html复制<meta name="viewport" content="width=device-width, initial-scale=1.0">
javascript复制board.addEventListener('touchstart', (e) => {
e.preventDefault();
const touch = e.touches[0];
const target = document.elementFromPoint(touch.clientX, touch.clientY);
if (target.tagName === 'TD') {
target.click();
}
});
6.2 性能优化建议
- 使用canvas重绘替代DOM操作
- 实现AI对战使用Web Worker
- 防抖处理高频事件
7. 项目扩展方向
7.1 人机对战实现
简单AI算法示例:
javascript复制function aiMove() {
// 简单策略:随机选择空位
const emptyCells = [];
for (let y = 0; y < 15; y++) {
for (let x = 0; x < 15; x++) {
if (!board[y][x]) emptyCells.push([x,y]);
}
}
if (emptyCells.length) {
const [x,y] = emptyCells[Math.floor(Math.random()*emptyCells.length)];
placePiece(x, y);
}
}
7.2 网络对战功能
使用WebSocket实现:
javascript复制const socket = new WebSocket('wss://yourserver.com/gomoku');
socket.onmessage = (e) => {
const {type, data} = JSON.parse(e.data);
if (type === 'move') {
document.querySelector(`td[data-x="${data.x}"][data-y="${data.y}"]`)
.textContent = data.player;
}
};
