public static int SimulateOptimalLCCountForFarmAssistantFarming(List <Village> villages, List <FarmVillage> farmVillages) { System.Console.WriteLine("Starting optimal LC count simulation."); // Update total lc for each village first. System.Console.WriteLine("Checking total LC count for all vilages for simulation purposes."); foreach (Village village in villages) { village.GetTotalTroops(); village.troops.lc = village.totalTroops.lc; } // Make copy of farm villages list. List <FarmVillage> farmCopy = new List <FarmVillage>();//new List<FarmVillage>(farmVillages); foreach (FarmVillage vill in farmVillages) { FarmVillage newVill = new FarmVillage(vill.x, vill.y, vill.isBarb, vill.wall, vill.clay, vill.wood, vill.iron, vill.minimumAttackIntervalInMinutes); farmCopy.Add(newVill); } int originalCount = Settings.LC_PER_BARB_ATTACK; int highestTotalHaul = 0; int optimalCount = 0; for (int iteration = 2; iteration < 50; iteration++) { DateTime currentTime = DateTime.Now; DateTime finishTime = DateTime.Now.AddDays(1); Settings.LC_PER_BARB_ATTACK = iteration; for (int i = 0; i < farmCopy.Count; i++) { farmCopy[i].lastSentAttackTime = DateTime.Now.AddDays(-10); farmCopy[i].UpdateAttackInterval(Settings.LC_PER_BARB_ATTACK * 80); farmCopy[i].lastAttackETA = DateTime.Now.AddDays(-10); } List <Tuple <DateTime, Village> > returnsOfAttacks = new List <Tuple <DateTime, Village> >(); int totalHaul = 0; while (currentTime < finishTime) { foreach (Village village in villages) { // Sort farm villages by distance to current village. Vector2 ourPos = new Vector2(village.x, village.y); farmCopy.Sort((a, b) => { Vector2 aPos = new Vector2(a.x, a.y); Vector2 bPos = new Vector2(b.x, b.y); return(Vector2.Distance(ourPos, aPos).CompareTo(Vector2.Distance(ourPos, bPos))); }); // Perform simulated attacks. foreach (FarmVillage farm in farmCopy) { // Attacks take like 1 second each so... currentTime = currentTime.AddSeconds(1); if (village.troops.lc < Settings.LC_PER_BARB_ATTACK) { continue; } if (currentTime < farm.lastAttackETA.AddMinutes(farm.minimumAttackIntervalInMinutes)) { continue; } float fields = Vector2.Distance(ourPos, new Vector2(farm.x, farm.y)); float travelTime = fields * 10; // Time to attack. village.troops.lc -= Settings.LC_PER_BARB_ATTACK; farm.lastAttackETA = currentTime.AddMinutes(travelTime); farm.lastSentAttackTime = currentTime; DateTime returnTime = currentTime.AddMinutes(travelTime * 2); // Below line is to know when to add haul and more lc back to the village. returnsOfAttacks.Add(new Tuple <DateTime, Village>(returnTime, village)); } // Simulate next village load time currentTime = currentTime.AddSeconds(4); } // Simulate Sleep currentTime.AddMinutes(15); // Check if we have LCs back home and add to total haul and current lc count. for (int i = returnsOfAttacks.Count - 1; i >= 0; i--) { if (returnsOfAttacks[i].Item1 > currentTime) { continue; } totalHaul += Settings.LC_PER_BARB_ATTACK * 80; returnsOfAttacks[i].Item2.troops.lc += Settings.LC_PER_BARB_ATTACK; returnsOfAttacks.RemoveAt(i); } } if (totalHaul > highestTotalHaul) { highestTotalHaul = totalHaul; optimalCount = Settings.LC_PER_BARB_ATTACK; } System.Console.WriteLine("With {0} lc per attack we can get maximum haul of: {1}.", Settings.LC_PER_BARB_ATTACK, totalHaul); } System.Console.WriteLine("Simulation finished. Simulated optimal count is {0} with maximum haul of {1} a day.", optimalCount, highestTotalHaul); Settings.LC_PER_BARB_ATTACK = originalCount; System.Console.ReadLine(); return(0); }
public static int SimulateOptimalFarmRadius(int lcCount, int x, int y, List <FarmVillage> farmVillages) { int optimalRadius = 0; int maximumHaul = 0; for (int radius = 0; radius < 30; radius++) // Test these radii. { // Simulation Variables. int currentLc = lcCount; int minimumSleepTime = 5; int maximumSleepTime = 15; int lcPerAttack = 10; int simulationDurationInMinutes = 60 * 24; int totalHaul = 0; int lcLeft = 0; DateTime currentTime = DateTime.Now; DateTime startTime = DateTime.Now; List <DateTime> returnsOfAttacks = new List <DateTime>(); // Make copy of farm villages list. List <FarmVillage> farmCopy = new List <FarmVillage>();//new List<FarmVillage>(farmVillages); foreach (FarmVillage vill in farmVillages) { FarmVillage newVill = new FarmVillage(vill.x, vill.y, vill.isBarb, vill.wall, vill.clay, vill.wood, vill.iron, vill.minimumAttackIntervalInMinutes); farmCopy.Add(newVill); } for (int i = 0; i < farmCopy.Count; i++) { farmCopy[i].lastSentAttackTime = DateTime.Now.AddDays(-1); farmCopy[i].UpdateAttackInterval(lcPerAttack * 80); } // Sort farms by distance. Vector2 ourPos = new Vector2(x, y); farmCopy.Sort((a, b) => { Vector2 aPos = new Vector2(a.x, a.y); Vector2 bPos = new Vector2(b.x, b.y); return(Vector2.Distance(ourPos, aPos).CompareTo(Vector2.Distance(ourPos, bPos))); }); while (currentTime < startTime.AddMinutes(simulationDurationInMinutes)) { if (lcCount < lcPerAttack) { // Simulate Sleep. System.Console.WriteLine("Simulating Sleep (1)"); currentTime = currentTime.AddMinutes((maximumSleepTime - minimumSleepTime) / 2); continue; } // Check if we have LCs back home and add to total haul and current lc count. for (int i = returnsOfAttacks.Count - 1; i >= 0; i--) { if (returnsOfAttacks[i] > currentTime) { continue; } totalHaul += lcPerAttack * 80; currentLc += lcPerAttack; returnsOfAttacks.RemoveAt(i); } // Send out LCs. for (int i = 0; i < farmCopy.Count; i++) { if (currentLc < lcPerAttack) { continue; } if (farmCopy[i].lastSentAttackTime.AddMinutes(farmCopy[i].minimumAttackIntervalInMinutes) > currentTime) { continue; } float fields = Vector2.Distance(ourPos, new Vector2(farmCopy[i].x, farmCopy[i].y)); if (fields > radius) { continue; } // Time to attack. currentLc -= lcPerAttack; farmCopy[i].lastSentAttackTime = currentTime; // Calculate distance to village. float totalFields = fields * 2; float totalDurationInMinutes = totalFields * 10; DateTime returnTime = currentTime.AddMinutes(totalDurationInMinutes); returnsOfAttacks.Add(returnTime); } //System.Console.WriteLine("Simulating Sleep (2)"); // Simulate Sleep. currentTime = currentTime.AddMinutes((maximumSleepTime - minimumSleepTime) / 2); } if (totalHaul > maximumHaul) { optimalRadius = radius; maximumHaul = totalHaul; System.Console.WriteLine("Found better radius of {0} with max loot of {1}, with {2} lc left", radius, totalHaul, currentLc); //System.Console.ReadLine(); } } System.Console.WriteLine("Optimal Radius is: {0} with {1} max loot.", optimalRadius, maximumHaul); //System.Console.ReadLine(); return(optimalRadius); }