feat(matching): IBotRoster + hardcoded BotRoster fixture (8 bots, one per class)
AIBotProfile carries the cosmetic metadata the AI rank-battle start endpoint composes into oppo_info. BotRoster.Pick is deterministic per MatchContext so mid-flight retries get the same opponent. ai_id values 4001..4008 are placeholders per the existing ai-start.md TODO — we have no live capture of the prod catalog. Future improvement: migrate Roster to a bot-roster.json seed under SVSim.Bootstrap/Data/seeds/ for editability without rebuilds. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
48
SVSim.UnitTests/Matching/BotRosterTests.cs
Normal file
48
SVSim.UnitTests/Matching/BotRosterTests.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using NUnit.Framework;
|
||||
using SVSim.BattleNode.Bridge;
|
||||
using SVSim.EmulatedEntrypoint.Matching;
|
||||
|
||||
namespace SVSim.UnitTests.Matching;
|
||||
|
||||
[TestFixture]
|
||||
public class BotRosterTests
|
||||
{
|
||||
private static MatchContext Ctx(string userName, string classId) => new(
|
||||
SelfDeckCardIds: Array.Empty<long>(),
|
||||
ClassId: classId, CharaId: classId, CardMasterName: "card_master_node_10015",
|
||||
CountryCode: "JP", UserName: userName, SleeveId: "0",
|
||||
EmblemId: "0", DegreeId: "0", FieldId: 0, IsOfficial: 0, BattleType: 11);
|
||||
|
||||
[Test]
|
||||
public void Pick_returns_a_bot_with_valid_ai_id()
|
||||
{
|
||||
var roster = new BotRoster();
|
||||
var bot = roster.Pick(Ctx("PlayerA", "1"));
|
||||
|
||||
Assert.That(bot.AiId, Is.InRange(4001, 4008));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Pick_returns_bot_with_class_metadata_set()
|
||||
{
|
||||
var roster = new BotRoster();
|
||||
var bot = roster.Pick(Ctx("PlayerA", "1"));
|
||||
|
||||
Assert.That(bot.ClassId, Is.InRange(1, 8));
|
||||
Assert.That(bot.CharaId, Is.InRange(1, 8));
|
||||
Assert.That(bot.UserName, Is.Not.Null.And.Not.Empty);
|
||||
Assert.That(bot.CountryCode, Is.EqualTo("NONE"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Pick_is_deterministic_per_match_context()
|
||||
{
|
||||
var roster = new BotRoster();
|
||||
var ctx = Ctx("PlayerA", "3");
|
||||
|
||||
var a = roster.Pick(ctx);
|
||||
var b = roster.Pick(ctx);
|
||||
|
||||
Assert.That(a, Is.EqualTo(b), "Same ctx → same bot, so mid-flight retries get the same opponent.");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user