1. HTML五子棋实现思路解析
五子棋作为经典策略游戏,用纯前端技术实现不仅能锻炼编程能力,还能深入理解DOM操作与游戏逻辑的结合。我选择HTML+CSS+JavaScript这个黄金组合来实现,原因有三:零依赖、跨平台、易分享。下面从棋盘绘制到胜负判断,完整拆解实现过程。
1.1 基础HTML结构设计
首先构建最简HTML骨架,注意添加响应式meta标签确保移动端适配:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>纯HTML五子棋</title> <style> /* CSS样式将在这里编写 */ </style> </head> <body> <div id="chessboard"></div> <script> // JavaScript代码将在这里编写 </script> </body> </html>关键点:viewport设置确保移动设备上棋盘不会缩放异常,所有代码内联便于单文件分享
1.2 棋盘生成方案对比
实现棋盘主要有三种方案:
- Canvas绘制:性能最佳但交互复杂
- SVG矢量图:缩放无损但代码量大
- DOM+CSS:最简单直观,适合初学者
我选择方案3,用嵌套div实现15×15网格:
#chessboard { display: grid; grid-template-columns: repeat(15, 30px); grid-template-rows: repeat(15, 30px); background-color: #DCB35C; border: 2px solid #000; } .cell { border: 1px solid #000; position: relative; cursor: pointer; }2. 核心游戏逻辑实现
2.1 落子与状态管理
用二维数组存储棋盘状态,0表示空,1表示黑子,2表示白子:
const board = Array(15).fill().map(() => Array(15).fill(0)); let currentPlayer = 1; // 黑棋先行 function handleClick(e) { const cell = e.target; const row = parseInt(cell.dataset.row); const col = parseInt(cell.dataset.col); if (board[row][col] !== 0) return; board[row][col] = currentPlayer; renderPiece(row, col); if (checkWin(row, col)) { alert(`${currentPlayer === 1 ? '黑棋' : '白棋'}获胜!`); resetGame(); return; } currentPlayer = 3 - currentPlayer; // 切换玩家 }2.2 胜负判定算法
五子棋核心算法是四方向检测,优化后的检查逻辑:
function checkWin(row, col) { const directions = [ [1, 0], // 水平 [0, 1], // 垂直 [1, 1], // 主对角线 [1, -1] // 副对角线 ]; return directions.some(([dx, dy]) => { let count = 1; // 正向检测 for (let i = 1; i <= 4; i++) { const r = row + i * dx; const c = col + i * dy; if (r < 0 || r >= 15 || c < 0 || c >= 15 || board[r][c] !== currentPlayer) break; count++; } // 反向检测 for (let i = 1; i <= 4; i++) { const r = row - i * dx; const c = col - i * dy; if (r < 0 || r >= 15 || c < 0 || c >= 15 || board[r][c] !== currentPlayer) break; count++; } return count >= 5; }); }3. 进阶功能实现
3.1 棋子视觉效果优化
用CSS伪元素实现立体棋子效果:
.piece { position: absolute; width: 24px; height: 24px; border-radius: 50%; top: 3px; left: 3px; box-shadow: 1px 1px 2px rgba(0,0,0,0.5); } .piece.black::after { content: ''; position: absolute; width: 18px; height: 18px; background: radial-gradient(circle at 30% 30%, #666, #000); border-radius: 50%; top: 3px; left: 3px; } .piece.white::after { content: ''; position: absolute; width: 18px; height: 18px; background: radial-gradient(circle at 30% 30%, #fff, #ccc); border-radius: 50%; top: 3px; left: 3px; }3.2 游戏状态持久化
使用localStorage实现断点续玩:
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); board.splice(0, 15, ...savedBoard); currentPlayer = savedPlayer; renderBoard(); } } // 初始化时调用loadGame()4. 性能优化与调试技巧
4.1 事件委托优化
棋盘使用单个事件监听器替代225个独立监听:
document.getElementById('chessboard').addEventListener('click', (e) => { if (e.target.classList.contains('cell')) { handleClick(e); } });4.2 常见问题排查
棋子显示异常:
- 检查z-index确保棋子位于网格上方
- 确认CSS中定位属性(position)设置正确
胜负判断失效:
- 调试时打印棋盘状态数组
- 边界检查要包含等号(<=14而非<15)
移动端点击延迟:
- 添加touchstart事件监听
- 引入fastclick库消除300ms延迟
// 解决移动端点击延迟 document.addEventListener('DOMContentLoaded', () => { FastClick.attach(document.body); }, false);5. 项目扩展方向
5.1 AI对战实现
基于极小化极大算法实现简单AI:
function aiMove() { let bestScore = -Infinity; let move = { row: 0, col: 0 }; // 简单评估函数 for (let i = 0; i < 15; i++) { for (let j = 0; j < 15; j++) { if (board[i][j] === 0) { let score = evaluatePosition(i, j); if (score > bestScore) { bestScore = score; move = { row: i, col: j }; } } } } board[move.row][move.col] = currentPlayer; renderPiece(move.row, move.col); if (checkWin(move.row, move.col)) { alert('AI获胜!'); resetGame(); return; } currentPlayer = 3 - currentPlayer; }5.2 多平台适配方案
Electron打包:
npm init electron-app@latest gomoku --template=webpackPWA离线支持:
- 添加manifest.json
- 注册Service Worker缓存资源
微信小程序移植:
- 将核心逻辑移植到小游戏API
- 使用Canvas重写渲染部分
实际开发中发现,用requestAnimationFrame优化渲染性能后,在低端手机上也能达到60fps流畅运行。对于更复杂的特效,可以引入WebGL渲染,但会大幅增加代码复杂度。