/// <summary> /// Двигаемся к золоту /// </summary> /// <param name="moveRate"></param> protected virtual void MoveToGold(MoveRate moveRate) { //TODO: исключить те, что супер далеко или те у которых уже полно пиратов других и своих var tilesWithGold = Board.AllTiles(x => x.Type != TileType.Water && x.Coins > 0).ToList(); //Исключаем, те, что уже у моих пиратов tilesWithGold.RemoveAll(t => MyPirates.Count(e => e.Position.Position == t.Position) >= t.Coins); if (!tilesWithGold.Any()) { return; } //Исключаем золото уже у чужого пирата tilesWithGold.RemoveAll(t => AllEnemies.Count(e => e.Position.Position == t.Position) >= t.Coins); if (!tilesWithGold.Any()) { return; } //Ищем минимальное растояние до золота до хода и после хода var distBefore = tilesWithGold.Select(t => new Tuple <int, Tile>(Distance(moveRate.Move.From.Position, t.Position), t)).ToList(); var distAfter = tilesWithGold.Select(t => new Tuple <int, Tile>(Distance(moveRate.Move.To.Position, t.Position), t)).ToList(); var minMovesBefore = distBefore.Select(t => t.Item1).Min(); var minMovesAfter = distAfter.Select(t => t.Item1).Min(); if (minMovesAfter >= minMovesBefore) { return; } moveRate.AddRate("MoveToGold", (Coef.MoveToGold * DistanceCoef(minMovesAfter))); }
/// <summary> /// Атака /// </summary> /// <param name="moveRate"></param> protected virtual void Atack(MoveRate moveRate) { var enemiesOnPosition = EnemiesOnPosition(moveRate.Move.To.Position); var coinsTo = GoldOnPosition(moveRate.Move.To.Position); var coinsFrom = GoldOnPosition(moveRate.Move.From.Position); if (enemiesOnPosition == 0) // || (coinsTo == 0 && coinsFrom == 0)) { return; } //Если стоим с золотом прямо у корабля - не атакуем если у врага нет золота //if (coinsFrom > 0 && coinsTo == 0 && Distance(MyShip.Position, moveRate.Move.Pirate.Position) == 1) // return; //Если кто-то другой без золота может атаковать этого же чудика, а я с золотом - не бьем var myEmptyFriendAtackers = MyPirates.Count(p => p.Position.Position != moveRate.Move.From.Position && GoldOnPosition(p.Position.Position) == 0 && Distance(p.Position.Position, moveRate.Move.To.Position) <= 1); if (myEmptyFriendAtackers > 0 && coinsFrom > 0) { return; } //Не атаковать если враг в 2-х ходах от его корабля var occupationTeamId = Board.Map[moveRate.Move.To.X, moveRate.Move.To.Y].OccupationTeamId; if (occupationTeamId.HasValue && Distance(Board.Teams[occupationTeamId.Value].Ship.Position, moveRate.Move.To.Position) < 3) { return; } moveRate.AddRate("Atack", (Coef.Atack + ((enemiesOnPosition - 1) * Coef.AtackManyEnemies)) * (1 + coinsFrom * 0.1) * (1 + coinsTo * 0.1)); }
/// <summary> /// Защищаем золото вместо похода с ним домой /// </summary> /// <param name="moveRate"></param> /// <returns></returns> protected override double DefenceGoldCoef(MoveRate moveRate) { var pos = moveRate.Move.From.Position; var goldOnPos = GoldOnPosition(pos); //Если золота > 1 и я от корабля не дальше чем 5 ходов if (goldOnPos < 2 || Distance(MyShip.Position, pos) > 5) { return(1); } //Нет других пиратов //TODO: Проверка по Id пирата который ходит var myOtherPirtates = MyPirates.Where(p => p.Position.Position != moveRate.Move.From.Position).ToList(); if (!myOtherPirtates.Any()) { return(1); } //Возле корабля не защищаем if (Distance(MyShip.Position, pos) == 1) { return(1); } //и до ближайшего моего пирата не менее 4-х ходов if (myOtherPirtates.Min(p => Distance(p.Position.Position, pos)) > 5) { return(1); } //Если уже людей сколько и золота - мотаем на корабль if (MyPirates.Count(p => Distance(p.Position.Position, pos) <= 1) >= Math.Min(2, goldOnPos)) { return(1); } //Если до ближайшего корабля противника меньше 3-х ходов if (AllEnemyShips.Min(s => Distance(s.Position, pos)) < 4) { return(1); } //Если я под атакой 2-х врагов - бежим if (Board.Teams.Count(t => t.Id != TeamId && t.Pirates.Any(p => Distance(p.Position.Position, pos) == 1)) > 1) { return(1); } return(0.2); }
/// <summary> /// Ход под удар /// </summary> /// <param name="moveRate"></param> protected override void MoveUnderAtack(MoveRate moveRate) { //Не боимся слазить с корабля стоя на нем if (moveRate.Move.From.Position == MyShip.Position) { return; } var myAtakers = AllEnemies.Count(p => Distance(p.Position.Position, moveRate.Move.To.Position) == 1); if (myAtakers == 0) { return; } var myDefence = MyPirates.Count(p => Distance(p.Position.Position, moveRate.Move.To.Position) == 1) - 1; if (myDefence < myAtakers) { moveRate.AddApplyToAllRate("MoveUnderAtack", Coef.MoveUnderAtack); } }