public void AddParticipant(Planet participant, PlanetTurn turn, int scheduledTurn) { AttackPlanParticipant order = new AttackPlanParticipant(); order.Source = participant; order.AttackersTurn = turn; order.ScheduledTurn = scheduledTurn; Participants.Add(order); }
public void AddParticipant(Planet participant, PlanetTurn turn, PlanetTurn defendersTurn) { AttackPlanParticipant order = new AttackPlanParticipant(); order.Source = participant; order.AttackersTurn = turn; order.ScheduledTurn = turn.TurnsFromNow; order.DefendersTurn = defendersTurn; Participants.Add(order); }
public void DeterminePlanetStrengthOnFleetArrival() { foreach (Planet defendingPlanet in All.PlanetsUnderattack()) { PlanetTurn lastTurn = defendingPlanet.TurnPrediction.LastTurn; if (defendingPlanet.DoesNotChangeOwner) { //defendingPlanet.MaxDesertersAllowed = Math.Min(defendingPlanet.NumShips, lastTurn.NumShips); } else { //So it does change owner, but is the owner me? if (lastTurn.Owner == 1) { defendingPlanet.ShipsRequiredToSurviveAttack = -1; //If I did not own it from the start, I can send no ships. if (defendingPlanet.IsMine) { //So the part that's left standing does not have to be here. // (this is a too simplified prediction, improve later. defendingPlanet.MaxDesertersAllowed = Math.Max(0 // Negative value, not good for the engine. , Math.Min(defendingPlanet.MaxDesertersAllowed , lastTurn.NumShips // Do not send ships we do not have, will end game quickly. )); } else { defendingPlanet.MaxDesertersAllowed = -1; } } else { //no, it is not mine, how many ships (at least) do we need to capture this? if (defendingPlanet.IsMine) { defendingPlanet.ShipsRequiredToSurviveAttack = lastTurn.NumShips + 1; defendingPlanet.MaxDesertersAllowed = -1; } else { if (defendingPlanet.WinningArmadaIsMine) { } else { defendingPlanet.MaxDesertersAllowed = 0; defendingPlanet.ShipsRequiredToSurviveAttack = defendingPlanet.LastAttackTurn.NumShips + 1; } } } } } }
internal static bool FightBattleAndOwnerSurvived(PlanetTurn lastCalculatedTurn, IGrouping <int, Fleet> turn) { Dictionary <int, int> participants = new Dictionary <int, int>(); participants.Add(lastCalculatedTurn.Owner, lastCalculatedTurn.NumShips); foreach (Fleet fl in turn) { int attackForce; if (participants.TryGetValue(fl.Owner, out attackForce)) { participants[fl.Owner] = attackForce + fl.NumShips; } else { participants.Add(fl.Owner, fl.NumShips); } } Fleet winner = new Fleet(0, 0, null, null, 0, 0); Fleet second = new Fleet(0, 0, null, null, 0, 0); foreach (var fleet in participants) { if (fleet.Value > second.NumShips) { if (fleet.Value > winner.NumShips) { second = winner; winner = new Fleet(fleet.Key, fleet.Value, null, null, 0, 0); } else { second = new Fleet(fleet.Key, fleet.Value, null, null, 0, 0); } } } bool survived; if (winner.NumShips > second.NumShips) { survived = lastCalculatedTurn.Owner == winner.Owner; lastCalculatedTurn.SetValues(winner.Owner, winner.NumShips - second.NumShips); } else { survived = true; lastCalculatedTurn.SetValues(lastCalculatedTurn.Owner, 0); } return(survived); }
public void DoTurn(Universe uni) { currentUniverse = uni; ProcessAttackQueue(); bool attackMade = false; int sumAttackForce = 0; List<AttackPlan> possibleTargets = new List<AttackPlan>(); foreach (var planet in CanUseInAtttack()) { sumAttackForce += planet.AttackForce; //possibleTargets.Clear(); PlanetTurn attackTurn = planet.TurnPrediction[0]; PlanetTurn highestStateTakeOver = new PlanetTurn(0); //find planets that can be attacked with this planets force, from which I have most to gain foreach (var route in planet.Routes .Where(target => IsNotEventuallyMine(target.Destination) && target.Destination.GrowthRate > 0)) { PlanetTurn stateTakeOver = null; PlanetTurn destinationState = route.DestinationStateOnArrival; PlanetTurn startAttackOnRun = attackTurn; if (!destinationState.IsMine) { AttackPlan plan = new AttackPlan(); if (planet.AttackForce > destinationState.NumShips) { stateTakeOver = route.Destination.CalcMaxGainUsingThisManyShips(planet, route.DistanceInTurns, destinationState.NumShips + 5); plan.Enabled = true; } else { do { destinationState = destinationState.Next; startAttackOnRun = startAttackOnRun.Next; } while (destinationState != null && startAttackOnRun.NumShips < destinationState.NumShips); plan.Enabled = destinationState != null && startAttackOnRun != null; if (plan.Enabled) { stateTakeOver = route.Destination.CalcMaxGainUsingThisManyShips(planet, destinationState.TurnsFromNow, startAttackOnRun.NumShips); } } if (plan.Enabled) { plan.AddParticipant(planet, startAttackOnRun, destinationState); plan.Target = route.Destination; plan.Enabled = true; plan.Sweetness = stateTakeOver.NumShips; possibleTargets.Add(plan); highestStateTakeOver = stateTakeOver; } } //PlanetTurn fullAttackState = planet.TurnPrediction.CalcMaxGainUsingThisManyShips(destinationState, planet.AttackForce, TurnPrediction); //planet.TurnPrediction.FindCheapestTakeOverPoint(destinationState.TurnsFromNow, TurnPrediction); } } foreach (AttackPlan plan in possibleTargets.OrderBy(item => -item.Sweetness).Take(10)) { ExecutePlans(plan); } var centerPlanet = currentUniverse.Me.Planets .OrderBy(item => Universe.Center.Delta(item)).FirstOrDefault(); if (centerPlanet != null) { int supportCount = 0; foreach (var planet in CanUseInAtttack()) { if (centerPlanet != planet) { supportCount++; currentUniverse.MakeMove(planet, centerPlanet, Math.Min(planet.AttackForce, 2)); } } } //if (!attackMade) //{ // int targetOwnerId = 0; // if (!currentUniverse.IsDominating) // { // if (rnd.NextDouble() > currentUniverse.Neutral.Planets.Count / (currentUniverse.Enemy.Planets.Count + 0.1)) // { // targetOwnerId = 2; // } // } // else // { // targetOwnerId = 2; // } // var target = currentUniverse.Planets.Values // .Where(planet => planet.LastAttackTurn.NumShips < sumAttackForce - planet.GrowthRate * 2 // && IsNotEventuallyMine(planet) // && planet.GrowthRate > 1 // && planet.Owner == targetOwnerId // ) // .OrderBy(planet => -((planet.GrowthRate + Math.Sqrt(planet.NumShips)) / 3) * 3) // .ThenBy(planet => currentUniverse.Me.ShipOnPlanetFocus.Delta(planet)) // .FirstOrDefault(); // if (target != null) // { // AttackPlan plan = new AttackPlan(); // plan.Enabled = true; // plan.Target = target; // foreach (var planet in CanUseInAtttack()) // { // plan.AddParticipant(planet, planet.TurnPrediction[0], target.TurnPrediction[0]); // } // attackMade = true; // ExecutePlans(plan); // } //} //if (!attackMade && sumAttackForce > 100) //{ // AttackPlan plan = new AttackPlan(); // plan.Enabled = true; // plan.DominationMove = true; // plan.Target = centerPlanet; // foreach (var planet in CanUseInAtttack().Where(item => item != centerPlanet)) // { // plan.AddParticipant(planet, planet.TurnPrediction[0], centerPlanet.TurnPrediction[0]); // } // attackMade = true; // ExecutePlans(plan); //} }
public void DoTurn(Universe uni) { currentUniverse = uni; ProcessAttackQueue(); bool attackMade = false; int sumAttackForce = 0; Dictionary <Planet, PlanetTurn> possibleTargets = new Dictionary <Planet, PlanetTurn>(); foreach (var planet in CanUseInAtttack()) { sumAttackForce += planet.AttackForce; possibleTargets.Clear(); PlanetTurn attackTurn = planet.TurnPrediction[0]; //find planets that can be attacked with this planets force. foreach (var route in planet.Routes .Where(target => IsNotEventuallyMine(target.Destination) && target.Destination.GrowthRate > 0)) { PlanetTurn state = route.Destination.TurnPrediction[route.DistanceInTurns + 1]; if (state.Owner != 1 && state.NumShips < planet.AttackForce) { possibleTargets.Add(route.Destination, state); } } // from the list find the planets from which I have most to gain or which are nearest. if (Universe.TurnCount < 3) { foreach (var item in possibleTargets.OrderBy( target => - target.Key.GrowthRate) .ThenBy(target => target.Value.NumShips)) { if (planet.IsNeutral) { if (planet.AttackForce > item.Value.NumShips) { AttackPlan plan = new AttackPlan(); plan.Enabled = true; plan.AddParticipant(planet, attackTurn, item.Value); plan.Target = item.Key; attackMade = true; ExecutePlans(plan); } else { break; } } } } else { foreach (var item in possibleTargets.OrderBy( target => - ((target.Key.IsNeutral ? 2 : 0) + target.Key.GrowthRate) / currentUniverse.Me.ShipOnPlanetFocus.Delta(target.Key))) { if (planet.AttackForce > item.Value.NumShips) { AttackPlan plan = new AttackPlan(); plan.Enabled = true; plan.AddParticipant(planet, attackTurn, item.Value); plan.Target = item.Key; attackMade = true; ExecutePlans(plan); } else { break; } } } } var centerPlanet = currentUniverse.Me.Planets .OrderBy(item => Universe.Center.Delta(item) + currentUniverse.Enemy.ShipOnPlanetFocus.Delta(item)).FirstOrDefault(); if (centerPlanet != null) { int supportCount = 0; foreach (var planet in CanUseInAtttack()) { if (centerPlanet != planet) { supportCount++; currentUniverse.MakeMove(planet, centerPlanet, Math.Min(planet.AttackForce, 2)); } } } if (!attackMade) { int targetOwnerId = 0; if (!currentUniverse.IsDominating) { if (rnd.NextDouble() > currentUniverse.Neutral.Planets.Count / (currentUniverse.Enemy.Planets.Count + 0.1)) { targetOwnerId = 2; } } else { targetOwnerId = 2; } var target = currentUniverse.Planets.Values .Where(planet => planet.LastAttackTurn.NumShips < sumAttackForce - planet.GrowthRate * 2 && IsNotEventuallyMine(planet) && planet.GrowthRate > 1 && planet.Owner == targetOwnerId ) .OrderBy(planet => - ((planet.GrowthRate + Math.Sqrt(planet.NumShips)) / 3) * 3) .ThenBy(planet => currentUniverse.Me.ShipOnPlanetFocus.Delta(planet)) .FirstOrDefault(); if (target != null) { AttackPlan plan = new AttackPlan(); plan.Enabled = true; plan.Target = target; foreach (var planet in CanUseInAtttack()) { plan.AddParticipant(planet, planet.TurnPrediction[0], target.TurnPrediction[0]); } attackMade = true; ExecutePlans(plan); } } if (!attackMade && sumAttackForce > 100) { AttackPlan plan = new AttackPlan(); plan.Enabled = true; plan.DominationMove = true; plan.Target = centerPlanet; foreach (var planet in CanUseInAtttack().Where(item => item != centerPlanet)) { plan.AddParticipant(planet, planet.TurnPrediction[0], centerPlanet.TurnPrediction[0]); } attackMade = true; ExecutePlans(plan); } }
private AttackPlan BuildDefensePlan(Planet planetUnderAttack, int maxTurnLookAhead) { AttackPlan defensePlan = new AttackPlan(); defensePlan.Target = planetUnderAttack; defensePlan.Reason = "Defense"; planetUnderAttack.IsLost = !planetUnderAttack.WinningArmadaIsMine; PlanetTurn turn = planetUnderAttack.TurnPrediction.FirstTurn; int defenseRequired = 0; if (turn != null) { //this is weird, we are in no danger of losing the planet still this method was called. Abort. if (planetUnderAttack.WinningArmadaIsMine) { return(defensePlan); } //the next turns tells me how many ships I needed, only works if my fleet was not the winning fleet. //that's why the previous exit. defenseRequired = planetUnderAttack.TurnPrediction[turn.TurnsFromNow + 1].NumShips + 1; } else { // So apparently I did not lose ownership of the planet, which means I never did own it. //see if we can block the attack. turn = planetUnderAttack.TurnPrediction.FirstTurn; defenseRequired = turn.NumShips; } int armadaVictoryTurn = turn.TurnsFromNow; //if we want to recapture the planet the next turn how many ships do we need. //Since the enemy gets reinforces immediately after a capture, we are at a -GrowthRate disadvantage. int maxWorthItDistance; switch (planetUnderAttack.GrowthRate) { case 0: case 1: maxWorthItDistance = 5; break; case 2: maxWorthItDistance = 10; break; case 3: case 4: maxWorthItDistance = 15; break; default: maxWorthItDistance = 25; break; } //defend, remember, it's sorted on distance so the closest planets are considered first. foreach (Route route in planetUnderAttack.Routes) { if (route.DistanceInTurns <= Math.Min(maxTurnLookAhead, maxWorthItDistance)) { //look for planet with defense capability Planet defender = route.Destination; if (defender.IsMine && planetUnderAttack.PlanetID != defender.PlanetID) { //is it close enough to contribute to the defense? int defenseTravelTime = (route.DistanceInTurns - 1); if (defenseTravelTime <= armadaVictoryTurn + 1) { //How many ships can we use int maxDelivarableShips = defender.AttackForce; if (defender.DoesNotChangeOwner) { int turnIndex = Math.Max(armadaVictoryTurn - defenseTravelTime, 0); maxDelivarableShips = defender.TurnPrediction[turnIndex].NumShips; } if (maxDelivarableShips > 0) { int prevRequired = defenseRequired; defenseRequired -= maxDelivarableShips; if (defender.NumShips > 0) { defensePlan.Enabled = true; int shipCount; if (defenseRequired > -1) { shipCount = Math.Min(defender.AttackForce, defender.NumShips); defensePlan.AddParticipant(defender, null, shipCount); } else { shipCount = Math.Min(Math.Min(defender.AttackForce, defender.NumShips), prevRequired); defensePlan.AddParticipant(defender, null, shipCount); break; } } } } } } } if (defenseRequired < 0) { planetUnderAttack.DoesNotChangeOwner = true; planetUnderAttack.AttackMovesAllowed = false; planetUnderAttack.IsLost = false; } //Planet is lost, no defense plan. if (planetUnderAttack.IsLost) { defensePlan.Participants.Clear(); } return(defensePlan); }
public void DoTurn(Universe uni) { currentUniverse = uni; ProcessAttackQueue(); bool attackMade = false; int sumAttackForce = 0; List <AttackPlan> possibleTargets = new List <AttackPlan>(); foreach (var planet in CanUseInAtttack()) { sumAttackForce += planet.AttackForce; //possibleTargets.Clear(); PlanetTurn attackTurn = planet.TurnPrediction[0]; PlanetTurn highestStateTakeOver = new PlanetTurn(0); //find planets that can be attacked with this planets force, from which I have most to gain foreach (var route in planet.Routes .Where(target => IsNotEventuallyMine(target.Destination) && target.Destination.GrowthRate > 0)) { PlanetTurn stateTakeOver = null; PlanetTurn destinationState = route.DestinationStateOnArrival; PlanetTurn startAttackOnRun = attackTurn; if (!destinationState.IsMine) { AttackPlan plan = new AttackPlan(); if (planet.AttackForce > destinationState.NumShips) { stateTakeOver = route.Destination.CalcMaxGainUsingThisManyShips(planet, route.DistanceInTurns, destinationState.NumShips + 5); plan.Enabled = true; } else { do { destinationState = destinationState.Next; startAttackOnRun = startAttackOnRun.Next; } while (destinationState != null && startAttackOnRun.NumShips < destinationState.NumShips); plan.Enabled = destinationState != null && startAttackOnRun != null; if (plan.Enabled) { stateTakeOver = route.Destination.CalcMaxGainUsingThisManyShips(planet, destinationState.TurnsFromNow, startAttackOnRun.NumShips); } } if (plan.Enabled) { plan.AddParticipant(planet, startAttackOnRun, destinationState); plan.Target = route.Destination; plan.Enabled = true; plan.Sweetness = stateTakeOver.NumShips; possibleTargets.Add(plan); highestStateTakeOver = stateTakeOver; } } //PlanetTurn fullAttackState = planet.TurnPrediction.CalcMaxGainUsingThisManyShips(destinationState, planet.AttackForce, TurnPrediction); //planet.TurnPrediction.FindCheapestTakeOverPoint(destinationState.TurnsFromNow, TurnPrediction); } } foreach (AttackPlan plan in possibleTargets.OrderBy(item => - item.Sweetness).Take(10)) { ExecutePlans(plan); } var centerPlanet = currentUniverse.Me.Planets .OrderBy(item => Universe.Center.Delta(item)).FirstOrDefault(); if (centerPlanet != null) { int supportCount = 0; foreach (var planet in CanUseInAtttack()) { if (centerPlanet != planet) { supportCount++; currentUniverse.MakeMove(planet, centerPlanet, Math.Min(planet.AttackForce, 2)); } } } //if (!attackMade) //{ // int targetOwnerId = 0; // if (!currentUniverse.IsDominating) // { // if (rnd.NextDouble() > currentUniverse.Neutral.Planets.Count / (currentUniverse.Enemy.Planets.Count + 0.1)) // { // targetOwnerId = 2; // } // } // else // { // targetOwnerId = 2; // } // var target = currentUniverse.Planets.Values // .Where(planet => planet.LastAttackTurn.NumShips < sumAttackForce - planet.GrowthRate * 2 // && IsNotEventuallyMine(planet) // && planet.GrowthRate > 1 // && planet.Owner == targetOwnerId // ) // .OrderBy(planet => -((planet.GrowthRate + Math.Sqrt(planet.NumShips)) / 3) * 3) // .ThenBy(planet => currentUniverse.Me.ShipOnPlanetFocus.Delta(planet)) // .FirstOrDefault(); // if (target != null) // { // AttackPlan plan = new AttackPlan(); // plan.Enabled = true; // plan.Target = target; // foreach (var planet in CanUseInAtttack()) // { // plan.AddParticipant(planet, planet.TurnPrediction[0], target.TurnPrediction[0]); // } // attackMade = true; // ExecutePlans(plan); // } //} //if (!attackMade && sumAttackForce > 100) //{ // AttackPlan plan = new AttackPlan(); // plan.Enabled = true; // plan.DominationMove = true; // plan.Target = centerPlanet; // foreach (var planet in CanUseInAtttack().Where(item => item != centerPlanet)) // { // plan.AddParticipant(planet, planet.TurnPrediction[0], centerPlanet.TurnPrediction[0]); // } // attackMade = true; // ExecutePlans(plan); //} }