Package com.fray.evo

Source Code of com.fray.evo.EcBuildOrder

package com.fray.evo;

import static com.fray.evo.ui.swingx.EcSwingXMain.messages;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;

import com.fray.evo.action.EcAction;
import com.fray.evo.action.EcActionMakeBuildable;
import com.fray.evo.util.ActionList;
import com.fray.evo.util.Building;
import com.fray.evo.util.GameLog;
import com.fray.evo.util.RaceLibraries;
import com.fray.evo.util.RunnableAction;
import com.fray.evo.util.ZergBuildingLibrary;
import com.fray.evo.util.ZergLibrary;

public final class EcBuildOrder extends EcState implements Serializable
{
  static final long    serialVersionUID  = 1L;
  public int        dronesGoingOnMinerals  = 6
  public int        dronesGoingOnGas  = 0;
  public int        dronesOnMinerals  = 0;
  public int        dronesOnGas      = 0;
 
  public boolean       droneIsScouting    = false;
 
  public final HashMap<EcAction,Building> actionBusyIn = new HashMap<EcAction, Building>();
  public ArrayList<ArrayList<EcAction>>   madeBusyBy;
 
  private transient ActionList  futureAction;
  public ArrayList<EcAction>    actions         = new ArrayList<EcAction>();

 
  public EcBuildOrder()
  {
        super();
        futureAction = new ActionList();
       
        ArrayList<Building> buildingList = RaceLibraries.getBuildingLibrary(settings.race).getList();
        madeBusyBy = new ArrayList<ArrayList<EcAction>>(buildingList.size());
        for(int i = 0; i < buildingList.size(); ++i)
          madeBusyBy.add(new ArrayList<EcAction>());

        addFutureAction(5, new RunnableAction(){
            @Override
            public void run(GameLog e)
            {
              dronesOnMinerals +=6;
              dronesGoingOnMinerals -=6;
            }});
  }
 
  public EcBuildOrder(EcState importDestination)
  {
    futureAction = new ActionList();
   
    //Fixed: Need to assign this to the variable, not the other way around.
    //-Lomilar
    importDestination.assign(this);
  }

  public void tick(GameLog e)
  {
    //Larva Production
    for (int hatchIndex = 0; hatchIndex < larva.size(); hatchIndex++) {
      if (getLarva(hatchIndex) < 3)
      {
        if (larvaProduction.get(hatchIndex) == 15)
        {
          if (e.isEnabled())
            e.printMessage(this, GameLog.MessageType.Obtained,
                " @" + messages.getString(ZergLibrary.Hatchery.getName()) + " #" + (hatchIndex+1) + " " + messages.getString(ZergLibrary.Larva.getName()) + " +1" );
          incrementLarva(hatchIndex);
          larvaProduction.set(hatchIndex, 0);
        }
        larvaProduction.increment(hatchIndex);
      }
    }

    //Accumulate Materials
    double mins = mineMinerals();
    minerals += mins;
    totalMineralsMined += mins;
    gas += mineGas();

    //Check Scouting Drone
    if(!droneIsScouting && scoutDrone != 0 && seconds >= scoutDrone ) {
      if (dronesGoingOnMinerals > 0) {
        droneIsScouting = true;
        dronesGoingOnMinerals--;
        if (e.isEnabled())
          e.printMessage(this, GameLog.MessageType.Scout, " +1 Scouting Drone");
      } else if (dronesOnMinerals > 0) {
        droneIsScouting = true;
        dronesOnMinerals--;
        if (e.isEnabled())
          e.printMessage(this, GameLog.MessageType.Scout, " +1 Scouting Drone");
      }
    }
  }
 
  @Override
  public EcBuildOrder clone() throws CloneNotSupportedException
  {
    final EcBuildOrder s = new EcBuildOrder();
    assign(s);
    return s;
  }

  private void assign(final EcBuildOrder s)
  {
    s.dronesGoingOnMinerals = dronesGoingOnMinerals;
    s.dronesGoingOnGas = dronesGoingOnGas;
    s.dronesOnMinerals = dronesOnMinerals;
    s.dronesOnGas = dronesOnGas;
    super.assign(s);
  }

    @Override
  public String toString()
  {
    return toUnitsOnlyString().replaceAll("\n"," ");
  }
 
