基于JS实现的中国象棋AI系统:多模块协同决策与分析

发布于:2025-08-19 ⋅ 阅读:(12) ⋅ 点赞:(0)

基于JavaScript实现的中国象棋AI系统:多模块协同决策与分析

引言

中国象棋是我国传统文化瑰宝,将其与现代AI技术结合,不仅能够传承传统文化,还能展示AI技术的魅力。本文将详细介绍一个基于JavaScript实现的中国象棋AI系统,该系统采用了多模块协同决策的架构,实现了意图分析、防御策略、进攻策略等多维度的棋局分析功能。

相关资源已经放在 github 上,欢迎star or fork

https://github.com/chenchihwen/chinese-chess-aihttps://github.com/chenchihwen/chinese-chess-ai在线使用

中国象棋对战游戏https://chenchihwen.github.io/chinese-chess-ai/在线无法调用 ollama 本地模型,只能使用人人对战模式

项目亮点

1. 多AI模块协同决策架构

本项目最大的亮点是采用了多AI模块协同决策的架构,包括:

  • 意图分析AI:分析对手的走棋意图和潜在威胁

  • 防御AI:负责评估己方将/帅的安全状况,提供防御建议

  • 进攻AI:寻找进攻机会,如将军或吃掉高价值棋子

  • 主决策引擎:综合各模块分析结果,做出最终决策

这种模块化设计使AI决策过程更加透明,也更符合人类棋手的思考方式。

2. 可视化AI分析结果

项目提供了直观的AI分析结果展示界面,玩家可以清晰地看到:

  • 对手意图分析(包括意图描述、威胁类型和威胁等级)

  • 防御分析(将/帅是否受威胁及防御建议)

  • 进攻分析(是否有将军机会及进攻建议)

  • 最终决策过程

这种透明化的AI决策过程,不仅增强了游戏的趣味性,还具有很好的教学价值。

3. 多层次AI决策机制

系统实现了多层次的AI决策机制:

  • LLM AI:高级AI决策(可选)

  • 传统AI:基于评估函数的中等AI决策

  • 随机走法生成:作为兜底方案

这种多层次的设计确保了AI系统的稳定性和可扩展性。

4. 完整的象棋规则实现

项目实现了完整的中国象棋规则,包括:

  • 各类棋子的走法规则(将/帅、士/仕、象/相、马、车、炮、兵/卒)

  • 特殊规则(如将帅不能照面、象不过河等)

  • 胜负判定(将死、困毙等)

系统架构与逻辑流程

整体架构

项目采用模块化设计,主要包括以下几个核心模块:

  1. 游戏核心模块(game-core.js):负责游戏的基本逻辑和流程控制

  2. 规则引擎模块(game-rules.js):实现象棋规则,判断走法是否合法

  3. AI模块

    • 意图分析模块(intent-analyzer.js)

    • 防御模块(defender.js)

    • 进攻模块(attacker.js)

    • 主决策引擎(main-engine.js)

    • LLM连接器(llm-connector.js)

  4. UI模块:负责游戏界面的渲染和交互

逻辑流程

1. 游戏初始化流程
// 游戏初始化
document.addEventListener('DOMContentLoaded', function() {
    game = new XiangQiGame();
    game.init();
});

游戏初始化时,会创建棋盘、设置初始棋子位置、加载历史数据等。

2. 玩家走棋流程
handleClick(event) {
    // 获取点击位置
    const col = Math.round((x - this.marginX) / this.cellSize);
    const row = Math.round((y - this.marginY) / this.cellSize);
    
    // 处理点击事件
    this.handleSquareClick(col, row);
}
​
handleSquareClick(col, row) {
    const piece = this.board[row][col];
    
    // 如果已选中棋子且点击位置是可行走法,则移动棋子
    if (this.selectedPiece && this.isPossibleMove(col, row)) {
        this.makeMove(this.selectedPiece.col, this.selectedPiece.row, col, row);
        return;
    }
    
    // 如果点击的是自己的棋子,则选中该棋子
    if (piece && this.isPieceOwnedByCurrentPlayer(piece)) {
        this.selectPiece(col, row);
    } else {
        // 否则取消选中
        this.selectedPiece = null;
        this.possibleMoves = [];
        this.drawBoard();
    }
}

玩家点击棋盘时,系统会判断是选择棋子还是移动棋子,并相应地更新游戏状态。

3. AI决策流程

