Files
maplecontest/docs/superpowers/specs/2026-06-09-balance-simulator-design.md
2026-06-09 01:39:21 +09:00

3.9 KiB

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 등).