public static List <FactoryState> CalculateFactoryState(Factory factory, SortedSet <Troop> troops, bool mockState = true) { List <FactoryState> states = new List <FactoryState>(); FactoryState lastState = new FactoryState(factory, Game.gameTime); states.Add(lastState); //add atleast 1 state to the list foreach (var troop in troops) { FactoryState newState = new FactoryState(lastState, troop); states.Add(newState); if (mockState == false) { if (newState.isAlly) { factory.armyAvailable = Math.Min(factory.armyAvailable, newState.count); } else { factory.armyAvailable = Math.Min(factory.armyAvailable, -newState.count); } } lastState = newState; } return(states); }
public void Solve() { Factory ally = mission.factory; SortedSet <Troop> mockTroops = new SortedSet <Troop>(ally.incoming); Troop testTroop = new Troop { start = ally, end = ally, count = 10, team = Team.Enemy, isAlly = false, isEnemy = true, turns = 1, endTime = Game.gameTime + 1, }; mockTroops.Add(testTroop); var mockStates = FactoryState.CalculateFactoryState(ally, mockTroops); //FactoryState lastState = mockStates.Last(); if (FactoryState.IsFactoryCaptured(mockStates) == false) { mission.successRating = MissionSuccessRating.Guaranteed; mission.acceptedMission.Add(testTroop); mission.missionEndTime = Game.gameTime + 1; } }
public static bool WillFactoryBeAlly(List <FactoryState> states) { FactoryState firstState = states.First(); bool allyLock = firstState.isAlly; for (int i = 0; i < states.Count; i++) { FactoryState state = states[i]; if (i + 1 < states.Count && state.gameTime == states[i + 1].gameTime) //if states occur at same time { continue; } if (allyLock && state.isEnemy) { return(false); } if (allyLock == false && state.isAlly) { allyLock = true; } } return(allyLock); }
public static void AddAction(Action action, Troop troop = null) { if (action.move == MoveType.Move) { action.start.count -= action.numRobots; action.start.armyAvailable -= action.numRobots; if (troop != null && troop.inTransit == false) { action.end.incoming.Add(troop); action.end.states = FactoryState.CalculateFactoryState(action.end, action.end.incoming); } //Console.Error.WriteLine("Move " + action.start.id + "-" + action.end.id + ": " + troop.count); } else if (action.move == MoveType.Inc) { action.start.count -= 10; action.start.armyAvailable -= 10; } else if (action.move == MoveType.Bomb) { action.end.incoming.Add(troop); Game.bomb--; } Action.actions.Add(action); }
public static void ProcessFactoryStates() { foreach (var factory in factories) { factory.states = FactoryState.CalculateFactoryState(factory, factory.incoming, false); } }
public void Solve() { Factory factory = mission.factory; mission.finalEnlistedTroops = new List <Troop>(); if (Game.bomb <= 0) { mission.successRating = MissionSuccessRating.Impossible; return; } foreach (var pair in factory.links.OrderBy(p => p.Value)) { Factory neighbour = pair.Key; int distance = pair.Value; int missionEndTime = Game.gameTime + distance + 1; FactoryState lastState = FactoryState.GetFactoryState(factory, missionEndTime); if (lastState.team == Team.Enemy && neighbour.isAlly && !Bomb.bombs.Values.Any(b => b.isAlly && b.end == mission.factory)) //no bombs going there { int finalArmyCount = lastState.count + (distance + 1) * lastState.production; Bomb bomb = new Bomb { isAlly = true, isEnemy = false, team = Team.Ally, start = neighbour, end = mission.factory, turns = distance + 1, endTime = missionEndTime, }; /*int inTransitEnemyCount = 0; * foreach (var troop in Troop.enemy.Where(t=>t.end == mission.factory).OrderBy(t=>t.endTime)) * { * if (distance == troop.turns) * { * inTransitEnemyCount += troop.count; * } * }*/ if (lastState.production >= 2)//Factory.globalStats.enemyTotalProduction / 2 //|| lastState.count >= Factory.globalStats.totalEnemyCount / 2) { bomb.count = lastState.count; mission.finalEnlistedTroops.Add(bomb); mission.successRating = MissionSuccessRating.Guaranteed; break; } } } }
public static List <FactoryState> CalculateFactoryState(Factory factory, SortedSet <Troop> troops, bool mockState = true) { List <FactoryState> states = new List <FactoryState>(); FactoryState lastState = new FactoryState(factory, Game.gameTime); states.Add(lastState); //add atleast 1 state to the list List <Troop> troopList = troops.ToList(); for (int i = 0; i < troopList.Count; i++) { Troop troop = troopList[i]; bool sameTime = false; if (i + 1 < troopList.Count && troop.endTime == troopList[i + 1].endTime) //if troop came at same time { sameTime = true; Troop nextTroop = troopList[i + 1]; Troop combinedTroop = new Troop { start = troop.start, end = troop.end, count = Math.Abs(troop.count + (troop.team == nextTroop.team?1:-1) * nextTroop.count), team = troop.count >= nextTroop.count?troop.team:nextTroop.team, isAlly = troop.count >= nextTroop.count?troop.isAlly:nextTroop.isAlly, isEnemy = troop.count >= nextTroop.count?troop.isEnemy:nextTroop.isEnemy, turns = troop.turns - Game.gameTime, endTime = troop.endTime, }; troop = combinedTroop; i++; } FactoryState newState = new FactoryState(lastState, troop, false); states.Add(newState); if (mockState == false) { if (newState.isAlly) { factory.armyAvailable = Math.Min(factory.armyAvailable, newState.count); } else { factory.armyAvailable = Math.Min(factory.armyAvailable, -newState.count); } } lastState = newState; } return(states); }
public static void AddMissions() { var orderedFactories = Factory.factories .OrderByDescending(factory => factory.stats.allyScore * factory.oldProduction); foreach (var factory in orderedFactories) { //if the factory will always be ally's if (FactoryState.WillFactoryBeAlly(factory.states)) { if (factory.oldProduction < 3 && factory.armyAvailable >= 10) { Mission newMission = new Mission(MissionType.Inc, factory); missions.Add(newMission); } else if (factory.oldProduction < 3) { Mission newMission = new Mission(MissionType.IncSupport, factory); missions.Add(newMission); } } else { if (Game.bomb > 0 && Game.gameTime > 1) { Mission bombMission = new Mission(MissionType.Bomb, factory); missions.Add(bombMission); } if (factory.isAlly) { Mission newMission = new Mission(MissionType.Defend, factory); missions.Add(newMission); } else { Mission newMission = new Mission(MissionType.Capture, factory); missions.Add(newMission); } //double missionScore = factory.stats.allyScore * factory.oldProduction; //Console.Error.WriteLine(factory.id + ": " + missionScore); //return; } } }
public static FactoryState GetFactoryState(Factory factory, Troop testTroop) { SortedSet <Troop> mockTroops = new SortedSet <Troop>(factory.incoming); mockTroops.Add(testTroop); var states = FactoryState.CalculateFactoryState(factory, mockTroops); foreach (var state in states) { if (state.troop != null && state.troop.id == testTroop.id) { return(state); } } return(null); }
public void Solve() { Factory factory = mission.factory; foreach (var pair in factory.links.OrderBy(p => p.Value)) { Factory neighbour = pair.Key; int distance = pair.Value; int missionEndTime = Game.gameTime + distance + 1; FactoryState lastState = FactoryState.GetFactoryState(factory, missionEndTime); if (lastState.team == Team.Enemy && neighbour.isAlly && factory.production == 3 && !Bomb.bombs.Values.Any(b => b.isAlly && b.end == mission.factory)) //no bombs going there { int finalArmyCount = lastState.count + (distance + 1) * lastState.production; //Console.Error.WriteLine("Bomb" + lastState.id + (closestTroop.end == factory)); if (finalArmyCount >= Factory.globalStats.totalEnemyCount / 2 || lastState.production >= Factory.globalStats.enemyTotalProduction / 2) { Bomb bomb = new Bomb { isAlly = true, isEnemy = false, team = Team.Ally, start = neighbour, end = mission.factory, turns = distance + 1, endTime = missionEndTime, }; mission.finalEnlistedTroops = new List <Troop>(); mission.finalEnlistedTroops.Add(bomb); mission.successRating = MissionSuccessRating.Guaranteed; break; } } } }
public static bool IsFactoryCaptured(List <FactoryState> states) { Team originalTeam = states.First().team; for (int i = 0; i < states.Count; i++) { FactoryState state = states[i]; if (i + 1 < states.Count && state.gameTime == states[i + 1].gameTime) //if states occur at same time { continue; } if (originalTeam != state.team) { return(true); } } return(false); }
public FactoryState(FactoryState factory, Troop troop) { id = factory.id; count = factory.count; production = factory.disabledTime > 0 ? 0 : factory.oldProduction; oldProduction = factory.oldProduction; gameTime = troop.endTime; this.troop = troop; disabledTime = Math.Max(0, factory.disabledTime--); SetTeam(factory.team); //team stays the same (default = neutral) if (factory.team != Team.Neutral) { int timeDiff = troop.endTime - factory.gameTime; this.count += timeDiff * production; } if (troop is Bomb) { int bombCount = Math.Max(this.count / 2, 10); this.count -= bombCount; this.count = Math.Max(0, this.count); this.oldProduction = Math.Max(oldProduction, production); this.production = 0; this.disabledTime = troop.endTime + 3; //Console.Error.WriteLine("Bomb " + troop.id + ": " + this.count); } else { this.count += (troop.team == factory.team) ? troop.count : -troop.count; if (this.count < 0) //if the troop captured the factory { this.count *= -1; SetTeam(troop.team); //team become the troops team } } }
public void AddPrereq(Troop troop) { Mission newMission = new Mission(MissionType.Capture, troop.end); HashSet <Troop> reqTroops; if (Strategy.curExecuted.Contains(newMission) || FactoryState.WillFactoryBeAlly(troop.end.states)) { return; //already cleared prereq } if (mission.prereqs.TryGetValue(newMission, out reqTroops)) { reqTroops.Add(troop); } else { mission.prereqs.Add(newMission, new HashSet <Troop> { troop }); } }
public static void CalculateAllArmyScore() { foreach (var factory in factories) { FactoryState lastState = factory.states.Last(); //assume the lastState for now double allyCount = 0; double enemyCount = 0; if (lastState.isAlly) { allyCount += lastState.count; } else if (lastState.team == Team.Enemy) { enemyCount += lastState.count; } factory.CalculateArmyScore(allyCount, enemyCount); factory.GetNearestEnemy(); } }
public void Solve() { mission.EnlistTroops(); if (mission.acceptedMission.Count == 0) { mission.successRating = MissionSuccessRating.Impossible; return; } SortedSet <Troop> mockTroops = new SortedSet <Troop>(mission.factory.incoming); List <Troop> finalEnlisted = new List <Troop>(); Factory factory = mission.factory; foreach (var mockTestTroop in mission.acceptedMission) { mockTroops.Add(mockTestTroop); finalEnlisted.Add(mockTestTroop); mission.troopsUsed += mockTestTroop.count; mission.missionEndTime = mockTestTroop.endTime; FactoryState lastState = new FactoryState(factory, Game.gameTime); bool allyLock = factory.isAlly; int armyAvailable = allyLock ? factory.count : 0; var ordered = mockTroops.ToList(); //iterate through the mock states for (int i = 0; i < ordered.Count; i++) { Troop troop = ordered[i]; FactoryState newState = new FactoryState(lastState, troop); //if two troops arrives at the same time if (i + 1 < ordered.Count && troop.endTime == ordered[i + 1].endTime) { lastState = newState; continue; } if (allyLock && newState.isEnemy) { allyLock = false; break; } if (allyLock == false && newState.isAlly) { allyLock = true; armyAvailable = newState.count; } if (factory.isAlly && troop == mockTestTroop) { armyAvailable = newState.count; } armyAvailable = Math.Min(armyAvailable, newState.count); lastState = newState; } if (allyLock)//mission is possible { int finalStateCount = mockTestTroop.count - armyAvailable + 1; if (finalStateCount <= 0) { return; //we didn't need to send anything } if (mission.type == MissionType.Capture)//mission.factory.team == Team.Enemy) { if (MissionReward.GetCaptureProbability(mission, 1, mission.missionEndTime - Game.gameTime)) { mockTestTroop.count = mockTestTroop.count - armyAvailable + 1; //don't oversend finalStateCount = 1; lastState.count = 1; } else { if (!MissionReward.GetCaptureProbability(mission, finalStateCount, mission.missionEndTime - Game.gameTime)) { mission.successRating = MissionSuccessRating.Unlikely; continue; } } } else { mockTestTroop.count = mockTestTroop.count - armyAvailable + 1; //don't oversend } mission.troopsUsed += -armyAvailable + 1; mission.finalState = lastState; mission.successRating = mission.prereqs.Count > 0 ? MissionSuccessRating.HasPrereq : MissionSuccessRating.Possible; mission.finalEnlistedTroops = finalEnlisted; return; //job's done } else { mission.successRating = MissionSuccessRating.NotEnoughTroops; } } }
public static void AddMissions() { var orderedFactories = Factory.factories .OrderByDescending(factory => factory.stats.allyScore * factory.oldProduction); foreach (var factory in orderedFactories) { //if the factory will always be ally's if (factory.isAlly && FactoryState.WillFactoryBeAlly(factory.states)) { int nearbyEnemyThreatCount = factory.GetNearbyEnemyThreats(); if (nearbyEnemyThreatCount == 0) //&& Factory.globalStats.totalAllyCount - 10 >= (2*Factory.globalStats.totalEnemyCount/3.0)) { if (factory.oldProduction < 3 && factory.armyAvailable >= 10) { Mission newMission = new Mission(MissionType.Inc, factory); missions.Add(newMission); } else if (factory.oldProduction < 3) //send inc support before becoming ally's? { Mission newMission = new Mission(MissionType.IncSupport, factory); missions.Add(newMission); } } else { if (nearbyEnemyThreatCount > 0) { Mission newMission = new Mission(MissionType.Reinforce, factory); newMission.troopsNeeded = nearbyEnemyThreatCount; missions.Add(newMission); } } } else { if (Game.bomb > 0 && Game.gameTime > 0) { Mission bombMission = new Mission(MissionType.Bomb, factory); missions.Add(bombMission); } if (factory.isAlly) { Mission newMission = new Mission(MissionType.Defend, factory); missions.Add(newMission); } else { if (!FactoryState.WillFactoryBeAlly(factory.states)) { Mission newMission = new Mission(MissionType.Capture, factory); missions.Add(newMission); } } //double missionScore = factory.stats.allyScore * factory.oldProduction; //Console.Error.WriteLine(factory.id + ": " + missionScore); //return; } } }