fix(sim): 빈 인카운터 즉시 승리·타겟 타이브레이크 결정성·주석·draw/empty 테스트
This commit is contained in:
@@ -52,6 +52,8 @@ export function loadData() {
|
||||
return { cards: cardsData.cards, starterDeck: cardsData.starterDeck, monsters };
|
||||
}
|
||||
|
||||
// 주의: 인게임은 플레이어가 카드를 직접 선택한다. 이 chooseAction은 밸런스 추정용 자동 플레이 휴리스틱일 뿐
|
||||
// 이며, Lua에 대응 AI가 없다(동기화 대상은 데미지/방어/의도/승패 규칙이지 플레이어 선택이 아님).
|
||||
// 손패에서 낼 카드 인덱스(-1=종료). 공격 우선, 없으면 스킬.
|
||||
export function chooseAction(hand, cards, energy) {
|
||||
const entries = hand.map((id, i) => ({ id, i })).filter((x) => cards[x.id].cost <= energy);
|
||||
@@ -70,7 +72,7 @@ export function chooseTarget(aliveMonsters, plannedDamage) {
|
||||
const eff = (m) => m.hp + m.block;
|
||||
const killable = aliveMonsters.filter((m) => eff(m) <= plannedDamage);
|
||||
const pool = killable.length ? killable : aliveMonsters;
|
||||
return pool.slice().sort((a, b) => eff(a) - eff(b))[0];
|
||||
return pool.slice().sort((a, b) => eff(a) - eff(b) || pool.indexOf(a) - pool.indexOf(b))[0];
|
||||
}
|
||||
|
||||
function bump(s, cost, dmg, blk) {
|
||||
@@ -83,6 +85,7 @@ function bump(s, cost, dmg, blk) {
|
||||
// 반환: { win, turns, playerHpRemaining, draw? }
|
||||
export function simulateCombat(data, rng, stats) {
|
||||
const { cards, starterDeck, monsters } = data;
|
||||
if (monsters.length === 0) return { win: true, turns: 0, playerHpRemaining: PLAYER_HP };
|
||||
let drawPile = shuffle(starterDeck, rng);
|
||||
let discard = [];
|
||||
let hand = [];
|
||||
@@ -128,7 +131,7 @@ export function simulateCombat(data, rng, stats) {
|
||||
discard.push(...hand); hand = [];
|
||||
for (const m of mob) {
|
||||
if (!m.alive) continue;
|
||||
m.block = 0;
|
||||
m.block = 0; // 매 턴 초기화 (이전 턴 블록 미이월)
|
||||
const it = m.intents[m.intentIdx];
|
||||
if (it) {
|
||||
if (it.kind === 'Attack') { const r = applyDamage(pHp, pBlock, it.value); pHp = r.hp; pBlock = r.block; }
|
||||
|
||||
Reference in New Issue
Block a user