Beispiel #1
0
        /// <summary>
        /// Двигаемся к закрытому
        /// </summary>
        /// <param name="moveRate"></param>
        protected virtual void MoveToUnknown(MoveRate moveRate)
        {
            var tilesWithUnknown = Board.AllTiles(x => x.Type == TileType.Unknown).ToList();

            if (!tilesWithUnknown.Any())
            {
                return;
            }

            //Ищем минимальное растояние до закрытого до хода и после хода
            var distBefore = tilesWithUnknown.Select(t => new Tuple <int, Tile>(Distance(moveRate.Move.From.Position, t.Position), t)).ToList();
            var distAfter  = tilesWithUnknown.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();

            //TODO: Ищем кол-во закрытых в радиусе. Приоритет отдать тем, что близко к своему караблю

            if (minMovesAfter >= minMovesBefore)
            {
                return;
            }

            moveRate.AddRate("MoveToUnknown", Coef.MoveToUnknown * DistanceCoef(minMovesAfter));
        }
Beispiel #2
0
 protected void AboardToShipWithGold(MoveRate moveRate)
 {
     if (moveRate.Move.WithCoins && TargetIsShip(moveRate.Move))
     {
         moveRate.AddRate("AboardToShipWithGold", Coef.AboardToShipWithGold);
     }
 }
Beispiel #3
0
        /// <summary>
        /// Отнимаем золото
        /// </summary>
        /// <param name="moveRate"></param>
        protected void MoveToOccupiedGold(MoveRate moveRate)
        {
            var tilesWithGold = Board.AllTiles(x => x.Type != TileType.Water && x.Coins > 0).ToList();

            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("MoveToOccupiedGold", (Coef.MoveToOccupiedGold * DistanceCoef(minMovesAfter)));
        }
Beispiel #4
0
        /// <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)));
        }
Beispiel #5
0
        /// <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));
        }
Beispiel #6
0
        /// <summary>
        /// перемещаем золото ближе к кораблю
        /// </summary>
        /// <param name="moveRate"></param>
        protected override void MoveToShipWithGold(MoveRate moveRate)
        {
            if (!moveRate.Move.WithCoins)
            {
                return;
            }

            var currentDistance = Distance(moveRate.Move.From.Position, MyShip.Position);
            var newDistance     = Distance(moveRate.Move.To.Position, MyShip.Position);

            if (currentDistance <= newDistance)
            {
                return;
            }

            moveRate.AddRate("MoveToShipWithGold", Coef.MoveToShipWithGold * DefenceGoldCoef(moveRate));
        }
Beispiel #7
0
        /// <summary>
        /// Двигаемся к золоту
        /// </summary>
        /// <param name="moveRate"></param>
        protected override void MoveToGold(MoveRate moveRate)
        {
            //Если я уже с золотом - нечего бегать за другим
            if (GoldOnPosition(moveRate.Move.From.Position) > 0)
            {
                return;
            }

            //Ищем все золото к кому приближаемся
            var tilesWithGold = Board.AllTiles(x => x.Type != TileType.Water && x.Coins > 0 && Distance(moveRate.Move.From.Position, x.Position) > Distance(moveRate.Move.To.Position, x.Position)).Select(t => new PosRate(t.Position)).ToList();

            if (!tilesWithGold.Any())
            {
                return;
            }

            //Для каждого золота считаем
            tilesWithGold.ForEach(t => t.Rate = t.Rate * MoveToGoldNewPosDistanceCoef(moveRate.Move.To.Position, t.Pos));

            //расстояние до своего корабля
            tilesWithGold.ForEach(t => t.Rate = t.Rate * MoveToGoldMyShipDistanceCoef(MyShip.Position, t.Pos));

            //расстояние до ближайшего чужего корабля
            tilesWithGold.ForEach(t => t.Rate = t.Rate * MoveToGoldEnemyShipDistanceCoef(t.Pos));

            //даем приемущество шариться по углам (треугольнико от углов)
            //tilesWithGold.ForEach(t => t.Rate = t.Rate * MoveToGoldCornersDistanceCoef(t.Pos));

            //Если двигаем корабль к золоту - чуток получаем приемущество
            //Если двигаем корабль - чуток получаем приемущество
            if (IsShipMove(moveRate.Move))
            {
                tilesWithGold.ForEach(t => t.Rate = t.Rate * 1.05);
            }

            //TODO: кол-во чужих и своих пиратов которым ближе чем мне. Исключам то золото которое не отнять или оно уже у нас
            tilesWithGold.ForEach(t => t.Rate = t.Rate * MoveToGoldOccupaneCoef(moveRate.Move.From.Position, t.Pos));


            //берем наилучший вариант
            var res = tilesWithGold.Max(t => t.Rate);

            moveRate.AddRate("MoveToGold", Coef.MoveToGold * res);
        }
Beispiel #8
0
        /// <summary>
        /// Уход от удара
        /// </summary>
        /// <param name="moveRate"></param>
        protected override void MoveFromAtack(MoveRate moveRate)
        {
            //Не боимся слазить с корабля стоя на нем
            if (moveRate.Move.From.Position == MyShip.Position)
            {
                return;
            }

            if (AllEnemies.Any(e => Distance(e.Position.Position, moveRate.Move.From.Position) == 1) &&
                AllEnemies.All(e => Distance(e.Position.Position, moveRate.Move.To.Position) != 1))
            {
                moveRate.AddRate("MoveFromAtack", Coef.MoveFromAtack
                                 * (moveRate.Move.WithCoins ? 1.3 : 1)
                                 * (GoldOnPosition(moveRate.Move.To.Position) > 0 ? 1.2 : 1)
                                 * (Distance(moveRate.Move.From.Position, MyShip.Position) > Distance(moveRate.Move.To.Position, MyShip.Position) ? 1.1 : 1)
                                 * (Distance(moveRate.Move.From.Position, MyShip.Position) < Distance(moveRate.Move.To.Position, MyShip.Position) ? 0.9 : 1)
                                 );
                moveRate.AddApplyToAllRate("MoveFromAtackToAll", Coef.MoveFromAtackToAll);
            }
        }
Beispiel #9
0
        /// <summary>
        /// перемещаем золото ближе к кораблю
        /// </summary>
        /// <param name="moveRate"></param>
        protected override void MoveShipToMyPirateWithGold(MoveRate moveRate)
        {
            if (!IsShipMove(moveRate.Move))
            {
                return;
            }

            var myPiratesWithGold = MyPirates.Where(p => GoldOnPosition(p.Position.Position) > 0 && Distance(moveRate.Move.From.Position, p.Position.Position) > Distance(moveRate.Move.To.Position, p.Position.Position)).ToList();

            if (!myPiratesWithGold.Any())
            {
                return;
            }

            var coins = myPiratesWithGold.Sum(p => GoldOnPosition(p.Position.Position));

            moveRate.AddRate("MoveShipToPirateWithGold", Coef.MoveToShipWithGold
                             * (myPiratesWithGold.Count > 1 ? (1 + myPiratesWithGold.Count * 0.1) : 1)
                             * (coins > 1 ? (1 + coins * 0.1) : 1)
                             );
        }
Beispiel #10
0
        /// <summary>
        /// Двигаемся к закрытому
        /// </summary>
        /// <param name="moveRate"></param>
        protected override void MoveToUnknown(MoveRate moveRate)
        {
            //Собираем все закрытые к которым приближаемся
            var tilesWithUnknown = Board.AllTiles(x => x.Type == TileType.Unknown && Distance(moveRate.Move.From.Position, x.Position) > Distance(moveRate.Move.To.Position, x.Position)).Select(t => new PosRate(t.Position)).ToList();

            if (!tilesWithUnknown.Any())
            {
                return;
            }

            //Cчитаем коэф закрытых к оставшемуся золоту - шансы на золото
            var hiddenGold = 37 - Board.AllTiles(t => t.Coins > 0).Sum(t => t.Coins) - Board.Teams.Sum(t => t.Ship.Coins);

            if (hiddenGold == 0)
            {
                return;
            }

            var unknownCount    = Board.AllTiles(t => t.Type == TileType.Unknown).Count();
            var goldPossibility = (double)unknownCount / hiddenGold;

            if (goldPossibility > 30)
            {
                goldPossibility = 0.3;
            }
            else if (goldPossibility > 8)
            {
                goldPossibility = 0.6;
            }
            else if (goldPossibility > 2)
            {
                goldPossibility = 0.8;
            }
            else
            {
                goldPossibility = 1;
            }

            //Для каждого:
            //расстояние до пирата
            tilesWithUnknown.ForEach(t => t.Rate = t.Rate * MoveToUnknownPirateDistanceCoef(moveRate.Move.To.Position, t.Pos));

            //расстояние до своего корабля
            tilesWithUnknown.ForEach(t => t.Rate = t.Rate * MoveToUnknownMyShipDistanceCoef(MyShip.Position, t.Pos));

            //расстояние до ближайшего чужего корабля
            tilesWithUnknown.ForEach(t => t.Rate = t.Rate * MoveToUnknownEnemyShipDistanceCoef(t.Pos));

            //даем приемущество шариться по углам (треугольнико от углов)
            tilesWithUnknown.ForEach(t => t.Rate = t.Rate * MoveToUnknownCornersDistanceCoef(t.Pos));

            //Если двигаем корабль - чуток получаем приемущество
            if (IsShipMove(moveRate.Move))
            {
                tilesWithUnknown.ForEach(t => t.Rate = t.Rate * 1.05);
            }

            //TODO: коэф присутствия врагов

            //берем наилучший вариант * goldPossibility
            var res = tilesWithUnknown.Max(t => t.Rate) * goldPossibility;

            moveRate.AddRate("MoveToUnknown", Coef.MoveToUnknown * res);
        }