Exemplo n.º 1
0
        public List <Move> Play(Stopwatch watch)
        {
// first turn: 1 planet each, same size
            // get neutral planets nearest / highest TimeToValue / Biggest!
            // (afhankelijk van hoe ver weg de tegenstander is, Bigger in begin better dan goedkoop klein planeetje vanwege verwachte langere duur spel)
            // TODO iets bedenken voor combinatie TimeToValue en nabijheid vijandelijke forces (of verwachte spelduur?)
            // TODO (neutral) planeet (veroveren) dichterbij vijand beter of juist niet?


            // check planets that turn from owner

            var healthQ = _gameState.GetHealthPlayerTotal(_me) / _gameState.GetHealthPlayerTotal(_enemyPlayer); // > 1 => winning! more aggressive?

            // Meer vanuit meerdere planeten tegelijk denken, vanuit meerdere planeten tegelijk naar 1 gezamenlijke neighbour sturen

            var myPlanets            = _gameState.Planets.Where(PH.IsMine).ToList();
            var planetsThatNeedHelp  = GetPlanetsThatNeedHelp(myPlanets);
            var planetsThatCanAttack = new List <Planet>(myPlanets);

//            Console.WriteLine($"# {watch.ElapsedMilliseconds} Checked helpless");
            HelpPlanets(planetsThatNeedHelp, planetsThatCanAttack);

//            Console.WriteLine($"# {watch.ElapsedMilliseconds} helped helpless");

            var possibleTargets = GetPossibleTargets();

//            Console.WriteLine($"# {watch.ElapsedMilliseconds} Checked targets");
            if (possibleTargets.hostiles.Any()) // TODO twee of meer... op basis van myPlanets.Count? misschien alleen Neutral? <---------------
            {
                var target  = possibleTargets.hostiles.First();
                var sources = target.NeighboringFriendlyPlanets;

                var source       = sources.First();
                var sourceHealth = source.Target.Health - PlanetMinHealth;
                var targetHealth = target.GetHealthAtTurnKnown(source.TurnsToReach).health;
                var powerNeeded  = targetHealth + PlanetMinTakeoverHealth;
                if (CheckIfEnoughHealthToSendShips(powerNeeded, source.Target))
                {
                    // TODO Check voor target.EnemyNeighbours die dichterbij zijn dan source.TurnsToReach  (en extract dit ff naar een method?) <--------------
//                    if (sourceHealth >= powerNeeded) // only if enemy planet can be taken
//                    {
                    AddMove(powerNeeded, source.Target,
                            target); // TODO meer sturen. Als andere enemy planet dichterbij is dan source, dan kunnen we elke turn allebei steeds een beetje sturen en blijft het alsnog van hem
                }

                // TODO loopje
                var source2 = sources.Skip(1).FirstOrDefault();
                if (source2 != null && !source.Target.InboundHostileShips.Any() && !source2.Target.InboundHostileShips.Any())
                {
                    var source2Health = source2.Target.Health - PlanetMinHealth;
                    var targetHealth2 = target.GetHealthAtTurnKnown(source2.TurnsToReach);
                    if (targetHealth2.owner != _me)
                    {
                        var powerNeeded2 = targetHealth2.health + PlanetMinTakeoverHealth;
                        if (sourceHealth + source2Health >= powerNeeded2) // only if enemy planet can be taken
                        {
                            var hq = (powerNeeded2) / (sourceHealth + source2Health);
                            // TODO half/half? dichtste meest? dichtste wachten tot even ver?
                            AddMove(hq * sourceHealth, source.Target,
                                    target); // TODO meer sturen. Als andere enemy planet dichterbij is dan source, dan kunnen we elke turn allebei steeds een beetje sturen en blijft het alsnog van hem
                            AddMove(hq * source2Health, source2.Target,
                                    target); // TODO meer sturen. Als andere enemy planet dichterbij is dan source, dan kunnen we elke turn allebei steeds een beetje sturen en blijft het alsnog van hem
                        }
                    }

//                    }
                }
            }
//            Console.WriteLine($"# {watch.ElapsedMilliseconds} sent to hostiles");

            if (possibleTargets.neutrals.Any())
            {
                var target = possibleTargets.neutrals.First();
                AttackNeutral(target);

                if (myPlanets.Count > 3)
                {
                    var target2 = possibleTargets.neutrals.Skip(1).FirstOrDefault();
                    if (target2 != null)
                    {
                        AttackNeutral(target2);
                    }
                }
            }
//            Console.WriteLine($"# {watch.ElapsedMilliseconds} sent to neutrals");

            // bij checken of je non-friendly planet wil aanvallen ook checken of je er niet al troepen heen hebt gestuurd
            foreach (var planet in planetsThatCanAttack)
            {
//                Console.WriteLine($"# {planet.Id}");
                if (planet.NeighboringPlanets.All(PH.IsMine)) // misschien ook als alleen Mine of Neutral, wanneer er andere planet is die wel NeighbouringEnemyPlanet heeft, om meer te focussen op enemy?
                {                                             // TODO mag ook als 1tje niet van mij is allemaal naar die sturen
//                    Console.WriteLine($"# {planet.Id} surrounded by friendly");
                    if (!planet.InboundHostileShips.Any())    // TODO zend zoveel als overblijft na laatste ship..
                    {
                        // TODO rekening houden met dat 1 van die planeten binnenkort naar de enemy gaat
                        var planetThatNeedsReinforcementsMost =
//                            planet.ShortestPaths.FirstOrDefault(p => PH.IsHostile(p.Target)).Via;
                            planet.NeighboringPlanets.OrderBy(p => p.NearestEnemyPlanetTurns).First(); // TODO which planet is that, houd rekening met HealthMax
                        // TODO divide between multiple planets?
                        var movePower = planet.Health - PlanetMinHealth;
                        AddMove(movePower, planet, planetThatNeedsReinforcementsMost, false);
                    }
                    continue;
                }

                // check of planeet wel health kan missen
//                var enemies = planet.NeighboringHostilePlanets.ToList();
                //planet.HealthPossibleToReceiveInTurns(enemyPlayer);
//                if (enemies.Any())
//                {
//                    foreach (var enemy in enemies)
//                    {
//                        var health = planet.GetHealthAtTurnKnown(enemy.TurnsToReach);
//                        var enemyHealth = enemy.Target.Health;
//                    }
//                }

                var closestEnemy   = planet.NeighbouringPlanetsDistanceTurns.FirstOrDefault(n => PH.IsHostile(n.Target));
                var closestNeutral = planet.NeighbouringPlanetsDistanceTurns.FirstOrDefault(n => PH.IsNeutral(n.Target));
                var target         = closestEnemy ?? closestNeutral; // kan niet null zijn want eerste if checkt alles Mine
//                var healthAtTurn = planet.GetHealthAtTurnKnown(target.TurnsToReach).health;

                var targetHealth = target.Target.GetHealthAtTurnKnown(target.TurnsToReach);
                if (targetHealth.owner == _me)//is al van mij?
                {
                    //choose other planet :) choose planet in loopje?
                    continue;
                }

                var powerNeeded = targetHealth.health + PlanetMinTakeoverHealth;
//                var planetHealth = planet.Health- PlanetMinHealth;
//                Console.WriteLine($"# {planet.Id} targetting {target.Target.Id} with {planetHealth} against {powerNeeded}");
                if (CheckIfEnoughHealthToSendShips(powerNeeded, planet))//planetHealth > powerNeeded && !planet.InboundShips.Any(PH.IsHostile))) // only if enemy planet can be taken
                {
                    AddMove(powerNeeded, planet, target.Target);
                    continue;
                }

                if (planet.HealthLimitAboutToBeExceeded) // too much health!
                {
                    var target2 = planet.NeighboringPlanets.First();
                    AddMove(planet.GrowthSpeed, planet, target2);
                }
            }

            return(_moves);
        }