private static int GetTurnsUntilAffordable(TurnCalculatorNode node, Currency cost) { if (node.PlayerData.CurrencyData.CanAfford(cost)) { return(0); } if (!node.PlayerData.CurrencyData.HasUtilisableCurrencies(cost)) { return(-1); } var suppliers = Cells.GetSuppliers(node.Buildings.Select(b => b as HexCell).ToList()); var suppliesPerTurn = suppliers.Sum(c => c.CalculateSupplies(node.PlayerData)); if (suppliesPerTurn <= 0) { return(-1); } var requiredSupplies = cost.supplies - node.PlayerData.CurrencyData.Supplies; var numTurns = Mathf.CeilToInt((float)requiredSupplies / suppliesPerTurn); const float maxTurnCount = 10; if (numTurns > maxTurnCount) { return(-1); } return(numTurns); }
private TurnCalculatorNode TryCreateNewNode(TurnCalculatorNode origin, ActionDefinition action) { if (action is BuildAction buildAction) { if (origin.Buildings.Contains(buildAction.prefab)) { return(null); } if (origin.PlayerData.TechnologyData.HasTechnology(buildAction.prefab.Technology)) { return(null); } if (!origin.PlayerData.TechnologyData.HasTechnologies(buildAction.techRequirements)) { return(null); } var turnCount = GetTurnsUntilAffordable(origin, buildAction.prefab.Cost); if (turnCount < 0) { return(null); } var costForHeuristic = targetCell == null ? targetUpgrade.cost : targetCell.Cost; return(new TurnCalculatorNode(origin, buildAction.prefab, turnCount, costForHeuristic)); } else if (action is UpgradeAction upgradeAction) { UpgradeAction.UpgradeDetails nextUpgrade; try { nextUpgrade = upgradeAction.upgradeDetails.First(u => !origin.PlayerData.TechnologyData.HasTechnology(u.tech)); } catch { return(null); } if (origin.PlayerData.TechnologyData.HasTechnology(nextUpgrade.tech)) { return(null); } if (!origin.PlayerData.TechnologyData.HasTechnologies(nextUpgrade.requiredTech)) { return(null); } var turnCount = GetTurnsUntilAffordable(origin, nextUpgrade.cost); if (turnCount < 0) { return(null); } var costForHeuristic = targetCell == null ? targetUpgrade.cost : targetCell.Cost; return(new TurnCalculatorNode(origin, nextUpgrade, turnCount, costForHeuristic)); } return(null); }
public TurnCalculatorNode(TurnCalculatorNode originalNode, UpgradeAction.UpgradeDetails upgrade, int numTurnsToAfford, Currency targetCost) { PlayerData = originalNode.PlayerData.Clone(); Buildings = originalNode.Buildings; ApplyCurrencyModifications(numTurnsToAfford, upgrade.cost); PlayerData.TechnologyData.AddTechnology(upgrade.tech); PreviousNode = originalNode; Action = "Upgrade " + upgrade.title; CalculateNodeCosts(targetCost); }
private void AddToOpenSet(TurnCalculatorNode node) { if (node.PlayerData.TurnNumber > 50) { return; } if (openSet.Any(openNode => openNode.IsEqual(node) && openNode.F < node.F)) { return; } if (closedSet.Any(closedNode => closedNode.IsEqual(node) && closedNode.F < node.F)) { return; } openSet.Add(node); }
private List <TurnCalculatorNode> GetNeighbouringNodes(TurnCalculatorNode node) { var neighbours = new List <TurnCalculatorNode>(); foreach (var building in node.Buildings) { foreach (var action in building.Actions) { var newNode = TryCreateNewNode(node, action); if (newNode != null) { neighbours.Add(newNode); } } } return(neighbours); }
private Queue <TurnCalculatorNode> ConstructGamePlan(TurnCalculatorNode node) { var queue = new Stack <TurnCalculatorNode>(); while (node != null) { queue.Push(node); node = node.PreviousNode; } var gamePlan = new Queue <TurnCalculatorNode>(); while (queue.Any()) { gamePlan.Enqueue(queue.Pop()); } return(gamePlan); }
private void ShowNextTurnSteps(TurnCalculatorNode node, int turnNumber, VisualElement container) { var numTurnsSinceLastAction = node.PlayerData.TurnNumber - turnNumber; for (int i = 0; i < numTurnsSinceLastAction; i++) { var details = new StepRowDetails { TurnNumber = turnNumber + i + 1, Label = "Next turn", StyleClass = "plan-step-nextturn", InitialSupplies = node.InitialSupplies + node.SuppliesPerTurn * i, InitialProduction = node.InitialProduction, SupplyDifference = node.SuppliesPerTurn, ProductionDifference = 0, PopulationDifference = 0, }; var step = CreateStepRow(details); container.Add(step); } }
public TurnCalculatorNode(TurnCalculatorNode originalNode, HexCell newCell, int numTurnsToAfford, Currency targetCost) { PlayerData = originalNode.PlayerData.Clone(); Buildings = originalNode.Buildings.ToList(); ApplyCurrencyModifications(numTurnsToAfford, newCell.Cost); PlayerData.TechnologyData.AddTechnology(newCell.Technology); if (newCell is BuildingCell building) { Buildings.Add(building); var currencyBonus = building.GetCurrencyBonus(); PlayerData.CurrencyData.Production.maximum += currencyBonus.production; PlayerData.CurrencyData.Population.maximum += currencyBonus.population; } PreviousNode = originalNode; Action = "Purchase " + newCell.DisplayName; CalculateNodeCosts(targetCost); }
private bool NodeAchievesGamePlan(TurnCalculatorNode node) { return(node.PlayerData.TechnologyData.HasTechnology(targetCell != null ? targetCell.Technology : targetUpgrade.tech)); }
public bool IsEqual(TurnCalculatorNode other) { return(other.PlayerData.HasSameData(PlayerData) && other.Buildings.Count == Buildings.Count && other.Buildings.All(b => Buildings.Contains(b))); }