private async Task <ScriptRunner <object> > GetCompiledBotScript(BotDto bot) { if (!_botScriptCache.ScriptStored(bot.Id)) { try { await _lock.WaitAsync(); var script = await _botLogic.GetBotScript(bot.Id); var botScript = _botScriptCompiler.Compile(script); _botScriptCache.StoreScript(bot.Id, botScript); } catch (Exception ex) { _logger.Log($"{ex}"); } finally { _lock.Release(); } } return(_botScriptCache.LoadScript(bot.Id)); }
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 async Task <BotDto> EditBot(BotDto bot) { _dbContext.Bots.Attach(_botMapper.Map(bot)); await _dbContext.SaveChangesAsync(); return(_botMapper.Map( await _dbContext.Bots.SingleOrDefaultAsync(x => x.Id == bot.Id))); }
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 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 UpdateMessages(BotDto bot, BotProperties botProperties) { foreach (var message in botProperties.Messages) { Messages.Add(new MessageToCreateDto { BotName = bot.Name, Content = message, DateTime = DateTime.UtcNow }); } }
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 static Bot Build(BotDto bot) { return(new Bot { Id = bot.Id, Name = bot.Name, PlayerName = bot.PlayerName, X = bot.X, Y = bot.Y, Orientation = bot.Orientation }); }
public void UpdateBotProperties(BotDto bot) { foreach (var botProperties in _botProperties.Values) { var botToUpdate = botProperties.Bots.Single(x => x.Id == bot.Id); botToUpdate.Update(bot); } var botPropertiesToUpdate = _botProperties.Values.Single(x => x.BotId == bot.Id); botPropertiesToUpdate.Update(bot); }
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 async Task <ActionResult> CreateBot([FromBody] BotDto botDto) { try { var bot = _mapper.Map <Bot>(botDto); await _botService.CreateNewBotAsync(bot); await _hubContext.Clients.All.BotUpdate("POST", JsonConvert.SerializeObject(_mapper.Map <BotDto>(bot))); return(Ok(_mapper.Map <BotDto>(bot))); } catch (InvalidOperationException ex) { return(BadRequest(ex.Message)); } }
public async Task Process(BotDto bot, ProcessingContext context) { var botProperties = context.GetBotProperties(bot.Id); try { var botScript = await GetCompiledBotScript(bot); var scriptGlobals = ScriptGlobals.Build(botProperties); await botScript.RunAsync(scriptGlobals); } catch { botProperties.CurrentMove = PossibleMoves.ScriptError; } }
public async Task <IActionResult> Get(int id, CancellationToken cancellationToken) { if (id < 1) { return(BadRequest()); } BotDto result = await _botService.Get(id, HttpContext.GetCurrentUserId(), cancellationToken); if (result == null) { return(NotFound()); } return(Ok(result)); }
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 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 async Task <ActionResult> UpdateBot(int id, [FromBody] BotDto botDto) { botDto.BotId = id; try { var updatedBotStatus = await _botService.UpdateBotAsync(_mapper.Map <Bot>(botDto)); await _hubContext.Clients.All.BotUpdate("PUT", JsonConvert.SerializeObject(botDto)); return(Ok(updatedBotStatus)); } catch (InvalidOperationException ex) { return(BadRequest(ex.Message)); } }
public async Task <BotDto> Create(BotDto bot, CancellationToken cancellationToken) { try { var owner = await _database.Users.FirstOrDefaultAsync(x => x.Id == bot.Owner.Id, cancellationToken); var script = await _database.Scripts.FirstOrDefaultAsync(x => x.Id == bot.Script.Id && x.Owner.Id == bot.Owner.Id, cancellationToken); var transport = await _database.Transports.FirstOrDefaultAsync(x => x.Id == bot.Transport.Id, cancellationToken); if (owner == null) { throw new GenericApiException((int)HttpStatusCode.UnprocessableEntity); } else if (script == null) { } else if (transport == null) { } var dbBot = new Bot { Name = bot.Name, Owner = owner, Script = script, BotState = BotState.Created, Transport = transport, Configuration = bot.Configuration }; var result = await _database.Bots.AddAsync(dbBot, cancellationToken); await _database.SaveChangesAsync(cancellationToken); return(result.Adapt <BotDto>()); } catch (OperationCanceledException) { return(null); } catch (Exception ex) { _logger.LogError(ex, "Error during bot creation."); throw; } }
public async Task <BotDto> CreateBot(BotDto bot) { var existingBot = await _dbContext.Bots.SingleOrDefaultAsync(x => x.Name == bot.Name); if (existingBot != null) { throw new BusinessException($"Bot with name {bot.Name} already exists!"); } var botEntity = _botMapper.Map(bot); botEntity.TimeOfBirth = DateTime.UtcNow; _dbContext.Bots.Add(botEntity); await _dbContext.SaveChangesAsync(); return(_botMapper.Map( await _dbContext.Bots.SingleOrDefaultAsync(x => x.Id == botEntity.Id))); }
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>(); }
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 BotMapper_Can_Map_BotDto_To_BotModel() { // Arrange var mapper = new BotMapper(); var botDto = new BotDto { Id = Guid.NewGuid(), Name = "BotName", X = 5, Y = 6, FromX = 7, FromY = 8, Orientation = PossibleOrientations.South, MaximumHealth = 100, CurrentHealth = 98, MaximumStamina = 200, CurrentStamina = 123, Move = PossibleMoves.MeleeAttack, LastAttackX = 1, LastAttackY = 2, TimeOfDeath = new DateTime(2000, 10, 1) }; // Act var botModel = mapper.Map(botDto); // Assert botModel.Should().BeEquivalentTo(botDto, properties => properties .Including(x => x.Id) .Including(x => x.Name) .Including(x => x.X) .Including(x => x.Y) .Including(x => x.FromX) .Including(x => x.FromY) .Including(x => x.Orientation) .Including(x => x.MaximumHealth) .Including(x => x.CurrentHealth) .Including(x => x.MaximumStamina) .Including(x => x.CurrentStamina) .Including(x => x.Move) .Including(x => x.LastAttackX) .Including(x => x.LastAttackY) .Including(x => x.TimeOfDeath)); }
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(); }
private async Task <Script> GetCompiledBotScript(BotDto bot) { if (!_botScriptCache.ScriptStored(bot.Id)) { try { var script = await _botLogic.GetBotScript(bot.Id); var botScript = _botScriptCompiler.Compile(script); _botScriptCache.StoreScript(bot.Id, botScript); } catch (Exception ex) { _logger.LogError($"{ex}"); } } return(_botScriptCache.LoadScript(bot.Id)); }
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); }
private async Task <Script> GetCompiledBotScript(BotDto bot) { if (!ScriptStored(bot.Id)) { try { var script = await _botLogic.GetBotScript(bot.Id); var botScript = Compile(script); StoreScript(bot.Id, botScript); } catch (Exception ex) { // } } return(LoadScript(bot.Id)); }
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); }