Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public void Update()
- {
- //1 == ignore; 0 == do; all floats begin at 0
- //so that the default value will force them to move
- List<float> heuristicValues = new List<float>();
- float buildBase = 0.0f;
- float buildBarracks = 0.0f;
- float buildRefinery = 0.0f;
- float trainWorker = 0.0f;
- float trainSoldier = 0.0f;
- float trainArcher = 0.0f;
- float computeGather = 0.0f;
- float computeMove = 0.0f;
- float attack = 0.0f;
- UpdateGameState();
- // If we have at least one base, assume the first one is our "main" base
- if (myBases.Count > 0)
- {
- mainBaseNbr = myBases[0];
- }
- else
- {
- mainBaseNbr = -1;
- }
- // If we have a base, find the closest mine to the base
- if (mines.Count > 0 && mainBaseNbr >= 0)
- {
- Unit baseUnit = GameManager.Instance.GetUnit(mainBaseNbr);
- mainMineNbr = FindClosestUnit(baseUnit.GridPosition, mines);
- }
- // Process all of the units, prioritize building new structures over
- // training units in terms of spending gold
- //ProcessWorkers();
- //ProcessSoldiers();
- //ProcessArchers();
- //ProcessBarracks();
- //ProcessBases();
- //new method calls to determine value of heuristics
- heuristicValues.Add(ComputeValueBuildBase(buildBase));
- heuristicValues.Add(ComputeValueBuildBarracks(buildBarracks));
- heuristicValues.Add(ComputeValueBuildRefinery(buildRefinery));
- heuristicValues.Add(ComputeValueTrainWorkers(trainWorker));
- heuristicValues.Add(ComputeValueTrainSoldiers(trainSoldier));
- heuristicValues.Add(ComputeValueTrainArchers(trainArcher));
- heuristicValues.Add(ComputeAttack(attack));
- heuristicValues.Add(ComputeMove(computeMove));
- heuristicValues.Add(ComputeGather(computeGather));
- //floats for searching through list;
- //int for storing place within list to run apporpriate method
- float highestVal = heuristicValues[0];
- float currentVal = 0.0f;
- int heurVal = 0;
- //search through list and run the method that has the highest value
- for (int i = 0; i < heuristicValues.Count; ++i)
- {
- currentVal = heuristicValues[i];
- if (highestVal < currentVal)
- {
- highestVal = currentVal;
- heurVal = i;
- }
- }
- foreach (int worker in myWorkers)
- {
- RunMethods(heurVal);
- }
- }
- #endregion
- /// <summary>
- /// Heuristics that compute the necessity of doing a certain action
- /// at a certain time. Methods return floats ranging from 0 - 1
- /// </summary>
- /// <param name="computeBase"> example of the type of float being passed into a method</param>
- /// <returns></returns>
- #region Heuristics
- //simple calculation for bases, barracks, and refineries because they either exist or they do not, 0 / 1
- private float ComputeValueBuildBase(float computeBase)
- {
- //if we have a base, set to 1 to signify completion
- if (myBases.Count == 1)
- {
- computeBase = 0.0f;
- }
- else
- {
- computeBase = 1.0f;
- }
- return computeBase;
- }
- private float ComputeValueBuildBarracks(float computeBarracks)
- {
- if (myBarracks.Count == 1)
- {
- computeBarracks = 0.0f;
- }
- else
- {
- computeBarracks = 1.0f;
- }
- return computeBarracks;
- }
- private float ComputeValueBuildRefinery(float computeRefinery)
- {
- if (myRefineries.Count == 1)
- {
- computeRefinery = 0.0f;
- }
- else
- {
- computeRefinery = 0.0f;
- }
- return computeRefinery;
- }
- private float ComputeValueTrainWorkers(float computeWorkers)
- {
- computeWorkers = 1 - (myWorkers.Count) / (2 * enemyWorkers.Count + myWorkers.Count + 1);
- return computeWorkers;
- }
- private float ComputeValueTrainSoldiers(float computeSoldiers)
- {
- //soldiers cost 150; assuming that they do more damage, prioritize 5 soldiers at most
- //after the archers have been made
- computeSoldiers = 1 - (mySoldiers.Count) / (3 * enemyWorkers.Count + mySoldiers.Count + 1);
- return computeSoldiers;
- }
- private float ComputeValueTrainArchers(float computeArchers)
- {
- //archers cost 100; prioritize 10 archers before any soldiers
- computeArchers = 1 - (myArchers.Count) / (2 * enemyWorkers.Count + myArchers.Count + 1);
- return computeArchers;
- }
- private float ComputeAttack(float computeAttack)
- {
- //another very simple heuristic, but I want my soldiers and archers to never stop until the enemy has been defeated
- if (enemyAgentNbr > 0 || enemyBarracks.Count > 0 || enemyBases.Count > 0)
- {
- computeAttack = 1.0f;
- }
- else
- {
- computeAttack = 0.0f;
- }
- return computeAttack;
- }
- private float ComputeGather(float computeGather)
- {
- //I need the workers to always gathering; there is no downside to having more gold
- computeGather = 1 - (Gold) / (mines.Capacity + 1);
- return computeGather;
- }
- private float ComputeMove(float computeMove)
- {
- //if there are spaces open on either mine
- computeMove = 1;
- return computeMove;
- }
- #endregion
- #region Heuristic Methods
- public void BuildBase()
- {
- // For each worker
- foreach (int worker in myWorkers)
- {
- // Grab the unit we need for this function
- Unit unit = GameManager.Instance.GetUnit(worker);
- // Make sure this unit actually exists and is idle
- if (unit != null && unit.CurrentAction == UnitAction.IDLE)
- {
- // If we have enough gold and need a base, build a base
- if (Gold >= Constants.COST[UnitType.BASE]
- && myBases.Count < 1)
- {
- // Find the closest build position to this worker's position (DUMB) and
- // build the base there
- Vector3Int toBuild = FindClosestBuildPosition(unit.GridPosition, UnitType.BASE);
- if (toBuild != Vector3Int.zero)
- {
- Build(unit, toBuild, UnitType.BASE);
- }
- }
- }
- }
- }
- public void BuildBarrack()
- {
- // For each worker
- foreach (int worker in myWorkers)
- {
- // Grab the unit we need for this function
- Unit unit = GameManager.Instance.GetUnit(worker);
- // Make sure this unit actually exists and is idle
- if (unit != null && unit.CurrentAction == UnitAction.IDLE)
- {
- //If we have enough gold and need a barracks, build a barracks
- if (Gold >= Constants.COST[UnitType.BARRACKS]
- && myBarracks.Count < 1)
- {
- // Find the closest build position to this worker's position and build
- // the barracks there
- Vector3Int toBuild = FindClosestBuildPosition(unit.GridPosition, UnitType.BARRACKS);
- if (toBuild != Vector3Int.zero)
- {
- Build(unit, toBuild, UnitType.BARRACKS);
- }
- }
- }
- }
- }
- public void BuildRefinery()
- {
- // For each worker
- foreach (int worker in myWorkers)
- {
- // Grab the unit we need for this function
- Unit unit = GameManager.Instance.GetUnit(worker);
- // Make sure this unit actually exists and is idle
- if (unit != null && unit.CurrentAction == UnitAction.IDLE)
- {
- // If we have enough gold and need a refinery, build a refinery
- if (Gold >= Constants.COST[UnitType.REFINERY]
- && myRefineries.Count < 1)
- {
- // Find the closest build position to this worker's position and build
- // the refinery there
- Vector3Int toBuild = FindClosestBuildPosition(unit.GridPosition, UnitType.REFINERY);
- if (toBuild != Vector3Int.zero)
- {
- Build(unit, toBuild, UnitType.REFINERY);
- }
- }
- }
- }
- }
- public void TrainWorkers()
- {
- // For each base, determine if it should train a worker
- foreach (int baseNbr in myBases)
- {
- // Get the base unit
- Unit baseUnit = GameManager.Instance.GetUnit(baseNbr);
- // If the base exists, is idle, we need a worker, and we have gold
- if (baseUnit != null && baseUnit.IsBuilt
- && baseUnit.CurrentAction == UnitAction.IDLE && myWorkers.Count < 10
- && Gold >= Constants.COST[UnitType.WORKER])
- {
- Train(baseUnit, UnitType.WORKER);
- }
- }
- }
- public void TrainSoldiers()
- {
- // For each barracks, train soldiers
- foreach (int barracksNbr in myBarracks)
- {
- // Get the barracks
- Unit barracksUnit = GameManager.Instance.GetUnit(barracksNbr);
- // If this barracks still exists, is idle, we need soldiers, and have gold
- if (!lastFighterWasSoldier && barracksUnit != null && barracksUnit.IsBuilt
- && barracksUnit.CurrentAction == UnitAction.IDLE
- && (mySoldiers.Count < 5
- || mySoldiers.Count <= enemySoldiers.Count * 1.5)
- && Gold >= Constants.COST[UnitType.SOLDIER])
- {
- Train(barracksUnit, UnitType.SOLDIER);
- lastFighterWasSoldier = !lastFighterWasSoldier;
- }
- }
- }
- public void TrainArchers()
- {
- // For each barracks, train archers
- foreach (int barracksNbr in myBarracks)
- {
- // Get the barracks
- Unit barracksUnit = GameManager.Instance.GetUnit(barracksNbr);
- // If this barracks still exists, is idle, we need archers, and have gold
- if (lastFighterWasSoldier && barracksUnit != null && barracksUnit.IsBuilt
- && barracksUnit.CurrentAction == UnitAction.IDLE
- && (myArchers.Count < 10
- || myArchers.Count <= enemyArchers.Count * 1.5)
- && Gold >= Constants.COST[UnitType.ARCHER])
- {
- Train(barracksUnit, UnitType.ARCHER);
- lastFighterWasSoldier = !lastFighterWasSoldier;
- }
- }
- }
- //same method as process archers, but they target the closest target instead of a random target
- public void ArchersAttack()
- {
- // For each soldier, determine what they should attack
- foreach (int archerNbr in myArchers)
- {
- // Get the unit
- Unit archerUnit = GameManager.Instance.GetUnit(archerNbr);
- // If the archer still exists and is idle
- if (archerUnit != null && archerUnit.CurrentAction == UnitAction.IDLE)
- {
- // If there are enemy soldiers, randomly select one and attack it
- if (enemySoldiers.Count > 0)
- {
- Attack(archerUnit, GameManager.Instance.GetUnit(
- enemySoldiers[FindClosestUnit(archerUnit.GridPosition, enemySoldiers)]));
- }
- // If there are enemy archers, randomly select one and attack it
- else if (enemyArchers.Count > 0)
- {
- Attack(archerUnit, GameManager.Instance.GetUnit(
- enemyArchers[FindClosestUnit(archerUnit.GridPosition, enemyArchers)]));
- }
- // If there are enemy workers, randomly select one and attack it
- else if (enemyWorkers.Count > 0)
- {
- Attack(archerUnit, GameManager.Instance.GetUnit(
- enemyWorkers[FindClosestUnit(archerUnit.GridPosition, enemyWorkers)]));
- }
- // If there are enemy bases, randomly select one and attack it
- else if (enemyBases.Count > 0)
- {
- Attack(archerUnit, GameManager.Instance.GetUnit(
- enemyBases[FindClosestUnit(archerUnit.GridPosition, enemyBases)]));
- }
- // If there are enemy barracks, randomly select one and attack it
- else if (enemyBarracks.Count > 0)
- {
- Attack(archerUnit, GameManager.Instance.GetUnit(
- enemyBarracks[FindClosestUnit(archerUnit.GridPosition, enemyBarracks)]));
- }
- // If there are enemy refineries, randomly select one and attack it
- else if (enemyRefineries.Count > 0)
- {
- Attack(archerUnit, GameManager.Instance.GetUnit(
- enemyRefineries[FindClosestUnit(archerUnit.GridPosition, enemyRefineries)]));
- }
- }
- }
- }
- //same method as process soldiers, but they target the closest target instead of a random target
- public void SoldiersAttack()
- {
- // For each soldier, determine what they should attack
- foreach (int soldierNbr in mySoldiers)
- {
- // Get this soldier
- Unit soldierUnit = GameManager.Instance.GetUnit(soldierNbr);
- // If this soldier still exists and is idle
- if (soldierUnit != null && soldierUnit.CurrentAction == UnitAction.IDLE)
- {
- // If there are enemy soldiers, randomly select one and attack it
- if (enemySoldiers.Count > 0)
- {
- Attack(soldierUnit, GameManager.Instance.GetUnit(
- enemySoldiers[FindClosestUnit(soldierUnit.GridPosition, enemySoldiers)]));
- }
- // If there are enemy archers, randomly select one and attack it
- else if (enemyArchers.Count > 0)
- {
- Attack(soldierUnit, GameManager.Instance.GetUnit(
- enemyArchers[FindClosestUnit(soldierUnit.GridPosition, enemyArchers)]));
- }
- // If there are enemy workers, randomly select one and attack it
- else if (enemyWorkers.Count > 0)
- {
- Attack(soldierUnit, GameManager.Instance.GetUnit(
- enemyWorkers[FindClosestUnit(soldierUnit.GridPosition, enemyWorkers)]));
- }
- // If there are enemy bases, randomly select one and attack it
- else if (enemyBases.Count > 0)
- {
- Attack(soldierUnit, GameManager.Instance.GetUnit(
- enemyBases[FindClosestUnit(soldierUnit.GridPosition, enemyBases)]));
- }
- // If there are enemy barracks, randomly select one and attack it
- else if (enemyBarracks.Count > 0)
- {
- Attack(soldierUnit, GameManager.Instance.GetUnit(
- enemyBarracks[FindClosestUnit(soldierUnit.GridPosition, enemyBarracks)]));
- }
- // If there are enemy refineries, randomly select one and attack it
- else if (enemyRefineries.Count > 0)
- {
- Attack(soldierUnit, GameManager.Instance.GetUnit(
- enemyRefineries[FindClosestUnit(soldierUnit.GridPosition, enemyRefineries)]));
- }
- }
- }
- }
- public void MoveWorkers()
- {
- // For each worker
- foreach (int worker in myWorkers)
- {
- // Grab the unit we need for this function
- Unit unit = GameManager.Instance.GetUnit(worker);
- // Make sure this unit actually exists and is idle
- if (unit != null && unit.CurrentAction == UnitAction.IDLE)
- {
- // Otherwise, just mine
- if (mainBaseNbr >= 0 && mainMineNbr >= 0)
- {
- // Grab the mine for this agent
- Unit mineUnit = GameManager.Instance.GetUnit(mainMineNbr);
- Unit baseUnit = GameManager.Instance.GetUnit(mainBaseNbr);
- if (mineUnit != null && baseUnit != null)
- { Gather(unit, mineUnit, baseUnit); }
- }
- }
- }
- }
- public void WorkersGather()
- {
- // For each worker
- foreach (int worker in myWorkers)
- {
- // Grab the unit we need for this function
- Unit unit = GameManager.Instance.GetUnit(worker);
- // Make sure this unit actually exists and is idle
- if (unit != null && unit.CurrentAction == UnitAction.IDLE)
- {
- // Otherwise, just mine
- if (mainBaseNbr >= 0 && mainMineNbr >= 0)
- {
- // Grab the mine for this agent
- Unit mineUnit = GameManager.Instance.GetUnit(mainMineNbr);
- Unit baseUnit = GameManager.Instance.GetUnit(mainBaseNbr);
- if (mineUnit != null && baseUnit != null)
- { Gather(unit, mineUnit, baseUnit); }
- }
- }
- }
- }
- #endregion
- //returns the closest target from the chosen list
- //Ignore
- private Unit ClosestTarget(Unit closestTarget, List<int>targetList)
- {
- foreach (int target in targetList)
- {
- closestTarget = GameManager.Instance.GetUnit(targetList[target]);
- if (GameManager.Instance.GetUnit(targetList[target + 1]).GridPosition.magnitude < closestTarget.GridPosition.magnitude)
- {
- closestTarget = GameManager.Instance.GetUnit(targetList[target + 1]);
- }
- }
- return closestTarget;
- }
- private void RunMethods(int heurVal)
- {
- switch (heurVal)
- {
- //build barracks
- case 1:
- BuildBarrack();
- break;
- //build refinery
- case 2:
- BuildRefinery();
- break;
- //train workers
- case 3:
- TrainWorkers();
- break;
- //train soldiers
- case 4:
- TrainSoldiers();
- break;
- //train archers
- case 5:
- TrainArchers();
- break;
- //attack
- case 6:
- ArchersAttack();
- SoldiersAttack();
- break;
- //move (for workers)
- case 7:
- MoveWorkers();
- break;
- //gather (for workers)
- case 8:
- WorkersGather();
- break;
- default:
- //i = 0 case
- BuildBase();
- break;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement