fix(tk2): match original SV (5-battle cap, no loss limit)

User clarified: the 0..7 win reward tiers came from Shadowverse Worlds
Beyond (sequel), not the original game we're emulating. Original SV's
Take Two caps at 5 total battles played and has no loss limit (verified
on prod: queueing continues with 2+ losses).

- arena-two-pick-rewards.json: drop 6w + 7w tiers (12 rows remain).
- ArenaTwoPickConfig: remove MaxLosses property.
- ArenaTwoPickService: termination is now battlesPlayed >= maxBattles
  (5 from MAX(reward.WinCount)). RecordBattleResult no longer flips
  IsSelectCompleted on the 2nd loss.
- ResolveMaxBattleCountAsync empty-catalog default 7 → 5.
- Tests updated for the new counts (16 → 12 rows, max 7 → 5).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
gamer147
2026-05-31 12:47:43 -04:00
parent dc19289818
commit 6381e4da51
7 changed files with 31 additions and 32 deletions

View File

@@ -87,7 +87,7 @@ public class ArenaTwoPickServiceEntryTests
var dto = await svc.EntryAsync(viewerId, consumeItemType: 3);
Assert.That(dto.EntryInfo.Id, Is.GreaterThan(0));
Assert.That(dto.EntryInfo.MaxBattleCount, Is.EqualTo(7));
Assert.That(dto.EntryInfo.MaxBattleCount, Is.EqualTo(5));
Assert.That(dto.CandidateClassIds.Count, Is.EqualTo(3));
Assert.That(dto.RewardList.Count, Is.EqualTo(1));
Assert.That(dto.RewardList[0].RewardType, Is.EqualTo(4));
@@ -96,7 +96,7 @@ public class ArenaTwoPickServiceEntryTests
var run = await db.ViewerArenaTwoPickRuns.FirstAsync(r => r.ViewerId == viewerId);
Assert.That(run.ClassId, Is.EqualTo(0));
Assert.That(run.MaxBattleCount, Is.EqualTo(7));
Assert.That(run.MaxBattleCount, Is.EqualTo(5));
// Re-read viewer to verify ticket was debited.
var updated = await db.Viewers.Include(v => v.Items).ThenInclude(i => i.Item).FirstAsync(v => v.Id == viewerId);

View File

@@ -128,9 +128,11 @@ public class ArenaTwoPickServiceFinishTests
}
[Test]
public async Task FinishAsync_at_2_losses_grants_loss_rewards_and_deletes_run()
public async Task FinishAsync_at_5_total_battles_with_0_wins_grants_loss_rewards_and_deletes_run()
{
var (db, svc, vid) = await SetupWithRunAsync(winCount: 0, lossCount: 2);
// Classic Take Two: run ends after 5 total battles played, regardless of W/L split.
// 0W 5L = floor-tier reward (1 ticket + 100 rupies).
var (db, svc, vid) = await SetupWithRunAsync(winCount: 0, lossCount: 5);
await using var _ = db;
var dto = await svc.FinishAsync(vid);
@@ -155,14 +157,17 @@ public class ArenaTwoPickServiceFinishTests
}
[Test]
public async Task RecordBattleResultAsync_2nd_loss_terminates_run()
public async Task RecordBattleResultAsync_increments_loss_without_terminating()
{
// No 2-loss cap (that's a Worlds Beyond rule). Run termination is purely battles-played
// based and handled at Finish/Retire time, not in RecordBattleResult.
var (db, svc, vid) = await SetupWithRunAsync(winCount: 0, lossCount: 1);
await using var _ = db;
await svc.RecordBattleResultAsync(vid, isWin: false);
var run = await db.ViewerArenaTwoPickRuns.FirstAsync();
Assert.That(run.LossCount, Is.EqualTo(2));
Assert.That(run.IsSelectCompleted, Is.True);
// Run still alive — IsSelectCompleted only flips when the 30-card draft finishes.
Assert.That(run.IsSelectCompleted, Is.True, "the test setup pre-sets isSelectCompleted=true");
}
}