/// <summary> /// Obtains the picks that will be used for the game. Will determine an initial score that will be used to order to picks initially, followed by finding FTBs and combos /// that will be interspersed based on cases outlined in tree diagram /// </summary> /// <returns>List of territory IDs of the final picks to be sent</returns> public List <TerritoryIDType> GetPicks() { if (BotState.Map.IsScenarioDistribution(BotState.Settings.DistributionModeID)) { var us = BotState.Map.GetTerritoriesForScenario(BotState.Settings.DistributionModeID, BotState.Me.ScenarioID); us.RandomizeOrder(); return(us); } int maxPicks = BotState.Settings.LimitDistributionTerritories == 0 ? BotState.Map.Territories.Count : (BotState.Settings.LimitDistributionTerritories * BotState.Players.Count(o => o.Value.State == GamePlayerState.Playing)); var pickableTerritories = BotState.DistributionStanding.Territories.Values.Where(o => o.OwnerPlayerID == TerritoryStanding.AvailableForDistribution).Select(o => o.ID).ToList(); bool isAntWastelanded = false; TerritoryIDType ausID = (TerritoryIDType)0; var map = BotMap.FromStanding(BotState, BotState.DistributionStanding); var weights = pickableTerritories.ToDictionary(o => o, terrID => { // Check if Ant is wastelanded for Aus score modifier map.Territories[terrID].OwnerPlayerID = BotState.Me.ID; if (map.Territories[terrID].Bonuses[0].Details.Name.Equals("Antarctica") && BotState.BonusPickValueCalculator.IsWastelandedBonus(map.Territories[terrID].Bonuses[0])) { isAntWastelanded = true; } else if (map.Territories[terrID].Bonuses[0].Details.Name.Equals("Australia")) { ausID = terrID; } // Only find value if bonus has significiant amount if (map.Territories[terrID].Bonuses.Count > 0) { BotBonus bonus = map.Territories[terrID].Bonuses[0]; bonus.SetMyPickValueHeuristic(); double r = bonus.ExpansionValue; return(r); } else { return(0); } }); // Check for if pick is in Aus if (!isAntWastelanded && weights.ContainsKey(ausID)) { weights[ausID] -= 25; } foreach (TerritoryIDType terrID in weights.Keys) { AILog.Log("Pick Values", map.Territories[terrID].Bonuses[0] + ": " + weights[terrID]); } // Check for FTBs and assign value for Aus based on Ant Wasteland boolean List <ComboBonuses> firstTurnBonusList = new List <ComboBonuses>(); List <ComboBonuses> comboList = new List <ComboBonuses>(); foreach (KeyValuePair <TerritoryIDType, double> pick in weights) { // Checks for FTB and combos if (BotState.BonusPickValueCalculator.IsFirstTurnBonus(map.Territories[pick.Key].Bonuses[0])) { ComboBonuses newCombo = new ComboBonuses(map.Territories[pick.Key].Bonuses[0], map); firstTurnBonusList.Add(newCombo); } else if (BotState.BonusPickValueCalculator.IsComboBonus(map.Territories[pick.Key].Bonuses[0], map)) { ComboBonuses newCombo = new ComboBonuses(map.Territories[pick.Key].Bonuses[0], map); comboList.Add(newCombo); } } ReorderCombosByNumberOfTerritories(ref firstTurnBonusList); ReorderCombosByNumberOfTerritories(ref comboList); AILog.Log("Picks", "Number of FTBs: " + firstTurnBonusList.Count); AILog.Log("Picks", "Number of Combos: " + comboList.Count); AILog.Log("Picks", "FTBs found:"); foreach (ComboBonuses ftb in firstTurnBonusList) { AILog.Log("Picks", "\tBonus: " + ftb.mainBonus.Details.Name); AILog.Log("Picks", "\t\t" + ftb.mainPick.Details.Name); for (int i = 0; i < ftb.adjacentPickTerritories.Count; i++) { if (ftb.adjacentPickTerritories[i].Details.Name.Equals(ftb.mainPick.Details.Name)) { continue; } AILog.Log("Picks", "\t\t\t" + ftb.adjacentPickTerritories[i].Details.Name); } } AILog.Log("Picks", "End of FTB list"); AILog.Log("Picks", "Combos found:"); foreach (ComboBonuses combo in comboList) { AILog.Log("Picks", "\tBonus: " + combo.mainBonus.Details.Name); AILog.Log("Picks", "\t\t" + combo.mainPick.Details.Name); for (int i = 0; i < combo.adjacentPickTerritories.Count; i++) { if (combo.adjacentPickTerritories[i].Details.Name.Equals(combo.mainPick.Details.Name)) { continue; } AILog.Log("Picks", "\t\t\t" + (combo.adjacentPickTerritories[i].Details.Name.Equals(combo.mainPick.Details.Name) ? combo.adjacentPickTerritories[++i].Details.Name : combo.adjacentPickTerritories[i].Details.Name)); } } AILog.Log("Picks", "End of combo list"); List <TerritoryIDType> picks = weights.OrderByDescending(o => o.Value).Take(maxPicks).Select(o => o.Key).Distinct().ToList(); //StatefulFogRemover.PickedTerritories = picks; AILog.Log("Picks", "Before final reshuffle:"); foreach (var terr in picks) { AILog.Log("Picks", "\t" + map.Territories[terr].Bonuses[0].Details.Name + ", " + map.Territories[terr].Details.Name); } ReorderPicksByCombos(firstTurnBonusList, comboList, ref picks); AILog.Log("Picks", "After final reshuffle:"); foreach (var terr in picks) { AILog.Log("Picks", "\t" + map.Territories[terr].Bonuses[0].Details.Name + ", " + map.Territories[terr].Details.Name); } Memory.PickTracker.SetPickList(picks); BotMap storedMap = BotState.VisibleMap.GetMapCopy(); Memory.PickTracker.pickMap = storedMap; return(picks); }