欢迎加入开源鸿蒙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);
        }
    }
}

游戏流程

  1. 验证落子合法性
  2. 放置棋子
  3. 检查胜负
  4. 切换玩家或触发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();
}

决策优先级

  1. 必胜检测:优先选择能立即获胜的位置
  2. 阻止对手:阻止对手即将获胜的位置
  3. 评估函数:寻找最有利的位置
  4. 随机选择:无法决策时的兜底方案

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 技术成果

成功实现了一个完整的五子棋游戏,包含:

  1. 游戏引擎:完整的15×15棋盘管理
  2. AI对手:基于评估函数的智能决策
  3. 双人模式:本地双人对战
  4. 撤销功能:支持悔棋操作
  5. 统计系统:分数和场次统计
  6. 数据持久化:LocalStorage保存
  7. 动画效果:流畅的视觉反馈

9.2 技术价值

  • 算法学习:实践评估函数算法
  • 游戏设计:完整的游戏状态管理
  • 用户体验:流畅的交互和动画

9.3 未来展望

后续可扩展功能:

  • Minimax算法升级
  • 难度级别调整
  • 游戏历史记录回放
  • 在线多人对战
  • 禁手规则(职业规则)

项目地址electron-openharmony-vue3

作者:Web Developer

版本:v1.0.0

更新时间:2026年6月

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