基于鸿蒙PC Electron框架技术完成的五子棋游戏 - 技术实现详解
开源鸿蒙五子棋项目摘要: 本项目基于开源鸿蒙平台开发五子棋游戏,支持双人对战与人机对战模式。技术架构采用三层设计(UI层、游戏逻辑层、数据层),核心实现包括15×15棋盘管理、胜负判断算法(四方向检测连续五子)及基于评估函数的AI决策(优先拦截/进攻
·
欢迎加入开源鸿蒙PC社区:
https://harmonypc.csdn.net/
atomgit仓库地址: https://atomgit.com/m0_66062719/aiwuziqi



一、项目概述
五子棋(Gomoku)是一款经典的策略对弈游戏,本应用实现了完整的游戏逻辑,支持双人对战和人机对战模式。游戏使用评估函数算法实现AI对手,提供智能的游戏体验。
1.1 功能定位
| 功能模块 | 核心能力 | 业务价值 |
|---|---|---|
| 游戏引擎 | 棋盘管理、胜负判断 | 核心游戏逻辑 |
| AI对手 | 评估函数决策 | 单人游戏体验 |
| 双人模式 | 轮流落子对战 | 社交娱乐 |
| 统计系统 | 分数和场次统计 | 竞技性激励 |
| 数据持久化 | 游戏数据保存 | 进度延续 |
1.2 技术目标
- 游戏完整性:完整实现五子棋规则
- AI智能:实现合理的AI决策算法
- 用户体验:流畅动画和直观交互
- 跨平台:一次开发,多端运行
二、技术架构设计
2.1 整体架构
┌─────────────────────────────────────────────────────────────┐
│ 表示层 (UI) │
│ 15×15棋盘、玩家信息、计分板、获胜弹窗 │
├─────────────────────────────────────────────────────────────┤
│ 业务逻辑层 │
│ Gomoku类:游戏引擎、AI决策、胜负判断 │
├─────────────────────────────────────────────────────────────┤
│ 数据层 │
│ LocalStorage:分数统计、游戏记录 │
└─────────────────────────────────────────────────────────────┘
2.2 核心类设计
class Gomoku {
constructor() {
this.boardSize = 15; // 15×15棋盘
this.board = []; // 棋盘数据
this.currentPlayer = 'black'; // 当前玩家
this.gameActive = true; // 游戏状态
this.isVsAI = false; // 是否人机对战
this.aiPlayer = 'white'; // AI玩家
this.humanPlayer = 'black'; // 人类玩家
this.moveHistory = []; // 落子历史
this.lastMove = null; // 最后一步
this.winningCells = []; // 获胜棋子
}
}
三、核心代码实现
3.1 棋盘初始化
createBoard() {
const boardElement = document.getElementById('board');
boardElement.innerHTML = '';
this.board = [];
for (let row = 0; row < this.boardSize; row++) {
this.board[row] = [];
for (let col = 0; col < this.boardSize; col++) {
this.board[row][col] = null;
const cell = document.createElement('div');
cell.className = 'cell';
cell.dataset.row = row;
cell.dataset.col = col;
// 添加星位标记
if (this.isStarPosition(row, col)) {
cell.classList.add('star');
}
boardElement.appendChild(cell);
}
}
}
棋盘结构:
- 15×15共225个格子
- 每个格子存储当前状态(null/black/white)
- 星位标记用于视觉参考
3.2 落子逻辑
makeMove(row, col) {
if (!this.gameActive || this.board[row][col] !== null) {
return;
}
// 检查是否是人机模式下的AI回合
if (this.isVsAI && this.currentPlayer === this.aiPlayer) {
return;
}
this.placeStone(row, col, this.currentPlayer);
if (this.checkWin(row, col)) {
this.handleWin();
} else if (this.checkDraw()) {
this.handleDraw();
} else {
this.switchPlayer();
// AI回合
if (this.isVsAI && this.currentPlayer === this.aiPlayer && this.gameActive) {
setTimeout(() => this.aiMove(), 300);
}
}
}
游戏流程:
- 验证落子合法性
- 放置棋子
- 检查胜负
- 切换玩家或触发AI
3.3 胜负判断
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 [dir1, dir2] of directions) {
let count = 1;
const cells = [[row, col]];
// 方向1
let r = row + dir1[0];
let c = col + dir1[1];
while (r >= 0 && r < this.boardSize && c >= 0 && c < this.boardSize && this.board[r][c] === player) {
count++;
cells.push([r, c]);
r += dir1[0];
c += dir1[1];
}
// 方向2
r = row + dir2[0];
c = col + dir2[1];
while (r >= 0 && r < this.boardSize && c >= 0 && c < this.boardSize && this.board[r][c] === player) {
count++;
cells.push([r, c]);
r += dir2[0];
c += dir2[1];
}
if (count >= 5) {
this.winningCells = cells;
return true;
}
}
return false;
}
判断逻辑:
- 检查四个方向(横、竖、两条对角线)
- 从当前位置向两个方向延伸
- 统计连续相同棋子数量
- 达到5个即获胜
四、AI算法实现
4.1 AI决策流程
findBestMove() {
// 首先检查是否有必胜位置
const winMove = this.findWinningMove(this.aiPlayer);
if (winMove) return winMove;
// 检查是否需要阻止对手获胜
const blockMove = this.findWinningMove(this.humanPlayer);
if (blockMove) return blockMove;
// 使用评估函数寻找最佳位置
let bestScore = -Infinity;
let bestMove = null;
const candidates = this.getCandidateMoves();
for (const { row, col } of candidates) {
const score = this.evaluatePosition(row, col);
if (score > bestScore) {
bestScore = score;
bestMove = { row, col };
}
}
return bestMove || this.getRandomMove();
}
决策优先级:
- 必胜检测:优先选择能立即获胜的位置
- 阻止对手:阻止对手即将获胜的位置
- 评估函数:寻找最有利的位置
- 随机选择:无法决策时的兜底方案
4.2 必胜位置检测
findWinningMove(player) {
for (let row = 0; row < this.boardSize; row++) {
for (let col = 0; col < this.boardSize; col++) {
if (this.board[row][col] === null) {
this.board[row][col] = player;
const wins = this.checkWin(row, col);
this.board[row][col] = null;
if (wins) {
return { row, col };
}
}
}
}
return null;
}
检测方法:
- 遍历所有空位
- 模拟落子
- 检查是否获胜
- 恢复棋盘状态
4.3 位置评估函数
evaluatePosition(row, col) {
let score = 0;
// 位置权重(中心位置更好)
const centerRow = this.boardSize / 2;
const centerCol = this.boardSize / 2;
const distanceFromCenter = Math.abs(row - centerRow) + Math.abs(col - centerCol);
score += (this.boardSize - distanceFromCenter) * 2;
// 评估各个方向的连子情况
const directions = [
[0, 1], // 横向
[1, 0], // 纵向
[1, 1], // 主对角线
[1, -1] // 副对角线
];
for (const [dr, dc] of directions) {
score += this.evaluateDirection(row, col, dr, dc, this.aiPlayer) * 10;
score += this.evaluateDirection(row, col, dr, dc, this.humanPlayer) * 8;
}
return score;
}
评估因素:
- 位置权重:中心位置更有价值
- 连子评估:评估各方向的连子潜力
- 进攻权重:AI进攻得分权重更高
- 防守权重:阻止对手得分权重稍低
4.4 方向评估
evaluateDirection(row, col, dr, dc, player) {
let score = 0;
let count = 0;
let blocked = 0;
// 正方向和反方向检查
for (let i = 1; i <= 4; i++) {
const r = row + dr * i;
const c = col + dc * i;
if (r < 0 || r >= this.boardSize || c < 0 || c >= this.boardSize) {
blocked++;
break;
}
if (this.board[r][c] === player) {
count++;
} else if (this.board[r][c] === null) {
break;
} else {
blocked++;
break;
}
}
// 评分规则
if (count >= 4) score = 10000;
else if (count === 3 && blocked === 0) score = 1000;
else if (count === 3 && blocked === 1) score = 100;
else if (count === 2 && blocked === 0) score = 50;
else if (count === 2 && blocked === 1) score = 10;
else if (count === 1 && blocked === 0) score = 5;
return score;
}
评分规则详解:
| 情况 | 描述 | 分数 | 战略意义 |
|---|---|---|---|
| 四连 | 活四或眠四 | 10000 | 必胜位置 |
| 活三 | 两端开放的三连 | 1000 | 极具威胁 |
| 眠三 | 一端被封的三连 | 100 | 有一定威胁 |
| 活二 | 两端开放的二连 | 50 | 发展潜力 |
| 眠二 | 一端被封的二连 | 10 | 有限潜力 |
| 活一 | 两端开放的一连 | 5 | 基础发展 |
五、界面设计
5.1 木质棋盘主题
.board {
display: grid;
grid-template-columns: repeat(15, 1fr);
background: linear-gradient(135deg, #d4a574 0%, #c4956a 50%, #b4855a 100%);
border-radius: 10px;
padding: 15px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
}
.board::before {
content: '';
position: absolute;
background:
linear-gradient(to right, rgba(0,0,0,0.3) 1px, transparent 1px),
linear-gradient(to bottom, rgba(0,0,0,0.3) 1px, transparent 1px);
background-size: calc(100% / 14) calc(100% / 14);
}
视觉效果:
- 仿真木纹渐变背景
- CSS网格绘制棋盘线
- 立体阴影效果
5.2 立体棋子效果
.stone.black {
background: radial-gradient(circle at 30% 30%, #4a4a4a, #1a1a1a);
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.5);
}
.stone.white {
background: radial-gradient(circle at 30% 30%, #ffffff, #d0d0d0);
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
}
棋子设计:
- 径向渐变模拟立体感
- 光源位于左上方(30% 30%)
- 阴影增强立体效果
5.3 获胜动画
.stone.win-stone {
animation: winPulse 0.5s ease-in-out infinite;
}
@keyframes winPulse {
0%, 100% {
box-shadow: 0 0 0 3px #ef4444;
}
50% {
box-shadow: 0 0 0 6px #ef4444;
}
}
六、数据持久化
6.1 LocalStorage使用
loadStats() {
const saved = localStorage.getItem('gomokuStats');
if (saved) {
const data = JSON.parse(saved);
this.scores = data.scores || this.scores;
this.stats = data.stats || this.stats;
}
}
saveStats() {
const data = {
scores: this.scores,
stats: this.stats
};
localStorage.setItem('gomokuStats', JSON.stringify(data));
}
存储数据结构:
{
scores: { black: 5, white: 3 },
stats: {
totalGames: 10,
blackWins: 5,
whiteWins: 3,
drawGames: 2
}
}
七、功能模块详解
7.1 撤销功能
undoMove() {
if (this.moveHistory.length === 0 || !this.gameActive) {
return;
}
// 人机模式下撤销两步
const undoCount = this.isVsAI ? 2 : 1;
for (let i = 0; i < undoCount && this.moveHistory.length > 0; i++) {
const lastMove = this.moveHistory.pop();
this.board[lastMove.row][lastMove.col] = null;
}
this.updateBoardUI();
this.updateUI();
}
撤销逻辑:
- 双人模式:撤销一步
- 人机模式:撤销两步(人类和AI各一步)
- 保持游戏公平性
7.2 模式切换
toggleMode() {
this.isVsAI = !this.isVsAI;
const btn = document.getElementById('toggleModeBtn');
btn.textContent = this.isVsAI ? '👥 双人对战' : '🤖 人机对战';
// 更新白方显示
const playerWhite = document.getElementById('playerWhite');
const whiteName = playerWhite.querySelector('.player-name');
whiteName.textContent = this.isVsAI ? 'AI' : '白方';
this.newGame();
}
八、AI算法优化建议
8.1 Minimax算法
当前实现使用评估函数,可以升级为Minimax算法:
minimax(board, depth, isMaximizing, alpha, beta) {
if (depth === 0 || this.isTerminal(board)) {
return this.evaluateBoard(board);
}
if (isMaximizing) {
let maxScore = -Infinity;
for (const move of this.getMoves(board)) {
const score = this.minimax(this.applyMove(board, move), depth - 1, false, alpha, beta);
maxScore = Math.max(maxScore, score);
alpha = Math.max(alpha, score);
if (beta <= alpha) break;
}
return maxScore;
}
// ...
}
8.2 剪枝策略
// Alpha-Beta剪枝减少搜索量
if (beta <= alpha) break;
8.3 候选位置优化
getCandidateMoves() {
const candidates = [];
const range = 2;
for (let row = 0; row < this.boardSize; row++) {
for (let col = 0; col < this.boardSize; col++) {
if (this.board[row][col] === null) {
// 只考虑周围有棋子的位置
let hasNeighbor = false;
for (let dr = -range; dr <= range; dr++) {
for (let dc = -range; dc <= range; dc++) {
if (this.board[row + dr]?.[col + dc] !== null) {
hasNeighbor = true;
}
}
}
if (hasNeighbor) candidates.push({ row, col });
}
}
}
return candidates;
}
九、总结
9.1 技术成果
成功实现了一个完整的五子棋游戏,包含:
- 游戏引擎:完整的15×15棋盘管理
- AI对手:基于评估函数的智能决策
- 双人模式:本地双人对战
- 撤销功能:支持悔棋操作
- 统计系统:分数和场次统计
- 数据持久化:LocalStorage保存
- 动画效果:流畅的视觉反馈
9.2 技术价值
- 算法学习:实践评估函数算法
- 游戏设计:完整的游戏状态管理
- 用户体验:流畅的交互和动画
9.3 未来展望
后续可扩展功能:
- Minimax算法升级
- 难度级别调整
- 游戏历史记录回放
- 在线多人对战
- 禁手规则(职业规则)
项目地址:electron-openharmony-vue3
作者:Web Developer
版本:v1.0.0
更新时间:2026年6月
更多推荐



所有评论(0)