public Planet GetFutureState(int numberOfTurns) { FillFutureStatesIfNeeded(); if (numberOfTurns > TurnsCount) { Planet futureState = new Planet(futureStates[TurnsCount]); if (futureState.Owner() <= 0) return futureState; futureState.NumShips(futureState.NumShips() + futureState.GrowthRate() * (numberOfTurns - TurnsCount)); return futureState; } return futureStates[numberOfTurns]; }
public override List<MovesSet> RunAll() { List<MovesSet> setList = new List<MovesSet>(); myPlanet = Context.MyPlanets()[0]; enemyPlanet = Context.EnemyPlanets()[0]; enemyDistance = Context.Distance(myPlanet, enemyPlanet); int canSend = Math.Min(myPlanet.NumShips(), myPlanet.GrowthRate() * Context.Distance(myPlanet, enemyPlanet)); Planets neutralPlanets = Context.NeutralPlanets(); Planets planets = new Planets(Config.MaxPlanets); planets.AddRange(neutralPlanets.Where(neutralPlanet => (Context.Distance(myPlanet, neutralPlanet) < Context.Distance(enemyPlanet, neutralPlanet)) && neutralPlanet.GrowthRate() > 0)); setList.Add(BruteForce(planets, canSend)); return setList; }
public int CompareNumberOfShipsLT(Planet planet1, Planet planet2) { int result = (planet1.NumShips() - planet2.NumShips()); if (result == 0) result = planet1.PlanetID() - planet2.PlanetID(); return result; }
public override Moves Run(Planet targetPlanet) { Moves moves = new Moves(); if (targetPlanet == null) return moves; Planets nearestPlanets = Context.GetClosestPlanetsToTargetBySectors(targetPlanet, Context.MyPlanets()); //Context.MyPlanets(); //MyPlanetsWithinProximityToPlanet(planet, Config.InvokeDistanceForInvade););); if (nearestPlanets.Count == 0) return moves; if (nearestPlanets.Count > 1) { Comparer comparer = new Comparer(Context) { TargetPlanet = targetPlanet }; nearestPlanets.Sort(comparer.CompareDistanceToTargetPlanetLT); } foreach (Planet nearestPlanet in nearestPlanets) { int canSend = Context.CanSendByPlanets(nearestPlanet, targetPlanet); if (canSend == 0) continue; int distance = Context.Distance(targetPlanet, nearestPlanet); Planet futurePlanet = Context.PlanetFutureStatus(targetPlanet, distance); if (futurePlanet.Owner() == 2)//Error? { #if LOG Logger.Log("InvadeAdvizer: Error?"); #endif moves.Clear(); return moves; } int needToSend = futurePlanet.NumShips() + 1; if (Config.InvadeSendMoreThanEnemyCanDefend) { int extraTurns = (int)Math.Ceiling(targetPlanet.NumShips() / (double)targetPlanet.GrowthRate()); if (Context.MyFutureProduction < Context.EnemyFutureProduction) extraTurns = 0; if ((Context.MyFutureProduction == Context.EnemyFutureProduction) && (Context.MyTotalShipCount <= Context.EnemyTotalShipCount)) extraTurns = 0; needToSend += Context.GetEnemyAid(targetPlanet, distance + extraTurns); } needToSend = moves.Aggregate(needToSend, (current, eachMove) => current - Context.CanSendByPlanets(Context.GetPlanet(eachMove.SourceID), Context.GetPlanet(eachMove.DestinationID))); //delay closer moves /*foreach (Move eachMove in moves) { int moveDistance = Context.Distance(eachMove.DestinationID, eachMove.SourceID); int turns = distance - moveDistance; eachMove.TurnsBefore = turns; needToSend -= Context.CanSend(Context.GetPlanet(eachMove.SourceID), turns); }*/ if (needToSend <= 0) return moves; canSend = Math.Min(needToSend, canSend); needToSend -= canSend; Move move = new Move(nearestPlanet, targetPlanet, canSend); moves.Add(move); if (needToSend <= 0) return moves; } moves.Clear(); return moves; }
private static void PlanetGrowth(Planet planetInFuture) { if (planetInFuture.Owner() != 0) { planetInFuture.NumShips(planetInFuture.NumShips() + planetInFuture.GrowthRate()); } }
private void CalcFutureState() { futureStates.Clear(); futureStates.Add(thisPlanet); canSend = thisPlanet.NumShips(); for (int turn = 1; turn <= TurnsCount; turn++) { Planet planetInFuture = new Planet(futureStates[turn - 1]); PlanetGrowth(planetInFuture); Fleets thisTurnFleets = GetThisTurnFleets(turn); int oldPlanetOwner = planetInFuture.Owner(); CalcFleetsOnPlanet(planetInFuture, thisTurnFleets); if (planetInFuture.Owner() != oldPlanetOwner) { PlanetOwnerSwitch pos = new PlanetOwnerSwitch( oldPlanetOwner, planetInFuture.Owner(), turn); ownerSwitches.Add(pos); } futureStates.Add(planetInFuture); if (planetInFuture.Owner() != 1) canSend = 0; if (planetInFuture.NumShips() >= canSend) continue; canSend = planetInFuture.NumShips(); } }
private static void CalcFleetsOnPlanet(Planet planetInFuture, Fleets thisTurnFleets) { // First is ownerID, second is number of ships List<Pair<int, int>> ships = new List<Pair<int, int>>(); if (thisTurnFleets.Count <= 0) return; const int owners = 2; for (int id = 1; id <= owners; ++id) { Fleets ownerFleets = PlanetWars.FleetsWithGivenOwner(thisTurnFleets, id); Pair<int, int> ownerShips = new Pair<int, int>(id, 0); // Add up fleets with the same owner foreach (Fleet ownerFleet in ownerFleets) { ownerShips.Second += ownerFleet.NumShips(); } // Add the ships from the planet to the corresponding fleet if (planetInFuture.Owner() == id) { ownerShips.Second += planetInFuture.NumShips(); } ships.Add(ownerShips); } // If the planet was neutral, it has it's own fleet if (planetInFuture.Owner() == 0) { ships.Add(new Pair<int, int>(0, planetInFuture.NumShips())); } BattleForPlanet(planetInFuture, ships); }
private static void BattleForPlanet(Planet planetInFuture, List<Pair<int, int>> ships) { // Were there any fleets other than the one on the planet? if (ships.Count <= 1) return; // Sorts the fleets in descending order by the number of ships in the fleet ships.Sort(Pair<int, int>.CompareSecondOfPair); Pair<int, int> winner = ships[0]; Pair<int, int> secondToWinner = ships[1]; if (winner.Second == secondToWinner.Second) { //old owner stays planetInFuture.NumShips(0); } else { planetInFuture.Owner(winner.First); planetInFuture.NumShips(winner.Second - secondToWinner.Second); } }
public int CanSendSafe(Planet planet) { Planet closestEnemyPlanet = GetClosestPlanet(planet, EnemyPlanets()); if (closestEnemyPlanet == null) { return planet.NumShips(); } int distance = Distance(planet, closestEnemyPlanet); Planets closePlanets = EnemyPlanetsWithinProximityToPlanet(planet, distance); int ships = 0; foreach (Planet closePlanet in closePlanets) { ships += closePlanet.NumShips(); } int safeCanSend = Math.Max(0, (planet.NumShips() - (ships - planet.GrowthRate() * distance))); //Logger.Log("Safe: " + safeCanSend + " notSafe:" + CanSend(planet)); //if (MyPlanets().Count == 1) return safeCanSend; //if (distance > 6) return CanSend(planet); //GetEnemyAid(planet, safeTurns);)); return Math.Min(safeCanSend, CanSend(planet)); }
public bool IsValid(Planet source, Planet dest, int numShips) { if (source.Owner() != 1) { //Logger.Log("InValid : not my planet: source = " + source + " Move: dest = " + dest + " num = " + numShips); return false; } if (source.PlanetID() == dest.PlanetID()) { //Logger.Log("InValid : source = dest: source = " + source + " Move: dest = " + dest + " num = " + numShips); return false; } if (numShips > source.NumShips()) { //Logger.Log("InValid : > numShips: source = " + source + " Move: dest = " + dest + " num = " + numShips); return false; } if (numShips > CanSendByPlanets(source, dest)) { //Logger.Log("InValid : > canSend: source = " + source + " Move: dest = " + dest + " num = " + numShips + " canSend = " +CanSend(source)); return false; } return true; }
//# Generates a string representation of a planet. This is used to send data //# about the planets to the client programs. public static string SerializePlanet(Planet planet) { int owner = planet.Owner(); string message = "P " + string.Format("{0:R}", planet.X()) + " " + string.Format("{0:R}", planet.Y()) + " " + owner + " " + planet.NumShips() + " " + planet.GrowthRate(); return message.Replace(".0 ", " "); }