public List<AttackPlan> BuildActionPlan(Universe uni) { currentUniverse = uni; StartOfTurn(); DefendOnwedPlanets(); DefendNeutralPlanets(MaxTurnLookaheadForNeutralDefense); List<AttackPlan> battleplan = new List<AttackPlan>(); foreach (Planet onwedPlanet in currentUniverse.Me.Planets.Where(OwnedPlanetCanSendAttackForce)) { if (SourcePlanetSelected(onwedPlanet)) { var planetTravelMap = Universe.TravelMap[onwedPlanet.PlanetID]; if (PlanetRouteSelected(onwedPlanet, planetTravelMap)) { bool continueRoute = true; AttackPlan attack = new AttackPlan(); foreach (Route route in planetTravelMap) { Planet hostile = currentUniverse.AllPlanetsOnPlanetId[route.TagetPlanetId]; if (!hostile.IsMine) { attack.Distance = route.DistanceInTurns; attack.Source = onwedPlanet; attack.Target = hostile; attack.Enabled = false; CreateAttackPlanForOwnedPlanet(attack, route, planetTravelMap, ref continueRoute); if (attack.Enabled) { battleplan.Add(attack); attack = new AttackPlan(); } } if (!continueRoute) { break; } } } PlanetRouteDeSelected(onwedPlanet, planetTravelMap); } } if (!TakeGamble_DoNotCountOutgoingShipsForOneTurn) { //attack planets for all fleets in transit foreach (Planet planet in uni.All.Planets) { if (!(planet.IsLost || planet.Armada.Count == 0)) { foreach (Fleet attackforce in planet.Armada) { if (attackforce.IsMine) { planet.RemoveShips(attackforce.NumShips); } } } } } TakeGamble_DoNotCountOutgoingShipsForOneTurn = false; return battleplan; }
private void AddPlan(AttackPlan plan) { if (IsHelpVisible) { toolStrip1.Items.OfType <ToolStripItem>().Where(x => x.Tag == null || x.Tag.ToString() != "OWN_VISIBILITY").ForEach(x => x.Visible = true); toolStrip2.Visible = true; AllPlans.Controls.Clear(); } var newPlanDropdownItm = new ToolStripMenuItem("", null, SelectPlan); newPlanDropdownItm.Text = GetAttackToolstripText(plan); AttackDropDown.DropDownItems.Add(newPlanDropdownItm); var newPlan = new AttackPlanControl(WorldUnits.Default.ImageList, plan); newPlan.Visible = false; newPlan.Dock = DockStyle.Fill; _plans.Add(plan, new Tuple <ToolStripMenuItem, AttackPlanControl>(newPlanDropdownItm, newPlan)); AllPlans.Controls.Add(newPlan); foreach (AttackPlanFrom attack in plan.Attacks) { newPlan.AddAttacker(attack); } Timer.Enabled = true; }
public ActionResult Attack(Board b, Player p, AttackPlan plan) { // Basic tests if (b.AttackIsInvalid(plan)) { return(ActionResult.INVALID); } // Always win var r = new ActionResult() { AttackWasInvalid = false, Plan = plan, AttackSucceeded = true, Animations = new List <BaseAnimation>() }; // Add battle animation r.Animations.Add(new AttackAnimation(b, plan.Attacker, plan.Defender, new System.Threading.Tasks.Task(() => { if (plan.Defender.Owner != null) { plan.Defender.Owner.Zones.Remove(plan.Defender); if (plan.Defender.Owner.Zones.Count == 0) { plan.Defender.Owner.IsDead = true; } } plan.Defender.Owner = plan.Attacker.Owner; plan.Attacker.Owner.Zones.Add(plan.Defender); plan.Defender.Strength = plan.Attacker.Strength - 1; plan.Attacker.Strength = 1; }))); return(r); }
private void RemovePlan(AttackPlan plan) { var attackControls = _plans[plan]; AllPlans.Controls.Remove(attackControls.Item2); AttackDropDown.DropDownItems.Remove(attackControls.Item1); _plans.Remove(plan); if (ActivePlan == attackControls.Item2) { if (AttackDropDown.DropDownItems.Count > 0) { SelectPlan(AttackDropDown.DropDownItems[0], EventArgs.Empty); } else { SelectPlan(null, EventArgs.Empty); } } if (!_plans.Any()) { ShowHelp(); } }
private void cbAttackPlans_TextUpdate(object sender, EventArgs e) { if (attackPlansBindingSource.Current != null) { AttackPlan plan = (AttackPlan)attackPlansBindingSource.Current; plan.Name = cbAttackPlans.Text; } }
public AttackPlanControl(ImageList imageList, AttackPlan plan) { InitializeComponent(); _unitImageList = imageList; Plan = plan; SetControlProperties(); }
public void AttackRemoveTarget(object sender, AttackPlan plan) { var e = new AttackEventArgs(plan, null); if (TargetRemoved != null) { TargetRemoved(sender, e); } }
/// <summary> /// Returns true if this attack is invalid /// </summary> /// <param name="plan"></param> /// <returns></returns> public bool AttackIsInvalid(AttackPlan plan) { return(plan == null || plan.Attacker == null || plan.Defender == null || plan.Attacker.Owner == null || plan.Attacker.Strength <= 1 || !plan.Attacker.Neighbors.Contains(plan.Defender) || plan.Attacker.Owner == plan.Defender.Owner); }
private string GetAttackToolstripText(AttackPlan plan) { Village vil = plan.Target; string attackDesc = string.Format(ControlsRes.AttackPlanCollectionControl_PlanExportCaption, vil.LocationString, vil.Name, Common.GetPrettyNumber(vil.Points), plan.Attacks.Count()); if (vil.HasPlayer) { attackDesc += string.Format(ControlsRes.AttackPlanCollectionControl_PlanExportCaption_OnPlayer, vil.Player.Name); } return(attackDesc); }
private static void AssignPlan(AttackPlan assignPlan, World world) { if (assignPlan != null) { var gelu = world.Objects.OfType <Gelu>().Single(); var catherine = world.Objects.OfType <Catherine>().Single(); var shift = new Point(1, 1); gelu.SetPathPlan(assignPlan.GeluPath.Select(p => p.Add(shift)).ToArray()); catherine.SetPathPlan(assignPlan.CatherinePath.Select(p => p.Add(shift)).ToArray()); } }
public VillageContextMenu(Map map, Village village, Action onVillageTypeChangeDelegate = null) { _village = village; _map = map; _onVillageTypeChangeDelegate = onVillageTypeChangeDelegate; _attackPlan = World.Default.Map.Manipulators.AttackManipulator.GetPlan(_village, out _isActiveAttackPlan, out _attacker, false); _menu = JanusContextMenu.Create(); AddAttackPlanItems(); _menu.AddSeparator(); if (map.Display.IsVisible(village)) { _menu.AddCommand(ControlsRes.ContextMenu_QuickDetails, OnPinPoint, Properties.Resources.LeftNavigation_QuickFind); } _menu.AddCommand(ControlsRes.ContextMenu_PinpointAndCenter, OnPinpointAndCenter, Properties.Resources.TeleportIcon); _menu.AddSeparator(); _menu.AddSetVillageTypeCommand(OnVillageTypeChange, village); if (World.Default.Settings.Church) { var church = _map.Manipulators.ChurchManipulator.GetChurch(_village); AddChurchCommands(_menu, church, ChurchChange_Click); } if (village.HasPlayer) { _menu.AddSeparator(); _menu.AddPlayerContextCommands(map, village.Player, false); if (village.HasTribe) { _menu.AddTribeContextCommands(map, village.Player.Tribe); } if (village.PreviousVillageDetails != null && village.PreviousVillageDetails.Player != village.Player && village.PreviousVillageDetails.Player != null) { var oldPlayer = World.Default.GetPlayer(village.PreviousVillageDetails.Player.Name); _menu.AddPlayerNobledContextCommands(map, oldPlayer ?? village.PreviousVillageDetails.Player, true); } } _menu.AddSeparator(); _menu.AddCommand(ControlsRes.ContextMenu_TwStats, OnTwStats); _menu.AddCommand(ControlsRes.ContextMenu_ToClipboard, OnToClipboard, Properties.Resources.clipboard); _menu.AddCommand(ControlsRes.ContextMenu_ToBbCode, OnBbCode, Properties.Resources.clipboard); }
public void HandleTouch(object sender, SKPoint location) { if (!GameBoard.CurrentPlayer.IsHuman) { return; } // Was this an end turn touch? if (Dimensions.EndTurnRect.Rect.Contains(location)) { Playing = GameBoard.EndTurn(); } // Figure out what zone was touched var zone = HitTestZone(location); if (zone == null) { return; } // Set an attacker if (this.Attacking == null) { if (zone.Owner.Number != GameBoard.CurrentTurn) { return; } this.Attacking = zone; return; } // Setup attack plan var plan = new AttackPlan() { Attacker = Attacking, Defender = zone }; // Execute the attack and see what the result is ExecuteAttackPlan(plan); }
public ActionResult Attack(Board b, Player p, AttackPlan plan) { // Basic tests if (b.AttackIsInvalid(plan)) { return(ActionResult.INVALID); } // Roll dice based on strength - note that one unit must stay home for attacker int attacker_roll = b.Roll(plan.Attacker.Strength - 1, 6); int defender_roll = b.Roll(plan.Defender.Strength, 6); bool wins = attacker_roll > defender_roll; // Handle the best roll var r = new ActionResult() { AttackWasInvalid = false, Plan = plan, AttackSucceeded = wins, Animations = new List <BaseAnimation>() }; r.Animations.Add(new AttackAnimation(b, plan.Attacker, plan.Defender, new System.Threading.Tasks.Task(() => { if (wins) { if (plan.Defender.Owner != null) { plan.Defender.Owner.Zones.Remove(plan.Defender); if (plan.Defender.Owner.Zones.Count == 0) { plan.Defender.Owner.IsDead = true; } } plan.Defender.Owner = plan.Attacker.Owner; plan.Attacker.Owner.Zones.Add(plan.Defender); plan.Defender.Strength = plan.Attacker.Strength - 1; } plan.Attacker.Strength = 1; }))); return(r); }
private void btnDelAttackPlan_Click(object sender, EventArgs e) { if (attackPlansBindingSource.Current != null) { AttackPlan plan = (AttackPlan)attackPlansBindingSource.Current; string msg = "Den Angriffsplan '" + plan.Name + "' wirklich löschen?"; string caption = "Angriffsplan löschen?"; if (Program.Language == LanguageType.English) { msg = "Really delete '" + plan.Name + "'?"; caption = "Delete Attack Plan?"; } // Sicherheitsabfrage! if (MessageBox.Show(msg, caption, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { m_AttackHandler.AttackPlans.Remove(plan); } } }
public void ExecuteAttackPlan(AttackPlan plan) { var result = GameBoard.BattleRule.Attack(GameBoard, GameBoard.Players[GameBoard.CurrentTurn], plan); // Safety check if (result.AttackWasInvalid) { return; } // Set up all animations in sequence if (result.Animations != null) { foreach (var a in result.Animations) { PlayQueue.Enqueue(a); } } // Clear attacker animation if any this.Attacking = null; }
private IEnumerable <AttackPlan> BuildDefensePlan(Planet planetUnderAttack, int maxTurnLookAhead) { List <AttackPlan> resultBuilder = new List <AttackPlan>(); planetUnderAttack.IsLost = true; int defenseRequired = planetUnderAttack.ShipsRequiredToSurviveAttack; //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 recaptureArmadaStrength = -planetUnderAttack.GrowthRate; int armadaVictoryTurn = planetUnderAttack.LostAfterNumberOfTurns; //defend, remember, it's sorted on distance so the closest planets are considered first. foreach (Route route in Universe.TravelMap[planetUnderAttack.PlanetID]) { if (route.DistanceInTurns <= maxTurnLookAhead) { //look for planet with defense capability Planet defender = currentUniverse.AllPlanetsOnPlanetId[route.TagetPlanetId]; if (defender.IsMine && planetUnderAttack.PlanetID != defender.PlanetID) { //is it close enough to contribute to the defense? int defenseTravelTime = (route.DistanceInTurns - 1); if (defenseTravelTime <= armadaVictoryTurn) { //How many ships can we use int maxDelivarableShips; maxDelivarableShips = defender.AttackForce; if (defender.CanSurviveIncommingAttack) { maxDelivarableShips = defender.AttackForce; // How many turns left before reinforcements will not make it in time? // armadaVictoryTurn - turnsLeftForDefense maxDelivarableShips += (armadaVictoryTurn - defenseTravelTime) * defender.GrowthRate; //can we do a recapture, count the fleets we can use for a counter attack in the turn after capture. recaptureArmadaStrength += defender.GrowthRate; } if (maxDelivarableShips > 0) { int prevRequired = defenseRequired; defenseRequired -= maxDelivarableShips; if (defender.NumShips > 0) { AttackPlan armada = new AttackPlan(); armada.Target = planetUnderAttack; armada.Source = defender; armada.Enabled = true; if (defenseRequired > -1) { armada.ShipCount = Math.Min(defender.AttackForce, defender.NumShips); resultBuilder.Add(armada); } else { armada.ShipCount = Math.Min(Math.Min(defender.AttackForce, defender.NumShips), maxDelivarableShips - prevRequired); resultBuilder.Add(armada); break; } } } } } } } if (defenseRequired < 0) { planetUnderAttack.CanSurviveIncommingAttack = true; planetUnderAttack.AttackMovesAllowed = false; planetUnderAttack.IsLost = false; } //Planet is lost, no defense plan. if (planetUnderAttack.IsLost) { resultBuilder.Clear(); } return(resultBuilder); }
public List <AttackPlan> BuildActionPlan(Universe uni) { currentUniverse = uni; StartOfTurn(); DefendOnwedPlanets(); DefendNeutralPlanets(MaxTurnLookaheadForNeutralDefense); List <AttackPlan> battleplan = new List <AttackPlan>(); foreach (Planet onwedPlanet in currentUniverse.Me.Planets.Where(OwnedPlanetCanSendAttackForce)) { if (SourcePlanetSelected(onwedPlanet)) { var planetTravelMap = Universe.TravelMap[onwedPlanet.PlanetID]; if (PlanetRouteSelected(onwedPlanet, planetTravelMap)) { bool continueRoute = true; AttackPlan attack = new AttackPlan(); foreach (Route route in planetTravelMap) { Planet hostile = currentUniverse.AllPlanetsOnPlanetId[route.TagetPlanetId]; if (!hostile.IsMine) { attack.Distance = route.DistanceInTurns; attack.Source = onwedPlanet; attack.Target = hostile; attack.Enabled = false; CreateAttackPlanForOwnedPlanet(attack, route, planetTravelMap, ref continueRoute); if (attack.Enabled) { battleplan.Add(attack); attack = new AttackPlan(); } } if (!continueRoute) { break; } } } PlanetRouteDeSelected(onwedPlanet, planetTravelMap); } } if (!TakeGamble_DoNotCountOutgoingShipsForOneTurn) { //attack planets for all fleets in transit foreach (Planet planet in uni.All.Planets) { if (!(planet.IsLost || planet.Armada.Count == 0)) { foreach (Fleet attackforce in planet.Armada) { if (attackforce.IsMine) { planet.RemoveShips(attackforce.NumShips); } } } } } TakeGamble_DoNotCountOutgoingShipsForOneTurn = false; return(battleplan); }
protected abstract void CreateAttackPlanForOwnedPlanet(AttackPlan attack, Route attackRoute, PlanetaryTravelRoute planetTravelMap, ref bool continueRoute);
public ActionResult Attack(Board b, Player p, AttackPlan plan) { // Basic tests if (b.AttackIsInvalid(plan)) { return(ActionResult.INVALID); } // Roll one die per strength counter, sort by highest rolls descending var attacker_rolls = (from x in b.MultiRoll(plan.Attacker.Strength - 1, 6) orderby x descending select x).ToList(); var defender_rolls = (from x in b.MultiRoll(plan.Defender.Strength, 6) orderby x descending select x).ToList(); // Compare each die from attacker to defender // Defender wins ties // Attacker wins any excess attackers that were not paired to a defender int attacker_losses = 0, defender_losses = 0; for (int i = 0; i < attacker_rolls.Count; i++) { if (i < defender_rolls.Count) { if (attacker_rolls[i] > defender_rolls[i]) { defender_losses++; } else if (attacker_rolls[i] < defender_rolls[i]) { attacker_losses++; } } else { defender_losses++; } } // Attacker wins if defender is reduced to zero var wins = (defender_losses >= plan.Defender.Strength); // Handle results var r = new ActionResult() { AttackWasInvalid = false, Plan = plan, AttackSucceeded = wins, Animations = new List <BaseAnimation>() }; r.Animations.Add(new AttackAnimation(b, plan.Attacker, plan.Defender, new System.Threading.Tasks.Task(() => { if (wins) { if (plan.Defender.Owner != null) { plan.Defender.Owner.Zones.Remove(plan.Defender); if (plan.Defender.Owner.Zones.Count == 0) { plan.Defender.Owner.IsDead = true; } } plan.Defender.Owner = plan.Attacker.Owner; plan.Attacker.Owner.Zones.Add(plan.Defender); plan.Defender.Strength = plan.Attacker.Strength - attacker_losses - 1; plan.Attacker.Strength = 1; } else { plan.Attacker.Strength = plan.Attacker.Strength - attacker_losses; plan.Defender.Strength = plan.Defender.Strength - defender_losses; } }))); return(r); }
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 AttackEventArgs(AttackPlan plan, AttackPlanFrom attacker) { Debug.Assert(attacker == null || attacker.Plan == plan); Attacker = attacker; Plan = 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); } }
protected override void CreateAttackPlanForOwnedPlanet(AttackPlan attack, Route attackRoute, PlanetaryTravelRoute planetTravelMap, ref bool continueRoute) { Planet myPlanet = attack.Source; Planet hostile = attack.Target; if (Universe.TurnCount > 1 && hostile.GrowthRate > 0) { //check to see if we need our strength (and leave some) if (myPlanet.IsUnderAttack && myPlanet.CanSurviveIncommingAttack && myPlanet.AttackForce < 10) { return; } if (myPlanet.PlanetID == 2) { if (hostile.PlanetID == 17) { } } if (Universe.TurnCount < SuperDefenseCutOffPoint) { //VERY aggressive move, putting a great army very near me. if ((attackRoute.DistanceInTurns < 5) && (hostile.IsUnderAttack) && ((double)hostile.Armada.EnemyFleetSize / ((double)myPlanet.AttackForce + 1) > 0.5)) { //Counter with aggressive defense, I will capture the planet // how many ships needed to block enemy? int shipsNeeded = Math.Max(hostile.Armada.EnemyFleetSize - hostile.Armada.FriendlyFleetSize, hostile.NumShips + attackRoute.GrowthForTravelDistance); currentUniverse.MakeMove(myPlanet, hostile, shipsNeeded + 1); continueRoute = false; return; } //Close quarters fighting is special. Can I kill him early? if (hostile.IsEnemy && (attackRoute.GrowthForTravelDistance + hostile.NumShips) < myPlanet.ShipCountAtStartOfTurn) { if (myPlanet.IsUnderAttack) { // Do not lose the planet, be defensive. continueRoute = false; return; } else { if (hostile.CanSurviveIncommingAttack) { //He is still healthy, attack int max = attackRoute.GrowthForTravelDistance + hostile.NumShips + hostile.GrowthRate; currentUniverse.MakeUnsafeMove(myPlanet, hostile, Math.Min(max, myPlanet.NumShips)); continueRoute = false; return; } //ok, so this planet is beat. next please. } } if (NearestEnemy == null || attackRoute.ActualDistance > NearestEnemy.ActualDistance) { return; } } if (Universe.IsDominating) { if (!myPlanet.IsUnderAttack) { if (hostile.CanSurviveIncommingAttack) { attack.ShipCount = (int)(myPlanet.AttackForce * 0.9); attack.Enabled = true; if (hostile.IsNeutral) { attack.Sweetness = (double)hostile.GrowthRate - 2; } if (hostile.IsEnemy) { attack.Sweetness = (double)hostile.GrowthRate; } } } } else { bool isNear = attackRoute.ActualDistance < Universe.TravelMap.AverageDistance; if (myPlanet.PlanetID == 7) { if (hostile.PlanetID == 14) { } } double ConnectedNess = Universe.TravelMap.AverageDistance / attackRoute.TargetConnectiveNess; if (isNear || Universe.IsDominating) { double powerbase = hostile.GrowthRate; if (hostile.IsNeutral) { powerbase += 0.5; } attack.Sweetness = (Math.Pow(powerbase, ConnectedNess) / (attackRoute.ActualDistance)); attack.ShipCount = myPlanet.AttackForce; if (hostile.IsEnemy) { bool fleetStrongrThanPlanet = attackRoute.GrowthForTravelDistance + hostile.NumShips < myPlanet.AttackForce; if (fleetStrongrThanPlanet || hostile.IsOnWishList) { //attack.Sweetness = -(hostile.NumShips + (hostile.GrowthRate * attackRoute.Distance)); //attack.Sweetness = Math.Pow(hostile.GrowthRate, 3) / Math.Pow(attackRoute.DistanceInTurns, 1.5); attack.Enabled = true; } } else { if (Universe.IsDominating || hostile.Armada.EffectiveFleetSizeForMe() < myPlanet.AttackForce || hostile.IsOnWishList) { //attack.ShipCount = (int)(hostile.NumShips * 1.10); attack.Enabled = true; } } System.Diagnostics.Debug.WriteLine( "(" + myPlanet.PlanetID + ") " + attack.ShipCount + " ==> (" + hostile.PlanetID + ") C: " + ConnectedNess + " D: (" + attackRoute.ActualDistance + ") Like:" + attack.Sweetness); } } } }
public void AttackSelect(object sender, AttackPlan plan) { var e = new AttackEventArgs(plan, null); AttackSelect(sender, e); }
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 List<AttackPlan> BuildActionPlan(Universe uni) { currentUniverse = uni; StartOfTurn(); DefendOnwedPlanets(); DefendNeutralPlanets(MaxTurnLookaheadForNeutralDefense); ProcessAttackQueue(); List<AttackPlan> battleplan = new List<AttackPlan>(); foreach (Planet onwedPlanet in currentUniverse.Me.Planets.Where(OwnedPlanetCanSendAttackForce)) { if (SourcePlanetSelected(onwedPlanet)) { var planetTravelMap = onwedPlanet.Routes; if (PlanetRouteSelected(onwedPlanet, planetTravelMap)) { bool continueRoute = true; AttackPlan attack = new AttackPlan(); foreach (Route route in SortRoutesForBattlePlanCreation(planetTravelMap)) { Planet hostile = route.Destination; if (!hostile.IsMine) { attack.Target = hostile; attack.Enabled = false; attack.Strategy = GetType().Name; attack.Reason = "CreateAttackPlanForOwnedPlanet"; CreateAttackPlanForOwnedPlanet(attack, route, planetTravelMap, ref continueRoute); if (attack.Enabled) { if (onwedPlanet.IdleForThisNumberOfTurns >= 15) { attack.Sweetness += onwedPlanet.IdleForThisNumberOfTurns; } battleplan.Add(attack); attack = new AttackPlan(); } } if (!continueRoute) { break; } } } PlanetRouteDeSelected(onwedPlanet, planetTravelMap); } } if (!TakeGamble_DoNotCountOutgoingShipsForOneTurn) { //attack planets for all fleets in transit foreach (Planet planet in uni.All.Planets) { if (!(planet.IsLost || planet.Armada.Count == 0)) { foreach (Fleet attackforce in planet.Armada) { if (attackforce.IsMine) { planet.RemoveShips(attackforce.NumShips); } } } } } TakeGamble_DoNotCountOutgoingShipsForOneTurn = false; return battleplan; }
protected bool ExecutePlans(AttackPlan sweetPlan) { bool movemade = false; foreach (AttackPlanParticipant attacker in sweetPlan.Participants) { Planet agressor = attacker.Source; agressor.IsInAttackQueue = attacker.ScheduledTurn > 0; if (attacker.ScheduledTurn <= 0) { if (attacker.DefendersTurn.Owner != 1 || sweetPlan.DominationMove) { if (agressor.IsMine) { int ships = attacker.AttackersTurn.NumShips; if (!sweetPlan.Target.IsMine) { ships = Math.Min(attacker.DefendersTurn.NumShips + 1, ships); } ships = Math.Min(ships, agressor.AttackForce); currentUniverse.MakeMove(agressor, sweetPlan.Target, ships); movemade = true; agressor.CreateTurnPredictions(); } } } else { //attacker.Source.MaxDesertersAllowed = 0; } attacker.ScheduledTurn--; } if (sweetPlan.Target.IsMine || sweetPlan.Participants.Count == 0) { foreach (AttackPlanParticipant attacker in sweetPlan.Participants) { attacker.Source.IsInAttackQueue = false; } attackQueue.Remove(sweetPlan); } sweetPlan.Target.AttackMovesAllowed = false; return movemade; }
protected override void CreateAttackPlanForOwnedPlanet(AttackPlan attack, Route attackRoute, PlanetaryTravelRoute planetTravelMap, ref bool continueRoute) { Planet hostile = attack.Target; Planet onwedPlanet = attack.Source; if (!hostile.IsMine) { //No use for planets that do not produce. if (hostile.GrowthRate == 0) { return; } // If my enemy is attacking this planet, but not doing this strong enough, // Do not attack this planet and let my enemies ships crash and burn. if (hostile.IsNeutral && hostile.IsUnderAttack && hostile.CanSurviveIncommingAttack && !hostile.IsOnWishList) { return; } double isNeutralBias = 0; double defenseBias = 0; if (hostile.IsNeutral) { isNeutralBias = 1; defenseBias = Math.Max(Math.Min(onwedPlanet.AttackForce / (hostile.NumShips + 1.0), 5), 0) / 2; } else { defenseBias = (Math.Max((int)Math.Min(onwedPlanet.AttackForce / (attackRoute.GrowthForTravelDistance + 1), 5), 0)) / 2.0; } //we are dominating, favor enemy. if (Universe.IsDominating) { if (hostile.IsNeutral) { isNeutralBias = -2; } else { isNeutralBias = 2; } } double wishListBias = 0; if (hostile.IsOnWishList) { // wishListBias = 3; } //Dominate planet? double dominatePlanetBias = 0.0; if (!hostile.IsNeutral) { if ((currentUniverse.Me.ShipCountInBase / 3 > attackRoute.GrowthForTravelDistance + hostile.NumShips) && (attackRoute.RelativePlanetDistance < 0.3)) { dominatePlanetBias = 2.72; attack.DominationMove = true; } } double growthBias = attackRoute.RelativeGrowthRate * 2; attack.ShipCount = (int)(onwedPlanet.NumShips * 0.6); attack.Sweetness = //favor closer planets attackRoute.RelativePlanetDistance + attackRoute.RelativeUniverseDistance + //favor stronger growing planets growthBias + //favor neutrals, they do not grow. isNeutralBias + wishListBias + dominatePlanetBias + defenseBias + hostile.GrowthRate ; attack.Enabled = true; } }