feat(tk2): weighted-group reward picking
Replaces the all-rows-granted reward model with per-group weighted pick. Each ArenaTwoPickReward row now belongs to a RewardGroup with a Weight; finish/retire groups the WinCount's rows by RewardGroup and picks exactly one row per group, weighted by Weight (excluding Weight==0). A RewardNum==0 outcome skips both the grant and the rewards[] emission. Empty WinCount catalogs emit empty arrays. Existing seed entries preserve deterministic behavior by living in single-option groups (each with weight 1). Future seasons can expand groups to multi-option for true randomized rewards (e.g. 200-280 rupies). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
[
|
||||
{ "win_count": 0, "reward_type": 4, "reward_id": 80001, "reward_num": 1 },
|
||||
{ "win_count": 0, "reward_type": 9, "reward_id": 0, "reward_num": 100 },
|
||||
{ "win_count": 1, "reward_type": 4, "reward_id": 80001, "reward_num": 1 },
|
||||
{ "win_count": 1, "reward_type": 9, "reward_id": 0, "reward_num": 300 },
|
||||
{ "win_count": 2, "reward_type": 4, "reward_id": 80001, "reward_num": 1 },
|
||||
{ "win_count": 2, "reward_type": 9, "reward_id": 0, "reward_num": 500 },
|
||||
{ "win_count": 3, "reward_type": 4, "reward_id": 80001, "reward_num": 1 },
|
||||
{ "win_count": 3, "reward_type": 9, "reward_id": 0, "reward_num": 700 },
|
||||
{ "win_count": 4, "reward_type": 4, "reward_id": 80001, "reward_num": 1 },
|
||||
{ "win_count": 4, "reward_type": 9, "reward_id": 0, "reward_num": 850 },
|
||||
{ "win_count": 5, "reward_type": 4, "reward_id": 80001, "reward_num": 1 },
|
||||
{ "win_count": 5, "reward_type": 9, "reward_id": 0, "reward_num": 1000 }
|
||||
{ "win_count": 0, "reward_group": 1, "weight": 1, "reward_type": 4, "reward_id": 80001, "reward_num": 1 },
|
||||
{ "win_count": 0, "reward_group": 2, "weight": 1, "reward_type": 9, "reward_id": 0, "reward_num": 100 },
|
||||
{ "win_count": 1, "reward_group": 1, "weight": 1, "reward_type": 4, "reward_id": 80001, "reward_num": 1 },
|
||||
{ "win_count": 1, "reward_group": 2, "weight": 1, "reward_type": 9, "reward_id": 0, "reward_num": 300 },
|
||||
{ "win_count": 2, "reward_group": 1, "weight": 1, "reward_type": 4, "reward_id": 80001, "reward_num": 1 },
|
||||
{ "win_count": 2, "reward_group": 2, "weight": 1, "reward_type": 9, "reward_id": 0, "reward_num": 500 },
|
||||
{ "win_count": 3, "reward_group": 1, "weight": 1, "reward_type": 4, "reward_id": 80001, "reward_num": 1 },
|
||||
{ "win_count": 3, "reward_group": 2, "weight": 1, "reward_type": 9, "reward_id": 0, "reward_num": 700 },
|
||||
{ "win_count": 4, "reward_group": 1, "weight": 1, "reward_type": 4, "reward_id": 80001, "reward_num": 1 },
|
||||
{ "win_count": 4, "reward_group": 2, "weight": 1, "reward_type": 9, "reward_id": 0, "reward_num": 850 },
|
||||
{ "win_count": 5, "reward_group": 1, "weight": 1, "reward_type": 4, "reward_id": 80001, "reward_num": 1 },
|
||||
{ "win_count": 5, "reward_group": 2, "weight": 1, "reward_type": 9, "reward_id": 0, "reward_num": 1000 }
|
||||
]
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace SVSim.Bootstrap.Importers;
|
||||
|
||||
/// <summary>
|
||||
/// Idempotent upsert of <see cref="ArenaTwoPickReward"/> rows from
|
||||
/// <c>arena-two-pick-rewards.json</c>. Key = (WinCount, RewardType, RewardId).
|
||||
/// <c>arena-two-pick-rewards.json</c>. Key = (WinCount, RewardGroup, RewardType, RewardId, RewardNum).
|
||||
/// </summary>
|
||||
public class ArenaTwoPickRewardImporter
|
||||
{
|
||||
@@ -22,23 +22,25 @@ public class ArenaTwoPickRewardImporter
|
||||
|
||||
var seeds = SeedLoader.LoadList<ArenaTwoPickRewardSeed>(path);
|
||||
var existing = await context.ArenaTwoPickRewards
|
||||
.ToDictionaryAsync(r => (r.WinCount, r.RewardType, r.RewardId));
|
||||
.ToDictionaryAsync(r => (r.WinCount, r.RewardGroup, r.RewardType, r.RewardId, r.RewardNum));
|
||||
|
||||
int upserted = 0;
|
||||
foreach (var s in seeds)
|
||||
{
|
||||
if (existing.TryGetValue((s.WinCount, s.RewardType, s.RewardId), out var row))
|
||||
if (existing.TryGetValue((s.WinCount, s.RewardGroup, s.RewardType, s.RewardId, s.RewardNum), out var row))
|
||||
{
|
||||
row.RewardNum = s.RewardNum;
|
||||
row.Weight = s.Weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.ArenaTwoPickRewards.Add(new ArenaTwoPickReward
|
||||
{
|
||||
WinCount = s.WinCount,
|
||||
RewardType = s.RewardType,
|
||||
RewardId = s.RewardId,
|
||||
RewardNum = s.RewardNum,
|
||||
WinCount = s.WinCount,
|
||||
RewardGroup = s.RewardGroup,
|
||||
Weight = s.Weight,
|
||||
RewardType = s.RewardType,
|
||||
RewardId = s.RewardId,
|
||||
RewardNum = s.RewardNum,
|
||||
});
|
||||
}
|
||||
upserted++;
|
||||
|
||||
@@ -4,8 +4,10 @@ namespace SVSim.Bootstrap.Models.Seed;
|
||||
|
||||
public class ArenaTwoPickRewardSeed
|
||||
{
|
||||
[JsonPropertyName("win_count")] public int WinCount { get; set; }
|
||||
[JsonPropertyName("reward_type")] public int RewardType { get; set; }
|
||||
[JsonPropertyName("reward_id")] public long RewardId { get; set; }
|
||||
[JsonPropertyName("reward_num")] public int RewardNum { get; set; }
|
||||
[JsonPropertyName("win_count")] public int WinCount { get; set; }
|
||||
[JsonPropertyName("reward_group")] public int RewardGroup { get; set; }
|
||||
[JsonPropertyName("weight")] public int Weight { get; set; } = 1;
|
||||
[JsonPropertyName("reward_type")] public int RewardType { get; set; }
|
||||
[JsonPropertyName("reward_id")] public long RewardId { get; set; }
|
||||
[JsonPropertyName("reward_num")] public int RewardNum { get; set; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user