Advertisement
Guest User

Untitled

a guest
Apr 22nd, 2018
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 21.23 KB | None | 0 0
  1. public void Update()
  2.         {
  3.             //1 == ignore; 0 == do; all floats begin at 0
  4.             //so that the default value will force them to move
  5.             List<float> heuristicValues = new List<float>();
  6.             float buildBase = 0.0f;
  7.             float buildBarracks = 0.0f;
  8.             float buildRefinery = 0.0f;
  9.             float trainWorker = 0.0f;
  10.             float trainSoldier = 0.0f;
  11.             float trainArcher = 0.0f;
  12.             float computeGather = 0.0f;
  13.             float computeMove = 0.0f;
  14.             float attack = 0.0f;
  15.  
  16.             UpdateGameState();
  17.  
  18.             // If we have at least one base, assume the first one is our "main" base
  19.             if (myBases.Count > 0)
  20.             {
  21.                 mainBaseNbr = myBases[0];
  22.             }
  23.             else
  24.             {
  25.                 mainBaseNbr = -1;
  26.             }
  27.  
  28.             // If we have a base, find the closest mine to the base
  29.             if (mines.Count > 0 && mainBaseNbr >= 0)
  30.             {
  31.                 Unit baseUnit = GameManager.Instance.GetUnit(mainBaseNbr);
  32.                 mainMineNbr = FindClosestUnit(baseUnit.GridPosition, mines);
  33.             }
  34.  
  35.             // Process all of the units, prioritize building new structures over
  36.             // training units in terms of spending gold
  37.             //ProcessWorkers();
  38.  
  39.             //ProcessSoldiers();
  40.  
  41.             //ProcessArchers();
  42.  
  43.             //ProcessBarracks();
  44.  
  45.             //ProcessBases();
  46.  
  47.             //new method calls to determine value of heuristics
  48.             heuristicValues.Add(ComputeValueBuildBase(buildBase));
  49.             heuristicValues.Add(ComputeValueBuildBarracks(buildBarracks));
  50.             heuristicValues.Add(ComputeValueBuildRefinery(buildRefinery));
  51.             heuristicValues.Add(ComputeValueTrainWorkers(trainWorker));
  52.             heuristicValues.Add(ComputeValueTrainSoldiers(trainSoldier));
  53.             heuristicValues.Add(ComputeValueTrainArchers(trainArcher));
  54.             heuristicValues.Add(ComputeAttack(attack));
  55.             heuristicValues.Add(ComputeMove(computeMove));
  56.             heuristicValues.Add(ComputeGather(computeGather));
  57.  
  58.             //floats for searching through list;
  59.             //int for storing place within list to run apporpriate method
  60.             float highestVal = heuristicValues[0];
  61.             float currentVal = 0.0f;
  62.             int heurVal = 0;
  63.  
  64.             //search through list and run the method that has the highest value
  65.             for (int i = 0; i < heuristicValues.Count; ++i)
  66.             {
  67.                 currentVal = heuristicValues[i];
  68.  
  69.                 if (highestVal < currentVal)
  70.                 {
  71.                     highestVal = currentVal;
  72.                     heurVal = i;
  73.                 }
  74.             }
  75.             foreach (int worker in myWorkers)
  76.             {
  77.                 RunMethods(heurVal);
  78.             }
  79.         }
  80.  
  81.         #endregion
  82.  
  83.         /// <summary>
  84.         /// Heuristics that compute the necessity of doing a certain action
  85.         /// at a certain time. Methods return floats ranging from 0 - 1
  86.         /// </summary>
  87.         /// <param name="computeBase"> example of the type of float being passed into a method</param>
  88.         /// <returns></returns>
  89.         #region Heuristics
  90.  
  91.         //simple calculation for bases, barracks, and refineries because they either exist or they do not, 0 / 1
  92.         private float ComputeValueBuildBase(float computeBase)
  93.         {
  94.             //if we have a base, set to 1 to signify completion
  95.             if (myBases.Count == 1)
  96.             {
  97.                 computeBase = 0.0f;
  98.             }
  99.  
  100.             else
  101.             {
  102.                 computeBase = 1.0f;
  103.             }
  104.  
  105.             return computeBase;
  106.         }
  107.  
  108.         private float ComputeValueBuildBarracks(float computeBarracks)
  109.         {
  110.             if (myBarracks.Count == 1)
  111.             {
  112.                 computeBarracks = 0.0f;
  113.             }
  114.  
  115.             else
  116.             {
  117.                 computeBarracks = 1.0f;
  118.             }
  119.  
  120.             return computeBarracks;
  121.         }
  122.  
  123.         private float ComputeValueBuildRefinery(float computeRefinery)
  124.         {
  125.             if (myRefineries.Count == 1)
  126.             {
  127.                 computeRefinery = 0.0f;
  128.             }
  129.  
  130.             else
  131.             {
  132.                 computeRefinery = 0.0f;
  133.             }
  134.  
  135.             return computeRefinery;
  136.         }
  137.  
  138.         private float ComputeValueTrainWorkers(float computeWorkers)
  139.         {
  140.             computeWorkers = 1 - (myWorkers.Count) / (2 * enemyWorkers.Count + myWorkers.Count + 1);
  141.  
  142.             return computeWorkers;
  143.         }
  144.  
  145.         private float ComputeValueTrainSoldiers(float computeSoldiers)
  146.         {
  147.             //soldiers cost 150; assuming that they do more damage, prioritize 5 soldiers at most
  148.             //after the archers have been made
  149.             computeSoldiers = 1 - (mySoldiers.Count) / (3 * enemyWorkers.Count + mySoldiers.Count + 1);
  150.             return computeSoldiers;
  151.         }
  152.  
  153.         private float ComputeValueTrainArchers(float computeArchers)
  154.         {
  155.             //archers cost 100; prioritize 10 archers before any soldiers
  156.             computeArchers = 1 - (myArchers.Count) / (2 * enemyWorkers.Count + myArchers.Count + 1);
  157.  
  158.             return computeArchers;
  159.         }
  160.  
  161.         private float ComputeAttack(float computeAttack)
  162.         {
  163.             //another very simple heuristic, but I want my soldiers and archers to never stop until the enemy has been defeated
  164.             if (enemyAgentNbr > 0 || enemyBarracks.Count > 0 || enemyBases.Count > 0)
  165.             {
  166.                 computeAttack = 1.0f;
  167.             }
  168.  
  169.             else
  170.             {
  171.                 computeAttack = 0.0f;
  172.             }
  173.  
  174.             return computeAttack;
  175.         }
  176.  
  177.         private float ComputeGather(float computeGather)
  178.         {
  179.             //I need the workers to always gathering; there is no downside to having more gold
  180.             computeGather = 1 - (Gold) / (mines.Capacity + 1);
  181.  
  182.             return computeGather;
  183.         }
  184.  
  185.         private float ComputeMove(float computeMove)
  186.         {
  187.             //if there are spaces open on either mine
  188.             computeMove = 1;
  189.  
  190.             return computeMove;
  191.         }
  192.  
  193.         #endregion
  194.  
  195.         #region Heuristic Methods
  196.         public void BuildBase()
  197.         {
  198.             // For each worker
  199.             foreach (int worker in myWorkers)
  200.             {
  201.                 // Grab the unit we need for this function
  202.                 Unit unit = GameManager.Instance.GetUnit(worker);
  203.  
  204.                 // Make sure this unit actually exists and is idle
  205.                 if (unit != null && unit.CurrentAction == UnitAction.IDLE)
  206.                 {
  207.                     // If we have enough gold and need a base, build a base
  208.                     if (Gold >= Constants.COST[UnitType.BASE]
  209.                         && myBases.Count < 1)
  210.                     {
  211.                         // Find the closest build position to this worker's position (DUMB) and
  212.                         // build the base there
  213.                         Vector3Int toBuild = FindClosestBuildPosition(unit.GridPosition, UnitType.BASE);
  214.                         if (toBuild != Vector3Int.zero)
  215.                         {
  216.                             Build(unit, toBuild, UnitType.BASE);
  217.                         }
  218.                     }
  219.                 }
  220.             }
  221.         }
  222.  
  223.         public void BuildBarrack()
  224.         {
  225.             // For each worker
  226.             foreach (int worker in myWorkers)
  227.             {
  228.                 // Grab the unit we need for this function
  229.                 Unit unit = GameManager.Instance.GetUnit(worker);
  230.  
  231.                 // Make sure this unit actually exists and is idle
  232.                 if (unit != null && unit.CurrentAction == UnitAction.IDLE)
  233.                 {
  234.                     //If we have enough gold and need a barracks, build a barracks
  235.                     if (Gold >= Constants.COST[UnitType.BARRACKS]
  236.                         && myBarracks.Count < 1)
  237.                     {
  238.                         // Find the closest build position to this worker's position and build
  239.                         // the barracks there
  240.                         Vector3Int toBuild = FindClosestBuildPosition(unit.GridPosition, UnitType.BARRACKS);
  241.                         if (toBuild != Vector3Int.zero)
  242.                         {
  243.                             Build(unit, toBuild, UnitType.BARRACKS);
  244.                         }
  245.                     }
  246.                 }
  247.             }
  248.         }
  249.  
  250.         public void BuildRefinery()
  251.         {
  252.             // For each worker
  253.             foreach (int worker in myWorkers)
  254.             {
  255.                 // Grab the unit we need for this function
  256.                 Unit unit = GameManager.Instance.GetUnit(worker);
  257.  
  258.                 // Make sure this unit actually exists and is idle
  259.                 if (unit != null && unit.CurrentAction == UnitAction.IDLE)
  260.                 {
  261.                     // If we have enough gold and need a refinery, build a refinery
  262.                     if (Gold >= Constants.COST[UnitType.REFINERY]
  263.                         && myRefineries.Count < 1)
  264.                     {
  265.                         // Find the closest build position to this worker's position and build
  266.                         // the refinery there
  267.                         Vector3Int toBuild = FindClosestBuildPosition(unit.GridPosition, UnitType.REFINERY);
  268.                         if (toBuild != Vector3Int.zero)
  269.                         {
  270.                             Build(unit, toBuild, UnitType.REFINERY);
  271.                         }
  272.                     }
  273.                 }
  274.             }
  275.         }
  276.  
  277.         public void TrainWorkers()
  278.         {
  279.             // For each base, determine if it should train a worker
  280.             foreach (int baseNbr in myBases)
  281.             {
  282.                 // Get the base unit
  283.                 Unit baseUnit = GameManager.Instance.GetUnit(baseNbr);
  284.  
  285.                 // If the base exists, is idle, we need a worker, and we have gold
  286.                 if (baseUnit != null && baseUnit.IsBuilt
  287.                     && baseUnit.CurrentAction == UnitAction.IDLE && myWorkers.Count < 10
  288.                     && Gold >= Constants.COST[UnitType.WORKER])
  289.                 {
  290.                     Train(baseUnit, UnitType.WORKER);
  291.                 }
  292.             }
  293.         }
  294.  
  295.         public void TrainSoldiers()
  296.         {
  297.             // For each barracks, train soldiers
  298.             foreach (int barracksNbr in myBarracks)
  299.             {
  300.                 // Get the barracks
  301.                 Unit barracksUnit = GameManager.Instance.GetUnit(barracksNbr);
  302.  
  303.                 // If this barracks still exists, is idle, we need soldiers, and have gold
  304.                 if (!lastFighterWasSoldier && barracksUnit != null && barracksUnit.IsBuilt
  305.                     && barracksUnit.CurrentAction == UnitAction.IDLE
  306.                     && (mySoldiers.Count < 5
  307.                     || mySoldiers.Count <= enemySoldiers.Count * 1.5)
  308.                     && Gold >= Constants.COST[UnitType.SOLDIER])
  309.                 {
  310.                     Train(barracksUnit, UnitType.SOLDIER);
  311.                     lastFighterWasSoldier = !lastFighterWasSoldier;
  312.                 }
  313.             }
  314.         }
  315.  
  316.         public void TrainArchers()
  317.         {
  318.             // For each barracks, train archers
  319.             foreach (int barracksNbr in myBarracks)
  320.             {
  321.                 // Get the barracks
  322.                 Unit barracksUnit = GameManager.Instance.GetUnit(barracksNbr);
  323.  
  324.                 // If this barracks still exists, is idle, we need archers, and have gold
  325.                 if (lastFighterWasSoldier && barracksUnit != null && barracksUnit.IsBuilt
  326.                          && barracksUnit.CurrentAction == UnitAction.IDLE
  327.                          && (myArchers.Count < 10
  328.                          || myArchers.Count <= enemyArchers.Count * 1.5)
  329.                          && Gold >= Constants.COST[UnitType.ARCHER])
  330.                 {
  331.                     Train(barracksUnit, UnitType.ARCHER);
  332.                     lastFighterWasSoldier = !lastFighterWasSoldier;
  333.                 }
  334.             }
  335.         }
  336.  
  337.         //same method as process archers, but they target the closest target instead of a random target
  338.         public void ArchersAttack()
  339.         {
  340.             // For each soldier, determine what they should attack
  341.             foreach (int archerNbr in myArchers)
  342.             {
  343.                 // Get the unit
  344.                 Unit archerUnit = GameManager.Instance.GetUnit(archerNbr);
  345.  
  346.                 // If the archer still exists and is idle
  347.                 if (archerUnit != null && archerUnit.CurrentAction == UnitAction.IDLE)
  348.                 {
  349.                     // If there are enemy soldiers, randomly select one and attack it
  350.                     if (enemySoldiers.Count > 0)
  351.                     {
  352.                         Attack(archerUnit, GameManager.Instance.GetUnit(
  353.                             enemySoldiers[FindClosestUnit(archerUnit.GridPosition, enemySoldiers)]));
  354.                     }
  355.                     // If there are enemy archers, randomly select one and attack it
  356.                     else if (enemyArchers.Count > 0)
  357.                     {
  358.                         Attack(archerUnit, GameManager.Instance.GetUnit(
  359.                             enemyArchers[FindClosestUnit(archerUnit.GridPosition, enemyArchers)]));
  360.                     }
  361.                     // If there are enemy workers, randomly select one and attack it
  362.                     else if (enemyWorkers.Count > 0)
  363.                     {
  364.                         Attack(archerUnit, GameManager.Instance.GetUnit(
  365.                             enemyWorkers[FindClosestUnit(archerUnit.GridPosition, enemyWorkers)]));
  366.                     }
  367.                     // If there are enemy bases, randomly select one and attack it
  368.                     else if (enemyBases.Count > 0)
  369.                     {
  370.                         Attack(archerUnit, GameManager.Instance.GetUnit(
  371.                             enemyBases[FindClosestUnit(archerUnit.GridPosition, enemyBases)]));
  372.                     }
  373.                     // If there are enemy barracks, randomly select one and attack it
  374.                     else if (enemyBarracks.Count > 0)
  375.                     {
  376.                         Attack(archerUnit, GameManager.Instance.GetUnit(
  377.                             enemyBarracks[FindClosestUnit(archerUnit.GridPosition, enemyBarracks)]));
  378.                     }
  379.                     // If there are enemy refineries, randomly select one and attack it
  380.                     else if (enemyRefineries.Count > 0)
  381.                     {
  382.                         Attack(archerUnit, GameManager.Instance.GetUnit(
  383.                             enemyRefineries[FindClosestUnit(archerUnit.GridPosition, enemyRefineries)]));
  384.                     }
  385.                 }
  386.             }
  387.         }
  388.  
  389.         //same method as process soldiers, but they target the closest target instead of a random target
  390.         public void SoldiersAttack()
  391.         {
  392.             // For each soldier, determine what they should attack
  393.             foreach (int soldierNbr in mySoldiers)
  394.             {
  395.                 // Get this soldier
  396.                 Unit soldierUnit = GameManager.Instance.GetUnit(soldierNbr);
  397.  
  398.                 // If this soldier still exists and is idle
  399.                 if (soldierUnit != null && soldierUnit.CurrentAction == UnitAction.IDLE)
  400.                 {
  401.                     // If there are enemy soldiers, randomly select one and attack it
  402.                     if (enemySoldiers.Count > 0)
  403.                     {
  404.                         Attack(soldierUnit, GameManager.Instance.GetUnit(
  405.                             enemySoldiers[FindClosestUnit(soldierUnit.GridPosition, enemySoldiers)]));
  406.                     }
  407.                     // If there are enemy archers, randomly select one and attack it
  408.                     else if (enemyArchers.Count > 0)
  409.                     {
  410.                         Attack(soldierUnit, GameManager.Instance.GetUnit(
  411.                             enemyArchers[FindClosestUnit(soldierUnit.GridPosition, enemyArchers)]));
  412.                     }
  413.                     // If there are enemy workers, randomly select one and attack it
  414.                     else if (enemyWorkers.Count > 0)
  415.                     {
  416.                         Attack(soldierUnit, GameManager.Instance.GetUnit(
  417.                             enemyWorkers[FindClosestUnit(soldierUnit.GridPosition, enemyWorkers)]));
  418.                     }
  419.                     // If there are enemy bases, randomly select one and attack it
  420.                     else if (enemyBases.Count > 0)
  421.                     {
  422.                         Attack(soldierUnit, GameManager.Instance.GetUnit(
  423.                             enemyBases[FindClosestUnit(soldierUnit.GridPosition, enemyBases)]));
  424.                     }
  425.                     // If there are enemy barracks, randomly select one and attack it
  426.                     else if (enemyBarracks.Count > 0)
  427.                     {
  428.                         Attack(soldierUnit, GameManager.Instance.GetUnit(
  429.                             enemyBarracks[FindClosestUnit(soldierUnit.GridPosition, enemyBarracks)]));
  430.                     }
  431.                     // If there are enemy refineries, randomly select one and attack it
  432.                     else if (enemyRefineries.Count > 0)
  433.                     {
  434.                         Attack(soldierUnit, GameManager.Instance.GetUnit(
  435.                             enemyRefineries[FindClosestUnit(soldierUnit.GridPosition, enemyRefineries)]));
  436.                     }
  437.                 }
  438.             }
  439.         }
  440.  
  441.         public void MoveWorkers()
  442.         {
  443.             // For each worker
  444.             foreach (int worker in myWorkers)
  445.             {
  446.                 // Grab the unit we need for this function
  447.                 Unit unit = GameManager.Instance.GetUnit(worker);
  448.  
  449.                 // Make sure this unit actually exists and is idle
  450.                 if (unit != null && unit.CurrentAction == UnitAction.IDLE)
  451.                 {
  452.                     // Otherwise, just mine
  453.                     if (mainBaseNbr >= 0 && mainMineNbr >= 0)
  454.                     {
  455.                         // Grab the mine for this agent
  456.                         Unit mineUnit = GameManager.Instance.GetUnit(mainMineNbr);
  457.                         Unit baseUnit = GameManager.Instance.GetUnit(mainBaseNbr);
  458.                         if (mineUnit != null && baseUnit != null)
  459.                         { Gather(unit, mineUnit, baseUnit); }
  460.                     }
  461.                 }
  462.             }
  463.         }
  464.  
  465.         public void WorkersGather()
  466.         {
  467.             // For each worker
  468.             foreach (int worker in myWorkers)
  469.             {
  470.                 // Grab the unit we need for this function
  471.                 Unit unit = GameManager.Instance.GetUnit(worker);
  472.  
  473.                 // Make sure this unit actually exists and is idle
  474.                 if (unit != null && unit.CurrentAction == UnitAction.IDLE)
  475.                 {
  476.                     // Otherwise, just mine
  477.                     if (mainBaseNbr >= 0 && mainMineNbr >= 0)
  478.                     {
  479.                         // Grab the mine for this agent
  480.                         Unit mineUnit = GameManager.Instance.GetUnit(mainMineNbr);
  481.                         Unit baseUnit = GameManager.Instance.GetUnit(mainBaseNbr);
  482.                         if (mineUnit != null && baseUnit != null)
  483.                         { Gather(unit, mineUnit, baseUnit); }
  484.                     }
  485.                 }
  486.             }
  487.         }
  488.  
  489.         #endregion
  490.  
  491.         //returns the closest target from the chosen list
  492.         //Ignore
  493.         private Unit ClosestTarget(Unit closestTarget, List<int>targetList)
  494.         {
  495.             foreach (int target in targetList)
  496.             {
  497.                 closestTarget = GameManager.Instance.GetUnit(targetList[target]);
  498.  
  499.                 if (GameManager.Instance.GetUnit(targetList[target + 1]).GridPosition.magnitude < closestTarget.GridPosition.magnitude)
  500.                 {
  501.                     closestTarget = GameManager.Instance.GetUnit(targetList[target + 1]);
  502.                 }
  503.             }
  504.  
  505.             return closestTarget;
  506.         }
  507.  
  508.         private void RunMethods(int heurVal)
  509.         {
  510.             switch (heurVal)
  511.             {
  512.                 //build barracks
  513.                 case 1:
  514.                     BuildBarrack();
  515.                     break;
  516.                 //build refinery
  517.                 case 2:
  518.                     BuildRefinery();
  519.                     break;
  520.                 //train workers
  521.                 case 3:
  522.                     TrainWorkers();
  523.                     break;
  524.                 //train soldiers
  525.                 case 4:
  526.                     TrainSoldiers();
  527.                     break;
  528.                 //train archers
  529.                 case 5:
  530.                     TrainArchers();
  531.                     break;
  532.                 //attack
  533.                 case 6:
  534.                     ArchersAttack();
  535.                     SoldiersAttack();
  536.                     break;
  537.                 //move (for workers)
  538.                 case 7:
  539.                     MoveWorkers();
  540.                     break;
  541.                 //gather (for workers)
  542.                 case 8:
  543.                     WorkersGather();
  544.                     break;
  545.                 default:
  546.                     //i = 0 case
  547.                     BuildBase();
  548.                     break;
  549.             }
  550.         }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement