基于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. 完整的象棋规则实现
项目实现了完整的中国象棋规则,包括:
各类棋子的走法规则(将/帅、士/仕、象/相、马、车、炮、兵/卒)
特殊规则(如将帅不能照面、象不过河等)
胜负判定(将死、困毙等)
系统架构与逻辑流程
整体架构
项目采用模块化设计,主要包括以下几个核心模块:
游戏核心模块(game-core.js):负责游戏的基本逻辑和流程控制
规则引擎模块(game-rules.js):实现象棋规则,判断走法是否合法
AI模块:
意图分析模块(intent-analyzer.js)
防御模块(defender.js)
进攻模块(attacker.js)
主决策引擎(main-engine.js)
LLM连接器(llm-connector.js)
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学习者的理想工具。
参考资料
中国象棋规则:象棋巫师 - 象棋百科全书
JavaScript Canvas API:Canvas API - Web API | MDN
象棋AI算法:Chessprogramming wiki
希望这篇博文对你有所帮助,如有任何问题,欢迎在评论区留言交流!