public void MakeMove(Planet ownedPlanet, Planet target, int shipCount) { MakeMove(ownedPlanet, target, shipCount, true); }
public void CreateTurnPredictionsForPlanet(Planet planet) { int planetID = planet.PlanetID; GrowthRate = planet.GrowthRate; ResetStats(); PlanetTurn lastCalculatedTurn = this[0]; lastCalculatedTurn.SetValues(planet.Owner, planet.NumShips); planet.LastAttackTurn = lastCalculatedTurn; PlanetTurn currentCalculatingTurn = lastCalculatedTurn.Next; planet.MaxDesertersAllowed = planet.NumShips; planet.ShipsRequiredToSurviveAttack = planet.NumShips; planet.DoesNotChangeOwner = true; int currentTurn = 1; if (planetID == 15) { } if (planet.Armada.Count > 0) { planet.IdleForThisNumberOfTurns = 0; foreach (var turn in planet.FleetArrivalByTurnsRemaining) { do { lastCalculatedTurn = currentCalculatingTurn; currentCalculatingTurn = GrowTurn(GrowthRate, currentCalculatingTurn); } while (currentTurn++ < turn.Key); LastAttackTurn = lastCalculatedTurn; bool survived = Universe.FightBattleAndOwnerSurvived(lastCalculatedTurn, turn); if (lastCalculatedTurn.IsMine) { planet.MaxDesertersAllowed = Math.Min(planet.MaxDesertersAllowed, lastCalculatedTurn.NumShips); } if (!survived) { planet.DoesNotChangeOwner = false; } } } while (currentCalculatingTurn != null) { lastCalculatedTurn = currentCalculatingTurn; currentCalculatingTurn = GrowTurn(GrowthRate, currentCalculatingTurn); } planet.WinningArmadaIsMine = lastCalculatedTurn.Owner == 1; //int lastTurn = planet.FleetArrivalByTurnsRemaining.Last().Key; //lastAttackTurn = this[lastTurn]; //for (int turnNumber = 1; turnNumber <= lastTurn; turnNumber++) //{ // lastCalculatedTurn = this[turnNumber]; // calc.Grow(); // lastCalculatedTurn.SetValues(calc.Owner, calc.NumShips); // if (Universe.FightBattle(calc, turnNumber)) // { // lastCalculatedTurn.SetValues(calc.Owner, calc.NumShips); // planet.LastAttackTurn = lastCalculatedTurn; // if (calc.IsMine) // { // planet.MaxDesertersAllowed = Math.Min(planet.MaxDesertersAllowed, calc.NumShips); // } // if (calc.IsEnemy) // { // planet.ShipsRequiredToSurviveAttack = Math.Max(planet.MaxDesertersAllowed, calc.NumShips + 1); // } // if (calc.IsNeutral) // { // planet.ShipsRequiredToSurviveAttack = Math.Min(planet.ShipsRequiredToSurviveAttack, calc.NumShips + 1); // } // } // else // { // lastCalculatedTurn.SetValues(calc.Owner, calc.NumShips); // } // if (!calc.DoesNotChangeOwner) // { // planet.DoesNotChangeOwner = false; // } //} }
// Parses a game state from a string. On success, returns 1. On failure, // returns 0. private int ParseGameState(string boardLayout) { List <Fleet> fleetbuilder = new List <Fleet>(); Dictionary <int, EditablePlayer> playerBuilder = new Dictionary <int, EditablePlayer>(); int planetID = 0; string[] lines = boardLayout.Replace("\r", "").Split('\n'); for (int i = 0; i < lines.Length; ++i) { string line = lines[i]; int commentBegin = line.IndexOf('#'); if (commentBegin >= 0) { line = line.Substring(0, commentBegin); } if (line.Trim().Length == 0) { continue; } string[] tokens = line.Split(' '); if (tokens.Length == 0) { continue; } switch (tokens[0]) { default: break; case "P": case "p": #region Add planet { if (tokens.Length != 6) { return(0); } Planet planet = BuildPlanet(planetID++, tokens); EditablePlayer player = EnsurePlayer(playerBuilder, planet.Owner); player.Planets.Add(planet); planet.IdleForThisNumberOfTurns++; player.ShipsOnBase += planet.NumShips; player.ShipGrowth += planet.GrowthRate; player.ShipsHeavyPoint.X += planet.X * (double)planet.NumShips; player.ShipsHeavyPoint.Y += planet.Y * (double)planet.NumShips; player.AbsolutePlanetFocus.Y += planet.Y; player.AbsolutePlanetFocus.X += planet.X; if (WishList.ContainsKey(planet.PlanetID)) { if (planet.IsMine) { WishList.Remove(planet.PlanetID); } else { planet.IsOnWishList = true; } } #endregion } break; case "F": case "f": { #region AddFleet if (tokens.Length != 7) { return(0); } Fleet fleet = BuildFleet(tokens); EditablePlayer player = EnsurePlayer(playerBuilder, fleet.Owner); player.Fleets.Add(fleet); player.Targets.Add(fleet.DestinationPlanetId); fleetbuilder.Add(fleet); player.ShipsInTransit += fleet.NumShips; player.ShipInTransitFocus.X += fleet.DestinationPlanet.X * (double)fleet.NumShips; player.ShipInTransitFocus.Y += fleet.DestinationPlanet.Y * (double)fleet.NumShips; #endregion } break; } } //That's me EditablePlayer personalityBuilder = EnsurePlayer(playerBuilder, 1); Me = new Player(personalityBuilder.Fleets, personalityBuilder.Planets, personalityBuilder.Targets); personalityBuilder.InitializePlayer(Me); EditablePlayer neutralityBuilder = EnsurePlayer(playerBuilder, 0); Neutral = new Player(neutralityBuilder.Fleets, neutralityBuilder.Planets, personalityBuilder.Targets); neutralityBuilder.InitializePlayer(Neutral); All = new Player(fleetbuilder, Planets.Values.ToList(), new List <int>()); foreach (EditablePlayer player in playerBuilder.Values) { TotalFleetCount += player.ShipsOnBase + player.ShipsInTransit; } EditablePlayer enemyBuilder = EnsurePlayer(playerBuilder, 2); Enemy = new Player(enemyBuilder.Fleets, enemyBuilder.Planets, enemyBuilder.Targets); enemyBuilder.InitializePlayer(Enemy); All.ShipGrowth = Me.ShipGrowth + Enemy.ShipGrowth + Neutral.ShipGrowth; if (Universe.TurnCount == 1) { CreatePlanetaryTravelRoutes(); } foreach (Planet futurePlane in Planets.Values) { futurePlane.CreateTurnPredictions(); } DeterminePlanetStrengthOnFleetArrival(); return(1); }
internal void MakeUnsafeMove(Planet ownedPlanet, Planet target, int shipCount) { MakeMove(ownedPlanet, target, shipCount, false); }
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); }
public Route(Planet source, Planet destination) { Source = source; Destination = destination; }
protected abstract bool OwnedPlanetCanSendAttackForce(Planet ownedPlanet);
protected virtual void PlanetRouteDeSelected(Planet onwedPlanet, PlanetaryTravelRoute planetTravelMap) { }
//return true if we should should search this route. false to skip it protected virtual bool PlanetRouteSelected(Planet onwedPlanet, PlanetaryTravelRoute routesFromPlanet) { return(true); }
//return true if we should should search this planet. false to skip it. protected virtual bool SourcePlanetSelected(Planet onwedPlanet) { return(true); }
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); }