  public String toShortString()
  {
    return (messages.getString("short.time") + timestamp() + "\t"+messages.getString("short.minerals")+":" + (int) minerals + "\t"+messages.getString("short.gas")+":" + (int) gas + "\t"+messages.getString("short.larva")+":" + getLarva() + "\t"+messages.getString("short.supply")+":"
        + ((int) supplyUsed) + "/" + supply());
  }

  public ArrayList<EcAction> getActions()
  {
    return actions;
  }

  public void addAction(EcAction ecActionBuildDrone)
  {
    actions.add(ecActionBuildDrone);
  }

  public void addFutureAction(int time, RunnableAction runnable)
  {
    time = seconds + time;
    futureAction.put(time, runnable);
    actionLength++;
  }

  public RunnableAction getFutureAction(int time)
  {
    RunnableAction result = futureAction.get(time);
    return result;
  }

  public boolean nothingGoingToHappen()
  {
    return futureAction.hasFutureActions();
  }

  public void consumeLarva(final GameLog e)
  {
    int highestLarvaHatch = 0;
    int highestLarva = 0;
   
    for (int i = 0;i < larva.size();i++)
      if (larva.get(i) > highestLarva)
      {
        highestLarvaHatch = i;
        highestLarva = larva.get(i);
      }
    final int finalHighestLarvaHatch = highestLarvaHatch;
       
    decrementLarva(finalHighestLarvaHatch);
  }

  public boolean hasSupply(double i)
  {
    if (supplyUsed + i <= supply())
      return true;
    return false;
  }

  public int mineralPatches()
  {
    return bases() * 8;
  }

  int[]    patches        = new int[24];
  public int  extractorsBuilding  = 0;
  public int  hatcheriesBuilding  = 0;
  public int  spawningPoolsInUse  = 0;
  public int  roachWarrensInUse  = 0;
  public int  infestationPitInUse  = 0;
  public int  nydusNetworkInUse = 0;

    private static double[][] cachedMineralsMined = new double[200][200];

    public double mineMinerals() {
        int mineralPatches = mineralPatches();
        if(dronesOnMinerals <= 0 || mineralPatches <= 0)
            return 0;

        if(dronesOnMinerals >= 200 || mineralPatches >= 200)
            return mineMineralsImpl();

        if(cachedMineralsMined[mineralPatches][dronesOnMinerals] == 0)
            cachedMineralsMined[mineralPatches][dronesOnMinerals] = mineMineralsImpl();

        return cachedMineralsMined[mineralPatches][dronesOnMinerals];
    }


    /**
     * Mines minerals on all bases perfectly per one second.
     *
     * okay, we got x patches, and y drones. so the amount of drones per patch should be (y - (y%x))/x
   * the drones%patches represent the amount of patches that have one worker more than the average.
   * also account for the far and near patches here, assuming half of the workes go to far patches and other half onto the near ones.
     */
  private double mineMineralsImpl()
  {
    final int drones = dronesOnMinerals;
    final int mineralPatches = mineralPatches();
     
      if(drones == 0 || mineralPatches == 0){
        return 0;
      }
     
     
      // an amount of workers do not fill a complete collection of patches
      int droneOverflow = drones % mineralPatches ;
     
      int avgPatchLoad = (drones - droneOverflow) / mineralPatches;
     
      // above 3 per patch is overmining and does not provide any improvement
      if( avgPatchLoad >= 3 ){
        avgPatchLoad = 3;
        droneOverflow = 0;
      }
     
      // since the overflow is also mining, those patches have a higher worker load!
      int lowerMiningWorkload = (mineralPatches > drones) ? 0 : (mineralPatches-droneOverflow);
      int higherMiningWorload = droneOverflow;
     
      // those are the patches with average load. We assume the half is on far patches, if the amount is odd, one more is on near patches
      int farPatchesLowLoad = Math.round(lowerMiningWorkload / 2.0f);
      int nearPatchesLowLoad = lowerMiningWorkload - farPatchesLowLoad;
     
      // those patches have average+1 load
      int nearPatchesHighLoad =  Math.round(higherMiningWorload / 2.0f);
      int farPatchesHighLoad = higherMiningWorload - nearPatchesHighLoad;
     
     
     
      double mineralsMined = 0.0;
      switch(avgPatchLoad){
        case 0:
          // only the overflow is mining
          mineralsMined += nearPatchesHighLoad * 45.0 / 60.0;
          mineralsMined += farPatchesHighLoad * 35.0 / 60.0;
          break;
        case 1:
          // with one workers on it
          mineralsMined += nearPatchesLowLoad * 45.0 / 60.0;
          mineralsMined += farPatchesLowLoad * 35.0 / 60.0;
         
          // with two worker on it
          mineralsMined += nearPatchesHighLoad * 90.0 / 60.0;
          mineralsMined += farPatchesHighLoad * 75.0 / 60.0;
          break;
        case 2:
          // with two workers on it
          mineralsMined += nearPatchesLowLoad * 90.0 / 60.0;
          mineralsMined += farPatchesLowLoad * 75.0 / 60.0;
         
          // with three worker on it
          mineralsMined += nearPatchesHighLoad * 102.0 / 60.0;
          mineralsMined += farPatchesHighLoad * 100.0 / 60.0;
          break;
        case 3:
          // all patches have three workers on it
          mineralsMined += nearPatchesLowLoad * 102.0 / 60.0;
          mineralsMined += farPatchesLowLoad * 100.0 / 60.0;
      }
      return mineralsMined;
  }

