All files / systems/ai AIPersonality.ts

100% Statements 8/8
100% Branches 4/4
100% Functions 5/5
100% Lines 8/8

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193                                                            19x                                                                                                                                                                                                                                                                         21x 21x                 63x 137x   63x             7x             3x    
/**
 * AI Personality System for Korean Martial Arts Combat
 * Defines behavioral archetypes that guide AI decision-making
 */
 
import { PlayerArchetype, TrigramStance } from "@/types";
 
/**
 * AI personality profile defining combat behavior
 */
export interface AIPersonality {
  readonly name: string;
  readonly koreanName: string;
  readonly archetype: PlayerArchetype;
  readonly aggressionLevel: number; // 0.0-1.0: How often AI attacks
  readonly defensePreference: number; // 0.0-1.0: Tendency to block/counter
  readonly comboTendency: number; // 0.0-1.0: Likelihood to continue combos
  readonly stanceSwitchFrequency: number; // 0.0-1.0: How often changes stance
  readonly feintChance: number; // 0.0-1.0: Probability of fake attacks
  readonly tacticalRetreatThreshold: number; // Health % to retreat
  readonly favoredStances: readonly TrigramStance[];
  readonly description: {
    readonly korean: string;
    readonly english: string;
  };
}
 
/**
 * Five AI personality archetypes inspired by Korean martial arts philosophy
 */
export const AI_PERSONALITIES: Record<string, AIPersonality> = {
  /**
   * 맹공자 (Maenggongja) - Fierce Attacker
   * Aggressive pressure fighter using Musa archetype
   */
  AGGRESSIVE_STRIKER: {
    name: "Aggressive Striker",
    koreanName: "맹공자",
    archetype: PlayerArchetype.MUSA,
    aggressionLevel: 0.85,
    defensePreference: 0.2,
    comboTendency: 0.7,
    stanceSwitchFrequency: 0.3,
    feintChance: 0.15,
    tacticalRetreatThreshold: 0.15,
    favoredStances: [
      TrigramStance.GEON, // Heaven - Direct force
      TrigramStance.JIN, // Thunder - Explosive power
      TrigramStance.LI, // Fire - Precision strikes
    ],
    description: {
      korean: "정면 돌파를 선호하는 공격적인 전사",
      english: "Aggressive warrior who prefers frontal assault",
    },
  },
 
  /**
   * 기술가 (Gisulga) - Technical Master
   * Precision fighter using Amsalja archetype
   */
  TECHNICAL_MASTER: {
    name: "Technical Master",
    koreanName: "기술가",
    archetype: PlayerArchetype.AMSALJA,
    aggressionLevel: 0.5,
    defensePreference: 0.6,
    comboTendency: 0.4,
    stanceSwitchFrequency: 0.7,
    feintChance: 0.35,
    tacticalRetreatThreshold: 0.35,
    favoredStances: [
      TrigramStance.SON, // Wind - Continuous pressure
      TrigramStance.GAM, // Water - Flow and adaptation
      TrigramStance.TAE, // Lake - Fluid manipulation
    ],
    description: {
      korean: "정밀한 기술로 약점을 노리는 달인",
      english: "Master who targets weaknesses with precise techniques",
    },
  },
 
  /**
   * 균형 잡힌 자 (Gyunhyeong Jabin-ja) - Balanced Fighter
   * All-around fighter using Jeongbo Yowon archetype
   */
  BALANCED_FIGHTER: {
    name: "Balanced Fighter",
    koreanName: "균형 잡힌 자",
    archetype: PlayerArchetype.JEONGBO_YOWON,
    aggressionLevel: 0.6,
    defensePreference: 0.5,
    comboTendency: 0.5,
    stanceSwitchFrequency: 0.5,
    feintChance: 0.25,
    tacticalRetreatThreshold: 0.25,
    favoredStances: [
      TrigramStance.GEON, // Heaven
      TrigramStance.GAM, // Water
      TrigramStance.GAN, // Mountain
      TrigramStance.GON, // Earth
    ],
    description: {
      korean: "공격과 방어의 조화를 추구하는 전략가",
      english: "Strategist seeking harmony between offense and defense",
    },
  },
 
  /**
   * 방어의 달인 (Bangeo-ui Dallin) - Defensive Specialist
   * Counter-attack focused using Hacker archetype
   */
  DEFENSIVE_SPECIALIST: {
    name: "Defensive Specialist",
    koreanName: "방어의 달인",
    archetype: PlayerArchetype.HACKER,
    aggressionLevel: 0.35,
    defensePreference: 0.8,
    comboTendency: 0.3,
    stanceSwitchFrequency: 0.4,
    feintChance: 0.4,
    tacticalRetreatThreshold: 0.4,
    favoredStances: [
      TrigramStance.GAN, // Mountain - Defensive mastery
      TrigramStance.GON, // Earth - Grounding
      TrigramStance.GAM, // Water - Adaptation
    ],
    description: {
      korean: "방어에서 반격의 기회를 찾는 전문가",
      english: "Expert who finds counter-attack opportunities through defense",
    },
  },
 
  /**
   * 혼돈의 전사 (Hondon-ui Jeonsa) - Chaos Warrior
   * Unpredictable fighter using Jojik Pokryeokbae archetype
   */
  CHAOS_WARRIOR: {
    name: "Chaos Warrior",
    koreanName: "혼돈의 전사",
    archetype: PlayerArchetype.JOJIK_POKRYEOKBAE,
    aggressionLevel: 0.75,
    defensePreference: 0.3,
    comboTendency: 0.6,
    stanceSwitchFrequency: 0.8,
    feintChance: 0.5,
    tacticalRetreatThreshold: 0.1,
    favoredStances: [
      TrigramStance.LI, // Fire - Unpredictable
      TrigramStance.SON, // Wind - Constant motion
      TrigramStance.JIN, // Thunder - Explosive
      TrigramStance.TAE, // Lake - Fluid
    ],
    description: {
      korean: "예측 불가능한 패턴으로 상대를 혼란시키는 전사",
      english: "Warrior who confuses opponents with unpredictable patterns",
    },
  },
};
 
/**
 * Get a random AI personality
 */
export function getRandomPersonality(): AIPersonality {
  const personalities = Object.values(AI_PERSONALITIES);
  return personalities[Math.floor(Math.random() * personalities.length)];
}
 
/**
 * Get personality by archetype
 */
export function getPersonalityByArchetype(
  archetype: PlayerArchetype
): AIPersonality {
  const personality = Object.values(AI_PERSONALITIES).find(
    (p) => p.archetype === archetype
  );
  return personality ?? AI_PERSONALITIES.BALANCED_FIGHTER;
}
 
/**
 * Get personality by name key
 */
export function getPersonalityByName(name: string): AIPersonality {
  return AI_PERSONALITIES[name] ?? AI_PERSONALITIES.BALANCED_FIGHTER;
}
 
/**
 * List all available personalities
 */
export function getAllPersonalities(): readonly AIPersonality[] {
  return Object.values(AI_PERSONALITIES);
}