基于HTML的五子棋游戏的设计与实现 - 课题设计
项目简介
这是一个基于HTML5、CSS3和JavaScript开发的经典五子棋游戏,支持双人对战和人机对战两种模式。游戏采用Canvas进行渲染,具有美观的界面和流畅的交互体验。
功能特性
核心功能
- ✅ 双人对战模式:两名玩家在同一设备上轮流落子
- ✅ 人机对战模式:玩家与AI对战,AI采用评分算法进行决策
- ✅ 胜负判定:自动检测横、竖、斜四个方向的连子情况
- ✅ 悔棋功能:支持撤销上一步操作
- ✅ 重新开始:可随时开始新游戏
- ✅ 音效系统:落子和胜利时播放音效
- ✅ 状态显示:实时显示当前玩家、步数和游戏状态
界面特色
- 🎨 渐变色棋盘背景,模拟真实木纹效果
- 🎨 棋子使用渐变和阴影,具有立体感
- 🎨 最后一手棋用红色标记,便于识别
- 🎨 响应式设计,支持不同屏幕尺寸
- 🎨 流畅的动画和交互效果
文件结构
wuziqi/
├── index.html # 游戏主页面
├── style.css # 样式文件
├── game.js # 游戏核心逻辑
└── README.MD # 项目说明文档
使用方法
运行游戏
- 直接双击
index.html文件在浏览器中打开 - 或将项目部署到Web服务器
游戏操作
-
选择游戏模式
- 点击"👥 双人对战"按钮开始双人对战
- 点击"🤖 人机对战"按钮开始与AI对战
-
落子
- 点击棋盘上的交叉点落子
- 黑方先行,双方轮流落子
- 最后一手棋用红色"+"标记
-
游戏控制
- 点击"🔄 重新开始"开始新游戏(需确认)
- 点击"↩️ 悔棋"撤销上一步
- 双人模式:撤销一步
- 人机模式:撤销两步(AI和玩家各一步)
- 点击"🏠 返回菜单"返回主菜单
- 点击音效按钮(🔊/🔇)开关音效
-
胜利条件
- 在横、竖、斜任意方向连成5个同色棋子即获胜
- 棋盘满且无胜负则为平局
界面说明
- 游戏状态卡片:显示当前玩家、游戏模式、游戏状态、当前步数
- 操作按钮卡片:包含所有游戏控制按钮
- 规则卡片:显示游戏规则说明
技术特性
- 画布大小:620×620像素
- 棋盘规格:15×15网格,间距40px,边距30px
- 星位标记:5个关键位置(3,3)、(3,11)、(7,7)、(11,3)、(11,11)
- AI响应延迟:500毫秒
技术实现
前端技术栈
- HTML5:页面结构,包含游戏面板和信息面板
- CSS3:样式设计与动画效果,采用Flexbox布局和响应式设计
- JavaScript (ES6+):游戏逻辑实现,使用ES6类语法
- Canvas API:棋盘绘制和渲染,包括渐变背景、网格、星位和棋子
- Web Audio API:音效系统,落子和胜利时播放音效
项目架构
1. HTML结构
- 容器布局:包含标题区、游戏容器和页脚
- 游戏面板:Canvas画布用于渲染棋盘
- 信息面板:包含游戏状态卡片、操作按钮卡片和规则卡片
- 按钮组件:双人对战、人机对战、重新开始、悔棋、返回菜单、音效开关
2. CSS样式
- 全局样式:使用Microsoft YaHei字体,渐变背景(#667eea到#764ba2)
- 响应式设计:支持900px和600px断点的媒体查询
- 按钮样式:五种渐变色按钮,带悬停和发光效果
- 动画效果:fadeIn动画,卡片渐入效果
- 滚动条样式:自定义webkit滚动条
3. JavaScript核心类
GomokuGame类 - 游戏核心逻辑类
- 配置参数:15x15棋盘,每格40px,边距30px
- 游戏状态:board数组、currentPlayer、gameMode、gameStatus、moveHistory、lastMove、stepCount
- 主要方法:
init()- 初始化游戏startGame(mode)- 开始游戏placePiece(row, col)- 落子checkWin(row, col)- 胜负检查aiMove()- AI落子evaluatePosition(row, col, player)- 位置评估undoMove()- 悔棋draw()- 绘制游戏画面
GameController类 - 游戏控制器类
- 负责初始化UI和绑定事件
- 管理按钮点击事件处理
- 控制游戏流程
核心算法
1. 胜负检查算法
javascript
checkWin(row, col) {
const player = this.board[row][col];
const directions = [
[[0, 1], [0, -1]], // 水平方向
[[1, 0], [-1, 0]], // 垂直方向
[[1, 1], [-1, -1]], // 对角线方向
[[1, -1], [-1, 1]] // 反对角线方向
];
// 遍历四个方向
for (const dir of directions) {
let count = 1;
// 向两个相反方向延伸统计连续同色棋子
for (const [dr, dc] of dir) {
let r = row + dr, c = col + dc;
while (r >= 0 && r < 15 && c >= 0 && c < 15 &&
this.board[r][c] === player) {
count++;
r += dr;
c += dc;
}
}
if (count >= 5) return true; // 连成5子及以上则获胜
}
return false;
}
2. AI评分算法
javascript
aiMove() {
let bestScore = -Infinity;
let bestMove = null;
// 遍历棋盘所有空位
for (let i = 0; i < 15; i++) {
for (let j = 0; j < 15; j++) {
if (this.board[i][j] === 0) {
// 计算进攻分数(AI落子)和防守分数(玩家落子)
const attackScore = this.evaluatePosition(i, j, 2);
const defendScore = this.evaluatePosition(i, j, 1);
// 取最大值作为综合分数
const score = Math.max(attackScore, defendScore);
if (score > bestScore) {
bestScore = score;
bestMove = { row: i, col: j };
}
}
}
}
if (bestMove) this.placePiece(bestMove.row, bestMove.col);
}
// 位置评分规则
getScore(count, blocked) {
if (blocked >= 2) return 0; // 两端都被阻挡,无法成五
switch (count) {
case 4: return blocked === 0 ? 10000 : 5000; // 活四/冲四
case 3: return blocked === 0 ? 1000 : 500; // 活三/眠三
case 2: return blocked === 0 ? 100 : 50; // 活二/眠二
case 1: return blocked === 0 ? 10 : 5; // 活一/眠一
default: return 0;
}
}
3. 悔棋算法
javascript
undoMove() {
if (this.moveHistory.length === 0) return;
if (this.gameMode === 'pvp') {
// 双人模式:撤销最后一步
const lastMove = this.moveHistory.pop();
this.board[lastMove.row][lastMove.col] = 0;
this.currentPlayer = lastMove.player;
this.stepCount--;
} else {
// 人机模式:撤销两步(AI和玩家各一步)
if (this.moveHistory.length >= 2) {
const aiMove = this.moveHistory.pop();
this.board[aiMove.row][aiMove.col] = 0;
const playerMove = this.moveHistory.pop();
this.board[playerMove.row][playerMove.col] = 0;
this.stepCount -= 2;
this.currentPlayer = 1; // 玩家先手
}
}
// 更新最后一步标记并重新绘制
this.lastMove = this.moveHistory.length > 0 ?
this.moveHistory[this.moveHistory.length - 1] : null;
this.draw();
}
数据结构
棋盘数组
javascript
// 15x15二维数组: 0=空, 1=黑, 2=白
const board = [
[0, 0, 0, ..., 0], // 15列
[0, 0, 0, ..., 0],
...
[0, 0, 0, ..., 0] // 15行
];
游戏状态对象
javascript
// GomokuGame类实例属性
{
gridSize: 15, // 棋盘大小
cellSize: 40, // 每格像素
padding: 30, // 边距
canvasSize: 620, // 画布大小:(15-1)*40 + 30*2
board: [[], [], ...], // 棋盘数组
currentPlayer: 1, // 当前玩家: 1=黑, 2=白
gameMode: 'pvp', // 游戏模式: 'pvp'或'pve'
gameStatus: 'waiting', // 游戏状态: 'waiting'/'playing'/'ended'
moveHistory: [], // 历史记录数组
lastMove: {row, col, player}, // 最后一步
stepCount: 0, // 步数
soundEnabled: true // 音效开关
}
历史记录结构
javascript
moveHistory = [
{row: 7, col: 7, player: 1}, // 第一步
{row: 7, col: 8, player: 2}, // 第二步
...
];
浏览器兼容性
- ✅ Chrome 90+
- ✅ Firefox 88+
- ✅ Safari 14+
- ✅ Edge 90+
扩展功能(可进一步开发)
- 难度选择:AI难度分级(简单/中等/困难)
- 在线对战:支持网络对战
- 棋局回放:按步骤回放对局
- 保存/加载:支持保存棋局到本地
- 排行榜:记录玩家胜率统计
- 皮肤更换:支持多种棋盘和棋子样式
- 限时模式:每步棋限时,超时判负
开发时间
- 需求分析与设计文档:1周
- 基础框架搭建:1周
- 核心逻辑实现:1周
- AI算法实现与优化:1周
- UI美化与测试:1周
- 文档完善与答辩准备:1周
性能优化
- Canvas高效渲染:使用Canvas API进行棋盘和棋子绘制,避免频繁DOM操作
- 事件绑定优化:仅在初始化时绑定一次Canvas点击事件
- 音容错处理:音效播放失败不影响游戏运行(try-catch包裹)
- 状态管理:集中管理游戏状态,避免全局变量污染
- 资源清理:游戏结束时自动清理临时数据
- 响应式优化:使用CSS媒体查询适配不同屏幕尺寸
代码规范
- 使用ES6类语法封装游戏逻辑
- 采用驼峰命名法
- 方法功能单一,职责清晰
- 注释详细,便于维护
- HTML结构语义化
- CSS使用BEM风格类命名
许可证
本项目为毕业设计作品,仅供学习和交流使用。
作者
xxx大学电子工程学院自动控制专业五子棋游戏毕业设计小组
注意:本游戏为课题设计项目,AI算法为简化版本,如需更高级的AI效果,可考虑使用Minimax算法或Alpha-Beta剪枝算法进行优化。