    private static double[][] cachedGasMined = new double[200][200];

    public double mineGas()
    {
      int gasExtra = getGasExtractors();
        if (gasExtra == 0 || dronesOnGas == 0)
      return 0;

        if(gasExtra >= 200 || dronesOnGas >= 200)
            return mineGasImpl();

        if(cachedGasMined[gasExtra][dronesOnGas] == 0)
            cachedGasMined[gasExtra][dronesOnGas] = mineGasImpl();

        return cachedGasMined[gasExtra][dronesOnGas];
    }

  // Mines gas on all bases perfectly per one second.
  private double mineGasImpl()
  {
    int drones = dronesOnGas;
    int[] extractors = new int[Math.min(getGasExtractors(),bases()*2)]; // Assign drones/patch
    for (int i = 0; i < extractors.length; i++)
      extractors[i] = 0;
    for (int i = 0; i < extractors.length; i++)
      // Assign first drone
      if (drones > 0)
      {
        extractors[i]++;
        drones--;
      }
    for (int i = 0; i < extractors.length; i++)
      // Assign second drone
      if (drones > 0)
      {
        extractors[i]++;
        drones--;
      }
    for (int i = 0; i < extractors.length; i++)
      // Assign third drone
      if (drones > 0)
      {
        extractors[i]++;
        drones--;
      }
    double gasMined = 0.0;
    for (int i = 0; i < extractors.length; i++)
      if (extractors[i] == 0)
        ;
      else if (extractors[i] == 1)
        gasMined += 38.0 / 60.0; // Per TeamLiquid
      else if (extractors[i] == 2)
        gasMined += 82.0 / 60.0; // Per TeamLiquid
      else
        gasMined += 114.0 / 60.0; // Per TeamLiquid

    return gasMined;
  }

  public String timestampIncremented(int increment)
  {
    int incrementedSeconds = seconds + increment;
    return incrementedSeconds / 60 + ":" + (incrementedSeconds%60 < 10 ? "0" : "") + incrementedSeconds % 60;
  }

  public int extractors()
  {
    return (bases() + hatcheriesBuilding) * 2;
  }
 
  public int getMineableGasExtractors()
  {
    return Math.min(bases() * 2, getGasExtractors());
  }

  public void makeBuildingBusy(Building consumes,EcActionMakeBuildable action)
  {
        action.makeBusy(madeBusyBy, actionBusyIn, consumes, buildings);
  }

    public void makeBuildingNotBusy(EcActionMakeBuildable action) {
        action.makeNotBusy(madeBusyBy, actionBusyIn);
    }

    public boolean doesNonBusyExist(Building building){
        if(!doesNonBusyReallyExist(building)){
            if(building == ZergBuildingLibrary.Hatchery){
                return doesNonBusyExist(ZergBuildingLibrary.Lair);
            }else if(building == ZergBuildingLibrary.Lair){
                return doesNonBusyExist(ZergBuildingLibrary.Hive);
            }else if(building == ZergBuildingLibrary.Spire){
                return doesNonBusyExist(ZergBuildingLibrary.GreaterSpire);
            }
            return false;
        }else{
            return true;
        }
    }

    public boolean doesNonBusyReallyExist(Building building){
      return madeBusyBy.get(building.getId()).size() < buildings.get(building);
    }
}
TOP

Related Classes of com.fray.evo.EcBuildOrder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.