AI决策是本项目的核心,其流程如下:

async aiMove() {
    try {
        // 显示AI分析区域
        const aiAnalysisDiv = document.getElementById('aiAnalysis');
        if (aiAnalysisDiv) {
            aiAnalysisDiv.style.display = 'block';
        }
        
        // 1. 进行意图分析
        let intentAnalysis = { intent: "分析中...", threat: "无威胁", threatLevel: 0 };
        if (this.moveHistory.length > 0) {
            const lastMove = this.moveHistory[this.moveHistory.length - 1];
            const pieceType = lastMove.piece.toLowerCase();
            const pieceName = this.pieceNames[lastMove.piece] || lastMove.piece;
            
            // 分析对手意图
            intentAnalysis = {
                intent: `对手移动了${pieceName},可能在调整阵型`,
                threat: pieceType === 'r' || pieceType === 'c' ? "中等威胁" : "低威胁",
                threatLevel: pieceType === 'r' || pieceType === 'c' ? 2 : 1
            };
        }
        
        // 2. 进行防御分析
        const isInCheck = this.isInCheck(this.currentPlayer);
        const defenseAnalysis = {
            kingInDanger: isInCheck,
            defenseRecommendation: isInCheck ? "将/帅受到威胁,必须立即保护!" : "将/帅暂无威胁"
        };
        
        // 3. 进行进攻分析
        const opponent = this.currentPlayer === 'red' ? 'black' : 'red';
        const opponentInCheck = this.isInCheck(opponent);
        const attackAnalysis = {
            canCheckmate: opponentInCheck,
            attackRecommendation: opponentInCheck ? "可以将军!" : "寻找进攻机会"
        };
        
        // 4. 显示分析结果
        this.displayAnalysisResults(intentAnalysis, defenseAnalysis, attackAnalysis);
        
        // 5. 获取AI走法
        let move = null;
        let finalDecision = "";
        
        // 5.1 尝试使用LLM AI
        if (window.llmAI) {
            try {
                finalDecision += "使用LLM AI生成走法\n";
                move = await window.llmAI.getMove(this.board, this.currentPlayer, this.moveHistory);
                
                if (move && move.from && move.to) {
                    finalDecision += `LLM AI决定从(${move.from.col},${move.from.row})移动到(${move.to.col},${move.to.row})\n`;
                } else {
                    finalDecision += "LLM AI返回了无效的走法,尝试使用传统AI\n";
                    move = null;
                }
            } catch (error) {
                finalDecision += `LLM AI调用失败,尝试使用传统AI\n`;
                move = null;
            }
        } else {
            finalDecision += "LLM AI未加载,使用传统AI\n";
        }
        
        // 5.2 如果LLM失败,使用传统AI
        if (!move) {
            move = this.getBestMove();
            
            if (move && move.from && move.to) {
                finalDecision += `传统AI决定从(${move.from.col},${move.from.row})移动到(${move.to.col},${move.to.row})\n`;
            } else {
                finalDecision += "传统AI返回了无效的走法,尝试生成随机走法\n";
                move = null;
            }
        }
        
        // 5.3 如果所有AI方法都失败,生成随机走法
        if (!move) {
            move = this.generateRandomMove(this.currentPlayer);
            if (move && move.from && move.to) {
                finalDecision += `随机生成走法从(${move.from.col},${move.from.row})移动到(${move.to.col},${move.to.row})\n`;
            }
        }
        
        // 6. 更新最终决策显示
        const finalDecisionDiv = document.getElementById('finalDecision');
        if (finalDecisionDiv) {
            finalDecisionDiv.textContent = finalDecision;
        }
        
        // 7. 执行走法
        if (move && move.from && move.to) {
            this.makeMove(move.from.col, move.from.row, move.to.col, move.to.row);
        } else {
            this.updateStatus('AI无法生成有效走法,请重新开始游戏');
        }
    } catch (error) {
        this.updateStatus('AI移动出错,请重新开始游戏');
    }
}

AI决策流程包括意图分析、防御分析、进攻分析、走法生成和执行等多个步骤,每个步骤都有明确的职责和输出。

4. 棋盘渲染流程
drawBoard() {
    // 清除画布
    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
    
    // 绘制背景
    this.ctx.fillStyle = '#F5DEB3';
    this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
    
    // 绘制网格线
    // ...
    
    // 绘制九宫格对角线
    this.drawPalaceDiagonals();
    
    // 绘制楚河汉界文字
    // ...
    
    // 绘制棋子
    this.drawPieces();
    
    // 绘制高亮
    this.drawHighlights();
}

棋盘渲染包括背景、网格线、九宫格、楚河汉界、棋子等多个元素的绘制,通过Canvas API实现。

核心AI模块详解

1. 意图分析模块

意图分析模块负责分析对手的走棋意图和潜在威胁,其核心逻辑如下:

analyze: function(board, moveHistory, currentPlayer) {
    // 获取对手最后一步走法
    let lastMove = moveHistory[moveHistory.length - 1];
    
    // 分析意图
    let intent = "";
    let threat = "无明确威胁";
    let threatLevel = 0;
    
    // 检查是否接近己方将/帅
    const ownKingPos = this.findKingPosition(board, currentPlayer);
    if (ownKingPos) {
        const distToKing = Math.abs(lastMove.to.col - ownKingPos.col) + 
                          Math.abs(lastMove.to.row - ownKingPos.row);
        
        if (distToKing <= 2) {
            intent = `对手${pieceName}接近我方${currentPlayer === 'red' ? '帅' : '将'},可能准备将军`;
            threat = "将军威胁";
            threatLevel = 3;
        } else if (distToKing <= 4) {
            intent = `对手${pieceName}向我方${currentPlayer === 'red' ? '帅' : '将'}方向移动,需要警惕`;
            threat = "潜在将军威胁";
            threatLevel = 2;
        }
    }
    
    // 如果没有检测到将军威胁,分析其他可能的意图
    if (threatLevel === 0) {
        // 检查是否是高价值棋子移动
        if (['r', 'n', 'c'].includes(pieceType)) {
            intent = `对手移动了高价值${pieceName},可能在准备进攻或加强控制`;
            threat = "战术部署";
            threatLevel = 1;
        } 
        // 检查是否是过河的兵/卒
        else if (pieceType === 'p') {
            const isOverRiver = (opponentPlayer === 'red' && lastMove.to.row < 5) || 
                               (opponentPlayer === 'black' && lastMove.to.row > 4);
            if (isOverRiver) {
                intent = `对手${pieceName}已过河,增加了攻击面`;
                threat = "增加攻击面";
                threatLevel = 1;
            } else {
                intent = `对手移动了${pieceName},可能在调整阵型`;
                threat = "阵型调整";
                threatLevel = 0;
            }
        } else {
            intent = `对手移动了${pieceName},可能在调整防御或准备后续行动`;
            threat = "一般行动";
            threatLevel = 0;
        }
    }
    
    return {
        intent: intent,
        threat: threat,
        threatLevel: threatLevel,
        lastMove: lastMove
    };
}

2. 防御模块

防御模块负责评估己方将/帅的安全状况,提供防御建议:

analyze: function(board, currentPlayer) {
    // 找到己方将/帅位置
    let ownKingPos = null;
    for (let row = 0; row < 10; row++) {
        for (let col = 0; col < 9; col++) {
            const piece = board[row][col];
            if (piece) {
                const isRed = piece === piece.toUpperCase();
                const pieceType = piece.toLowerCase();
                
                if (pieceType === 'k' && 
                    ((currentPlayer === 'red' && isRed) || 
                     (currentPlayer === 'black' && !isRed))) {
                    ownKingPos = { col, row };
                    break;
                }
            }
        }
        if (ownKingPos) break;
    }
    
    // 检查将/帅是否受到威胁
    let kingInDanger = false;
    let threateningPieces = [];
    
    if (ownKingPos) {
        // 遍历对方棋子,检查是否有棋子可以攻击己方将/帅
        for (let row = 0; row < 10; row++) {
            for (let col = 0; col < 9; col++) {
                const piece = board[row][col];
                if (piece) {
                    const isRed = piece === piece.toUpperCase();
                    if ((currentPlayer === 'red' && !isRed) || 
                        (currentPlayer === 'black' && isRed)) {
                        if (this.canAttack(board, { col, row, piece }, ownKingPos)) {
                            kingInDanger = true;
                            threateningPieces.push({ col, row, piece });
                        }
                    }
                }
            }
        }
    }
    
    // 生成防御建议
    let defenseRecommendation = "";
    
    if (kingInDanger) {
        defenseRecommendation = "将/帅受到威胁,必须立即保护!";
    } else {
        defenseRecommendation = "将/帅暂无威胁,可以考虑进攻或加强防御。";
    }
    
    return {
        kingInDanger: kingInDanger,
        threateningPieces: threateningPieces,
        defenseRecommendation: defenseRecommendation
    };
}

