当前位置: 首页 > news >正文

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

基于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 AIif (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失败,使用传统AIif (!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


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

http://www.xdnf.cn/news/1325071.html

相关文章:

  • leetcode4_452 and 763
  • 一道同分排名的SQL题
  • Django开发Web应用
  • Dubbo 的SPI
  • 15.三数之和
  • vue3 el-table-column 列头添加 图标按钮
  • 使用websockets中的一些问题和解决方法
  • day25|学习前端js
  • Day7--滑动窗口与双指针--1695. 删除子数组的最大得分,2958. 最多 K 个重复元素的最长子数组,2024. 考试的最大困扰度
  • JavaSE——高级篇
  • Java面试宝典:Redis 入门与应用
  • Poisson分布:稀有事件建模的理论基石与演进
  • 用随机森林填补缺失值:原理、实现与实战
  • 力扣hot100:移动零问题的巧妙解决:双指针与原地交换策略(283)
  • 开发避坑指南(28):Spring Boot端点检查禁用失效解决方案
  • Vue3 中使用 Element Plus 完整指南
  • Spring AI Alibaba 项目接入兼容 OpenAI API 的大模型
  • 杂记 05
  • 母猪姿态转换行为识别:计算机视觉与行为识别模型调优指南
  • Android使用Kotlin协程+Flow实现打字机效果
  • Python 作用域 (scope) 与闭包 (closure)
  • 【学习嵌入式-day-27-进程间通信】
  • Docker常见指令速查
  • 用户认证技术
  • STL库——string(类函数学习)
  • SQL详细语法教程(六)存储+索引
  • AI心理助手开发文档
  • 在python中等号左边的都是对象,在matlab中等号a = 3+2 a就是个变量
  • 力扣hot100:盛最多水的容器:双指针法高效求解最大容量问题(11)
  • openfeign 只有接口如何创建bean的