public async Task Postprocessor_Go_Should_Kill_Bots_That_Have_Zero_Health_Left() { // Arrange var randomHelper = new Mock <IRandomHelper>(); var postprocessor = new Postprocessor(randomHelper.Object); var arena = new ArenaDto { Width = 1, Height = 1 }; var bot = new BotDto { Id = Guid.NewGuid(), CurrentHealth = 0 }; var bots = new List <BotDto>(new[] { bot }); var context = ProcessingContext.Build(arena, bots); var botProperties = BotProperties.Build(bot, arena, bots); botProperties.CurrentMove = PossibleMoves.Idling; context.AddBotProperties(bot.Id, botProperties); // Act await postprocessor.Go(context); // Assert context.Bots.Should().HaveCount(1); context.Bots.Should().ContainEquivalentOf(new BotDto { Move = PossibleMoves.Died }, c => c.Including(p => p.Move)); }
public async Task BotProcessingFactory_Process_With_Valid_Script_Should_Register_Correct_Move() { // Arrange var botLogic = new Mock <IBotLogic>(); var botScriptCompiler = new BotScriptCompiler(); var botScriptCache = new BotScriptCache(); var logger = new Mock <ILogger>(); var botProcessingFactory = new BotProcessingFactory( botLogic.Object, botScriptCompiler, botScriptCache, logger.Object); var arena = new ArenaDto { Width = 4, Height = 3 }; var bot = new BotDto { Id = Guid.NewGuid() }; var bots = new List <BotDto>(new[] { bot }); var context = ProcessingContext.Build(arena, bots); context.AddBotProperties(bot.Id, BotProperties.Build(bot, arena, bots)); var botScript = "WalkForward();".Base64Encode(); // Mock botLogic.Setup(x => x.GetBotScript(It.IsAny <Guid>())).ReturnsAsync(botScript); // Act await botProcessingFactory.Process(bot, context); // Assert context.GetBotProperties(bot.Id).CurrentMove.Should().Be(PossibleMoves.WalkForward); }
public async Task Postprocessor_Go_Should_Ignore_Bots_That_Have_Negative_Stamina_Left() { // Arrange var randomHelper = new Mock <IRandomHelper>(); var postprocessor = new Postprocessor(randomHelper.Object); var arena = new ArenaDto { Width = 3, Height = 3 }; var bot = new BotDto { Id = Guid.NewGuid(), X = 1, Y = 1, CurrentHealth = 1, CurrentStamina = -1 }; var bots = new List <BotDto>(new[] { bot }); var context = ProcessingContext.Build(arena, bots); var botProperties = BotProperties.Build(bot, arena, bots); botProperties.CurrentMove = PossibleMoves.WalkForward; context.AddBotProperties(bot.Id, botProperties); // Act await postprocessor.Go(context); // Assert context.Bots.Should().HaveCount(1); context.Bots.Should().ContainEquivalentOf(new BotDto { X = 1, Y = 1, CurrentStamina = 0, Move = PossibleMoves.Idling }, c => c.Including(p => p.X) .Including(p => p.Y) .Including(p => p.CurrentStamina) .Including(p => p.Move)); }
public async Task BotProcessingFactory_Process_Without_Valid_Script_Should_Register_ScriptError() { // Arrange var botLogic = new Mock <IBotLogic>(); var botScriptCompiler = new Mock <IBotScriptCompiler>(); var botScriptCache = new Mock <IBotScriptCache>(); var logger = new Mock <ILogger>(); var botProcessingFactory = new BotProcessingFactory( botLogic.Object, botScriptCompiler.Object, botScriptCache.Object, logger.Object); var arena = new ArenaDto { Width = 4, Height = 3 }; var bot = new BotDto { Id = Guid.NewGuid() }; var bots = new List <BotDto>(new[] { bot }); var context = ProcessingContext.Build(arena, bots); context.AddBotProperties(bot.Id, BotProperties.Build(bot, arena, bots)); // Act await botProcessingFactory.Process(bot, context); // Assert context.GetBotProperties(bot.Id).CurrentMove.Should().Be(PossibleMoves.ScriptError); }
void CopyBot(Player p, string botName, string newName) { if (newName == null) { p.Message("Name of new bot required."); return; } if (!Formatter.ValidName(p, newName, "bot")) { return; } PlayerBot bot = Matcher.FindBots(p, botName); if (bot == null) { return; } PlayerBot clone = new PlayerBot(newName, p.level); BotProperties props = new BotProperties(); props.FromBot(bot); props.ApplyTo(clone); clone.Owner = p.name; clone.SetModel(clone.Model); BotsFile.LoadAi(props, clone); // Preserve custom name tag if (bot.DisplayName == bot.name) { clone.DisplayName = newName; } TryAddBot(p, clone); }
public async Task Postprocessor_Go_Should_Allow_A_Bot_To_Teleport_Onto_Another_Idling_Bot() { // Arrange var randomHelper = new Mock <IRandomHelper>(); var postprocessor = new Postprocessor(randomHelper.Object); var arena = new ArenaDto(4, 1); var bot1 = new BotDto { Id = Guid.NewGuid(), X = 0, Y = 0, Orientation = PossibleOrientations.East, CurrentStamina = 15, CurrentHealth = 1 }; var bot2 = new BotDto { Id = Guid.NewGuid(), X = 3, Y = 0, Orientation = PossibleOrientations.West, CurrentStamina = 1, CurrentHealth = 1 }; var bots = new List <BotDto>(new[] { bot1, bot2 }); var context = ProcessingContext.Build(arena, bots); var bot1Properties = BotProperties.Build(bot1, arena, bots); var bot2Properties = BotProperties.Build(bot2, arena, bots); bot1Properties.CurrentMove = PossibleMoves.Teleport; bot1Properties.MoveDestinationX = 3; bot1Properties.MoveDestinationY = 0; bot2Properties.CurrentMove = PossibleMoves.Idling; context.AddBotProperties(bot1.Id, bot1Properties); context.AddBotProperties(bot2.Id, bot2Properties); // Act await postprocessor.Go(context); // Assert context.Bots.Should().HaveCount(2); context.Bots.Should().ContainEquivalentOf(new BotDto { X = 3, Y = 0, FromX = 0, FromY = 0, Orientation = PossibleOrientations.East, CurrentStamina = 15 - Constants.STAMINA_ON_TELEPORT, Move = PossibleMoves.Teleport }, c => c .Including(p => p.X) .Including(p => p.Y) .Including(p => p.FromX) .Including(p => p.FromY) .Including(p => p.Orientation) .Including(p => p.CurrentStamina) .Including(p => p.Move)); context.Bots.Should().ContainEquivalentOf(new BotDto { X = 0, Y = 0, Orientation = PossibleOrientations.West, CurrentStamina = 1, Move = PossibleMoves.Idling }, c => c.Including(p => p.X) .Including(p => p.Y) .Including(p => p.Orientation) .Including(p => p.CurrentStamina) .Including(p => p.Move)); }
public BotResult(BotProperties botProperties) { X = botProperties.X; Y = botProperties.Y; Orientation = botProperties.Orientation; CurrentStamina = botProperties.CurrentStamina; Move = PossibleMoves.Idling; Memory = botProperties.Memory; }
public LiteDBStorage(BotProperties botProperties) { _db = new LiteDatabase(Path.Combine( botProperties.DataDirectory, botProperties.InstanceName.ToLowerInvariant() + ".db")); BsonMapper.Global.EmptyStringToNull = false; InitPropertyStorage(); InitEventStorage(); }
public async Task Postprocessor_Go_Should_Execute_A_Teleport_Before_A_Regular_Move_And_Thus_Block_Other_Bots_In_Their_Path() { // Arrange var randomHelper = new Mock <IRandomHelper>(); var postprocessor = new Postprocessor(randomHelper.Object); var arena = new ArenaDto { Width = 5, Height = 1 }; var bot1 = new BotDto { Id = Guid.NewGuid(), X = 0, Y = 0, Orientation = PossibleOrientations.East, CurrentStamina = 15, CurrentHealth = 1 }; var bot2 = new BotDto { Id = Guid.NewGuid(), X = 4, Y = 0, Orientation = PossibleOrientations.West, CurrentStamina = 1, CurrentHealth = 1 }; var bots = new List <BotDto>(new[] { bot1, bot2 }); var context = ProcessingContext.Build(arena, bots); var bot1Properties = BotProperties.Build(bot1, arena, bots); var bot2Properties = BotProperties.Build(bot2, arena, bots); bot1Properties.CurrentMove = PossibleMoves.Teleport; bot1Properties.MoveDestinationX = 3; bot1Properties.MoveDestinationY = 0; bot2Properties.CurrentMove = PossibleMoves.WalkForward; context.AddBotProperties(bot1.Id, bot1Properties); context.AddBotProperties(bot2.Id, bot2Properties); // Act await postprocessor.Go(context); // Assert context.Bots.Should().HaveCount(2); context.Bots.Should().ContainEquivalentOf(new BotDto { X = 3, Y = 0, Orientation = PossibleOrientations.East, CurrentStamina = 15 - Constants.STAMINA_ON_TELEPORT, Move = PossibleMoves.Teleport }, c => c.Including(p => p.X) .Including(p => p.Y) .Including(p => p.Orientation) .Including(p => p.CurrentStamina) .Including(p => p.Move)); context.Bots.Should().ContainEquivalentOf(new BotDto { X = 4, Y = 0, Orientation = PossibleOrientations.West, CurrentStamina = 1, Move = PossibleMoves.Idling }, c => c.Including(p => p.X) .Including(p => p.Y) .Including(p => p.Orientation) .Including(p => p.CurrentStamina) .Including(p => p.Move)); }
public Task Go(ProcessingContext context) { foreach (var bot in context.Bots) { var botProperties = BotProperties.Build(bot, context.Arena, context.Bots); context.AddBotProperties(bot.Id, botProperties); } return(Task.CompletedTask); }
public TrackerService( ILogger <TrackerService> logger, BotProperties botProperties, IGuildPropertyStorage guildPropertyStorage, IDiscordClient client) { _logger = logger; _botProperties = botProperties; _guildPropertyStorage = guildPropertyStorage; _client = client; }
public async Task Postprocessor_Go_Should_Not_Move_Two_Bots_That_Are_Facing_Each_Other() { // Arrange var randomHelper = new Mock <IRandomHelper>(); var postprocessor = new Postprocessor(randomHelper.Object); var arena = new ArenaDto { Width = 4, Height = 1 }; var bot1 = new BotDto { Id = Guid.NewGuid(), X = 1, Y = 0, Orientation = PossibleOrientations.East, CurrentStamina = 3, CurrentHealth = 1 }; var bot2 = new BotDto { Id = Guid.NewGuid(), X = 2, Y = 0, Orientation = PossibleOrientations.West, CurrentStamina = 4, CurrentHealth = 1 }; var bots = new List <BotDto>(new[] { bot1, bot2 }); var context = ProcessingContext.Build(arena, bots); var bot1Properties = BotProperties.Build(bot1, arena, bots); var bot2Properties = BotProperties.Build(bot2, arena, bots); bot1Properties.CurrentMove = PossibleMoves.WalkForward; bot2Properties.CurrentMove = PossibleMoves.WalkForward; context.AddBotProperties(bot1.Id, bot1Properties); context.AddBotProperties(bot2.Id, bot2Properties); // Act await postprocessor.Go(context); // Assert context.Bots.Should().HaveCount(2); context.Bots.Should().ContainEquivalentOf(new BotDto { X = 1, Y = 0, Orientation = PossibleOrientations.East, CurrentStamina = 3, Move = PossibleMoves.Idling }, c => c.Including(p => p.X) .Including(p => p.Y) .Including(p => p.Orientation) .Including(p => p.CurrentStamina) .Including(p => p.Move)); context.Bots.Should().ContainEquivalentOf(new BotDto { X = 2, Y = 0, Orientation = PossibleOrientations.West, CurrentStamina = 4, Move = PossibleMoves.Idling }, c => c.Including(p => p.X) .Including(p => p.Y) .Including(p => p.Orientation) .Including(p => p.CurrentStamina) .Including(p => p.Move)); }
public void BotProperties_Build_From_Bot_And_Arena_Should_Copy_Properties() { // Arrange var bot = new BotDto { Id = Guid.NewGuid(), X = 1, Y = 2, Orientation = PossibleOrientations.East, Move = PossibleMoves.Teleport, MaximumHealth = 100, CurrentHealth = 99, MaximumStamina = 1000, CurrentStamina = 999, Memory = new Dictionary <String, String>().Serialize() }; var arena = new ArenaDto { Width = 7, Height = 8 }; var bots = new List <BotDto> { new BotDto { Id = Guid.NewGuid(), Name = "BotName", X = 22, Y = 33, Orientation = PossibleOrientations.West } }; // Act var result = BotProperties.Build(bot, arena, bots); // Assert result.Should().NotBeNull(); result.BotId.Should().Be(bot.Id); result.Width.Should().Be(arena.Width); result.Height.Should().Be(arena.Height); result.X.Should().Be(bot.X); result.Y.Should().Be(bot.Y); result.Orientation.Should().Be(bot.Orientation); result.LastMove.Should().Be(bot.Move); result.MaximumHealth.Should().Be(bot.MaximumHealth); result.CurrentHealth.Should().Be(bot.CurrentHealth); result.MaximumStamina.Should().Be(bot.MaximumStamina); result.CurrentStamina.Should().Be(bot.CurrentStamina); result.Memory.Should().BeEquivalentTo(bot.Memory.Deserialize <Dictionary <String, String> >()); result.Messages.Should().BeEquivalentTo(new List <String>()); result.Bots.Should().BeEquivalentTo(bots, p => p .Including(x => x.Id) .Including(x => x.Name) .Including(x => x.X) .Including(x => x.Y) .Including(x => x.Orientation)); result.CurrentMove.Should().Be(PossibleMoves.Idling); }
public void UpdateMessages(BotDto bot, BotProperties botProperties) { foreach (var message in botProperties.Messages) { Messages.Add(new MessageToCreateDto { BotName = bot.Name, Content = message, DateTime = DateTime.UtcNow }); } }
static void Main(string[] args) { try { if (args.Length == 0 || args[0] == "help") { Console.WriteLine("Expecting command"); Console.WriteLine("Available commands:"); Console.WriteLine(" * run <instanceName> <arguments>"); Console.WriteLine(" --discord-token - discord auth token string [MANDATORY]"); Console.WriteLine(" --tracker-url - tracker service url [default=none]"); Console.WriteLine(" --tracker-token - tracker service auth token [default=none]"); Console.WriteLine(" --data-directory - db storage location [default=./]"); Console.WriteLine(" * stop <instanceName>"); return; } BotProperties botProperties = BotProperties.Parse(args); _instanceName = botProperties.InstanceName; NLog.LayoutRenderers.LayoutRenderer.Register("instance", (logevent) => botProperties.InstanceName); NLog.LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration("logger.config"); _logger = NLog.LogManager.GetCurrentClassLogger(); if (string.IsNullOrEmpty(_instanceName)) { throw new ArgumentException("Instance name is not set"); } if (botProperties.Command == "run") { Run(botProperties); } else if (botProperties.Command == "stop") { Stop(); } else { throw new ArgumentException("Unknown command '" + botProperties.Command + "'"); } } catch (Exception ex) { LogError(ex.ToString()); } finally { NLog.LogManager.Shutdown(); } }
public void BotResult_GetInflictedDamage_Should_Return_Zero_For_Unknown_BotId() { // Arrange var bot = new BotDto(); var arena = new ArenaDto(); var botProperties = BotProperties.Build(bot, arena, new List<BotDto>()); var botResult = BotResult.Build(botProperties); // Act var result = botResult.GetInflictedDamage(Guid.NewGuid()); // Assert result.Should().BeZero(); }
public void Building_A_Move_From_TurningAround_Move_Should_Create_An_Instance_Of_TurnAround() { // Arrange var bot = new BotDto { }; var arena = new ArenaDto { Width = 1, Height = 1 }; var botProperties = BotProperties.Build(bot, arena, new List<BotDto>()); botProperties.CurrentMove = PossibleMoves.TurningAround; var randomHelper = new Mock<IRandomHelper>(); // Act var move = Move.Build(botProperties, randomHelper.Object); // Assert move.Should().NotBeNull(); move.Should().BeOfType<TurnAround>(); }
public void BotResult_InflictDamage_Once_Should_Correctly_Register_Damage() { // Arrange var bot = new BotDto(); var arena = new ArenaDto(); var botProperties = BotProperties.Build(bot, arena, new List<BotDto>()); var botResult = BotResult.Build(botProperties); var botId = Guid.NewGuid(); var damage = 123; // Act botResult.InflictDamage(botId, damage); // Assert botResult.GetInflictedDamage(botId).Should().Be(damage); }
public void Executing_An_Unsupported_Move_Should_Do_Nothing(PossibleMoves unsupportedMove) { // Arrange var bot = new BotDto(); var arena = new ArenaDto(1, 1); var botProperties = BotProperties.Build(bot, arena, new List <BotDto>()); botProperties.CurrentMove = unsupportedMove; var randomHelper = new Mock <IRandomHelper>(); // Act var result = Move.Build(botProperties, randomHelper.Object).Go(); // Assert result.Should().NotBeNull(); result.Move.Should().Be(unsupportedMove); }
public void Building_A_Move_From_Unsupported_Move_Should_Create_An_Instance_Of_EmptyMove(PossibleMoves unsupportedMove) { // Arrange var bot = new BotDto(); var arena = new ArenaDto(1, 1); var botProperties = BotProperties.Build(bot, arena, new List <BotDto>()); botProperties.CurrentMove = unsupportedMove; var randomHelper = new Mock <IRandomHelper>(); // Act var move = Move.Build(botProperties, randomHelper.Object); // Assert move.Should().NotBeNull(); move.Should().BeOfType <EmptyMove>(); }
private BotProperties BuildBotProperties() { var bot = new BotDto { X = 1, Y = 2, Orientation = PossibleOrientations.North, Move = PossibleMoves.Idling, MaximumHealth = 100, CurrentHealth = 99, MaximumStamina = 250, CurrentStamina = 150, Memory = new Dictionary <string, string>().Serialize() }; var arena = new ArenaDto(10, 20); return(BotProperties.Build(bot, arena, new List <BotDto>())); }
public void Building_A_Move_From_WalkForward_Move_Should_Create_An_Instance_Of_WalkForward() { // Arrange var bot = new BotDto { }; var arena = new ArenaDto(1, 1); var botProperties = BotProperties.Build(bot, arena, new List <BotDto>()); botProperties.CurrentMove = PossibleMoves.WalkForward; var randomHelper = new Mock <IRandomHelper>(); // Act var move = Move.Build(botProperties, randomHelper.Object); // Assert move.Should().NotBeNull(); move.Should().BeOfType <WalkForward>(); }
public void BotResult_InflictDamage_Twice_Should_Correctly_Register_All_Damage() { // Arrange var bot = new BotDto(); var arena = new ArenaDto(); var botProperties = BotProperties.Build(bot, arena, new List<BotDto>()); var botResult = BotResult.Build(botProperties); var botId = Guid.NewGuid(); var firstDamage = 123; var secondDamage = 234; // Act botResult.InflictDamage(botId, firstDamage); botResult.InflictDamage(botId, secondDamage); // Assert botResult.GetInflictedDamage(botId).Should().Be(firstDamage + secondDamage); }
public void Executing_A_RangedAttack_Into_Thin_Air_Should_Not_Inflict_Damage(int moveDestinationX, int moveDestinationY) { // Arrange var bot = new BotDto { CurrentHealth = 100, X = 1, Y = 1, Orientation = PossibleOrientations.North }; var victim = new BotDto { Id = Guid.NewGuid(), CurrentHealth = 100, X = 1, Y = 0 }; var arena = new ArenaDto { Width = 3, Height = 3 }; var botProperties = BotProperties.Build(bot, arena, new List<BotDto>(new[] { victim })); botProperties.CurrentMove = PossibleMoves.RangedAttack; botProperties.MoveDestinationX = moveDestinationX; botProperties.MoveDestinationY = moveDestinationY; var randomHelper = new Mock<IRandomHelper>(); // Act var result = Move.Build(botProperties, randomHelper.Object).Go(); // Assert result.Should().NotBeNull(); result.GetInflictedDamage(victim.Id).Should().BeZero(); }
public void ProcessingContext_AddBotProperties_Should_Add_BotProperties() { // Arrange var arena = new ArenaDto(4, 5); var bot = new BotDto { Id = Guid.NewGuid() }; var bots = new List <BotDto>(new[] { bot }); var processingContext = ProcessingContext.Build(arena, bots); var botProperties = BotProperties.Build(bot, arena, bots); // Act processingContext.AddBotProperties(bot.Id, botProperties); var result = processingContext.GetBotProperties(bot.Id); // Assert result.Should().NotBeNull(); result.Should().BeSameAs(botProperties); }
public void Executing_A_SelfDestruct_Should_Kill_The_Bot() { // Arrange var bot = new BotDto { CurrentHealth = 100 }; var arena = new ArenaDto(1, 1); var botProperties = BotProperties.Build(bot, arena, new List <BotDto>()); botProperties.CurrentMove = PossibleMoves.SelfDestruct; var randomHelper = new Mock <IRandomHelper>(); // Act var result = Move.Build(botProperties, randomHelper.Object).Go(); // Assert result.Should().NotBeNull(); result.Move.Should().Be(PossibleMoves.SelfDestruct); result.CurrentHealth.Should().BeZero(); }
public void Executing_A_RangedAttack_To_A_Victim_Should_Inflict_Damage() { // Arrange var bot = new BotDto { CurrentHealth = 100, X = 1, Y = 1, Orientation = PossibleOrientations.North }; var victim = new BotDto { Id = Guid.NewGuid(), CurrentHealth = 100, X = 1, Y = 0, Orientation = PossibleOrientations.South }; var arena = new ArenaDto { Width = 3, Height = 3 }; var botProperties = BotProperties.Build(bot, arena, new List<BotDto>(new[] { victim })); botProperties.CurrentMove = PossibleMoves.RangedAttack; botProperties.MoveDestinationX = 1; botProperties.MoveDestinationY = 0; var expectedDamage = Constants.RANGED_DAMAGE; var randomHelper = new Mock<IRandomHelper>(); // Act var result = Move.Build(botProperties, randomHelper.Object).Go(); // Assert result.Should().NotBeNull(); result.GetInflictedDamage(victim.Id).Should().Be(expectedDamage); }
public async Task Postprocessor_Go_Should_Work() { // Arrange var randomHelper = new Mock <IRandomHelper>(); var postprocessor = new Postprocessor(randomHelper.Object); var arena = new ArenaDto { Width = 1, Height = 3 }; var bot = new BotDto { Id = Guid.NewGuid(), X = 0, Y = 2, Orientation = PossibleOrientations.North, CurrentStamina = 10, CurrentHealth = 1 }; var bots = new List <BotDto>(new[] { bot }); var context = ProcessingContext.Build(arena, bots); var botProperties = BotProperties.Build(bot, arena, bots); botProperties.CurrentMove = PossibleMoves.WalkForward; context.AddBotProperties(bot.Id, botProperties); // Act await postprocessor.Go(context); // Assert context.Bots.Should().HaveCount(1); context.Bots.Should().ContainEquivalentOf(new BotDto { X = 0, Y = 1, FromX = 0, FromY = 2, Orientation = PossibleOrientations.North, CurrentStamina = 9, Move = PossibleMoves.WalkForward }, c => c .Including(p => p.X) .Including(p => p.Y) .Including(p => p.FromX) .Including(p => p.FromY) .Including(p => p.Orientation) .Including(p => p.CurrentStamina) .Including(p => p.Move)); }
public void Turning_Around_Should_Work(PossibleOrientations originOrientation, PossibleOrientations destinationOrientation) { // Arrange var bot = new BotDto { Orientation = originOrientation }; var arena = new ArenaDto { Width = 1, Height = 1 }; var botProperties = BotProperties.Build(bot, arena, new List<BotDto>()); botProperties.CurrentMove = PossibleMoves.TurningAround; var randomHelper = new Mock<IRandomHelper>(); var move = Move.Build(botProperties, randomHelper.Object); // Act var botResult = move.Go(); // Assert botResult.Should().NotBeNull(); botResult.Move.Should().Be(PossibleMoves.TurningAround); botResult.Orientation.Should().Be(destinationOrientation); }
public void Vision_Build_Should_Build_Correctly() { // Arrange var arena = new ArenaDto(1, 1); var bot = new BotDto { Id = Guid.NewGuid() }; var bots = new List <BotDto>(new[] { bot }); var botProperties = BotProperties.Build(bot, arena, bots); // Act var result = Vision.Build(botProperties); // Assert result.Should().NotBeNull(); result.Bots.Should().NotBeNull(); result.Bots.Should().HaveCount(0); result.FriendlyBots.Should().NotBeNull(); result.FriendlyBots.Should().HaveCount(0); result.EnemyBots.Should().NotBeNull(); result.EnemyBots.Should().HaveCount(0); }