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

@@ -171,8 +171,8 @@ public class ArenaTwoPickService : IArenaTwoPickService
var rawMaxWins = await _rewards.GetMaxWinCountAsync();
if (rawMaxWins == 0)
{
Console.Error.WriteLine("[ArenaTwoPickService] ArenaTwoPickRewards catalog empty; defaulting MaxBattleCount=7. Run SVSim.Bootstrap to seed.");
return 7;
Console.Error.WriteLine("[ArenaTwoPickService] ArenaTwoPickRewards catalog empty; defaulting MaxBattleCount=5. Run SVSim.Bootstrap to seed.");
return 5;
}
return rawMaxWins;
}
@@ -285,9 +285,12 @@ public class ArenaTwoPickService : IArenaTwoPickService
var run = await _runs.GetByViewerIdAsync(viewerId)
?? throw new ArenaTwoPickException("arena_two_pick_no_active_run");
var maxWins = await _rewards.GetMaxWinCountAsync();
var aCfg = _config.Get<SVSim.Database.Models.Config.ArenaTwoPickConfig>();
bool runOver = run.WinCount >= maxWins || run.LossCount >= aCfg.MaxLosses;
// Classic SV Take Two: run ends after MaxBattles total games played, regardless of the
// win/loss split. No separate loss cap (Worlds Beyond's 2-loss rule does not apply here).
// MaxBattles is derived from MAX(reward.WinCount), which is 5 for the live TK2 catalog.
var maxBattles = await ResolveMaxBattleCountAsync();
int battlesPlayed = run.WinCount + run.LossCount;
bool runOver = battlesPlayed >= maxBattles;
if (requireComplete && !runOver)
throw new ArenaTwoPickException("arena_two_pick_run_not_complete");
@@ -339,11 +342,6 @@ public class ArenaTwoPickService : IArenaTwoPickService
results.Add(isWin);
run.ResultListJson = JsonSerializer.Serialize(results);
if (isWin) run.WinCount += 1; else run.LossCount += 1;
// Mark run complete if max losses reached (win-cap is handled by Finish/Retire).
if (run.LossCount >= aCfg.MaxLosses)
run.IsSelectCompleted = true;
await _runs.UpsertAsync(run);
var viewer = await LoadViewerForGrantsAsync(viewerId);