# AI 전투 시뮬레이터 (TODO 항목 F) — 설계 > 작성: 2026-06-09 / 상태: 승인됨 / 근거: TODO.md 항목 F + gen-slaydeck.mjs 전투 규칙 + D 데이터. > 선행: D(데이터 외부화) 완료. ## 문제 박재오 강점(백엔드·AI 자동화) 활용처로 기획됐으나 코드 없음. 카드/적 밸런싱을 손으로 검증해야 한다. 데이터 기반 자동 밸런스 검증 도구가 필요하다. ## 목표 `data/cards.json`·`data/enemies.json`를 입력으로, 전투를 몬테카를로로 N회 자동 시뮬레이션해 승률·평균 턴·OP 카드 탐지 리포트를 출력하는 오프라인 Node CLI(`tools/sim-balance.mjs`). ## 설계 ### 구조 `tools/sim-balance.mjs` 단일 파일, 섹션 분리: 1. **데이터 로드**: `data/cards.json`·`data/enemies.json`(D와 동일 소스). `activeEnemy` 사용. 2. **시드 PRNG**: mulberry32(시드 고정 → 재현 가능, 데이터 바꾸면 결과 변동). 3. **전투 엔진**(Lua 규칙 미러): 아래 규칙을 JS로 재현. 4. **플레이어 정책**(휴리스틱 A). 5. **집계·리포트**. 6. **CLI 파싱·출력**. ### 전투 규칙 (gen-slaydeck.mjs Lua와 동일) - 시작: 플레이어 `hp=PLAYER_HP(상수 80)`, `block=0`; 적 `hp=maxHp`, `block=0`, `intentIdx=0`(0-base). 덱 = `starterDeck` 셔플(PRNG). - 플레이어 턴 시작: `energy=3`, `block=0`, 5장 드로우(덱 소진 시 버림 더미 셔플해 재활용). - 플레이어 행동: 정책이 카드 선택 → 사용 시 `energy -= cost`, `Attack`→적에 `damage`(적 block 우선 차감), `Skill`→플레이어 `block += block`. 사용 카드는 버림. 더 둘 수 없으면 턴 종료. - 적 턴: 적 `block=0` → 현재 의도 실행(`Attack`→플레이어에 피해(플레이어 block 우선 차감), `Defend`→적 `block += value`) → `intentIdx=(intentIdx+1)%len`. - 승패: 적 hp≤0 승리, 플레이어 hp≤0 패배. 턴 상한 `MAX_TURNS=100`(초과 시 무승부로 집계, 경고). ### 플레이어 정책 (휴리스틱 A) 매 플레이어 행동 루프: 1. **치사 판단**: 손패의 Attack 카드들로 이번 턴 낼 수 있는 최대 데미지(에너지 한도 내) ≥ `적 hp + 적 block` 이면 → 그 Attack들을 사용(킬). 2. 아니면 **적 의도가 Attack**이면 → 손패 Defend(Skill+block) 카드를 사용(에너지 닿는 한), 이후 잔여 에너지로 Attack 사용. 3. 아니면(적 Defend 의도) → Attack 우선 사용. 4. 사용 가능한 카드(에너지≥cost)가 없으면 턴 종료. - 동률 선택은 에너지 효율(뎀/E 또는 블록/E) 높은 카드 우선. ### 리포트 지표 - 전체: 승률(%), 평균·중앙값 턴 수, 승리 시 평균 잔여 HP, 패배율, (무승부 시 경고). - 카드별: 사용 횟수, 누적 데미지/방어, **에너지당 효율**(Attack=총뎀/총E, Skill=총블록/총E). - **OP 탐지**: 같은 kind 내 효율이 그 kind 중앙값의 ≥1.5배인 카드를 ⚠️로 플래그. 최다/최소 사용 카드 표기. ### CLI `node tools/sim-balance.mjs [N] [--seed S]` — 기본 `N=2000`, `seed=1`. 표 형식 출력. ### 동기화 위험 JS 전투 규칙은 Lua(`gen-slaydeck.mjs`)와 **중복**이다(공유 불가). 데이터(JSON)는 공유. 파일 상단에 "전투 규칙 변경 시 gen-slaydeck.mjs Lua와 동기화" 주석 명시. ## 검증 (TDD + CLI) - 전투 엔진/정책 핵심을 순수 함수로 분리해 단위 테스트(Node 내장 `node:test`): 데미지 방어차감, 치사 판단, 적 의도 사이클, 승/패 종료. - `node tools/sim-balance.mjs` → 승률·턴·카드 통계 출력. - `data/cards.json`에서 강타 damage↑ → 승률·강타 효율 상승(데이터 반영). - 동일 시드 2회 → 동일 출력(결정성). ## 범위 밖 (금지) - 상태이상·드로우·복합효과, 다중 적, 로그라이크 메타. 메이커 런타임 연동. - 새 카드/적 추가(현 데이터로 검증). 정책 고도화(MCTS 등).