3. 进攻模块

进攻模块负责寻找进攻机会,如将军或吃掉高价值棋子:

analyze: function(board, currentPlayer) {
    // 找到对方将/帅位置
    let opponentKingPos = null;
    for (let row = 0; row < 10; row++) {
        for (let col = 0; col < 9; col++) {
            const piece = board[row][col];
            if (piece) {
                const isRed = piece === piece.toUpperCase();
                const pieceType = piece.toLowerCase();
                
                if (pieceType === 'k' && 
                    ((currentPlayer === 'red' && !isRed) || 
                     (currentPlayer === 'black' && isRed))) {
                    opponentKingPos = { col, row };
                    break;
                }
            }
        }
        if (opponentKingPos) break;
    }
    
    // 检查是否可以将军/吃掉对方将帅
    let canCheckmate = false;
    
    if (opponentKingPos) {
        // 遍历己方棋子,检查是否有棋子可以攻击对方将/帅
        for (let row = 0; row < 10; row++) {
            for (let col = 0; col < 9; col++) {
                const piece = board[row][col];
                if (piece) {
                    const isRed = piece === piece.toUpperCase();
                    if ((currentPlayer === 'red' && isRed) || 
                        (currentPlayer === 'black' && !isRed)) {
                        if (this.canAttack(board, { col, row, piece }, opponentKingPos)) {
                            canCheckmate = true;
                            break;
                        }
                    }
                }
            }
            if (canCheckmate) break;
        }
    }
    
    // 生成进攻建议
    let attackRecommendation = "";
    
    if (canCheckmate) {
        attackRecommendation = "发现将军/吃帅机会,应立即执行!";
    } else {
        // 检查是否有高价值棋子可以吃
        // ...
        
        if (canCaptureHighValue) {
            attackRecommendation = "发现可以吃掉对方高价值棋子,应考虑执行。";
        } else {
            attackRecommendation = "暂无明显进攻机会,考虑调整阵型为后续进攻做准备。";
        }
    }
    
    return {
        canCheckmate: canCheckmate,
        attackRecommendation: attackRecommendation
    };
}

项目实现中的技术难点与解决方案

1. 多AI模块协同决策

难点:如何协调多个AI模块,使它们能够协同工作,共同做出决策。

解决方案:采用模块化设计,每个AI模块负责特定的分析任务,并通过主决策引擎进行协调。各模块通过标准化的接口进行通信,确保数据流的一致性和可靠性。

2. 象棋规则的完整实现

难点:中国象棋规则复杂,特别是马的"蹩马腿"、象的"塞象眼"等特殊规则的实现。

解决方案:将规则引擎独立为一个模块,针对每种棋子实现专门的走法判断函数,并通过单元测试确保规则的正确性。

static getKnightMoves(game, col, row) {
    const moves = [];
    
    const knightMoves = [
        [2, 1], [2, -1], [-2, 1], [-2, -1],
        [1, 2], [1, -2], [-1, 2], [-1, -2]
    ];
    
    const blockPositions = [
        [1, 0], [1, 0], [-1, 0], [-1, 0],
        [0, 1], [0, -1], [0, 1], [0, -1]
    ];
    
    for (let i = 0; i < knightMoves.length; i++) {
        const [dx, dy] = knightMoves[i];
        const [bx, by] = blockPositions[i];
        
        const newCol = col + dx;
        const newRow = row + dy;
        const blockCol = col + bx;
        const blockRow = row + by;
        
        if (newCol >= 0 && newCol < game.boardWidth && 
            newRow >= 0 && newRow < game.boardHeight) {
            
            // 检查是否蹩马腿
            if (!game.board[blockRow][blockCol]) {
                const targetPiece = game.board[newRow][newCol];
                if (!targetPiece || !this.isPieceOwnedByCurrentPlayer(game, targetPiece)) {
                    moves.push({ col: newCol, row: newRow });
                }
            }
        }
    }
    
    return moves;
}

3. AI分析结果的可视化

难点:如何将AI的分析过程和结果以直观、易懂的方式展示给用户。

解决方案:设计专门的UI组件,将AI分析结果分类展示,并使用不同的颜色和图标增强可读性。

displayAnalysisResults(intentAnalysis, defenseAnalysis, attackAnalysis) {
    // 更新意图分析结果
    const intentDiv = document.getElementById('intentAnalysis');
    if (intentDiv) {
        let intentHtml = `<strong>对手意图分析:</strong><br>`;
        intentHtml += `意图: ${intentAnalysis.intent || '未知'}<br>`;
        intentHtml += `威胁: ${intentAnalysis.threat || '无'}<br>`;
        intentHtml += `威胁等级: ${intentAnalysis.threatLevel || 0}/3<br>`;
        intentDiv.innerHTML = intentHtml;
    }
    
    // 更新防御分析结果
    const defenseDiv = document.getElementById('defenseAnalysis');
    if (defenseDiv) {
        let defenseHtml = `<strong>防御分析:</strong><br>`;
        defenseHtml += `将/帅受威胁: ${defenseAnalysis.kingInDanger ? '是' : '否'}<br>`;
        defenseHtml += `防御建议: ${defenseAnalysis.defenseRecommendation || '无'}<br>`;
        defenseDiv.innerHTML = defenseHtml;
    }
    
    // 更新进攻分析结果
    const attackDiv = document.getElementById('attackAnalysis');
    if (attackDiv) {
        let attackHtml = `<strong>进攻分析:</strong><br>`;
        attackHtml += `可将军: ${attackAnalysis.canCheckmate ? '是' : '否'}<br>`;
        attackHtml += `进攻建议: ${attackAnalysis.attackRecommendation || '无'}<br>`;
        attackDiv.innerHTML = attackHtml;
    }
}

4. 多层次AI决策机制的实现

难点:如何在不同的AI决策方法之间平滑切换,确保系统的稳定性和可靠性。

解决方案:采用降级策略,先尝试使用高级AI(LLM),如果失败则降级到传统AI,最后使用随机走法作为兜底方案。

// 尝试使用LLM AI
if (window.llmAI) {
    try {
        move = await window.llmAI.getMove(this.board, this.currentPlayer, this.moveHistory);
        if (!move || !move.from || !move.to) {
            move = null; // 降级到传统AI
        }
    } catch (error) {
        move = null; // 降级到传统AI
    }
}

// 如果LLM失败,使用传统AI
if (!move) {
    move = this.getBestMove();
    if (!move || !move.from || !move.to) {
        move = null; // 降级到随机走法
    }
}

// 如果所有AI方法都失败,生成随机走法
if (!move) {
    move = this.generateRandomMove(this.currentPlayer);
}

项目扩展与优化方向

1. AI能力提升

  • 引入深度学习模型,提高AI的棋力

  • 增加开局库和残局库,提高特定阶段的AI表现

  • 优化评估函数,使AI能够更准确地评估局面

2. 用户体验优化

  • 添加走法提示功能,帮助初学者学习象棋

  • 增加棋局回放功能,方便复盘分析

  • 支持棋谱导入导出,便于分享和学习

3. 多平台支持

  • 开发移动端适配版本,支持触摸操作

  • 实现在线对战功能,支持玩家之间的对弈

  • 添加云端AI服务,提供更强大的AI对手

4. 教学功能增强

  • 添加象棋教程和练习题

  • 实现AI辅助分析功能,帮助玩家提高棋艺

  • 增加棋局评论功能,提供专业的棋局分析

总结

本项目通过JavaScript实现了一个功能完善的中国象棋AI系统,采用多模块协同决策的架构,实现了意图分析、防御策略、进攻策略等多维度的棋局分析功能。系统不仅能够提供合理的AI对手,还能够展示AI的决策过程,具有很好的教学价值。

项目的核心亮点在于多AI模块协同决策架构、可视化AI分析结果、多层次AI决策机制以及完整的象棋规则实现。这些特性使得本项目不仅是一个游戏,更是一个学习象棋和AI技术的平台。

未来,我们将继续优化AI能力,提升用户体验,支持多平台,增强教学功能,使这个项目成为象棋爱好者和AI学习者的理想工具。

参考资料

  1. 中国象棋规则:象棋巫师 - 象棋百科全书

  2. JavaScript Canvas API:Canvas API - Web API | MDN

  3. 象棋AI算法:Chessprogramming wiki


希望这篇博文对你有所帮助,如有任何问题,欢迎在评论区留言交流!


网站公告

今日签到

点亮在社区的每一天
去签到