3575 字
18 分钟
AI技术实现文档 - 《无尽牌域》敌人AI系统 - 程序实现指南
AI技术实现文档
《无尽牌域》敌人AI系统 - 程序实现指南
📋 文档信息
- 版本: v1.0
- 日期: 2026-05-08
- 作者: GameDesigner
- 对应AI设计文档: AI-Design-Enemy-Behavior.md
- 状态: 技术实现阶段
📁 目录
1. 数据结构设计
1.1 敌人基础属性
// TypeScript 定义 - 敌人基础属性interface Enemy { id: string; // 唯一标识 name: string; // 敌人名称 type: EnemyType; // 敌人类型 maxHp: number; // 最大生命值 currentHp: number; // 当前生命值 baseAttack: number; // 基础攻击力 baseDefense: number; // 基础防御力 armor: number; // 当前护甲值 energy: number; // 当前能量 buffs: Buff[]; // 当前Buff列表 debuffs: Debuff[]; // 当前Debuff列表 skills: Skill[]; // 可用技能列表 usedSkills: Set<string>; // 已使用的技能(限制用) aiState: AIState; // AI当前状态 intent: Intent; // 当前意图 nextIntent: Intent; // 下回合意图(用于预告) decisionLog: DecisionRecord[]; // 决策日志(调试用)}
type EnemyType = 'AGGRESSIVE' | 'DEFENSIVE' | 'STRATEGIC' | 'BERSERKER';1.2 意图系统
// 意图类型定义interface Intent { type: IntentType; target: 'PLAYER' | 'ALL_ENEMIES' | 'SELF'; value: number; // 效果数值 description: string; // 显示文本 icon: string; // 图标名称 skill?: Skill; // 如果是技能,显示技能详情 turnsUntilExecution?: number; // 几回合后执行(预告用)}
type IntentType = | 'ATTACK' // 普通攻击 | 'HEAVY_ATTACK' // 强力攻击 | 'AOE_ATTACK' // AOE攻击 | 'DEFEND' // 防御 | 'HEAL' // 回血 | 'BUFF' // 增益 | 'DEBUFF' // 减益 | 'SPECIAL' // 特殊技能 | 'IDLE' // 待机 | 'UNKNOWN'; // 未知1.3 技能定义
// 技能数据结构interface Skill { id: string; name: string; cost: number; // 能量消耗 type: 'ATTACK' | 'DEFEND' | 'HEAL' | 'BUFF' | 'DEBUFF' | 'AOE'; baseValue: number; // 基础效果值 scaling?: ScalingInfo; // 数值成长 effect: SkillEffect; // 技能效果 cooldown: number; // 冷却回合 currentCooldown: number; // 当前冷却 maxUsesPerBattle: number; // 每场战斗最大使用次数 triggerConditions: Condition[]; // 触发条件}
interface ScalingInfo { attribute: 'attack' | 'defense' | 'hp' | 'turns'; multiplier: number; additive: number;}
// 技能效果interface SkillEffect { damage?: number; armorGain?: number; healAmount?: number; buff?: BuffType; debuff?: DebuffType; special?: SpecialEffect;}1.4 AI状态
// AI状态机interface AIState { phase: 'NORMAL' | 'ENRAGED' | 'EXHAUSTED'; // 阶段 turnCount: number; // 回合数 cumulativeDamage: number; // 累计造成伤害 cumulativeHealing: number; // 累计治疗 strategy: 'ATTACK' | 'DEFEND' | 'BALANCED'; // 当前策略 detectedPlayerStrategy?: PlayerStrategy; // 检测到的玩家策略 predictedPlayerAction?: ActionType; // 预测的玩家行动}2. AI核心框架
2.1 主循环
// AI主循环 - 每回合敌人行动时调用class EnemyAIController {
/** * 执行敌人回合 */ async executeTurn(enemy: Enemy, player: Player, gameState: GameState): Promise<TurnResult> { // 1. 更新状态 this.updateEnemyState(enemy, gameState);
// 2. 检测触发条件(特殊技能等) const triggeredSkill = this.checkTriggeredSkills(enemy, gameState); if (triggeredSkill) { return this.executeSkill(enemy, player, triggeredSkill); }
// 3. 评估局势 const situation = this.evaluateSituation(enemy, player, gameState);
// 4. 生成候选行动 const candidateActions = this.generateCandidateActions(enemy, situation);
// 5. 评分并选择最佳行动 const bestAction = this.selectBestAction(candidateActions, enemy, situation);
// 6. 记录决策(调试用) this.logDecision(enemy, bestAction, candidateActions);
// 7. 执行行动 const result = await this.executeAction(enemy, player, bestAction);
// 8. 设置下回合意图预告 this.updateNextIntent(enemy, bestAction);
return result; }
/** * 更新敌人状态 */ private updateEnemyState(enemy: Enemy, gameState: GameState): void { enemy.aiState.turnCount++;
// 更新buff/debuff enemy.buffs = enemy.buffs.filter(buff => { buff.remainingTurns--; return buff.remainingTurns > 0; });
enemy.debuffs = enemy.debuffs.filter(debuff => { debuff.remainingTurns--; return debuff.remainingTurns > 0; });
// 更新技能冷却 enemy.skills.forEach(skill => { if (skill.currentCooldown > 0) { skill.currentCooldown--; } }); }
/** * 评估当前局势 */ private evaluateSituation(enemy: Enemy, player: Player, gameState: GameState): Situation { return { playerHpPercent: player.currentHp / player.maxHp, enemyHpPercent: enemy.currentHp / enemy.maxHp, playerThreatLevel: this.calculatePlayerThreat(player), selfPreservationNeed: this.calculateSelfPreservationNeed(enemy), canFinishPlayer: enemy.currentAttack >= player.currentHp, isInDanger: enemy.currentHp < enemy.maxHp * 0.3, }; }}2.2 决策评分系统
// 决策评分系统class DecisionScorer {
/** * 计算行动的评分 */ calculateScore(action: Action, enemy: Enemy, situation: Situation, difficulty: Difficulty): number { let score = 0;
// 基础分数 score += action.baseScore;
// 根据敌人类型调整 score += this.applyTypeModifier(action, enemy.type);
// 根据局势调整 score += this.applySituationModifier(action, situation);
// 根据难度调整 score += this.applyDifficultyModifier(action, difficulty);
// 随机扰动(增加不可预测性) score += this.addRandomNoise(difficulty);
return score; }
/** * 根据敌人类型调整分数 */ private applyTypeModifier(action: Action, type: EnemyType): number { const typeModifiers = { 'AGGRESSIVE': { 'ATTACK': 30, 'DEFEND': -20, 'HEAL': -30 }, 'DEFENSIVE': { 'ATTACK': -10, 'DEFEND': 30, 'HEAL': 20 }, 'STRATEGIC': { 'ATTACK': 0, 'DEFEND': 0, 'HEAL': 0 }, 'BERSERKER': { 'ATTACK': 50, 'DEFEND': -40, 'HEAL': 0 }, };
return typeModifiers[type][action.type] || 0; }
/** * 根据局势调整分数 */ private applySituationModifier(action: Action, situation: Situation): number { let modifier = 0;
// 如果可以击杀玩家,大幅提高攻击权重 if (situation.canFinishPlayer && action.type === 'ATTACK') { modifier += 100; }
// 如果敌人危险,提高防御权重 if (situation.isInDanger && action.type === 'DEFEND') { modifier += 50; }
// 如果玩家生命很低,提高攻击权重(处决模式) if (situation.playerHpPercent < 0.3 && action.type === 'ATTACK') { modifier += 40; }
return modifier; }
/** * 根据难度调整分数 */ private applyDifficultyModifier(action: Action, difficulty: Difficulty): number { switch (difficulty) { case 'EASY': return -10; case 'NORMAL': return 0; case 'HARD': return 10; default: return 0; } }
/** * 添加随机扰动 */ private addRandomNoise(difficulty: Difficulty): number { const noiseRange = { 'EASY': 30, 'NORMAL': 15, 'HARD': 5 }; return (Math.random() - 0.5) * 2 * noiseRange[difficulty]; }}3. 敌人类型实现
3.1 激进型敌人
// 激进型AI实现class AggressiveAI extends BaseAI {
generateActions(enemy: Enemy, situation: Situation): Action[] { const actions: Action[] = [];
// 攻击永远是第一选择 actions.push({ type: 'ATTACK', baseScore: 70, execute: () => this.performAttack(enemy), target: 'PLAYER' });
// 如果有特殊攻击技能 const specialAttack = enemy.skills.find(s => s.type === 'ATTACK' && s.currentCooldown === 0 ); if (specialAttack) { actions.push({ type: 'SPECIAL_ATTACK', baseScore: 60, execute: () => this.executeSkill(enemy, specialAttack), target: 'PLAYER', skill: specialAttack }); }
// 生命危急时可能选择防御 if (situation.isInDanger) { actions.push({ type: 'DEFEND', baseScore: 20, execute: () => this.performDefend(enemy), target: 'SELF' }); }
return actions; }
private async performAttack(enemy: Enemy): Promise<TurnResult> { const attackBonus = this.calculateAttackBonus(enemy); const damage = Math.floor((enemy.baseAttack + attackBonus) * this.getRandomMultiplier()); const actualDamage = this.applyDamageToTarget(enemy, this.player, damage);
return { type: 'ATTACK', damage: actualDamage, description: `${enemy.name} 攻击造成了 ${actualDamage} 点伤害!` }; }}3.2 防御型敌人
// 防御型AI实现class DefensiveAI extends BaseAI {
generateActions(enemy: Enemy, situation: Situation): Action[] { const actions: Action[] = [];
// 检查是否需要防御 if (enemy.armor < 10 || situation.playerThreatLevel > 15) { actions.push({ type: 'DEFEND', baseScore: 50, execute: () => this.performDefend(enemy), target: 'SELF' }); }
// 检查是否需要治疗 if (enemy.currentHp < enemy.maxHp * 0.5) { const healSkill = enemy.skills.find(s => s.type === 'HEAL'); if (healSkill && healSkill.currentCooldown === 0) { actions.push({ type: 'HEAL', baseScore: 40, execute: () => this.executeHeal(enemy, healSkill), target: 'SELF', skill: healSkill }); } }
// 低威胁时才攻击 if (situation.playerThreatLevel < 10) { actions.push({ type: 'ATTACK', baseScore: 30, execute: () => this.performAttack(enemy), target: 'PLAYER' }); }
return actions; }}3.3 策略型敌人
// 策略型AI实现class StrategicAI extends BaseAI {
generateActions(enemy: Enemy, situation: Situation): Action[] { const actions: Action[] = [];
// 1. 检测玩家策略 const playerStrategy = this.detectPlayerStrategy(this.player, enemy.aiState);
// 2. 根据玩家策略调整行为 const counterStrategy = this.getCounterStrategy(playerStrategy);
// 3. 根据当前回合调整行为 const turnBasedAction = this.getTurnBasedAction(enemy, situation);
// 合并所有候选行动 actions.push(...turnBasedAction);
return actions; }
/** * 检测玩家策略 */ private detectPlayerStrategy(player: Player, aiState: AIState): PlayerStrategy { const recentActions = player.actionHistory.slice(-3); const attackRatio = recentActions.filter(a => a.type === 'ATTACK').length / 3; const defenseRatio = recentActions.filter(a => a.type === 'DEFEND').length / 3; const avgCost = recentActions.reduce((sum, a) => sum + a.cost, 0) / 3;
if (avgCost > 3) return 'CONTROL'; if (attackRatio > 0.6) return 'RUSH'; if (defenseRatio > 0.5) return 'DEFENSE'; return 'BALANCED'; }
/** * 获取反制策略 */ private getCounterStrategy(playerStrategy: PlayerStrategy): Action[] { switch (playerStrategy) { case 'RUSH': return [{ type: 'DEFEND', baseScore: 60, execute: () => this.performDefend(this.enemy), target: 'SELF' }]; case 'CONTROL': return [{ type: 'ATTACK', baseScore: 60, execute: () => this.performAttack(this.enemy), target: 'PLAYER' }]; default: return []; } }}3.4 狂暴型敌人
// 狂暴型AI实现class BerserkerAI extends BaseAI {
generateActions(enemy: Enemy, situation: Situation): Action[] { const actions: Action[] = []; const rageLevel = this.calculateRageLevel(enemy);
// 狂暴等级影响攻击 if (rageLevel >= 1) { actions.push({ type: 'HEAVY_ATTACK', baseScore: 80, execute: () => this.performHeavyAttack(enemy, rageLevel), target: 'PLAYER' }); }
// 检查血量触发狂暴技能 if (enemy.currentHp < enemy.maxHp * 0.5 && !enemy.hasUsedRageSkill) { actions.push({ type: 'RAGE_SKILL', baseScore: 100, execute: () => this.executeRageSkill(enemy), target: 'SELF' }); }
// 普通攻击(次优先) actions.push({ type: 'ATTACK', baseScore: 60, execute: () => this.performAttack(enemy), target: 'PLAYER' });
return actions; }
/** * 计算狂暴等级 */ private calculateRageLevel(enemy: Enemy): number { const hpPercent = enemy.currentHp / enemy.maxHp;
if (hpPercent > 0.7) return 0; // 正常 if (hpPercent > 0.4) return 1; // 愤怒(攻击力+50%) if (hpPercent > 0.1) return 2; // 狂暴(攻击力+100%,无视防御) return 3; // 死亡挣扎(攻击力+200%,自伤) }}4. BOSS AI实现
4.1 BOSS基础类
// BOSS AI基类abstract class BossAI extends BaseAI { protected phases: BossPhase[]; protected currentPhaseIndex: number;
/** * 判断阶段转换 */ protected checkPhaseTransition(enemy: Enemy): void { const hpPercent = enemy.currentHp / enemy.maxHp; const currentPhase = this.phases[this.currentPhaseIndex];
if (this.currentPhaseIndex < this.phases.length - 1) { const nextPhase = this.phases[this.currentPhaseIndex + 1]; if (hpPercent <= nextPhase.hpThreshold) { this.transitionToPhase(enemy, nextPhase); } } }
/** * 阶段转换 */ protected async transitionToPhase(enemy: Enemy, newPhase: BossPhase): Promise<void> { this.currentPhaseIndex++;
await this.playPhaseTransitionAnimation(enemy, newPhase);
if (newPhase.statModifier) { enemy.baseAttack *= newPhase.statModifier.attackMultiplier; enemy.maxHp *= newPhase.statModifier.hpMultiplier; }
if (newPhase.phaseSkill) { await this.executeSkill(enemy, newPhase.phaseSkill); }
EventBus.emit('boss:phase_transition', { enemy: enemy, newPhase: newPhase, phaseNumber: this.currentPhaseIndex + 1 }); }}
/** * BOSS阶段定义 */interface BossPhase { name: string; hpThreshold: number; // 触发此阶段的血量百分比 behaviorPattern: string; // 行为模式名称 statModifier?: { attackMultiplier: number; hpMultiplier: number; }; phaseSkill?: Skill; availableSkills: Skill[]; attackPatterns: AttackPattern[];}4.2 炎魔领主实现
// 炎魔领主AIclass InfernoLordAI extends BossAI { private flameStormCooldown: number = 0;
constructor() { super();
this.phases = [ { name: '试探', hpThreshold: 1.0, behaviorPattern: 'PROBING', availableSkills: [], attackPatterns: [ { name: '普通攻击', weight: 40, execute: () => this.normalAttack() }, { name: '火焰斩', weight: 30, execute: () => this.flameSlash() }, { name: '防御', weight: 30, execute: () => this.defend() } ] }, { name: '狂怒', hpThreshold: 0.7, statModifier: { attackMultiplier: 1.3, hpMultiplier: 1.0 }, behaviorPattern: 'ENRAGED', availableSkills: [], attackPatterns: [ { name: '火焰风暴预告', weight: 20, execute: () => {}, intentPreviewTurns: 2 }, { name: '火焰风暴', weight: 0, execute: () => this.flameStorm() }, { name: '强化攻击', weight: 50, execute: () => this.heavyAttack() }, { name: '防御', weight: 20, execute: () => this.defend() } ] }, { name: '死亡挣扎', hpThreshold: 0.3, statModifier: { attackMultiplier: 1.5, hpMultiplier: 1.0 }, behaviorPattern: 'DESPERATE', availableSkills: [], attackPatterns: [ { name: '地狱火预告', weight: 30, execute: () => {}, intentPreviewTurns: 1 }, { name: '地狱火', weight: 0, execute: () => this.inferno() }, { name: '疯狂攻击', weight: 70, execute: () => this.franticAttack() } ] } ]; }
/** * 火焰风暴技能 */ private async flameStorm(): Promise<TurnResult> { const damage = 12;
this.gameState.allCharacters.forEach(char => { this.applyDamage(char, damage); this.applyDebuff(char, { type: 'BURNING', damage: 3, turns: 3 }); });
this.flameStormCooldown = 3;
return { type: 'AOE_ATTACK', damage: damage, description: '炎魔领主释放火焰风暴!所有人受到12点伤害并被点燃!' }; }
/** * 地狱火(终极技能) */ private async inferno(): Promise<TurnResult> { const damage = 30;
this.gameState.allCharacters.forEach(char => { this.applyDamage(char, damage); });
this.enemy.nextIntent = { type: 'IDLE', description: '疲劳中...' };
return { type: 'ULTIMATE', damage: damage, description: '炎魔领主释放地狱火!所有人受到30点伤害!BOSS进入疲劳状态!' }; }}5. 意图预告系统
5.1 意图更新逻辑
// 意图预告系统class IntentSystem {
/** * 更新敌人意图 */ updateIntent(enemy: Enemy, action: Action): Intent { const intent = this.createIntentFromAction(action);
// 设置预告(如果是特殊技能) if (action.skill?.type === 'SPECIAL') { enemy.nextIntent = intent; intent.turnsUntilExecution = 2; intent.description = `准备释放 ${action.skill.name}...`; } else { enemy.nextIntent = null; }
return intent; }
/** * 根据行动创建意图 */ private createIntentFromAction(action: Action): Intent { const intentMap: Record<string, Partial<Intent>> = { 'ATTACK': { type: 'ATTACK', icon: 'sword', description: `攻击造成 ${action.damage || '?'} 点伤害` }, 'HEAVY_ATTACK': { type: 'HEAVY_ATTACK', icon: 'sword_fire', description: `强力攻击造成 ${action.damage || '?'} 点伤害` }, 'AOE_ATTACK': { type: 'AOE_ATTACK', icon: 'explosion', description: `对所有人造成 ${action.damage || '?'} 点伤害` }, 'DEFEND': { type: 'DEFEND', icon: 'shield', description: `获得 ${action.armorGained || '?'} 点护甲` }, 'HEAL': { type: 'HEAL', icon: 'heart', description: `回复 ${action.healAmount || '?'} 点生命` }, 'SPECIAL': { type: 'SPECIAL', icon: 'star', description: action.skill?.name || '特殊技能' } };
return { ...intentMap[action.type], target: action.target, value: action.damage || action.armorGained || action.healAmount } as Intent; }}6. 流程图
6.1 AI主流程
┌─────────────────────────────────────────────────────────────┐│ 敌人回合开始 │└─────────────────────────────────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────────────┐│ 1. 检查回合开始触发条件 ││ - Buff/Debuff更新 ││ - 技能冷却减少 ││ - 特殊事件检测 │└─────────────────────────────────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────────────┐│ 2. 检查强制行动 ││ - 眩晕/冻结/睡眠 → 跳过回合 ││ - 强制技能触发 → 执行强制技能 ││ - 疲劳状态 → 跳过回合 │└─────────────────────────────────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────────────┐│ 3. 检测特殊技能触发 ││ 遍历所有技能:skill.triggerConditions ││ ├─ 生命值阈值触发? ││ ├─ 回合数触发? ││ ├─ 玩家行动触发? ││ └─ 组合条件触发? ││ 如果触发 → 执行特殊技能 → 返回结果 │└─────────────────────────────────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────────────┐│ 4. 评估当前局势 ││ - 玩家HP% ││ - 敌人HP% ││ - 玩家威胁等级 ││ - 敌人自保需求 ││ - 是否可处决玩家 │└─────────────────────────────────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────────────┐│ 5. 生成候选行动列表 ││ 根据敌人类型生成行动: ││ AGGRESSIVE → 攻击为主 ││ DEFENSIVE → 防御/治疗为主 ││ STRATEGIC → 分析后决策 ││ BERSERKER → 血量越低越疯狂 ││ 每个行动包含:行动类型、基础评分、执行函数 │└─────────────────────────────────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────────────┐│ 6. 评分并排序候选行动 ││ - 应用类型修正 ││ - 应用局势修正 ││ - 应用难度修正 ││ - 添加随机扰动 ││ - 按评分降序排列 │└─────────────────────────────────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────────────┐│ 7. 选择并执行最佳行动 ││ 选择评分最高的行动 ││ → 执行行动动画 ││ → 应用效果(伤害/治疗/Buff等) ││ → 返回行动结果 │└─────────────────────────────────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────────────┐│ 8. 更新意图预告 ││ - 计算下回合行动 ││ - 如果是特殊技能,设置2回合预告 ││ - 更新UI显示 │└─────────────────────────────────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────────────┐│ 敌人回合结束 │└─────────────────────────────────────────────────────────────┘6.2 伤害计算公式
function calculateDamage( attacker: Character, defender: Character, baseDamage: number): { rawDamage: number, actualDamage: number, blocked: boolean } {
// 1. 计算原始伤害 let rawDamage = baseDamage;
// 2. 应用攻击方Buff if (attacker.hasBuff('WEAKEN')) { rawDamage *= 0.75; }
// 3. 计算最终伤害 let actualDamage = Math.max(1, rawDamage - defender.armor);
// 4. 应用防御方Debuff if (defender.hasDebuff('VULNERABLE')) { actualDamage *= 1.5; }
// 5. 暴击判定 let isCrit = false; if (Math.random() < attacker.critChance) { actualDamage *= attacker.critMultiplier; isCrit = true; }
// 6. 无视防御判定(狂暴型特殊) if (attacker.ignoreDefense) { actualDamage = rawDamage; }
return { rawDamage: Math.floor(rawDamage), actualDamage: Math.floor(actualDamage), blocked: defender.armor > 0 };}7. 服务器端 vs 客户端架构
7.1 推荐架构
# 在线游戏(PvP)推荐架构
服务器端(权威): ✅ AI决策逻辑(防止客户端作弊) ✅ 战斗状态同步 ✅ 技能效果计算 ✅ 随机数生成(伪随机,确保公平)
客户端(预测): ✅ UI动画播放 ✅ 音效/特效 ✅ 意图预告显示(从服务器同步) ✅ 本地AI模拟(用于即时反馈,但服务器结果为准)7.2 通信协议
// 客户端 → 服务器:请求AI行动interface AIActionRequest { type: 'AI_TURN'; enemyId: string; gameStateHash: string; // 状态校验}
// 服务器 → 客户端:AI行动结果interface AIActionResponse { type: 'AI_ACTION'; enemyId: string; action: { type: string; damage?: number; effects: Effect[]; }; newIntent: Intent; // 下回合意图 nextAction?: Intent; // 2回合后意图(预告) serverTimestamp: number;}📝 版本日志
v1.0 (2026-05-08)
- 初始版本
- 完成TypeScript类型定义
- 完成4种敌人AI实现
- 完成BOSS AI框架
- 完成意图预告系统
- 完成流程图设计
- 完成服务器/客户端架构设计
文档结束 | 供程序员实现参考
AI技术实现文档 - 《无尽牌域》敌人AI系统 - 程序实现指南
https://021028.xyz/posts/default/59/