} // calculated at turn start public void SetInboundShips(IEnumerable <Ship> ships) { HealthAtTurnKnown = new Dictionary <int, (float health, int?owner, bool ownerChanged)>(NeighbouringPlanetsDistanceTurns?.Last()?.TurnsToReach ?? 0); InboundShips = ships.OrderBy(s => s.TurnsToReachTarget).ToList(); InboundHostileShips = InboundShips.Where(s => PH.IsHostile(s)).ToList(); HealthDiffInboundForTurns = InboundShips.GroupBy(s => s.TurnsToReachTarget, s => s).ToDictionary(g => g.Key, g => g.GroupBy(s2 => s2.Owner).Select(s => (s.Key, s.Sum(s2 => s2.Power))).ToList() ); }
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); }