public override Moves Run(Planet supplyPlanet) { Moves moves = new Moves(); if (supplyPlanet == null) return moves; Planets frontPlanets = Context.GetFrontPlanets(); if (frontPlanets == null) return moves; if (frontPlanets.Count == 0) return moves; if (frontPlanets.IndexOf(supplyPlanet) != -1) return moves; IPathFinder pathFinder = new ClosestPathFinder(Context); //new DirectPathFinder(Context); //new DijkstraPathFinder(Context); Planet dest = pathFinder.FindNextPlanetInPath(supplyPlanet); if (dest != null) { int canSend = Context.CanSend(supplyPlanet); if (canSend == 0) return moves; Move move = new Move(supplyPlanet, dest, canSend); moves.Add(move); } return moves; }
public MovesSet(IEnumerable<Move> movesSet, double score, string adviserName, PlanetWars context) { this.context = context; MaxDistance = Int32.MinValue; MinDistance = Int32.MaxValue; AverageDistance = 0; SummaryNumShips = 0; NumShipsByTurns = 0; moves = new Moves(); foreach (Move move in movesSet) { AddMove(move); } Score = score; AdviserName = adviserName; }
public override Moves Run(Planet planet) { Moves moves = new Moves(); loseTurn = 0; //Planet planet = SelectPlanetForAdvise(); if (planet == null) return moves; List<Step> saveSteps = Context.GetMyPlanetSaveSteps(planet); if (saveSteps.Count == 0) return moves; foreach (Step t in saveSteps) { Planets planetsCanHelp = Context.MyPlanetsWithinProximityToPlanet(planet, t.ToTurn); Comparer comparer = new Comparer(Context) {TargetPlanet = planet}; planetsCanHelp.Sort(comparer.CompareDistanceToTargetPlanetLT); int sendedShipsNum = 0; foreach (Planet nearPlanet in planetsCanHelp) { int canSend = Math.Min(t.NumShips - sendedShipsNum, Context.CanSendByPlanets(nearPlanet, planet)); if (canSend <= 0) continue; int distance = Context.Distance(planet, nearPlanet); Move move = new Move(nearPlanet.PlanetID(), planet.PlanetID(), canSend); if (distance < t.ToTurn) { //delay move move.TurnsBefore = t.ToTurn - distance; //move = new Move(nearPlanet.PlanetID(), planet.PlanetID(), Context.CanSend(nearPlanet, move.TurnsBefore)); } moves.Add(move); sendedShipsNum += canSend; } if (sendedShipsNum < t.NumShips) { loseTurn = t.NumShips; } } return moves; }
public override Moves Run(Planet stealPlanet) { Moves moves = new Moves(); PlanetHolder planetHolder = Context.GetPlanetHolder(stealPlanet); List<PlanetOwnerSwitch> switches = planetHolder.GetOwnerSwitchesFromNeutralToEnemy(); if (switches.Count == 0) return moves; Planet futurePlanet = null; int turn = 0; for (int i = 0; i < switches.Count; i++) { turn = switches[i].TurnsBefore + 1; futurePlanet = Context.PlanetFutureStatus(stealPlanet, turn); if (futurePlanet.Owner() != 1) break; futurePlanet = null; } if (futurePlanet == null) return moves; Planets myPlanets = Context.MyPlanetsWithinProximityToPlanet(stealPlanet, turn); if (myPlanets.Count == 0) return moves; int needToSend = futurePlanet.NumShips() + 1; //needToSend += Context.GetEnemyAid(stealPlanet, turn); foreach (Planet myPlanet in myPlanets) { int distance = Context.Distance(myPlanet, stealPlanet); int canSend = Context.CanSendByPlanets(myPlanet, stealPlanet); if (canSend == 0) continue; int send = Math.Min(canSend, needToSend); needToSend -= send; Move move = new Move(myPlanet, stealPlanet, send) {TurnsBefore = turn - distance}; moves.Add(move); if (needToSend <= 0) return moves; } moves.Clear(); return moves; }
public override Moves Run(Planet targetPlanet) { Moves moves = new Moves(); if (targetPlanet == null) return moves; Planets myPlanets = Context.MyPlanets(); if (myPlanets.Count == 0) return moves; Comparer comparer = new Comparer(Context) {TargetPlanet = targetPlanet}; myPlanets.Sort(comparer.CompareDistanceToTargetPlanetLT); PlanetHolder holder = Context.GetPlanetHolder(targetPlanet); foreach (Planet myPlanet in myPlanets) { int targetDistance = Context.Distance(myPlanet, targetPlanet); int myCanSend = Context.CanSendByPlanets(myPlanet, targetPlanet); if (myCanSend == 0) continue; Planet futurePlanet = Context.PlanetFutureStatus(targetPlanet, targetDistance); if (futurePlanet.Owner() != 2) continue; if (holder.IsNeutralToEnemySwith(targetDistance)) continue; int needToSend = 1 + futurePlanet.NumShips(); if (Config.AttackSendMoreThanEnemyCanDefend) needToSend += Context.GetEnemyAid(targetPlanet, targetDistance); needToSend = moves.Aggregate(needToSend, (current, eachMove) => current - Context.CanSend(Context.GetPlanet(eachMove.SourceID))); if (needToSend <= 0) return moves; int canSend = Math.Min(needToSend, myCanSend); needToSend -= canSend; Move move = new Move(myPlanet, targetPlanet, canSend); moves.Add(move); if (needToSend <= 0) return moves; } return new Moves(); }
public override List<MovesSet> RunAll() { List<MovesSet> movesSet = new List<MovesSet>(); Planets planetsForAdvise = Context.MyEndangeredPlanets(); foreach (Planet planet in planetsForAdvise) { Moves moves = Run(planet); if (moves.Count <= 0) continue; MovesSet set = new MovesSet(moves, 0, GetAdviserName(), Context); //double score = enemyPlanet.GrowthRate() / Context.AverageMovesDistance(moves); double score = 2 * planet.GrowthRate() * (loseTurn > 0 ? loseTurn : Config.ScoreTurns) - set.NumShipsByTurns / set.AverageDistance; set.Score = score; if (loseTurn == 0) { movesSet.Add(set); } else { //todo delete bigger then target Moves newMoves = new Moves(); foreach (Move move in set.GetMoves()) { if (Context.GetPlanet(move.SourceID).NumShips() < Context.GetPlanet(move.DestinationID).NumShips()) newMoves.Add(new Move(move)); } if (newMoves.Count > 0) { set = new MovesSet(newMoves, 0, GetAdviserName(), Context); movesSet.Add(set); } } } return movesSet; }
public MovesSet BruteForce(Planets planets, int canSend) { int scoreTurns = Config.ScoreTurns;//Context.Distance(myPlanet, enemyPlanet); int n = planets.Count; //int secondMoveCanSend = myPlanet.NumShips() - canSend + myPlanet.GrowthRate(); int secondMoveCanSend = Math.Min(myPlanet.NumShips() - canSend + myPlanet.GrowthRate(), myPlanet.GrowthRate() * Context.Distance(myPlanet, enemyPlanet)); List<MovesSet> sets = new List<MovesSet>(); int size = (1 << n); for (int i = 0; i < size; i++) { if (CheckTimeFunc != null) if (!CheckTimeFunc()) break; int ships = 0; int score = 0; int returners = 0; Moves moves = new Moves(); Planets targetPlanets = new Planets(Config.MaxPlanets); for (int j = 0; j < n; j++) { if (CheckTimeFunc != null) if (!CheckTimeFunc()) break; if ((i & (1 << j)) <= 0) continue; Planet target = planets[j]; targetPlanets.Add(target); int distance = Context.Distance(myPlanet, target); int needShips = target.NumShips() + 1; if (Context.Distance(myPlanet, target) >= Context.Distance(enemyPlanet, target)) needShips += 1; if (myPlanet.NumShips() > canSend && enemyDistance > distance * 2) { //HowMany ships can return to myPlanet before enemy returners += (enemyDistance - distance * 2) * myPlanet.GrowthRate(); if (returners > myPlanet.NumShips() - canSend) returners = myPlanet.NumShips() - canSend; } int growTurns = Math.Max(0, scoreTurns - Context.Distance(myPlanet.PlanetID(), target.PlanetID())); score += growTurns * target.GrowthRate() - needShips; ships += needShips; if (ships > canSend + returners) { break; } moves.Add( new Move( myPlanet.PlanetID(), target.PlanetID(), needShips) ); } if (ships > canSend + returners) continue; //clear set MovesSet set = new MovesSet(moves, score, GetAdviserName(), Context); sets.Add(set); //sets with additional planet, divided for 2 turns int firstMoveCanSend = canSend + returners - ships; if (firstMoveCanSend < 0) firstMoveCanSend = 0; foreach (Planet additionalPlanet in planets) { if (targetPlanets.Contains(additionalPlanet)) continue; int needShips = additionalPlanet.NumShips() + 1; if (Context.Distance(myPlanet, additionalPlanet) >= Context.Distance(enemyPlanet, additionalPlanet)) needShips += 1; if (firstMoveCanSend + secondMoveCanSend < needShips) continue; //this planet we can invade in another set: this set + this planet if (firstMoveCanSend >= needShips) continue; MovesSet additionalSet = new MovesSet(set, Context); if (firstMoveCanSend > 0) additionalSet.AddMove(new Move(myPlanet, additionalPlanet, firstMoveCanSend)); additionalSet.AddMove(new Move(myPlanet, additionalPlanet, needShips - firstMoveCanSend) { TurnsBefore = 1 }); int growTurns = Math.Max(0, scoreTurns - Context.Distance(myPlanet.PlanetID(), additionalPlanet.PlanetID())); additionalSet.Score += (growTurns - 1) * additionalPlanet.GrowthRate() - needShips; sets.Add(additionalSet); } } if (sets.Count == 0) return null; if (sets.Count > 1) { sets.Sort(new Comparer(null).CompareSetScoreGT); } /*foreach (MovesSet movesSet in sets) { Logger.Log("score: " + movesSet.Score + " " + movesSet); }*/ return sets[0]; }
private void SelectAndMakeMoves() { if (setList == null) return; int n = setList.Count; if (n == 0) return; List<List<MovesSet>> sets = new List<List<MovesSet>>(); int size = (1 << n); for (int i = 0; i < size; i++) { if (!CheckTime()) break; List<MovesSet> currentSetList = new List<MovesSet>(); Moves totalMoves = new Moves(); //int invadeNumber = Config.MaxInvades; for (int j = 0; j < n; j++) { if (!CheckTime()) break; if ((i & (1 << j)) <= 0) continue; MovesSet set = setList[j]; //if (setList[j].AdviserName == "Invade") invadeNumber--; //if (invadeNumber < 0) break; currentSetList.Add(set); Moves moves = set.GetMoves(); foreach (Move move in moves) { if (move.TurnsBefore > 0) continue; bool found = false; foreach (Move t in totalMoves) { if (t.SourceID != move.SourceID) continue; found = true; t.AddShips(move.NumShips); break; } if (!found) { totalMoves.Add(new Move(move)); } } } bool isValid = totalMoves.All(totalMove => Context.IsValid(totalMove)); /*if (!isValid) foreach (Move totalMove in totalMoves) { if (!Context.IsValid(totalMove)) { Logger.Log("InValid: " + totalMove); break; } } */ if (!isValid) continue; sets.Add(currentSetList); } setList.Clear(); if (sets.Count > 1) { sets.Sort(new Comparer(null).CompareSetListScoreGT); } if (sets.Count > 0) { MakeMoves(sets[0]); } }
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; }
public Moves GetMoves() { Moves result = new Moves(moves); return result; }
//From my strongest to closest suitable enemy public List<MovesSet> InvadeAction() { List<MovesSet> movesSet = new List<MovesSet>(); Planets myPlanets = Context.MyStrongestPlanets(1); if (myPlanets.Count == 0) return movesSet; Planet myStrongestPlanet = myPlanets[0]; int canSend = Context.CanSend(myStrongestPlanet); Planets targetFuturePlanets = new Planets(Config.MaxPlanets); targetFuturePlanets.AddRange(from eachPlanet in Context.Planets() where eachPlanet.GrowthRate() != 0 let distance = Context.Distance(myStrongestPlanet, eachPlanet) select Context.PlanetFutureStatus(eachPlanet, distance) into futurePlanet where futurePlanet.Owner() == 0 && canSend > futurePlanet.NumShips() + 1 select futurePlanet); if (targetFuturePlanets.Count == 0) return movesSet; Comparer comparer = new Comparer(Context) { TargetPlanet = myStrongestPlanet }; targetFuturePlanets.Sort(comparer.CompareDistanceToTargetPlanetLT); Moves moves = new Moves(1) { new Move(myStrongestPlanet, targetFuturePlanets[0], Math.Min(canSend, targetFuturePlanets[0].NumShips() + 1)) }; movesSet.Add(new MovesSet(moves, 99999, GetAdviserName(), Context)); return movesSet; }
//From my strongest to closest suitable enemy public List<MovesSet> ReFrontAction() { List<MovesSet> movesSet = new List<MovesSet>(); Planets frontPlanets = Context.GetFrontPlanets(); if (frontPlanets == null) return movesSet; if (frontPlanets.Count < 2) return movesSet; Moves moves = new Moves(frontPlanets.Count - 1); frontPlanets.Sort(new Comparer(Context).CompareGrowsRateGT); Planet target = frontPlanets[0]; foreach (Planet frontPlanet in frontPlanets) { if (frontPlanet.PlanetID() == target.PlanetID()) continue; moves.Add(new Move(frontPlanet, target, Context.CanSendSafe(frontPlanet))); } movesSet.Add(new MovesSet(moves, 9999, GetAdviserName(), Context)); return movesSet; }
public int MaxMovesDistance(Moves moves) { if (moves.Count == 0) return 0; int maxDistance = 0; foreach (Move move in moves) { int distance = Distance(move.SourceID, move.DestinationID); if (maxDistance < distance) maxDistance = distance; } return maxDistance; }
public double AverageMovesDistance(Moves moves) { if (moves.Count == 0) return 0; double sumDistance = 0; foreach (Move move in moves) { sumDistance += Distance(move.SourceID, move.DestinationID); } return sumDistance/moves.Count; }