kora-bot/Source/CheckItem.cpp

565 lines
19 KiB
C++

#include "CheckItem.h"
void CheckItem::checkBases()
{
for (size_t i = 0; i < Macro::players.at(Macro::selfID).bases.size(); i++)
{
int freed = 0;
Macro::players.at(Macro::selfID).bases.at(i).getResources();
if (Macro::players.at(Macro::selfID).bases.at(i).mineralPatches * 2
< Macro::players.at(Macro::selfID).bases.at(i).mineralWorkers)
{
for (size_t j = 0; j < Macro::players.at(Macro::selfID).units.size(); j++)
{
if (Macro::players.at(Macro::selfID).units.at(j).unit->getType() == UnitTypes::Zerg_Drone && freed < 2)
{
if (Macro::players.at(Macro::selfID).units.at(j).miningBase == i)
{
Macro::freeUnit(j);
freed++;
}
}
}
}
}
}
void CheckItem::checkEvoChamber()
{
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Evolution_Chamber) == 0
&& Broodwar->self()->supplyUsed() >= 60 && !Macro::queueHas(UnitTypes::Zerg_Evolution_Chamber))
{
QueueEntry qe = QueueEntry(UnitTypes::Zerg_Evolution_Chamber, false, 0.0);
Macro::queue.push_back(qe);
}
}
void CheckItem::checkGas()
{
if (Broodwar->self()->supplyUsed() >= 30)
{
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Extractor) < 1
&& !Macro::queueHas(UnitTypes::Zerg_Extractor))
{
Macro::queue.push_back(QueueEntry(UnitTypes::Zerg_Extractor, false, 0.0));
}
}
if (Broodwar->self()->supplyUsed() >= 80)
{
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Extractor) < 2
&& !Macro::queueHas(UnitTypes::Zerg_Extractor))
{
Macro::queue.push_back(QueueEntry(UnitTypes::Zerg_Extractor, false, 0.0));
}
}
if (Broodwar->self()->supplyUsed() >= 120)
{
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Extractor) < Macro::players.at(Macro::selfID).bases.size()
&& !Macro::queueHas(UnitTypes::Zerg_Extractor))
{
Macro::queue.push_back(QueueEntry(UnitTypes::Zerg_Extractor, false, 0.0));
}
}
}
void CheckItem::checkGroundArmor()
{
bool chk = false;
if (Broodwar->self()->getUpgradeLevel(UpgradeTypes::Zerg_Carapace) == 0)
{
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Evolution_Chamber) > 0
&& !Macro::queueHas(UpgradeTypes::Zerg_Carapace)
&& Broodwar->getFrameCount() > 480 * 24)
chk = true;
}
else if (Broodwar->self()->getUpgradeLevel(UpgradeTypes::Zerg_Carapace) == 1)
{
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Evolution_Chamber) > 0
&& Util::countUnits(Macro::selfID, UnitTypes::Zerg_Lair) > 0
&& !Macro::queueHas(UpgradeTypes::Zerg_Carapace))
chk = true;
}
else if (Broodwar->self()->getUpgradeLevel(UpgradeTypes::Zerg_Carapace) == 2)
{
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Evolution_Chamber) > 0
&& Util::countUnits(Macro::selfID, UnitTypes::Zerg_Hive) > 0
&& !Macro::queueHas(UpgradeTypes::Zerg_Carapace))
chk = true;
}
if (chk)
{
QueueEntry qe = QueueEntry(UpgradeTypes::Zerg_Carapace, false, 0.0);
Macro::queue.push_back(qe);
}
}
void CheckItem::checkHive()
{
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Hive) == 0
&& Util::completedBuilding(UnitTypes::Zerg_Queens_Nest)
&& !Macro::queueHas(UnitTypes::Zerg_Hive))
{
QueueEntry qe = QueueEntry(UnitTypes::Zerg_Hive, false, 0.0);
Macro::queue.push_back(qe);
}
}
void CheckItem::checkHydraDen()
{
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Hydralisk_Den) == 0
&& Broodwar->self()->supplyUsed() >= 40 && !Macro::queueHas(UnitTypes::Zerg_Hydralisk_Den))
{
QueueEntry qe = QueueEntry(UnitTypes::Zerg_Hydralisk_Den, false, 0.0);
Macro::queue.push_back(qe);
}
}
void CheckItem::checkHydralisk()
{
if (Util::completedBuilding(UnitTypes::Zerg_Hydralisk_Den)
&& !Macro::queueHas(UnitTypes::Zerg_Hydralisk))
{
QueueEntry qe = QueueEntry(UnitTypes::Zerg_Hydralisk, false, 0.0);
Macro::queue.push_back(qe);
}
}
void CheckItem::checkHydraRange()
{
if (Broodwar->self()->getUpgradeLevel(UpgradeTypes::Grooved_Spines) == 0
&& !Macro::queueHas(UpgradeTypes::Grooved_Spines)
&& Util::countUnits(Macro::selfID, UnitTypes::Zerg_Hydralisk_Den) >= 1
&& Broodwar->self()->supplyUsed() >= 80)
{
Macro::queue.push_back(QueueEntry(UpgradeTypes::Grooved_Spines, false, 0.0));
}
}
void CheckItem::checkHydraSpeed()
{
if (Broodwar->self()->getUpgradeLevel(UpgradeTypes::Muscular_Augments) == 0
&& !Macro::queueHas(UpgradeTypes::Muscular_Augments)
&& Util::countUnits(Macro::selfID, UnitTypes::Zerg_Hydralisk_Den) >= 1
&& Broodwar->self()->supplyUsed() >= 80)
{
Macro::queue.push_back(QueueEntry(UpgradeTypes::Muscular_Augments, false, 0.0));
}
}
void CheckItem::checkLair()
{
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Lair) == 0
&& Util::countUnits(Macro::selfID, UnitTypes::Zerg_Hive) == 0
&& Util::completedBuilding(UnitTypes::Zerg_Spawning_Pool)
&& Broodwar->self()->supplyUsed() >= 80
&& !Macro::queueHas(UnitTypes::Zerg_Lair))
{
QueueEntry qe = QueueEntry(UnitTypes::Zerg_Lair, false, 0.0);
Macro::queue.push_back(qe);
}
}
void CheckItem::checkLingSpeed()
{
if (Broodwar->self()->getUpgradeLevel(UpgradeTypes::Metabolic_Boost) == 0
&& !Macro::queueHas(UpgradeTypes::Metabolic_Boost)
&& Util::countUnits(Macro::selfID, UnitTypes::Zerg_Spawning_Pool) >= 1
&& Broodwar->self()->supplyUsed() >= 80)
{
Macro::queue.push_back(QueueEntry(UpgradeTypes::Metabolic_Boost, false, 0.0));
}
}
// things to consider:
// - how many hatcheries there currently are
// - how many resources are currently being brought in
void CheckItem::checkMacroHatch()
{
if (!Macro::macroHatch)
{
/*if (Broodwar->elapsedTime() >= 300)
{
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Hatchery) <= 2)
{
Macro::queue.push_back(QueueEntry(UnitTypes::Zerg_Hatchery, false, 0.0));
Macro::setMacroHatch(true);
}
}*/
int minWorkers = 0;
for (auto b : Macro::players.at(Macro::selfID).bases)
{
minWorkers += b.mineralWorkers;
}
int minIncome = minWorkers * 55;
int larvaPerMin = Util::countUnits(Macro::selfID, UnitTypes::Zerg_Hatchery) * 4;
int minSpent = larvaPerMin * 100;
if (Broodwar->elapsedTime() >= 300
&& minIncome > minSpent
&& !Macro::queueHas(UnitTypes::Zerg_Hatchery))
{
Macro::queue.push_back(QueueEntry(UnitTypes::Zerg_Hatchery, false, 0.0));
Macro::setMacroHatch(true);
}
}
}
void CheckItem::checkMissile()
{
bool chk = false;
if (Broodwar->self()->getUpgradeLevel(UpgradeTypes::Zerg_Missile_Attacks) == 0)
{
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Evolution_Chamber) > 0
&& !Macro::queueHas(UpgradeTypes::Zerg_Missile_Attacks)
&& Broodwar->getFrameCount() > 480 * 24)
chk = true;
}
else if (Broodwar->self()->getUpgradeLevel(UpgradeTypes::Zerg_Missile_Attacks) == 1)
{
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Evolution_Chamber) > 0
&& Util::countUnits(Macro::selfID, UnitTypes::Zerg_Lair) > 0
&& !Macro::queueHas(UpgradeTypes::Zerg_Missile_Attacks))
chk = true;
}
else if (Broodwar->self()->getUpgradeLevel(UpgradeTypes::Zerg_Missile_Attacks) == 2)
{
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Evolution_Chamber) > 0
&& Util::countUnits(Macro::selfID, UnitTypes::Zerg_Hive) > 0
&& !Macro::queueHas(UpgradeTypes::Zerg_Missile_Attacks))
chk = true;
}
if(chk)
{
QueueEntry qe = QueueEntry(UpgradeTypes::Zerg_Missile_Attacks, false, 0.0);
Macro::queue.push_back(qe);
}
}
void CheckItem::checkMutalisk()
{
if (Util::completedBuilding(UnitTypes::Zerg_Spire)
&& !Macro::queueHas(UnitTypes::Zerg_Mutalisk)
&& Broodwar->elapsedTime() >= 300)
{
QueueEntry qe = QueueEntry(UnitTypes::Zerg_Mutalisk, false, 0.0);
Macro::queue.push_back(qe);
}
}
// determine if a new base is needed
// things to consider:
// - how many resources are currently being brought in
void CheckItem::checkNewBase()
{
if (!Macro::newBase)
{
if (Broodwar->elapsedTime() >= 180)
{
if (Macro::players.at(Macro::selfID).bases.size() == 1
&& Util::countUnits(Macro::selfID, UnitTypes::Zerg_Hatchery) < 2)
{
Macro::queue.push_back(QueueEntry(UnitTypes::Zerg_Hatchery, false, 0.0));
Macro::setNewBase(true);
}
}
if (Broodwar->elapsedTime() >= 600)
{
if (Macro::players.at(Macro::selfID).bases.size() == 2
&& !Macro::newBase)
{
Macro::queue.push_back(QueueEntry(UnitTypes::Zerg_Hatchery, false, 0.0));
Macro::setNewBase(true);
}
}
int minPatches = 0;
for (size_t i = 0; i < Macro::players.at(Macro::selfID).bases.size(); i++)
{
minPatches += Macro::players.at(Macro::selfID).bases.at(i).mineralPatches;
}
if (Macro::players.at(Macro::selfID).bases.size() >= 3
&& !Macro::newBase
&& minPatches <= 22)
{
Macro::queue.push_back(QueueEntry(UnitTypes::Zerg_Hatchery, false, 0.0));
Macro::setNewBase(true);
}
}
}
void CheckItem::checkOverlordSpeed()
{
if (Broodwar->self()->getUpgradeLevel(UpgradeTypes::Pneumatized_Carapace) == 0
&& !Macro::queueHas(UpgradeTypes::Pneumatized_Carapace)
&& (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Lair) >= 1
|| Util::countUnits(Macro::selfID, UnitTypes::Zerg_Hive) >= 1))
{
Macro::queue.push_back(QueueEntry(UpgradeTypes::Pneumatized_Carapace, false, 0.0));
}
}
void CheckItem::checkQueensNest()
{
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Queens_Nest) == 0
&& Util::countUnits(Macro::selfID, UnitTypes::Zerg_Lair) + Util::countUnits(Macro::selfID, UnitTypes::Zerg_Hive) >= 1
&& Broodwar->self()->supplyUsed() >= 140
&& !Macro::queueHas(UnitTypes::Zerg_Queens_Nest))
{
QueueEntry qe = QueueEntry(UnitTypes::Zerg_Queens_Nest, false, 0.0);
Macro::queue.push_back(qe);
}
}
void CheckItem::checkSpawningPool()
{
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Spawning_Pool) == 0
&& Broodwar->self()->supplyUsed() >= 26
&& !Macro::queueHas(UnitTypes::Zerg_Spawning_Pool))
{
QueueEntry qe = QueueEntry(UnitTypes::Zerg_Spawning_Pool, false, 0.0);
Macro::queue.push_back(qe);
}
}
void CheckItem::checkSpire()
{
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Spire) == 0
&& Util::countUnits(Macro::selfID, UnitTypes::Zerg_Lair) + Util::countUnits(Macro::selfID, UnitTypes::Zerg_Hive) >= 1
&& Broodwar->self()->supplyUsed() >= 140
&& !Macro::queueHas(UnitTypes::Zerg_Spire))
{
QueueEntry qe = QueueEntry(UnitTypes::Zerg_Spire, false, 0.0);
Macro::queue.push_back(qe);
}
}
void CheckItem::checkSpore()
{
int sporesNeeded = 0;
for (size_t i = 0; i < Macro::players.at(Macro::selfID).bases.size(); i++)
{
if (Macro::players.at(Macro::selfID).bases.at(i).sporeCount
+ Macro::players.at(Macro::selfID).bases.at(i).creepColonyCount
< Macro::players.at(Macro::selfID).bases.at(i).desiredSporeCount())
{
sporesNeeded += (Macro::players.at(Macro::selfID).bases.at(i).desiredSporeCount() - Macro::players.at(Macro::selfID).bases.at(i).sporeCount);
}
}
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Evolution_Chamber) > 0
&& Macro::queueCount(UnitTypes::Zerg_Spore_Colony) < 2
&& Macro::queueCount(UnitTypes::Zerg_Spore_Colony) < sporesNeeded)
{
QueueEntry qe = QueueEntry(UnitTypes::Zerg_Spore_Colony, false, 0.0);
Macro::queue.push_back(qe);
}
}
// things to consider:
// how many sunkens are needed
// how many have been built
void CheckItem::checkSunken()
{
int sunkensNeeded = 0;
for (size_t i = 0; i < Macro::players.at(Macro::selfID).bases.size(); i++)
{
if (Macro::players.at(Macro::selfID).bases.at(i).sunkenCount
+ Macro::players.at(Macro::selfID).bases.at(i).creepColonyCount
< Macro::players.at(Macro::selfID).bases.at(i).desiredSunkenCount())
{
sunkensNeeded += (Macro::players.at(Macro::selfID).bases.at(i).desiredSunkenCount()
- Macro::players.at(Macro::selfID).bases.at(i).sunkenCount
- Macro::players.at(Macro::selfID).bases.at(i).creepColonyCount);
}
}
sunkensNeeded -= Macro::queueCount(UnitTypes::Zerg_Sunken_Colony);
if (Broodwar->self()->supplyUsed() >= 36
&& Macro::queueCount(UnitTypes::Zerg_Sunken_Colony) < 3
&& Macro::queueCount(UnitTypes::Zerg_Sunken_Colony) < sunkensNeeded)
{
QueueEntry qe = QueueEntry(UnitTypes::Zerg_Sunken_Colony, false, 0.0);
Macro::queue.push_back(qe);
}
}
void CheckItem::checkSupply()
{
int currentSupply = Broodwar->self()->supplyUsed();
int totalSupply = Broodwar->self()->supplyTotal() + (Util::eggCount(UnitTypes::Zerg_Overlord) * 16);
int availableSupply = totalSupply - currentSupply;
int hatchCount = Util::countUnits(Macro::selfID, UnitTypes::Zerg_Hatchery);
if (availableSupply <= (hatchCount * 4)
&& !Macro::queueHas(UnitTypes::Zerg_Overlord)
&& totalSupply < 400)
{
QueueEntry qe = QueueEntry(UnitTypes::Zerg_Overlord, false, 0.0);
Macro::queue.push_back(qe);
}
}
//@TODO clean this up
void CheckItem::checkWorkers()
{
// check if any bases are oversaturated, unassign extra workers
// check unassigned workers
// if a base doesn't have (mins*2) mineral miners, go there, same with gas
//@TODO use the built-in getUnits with a filter to reduce the size of this for loop
for (size_t i = 0; i < Macro::players.at(Macro::selfID).units.size(); i++)
{
//auto start = std::chrono::high_resolution_clock::now();
if (Macro::players.at(Macro::selfID).units.at(i).unit->getType() == UnitTypes::Zerg_Drone)
{
if (Macro::players.at(Macro::selfID).units.at(i).isIdle()
&& Macro::players.at(Macro::selfID).units.at(i).action != "scout")
{
// if(resourceToMine()) == "minerals"
int base = Macro::findMiningBase(Macro::players.at(Macro::selfID).units.at(i).unit, "gas");
if (base > -1)
{
if (Macro::players.at(Macro::selfID).units.at(i).unit->gather(Macro::players.at(Macro::selfID).bases.at(base).base->getClosestUnit(IsRefinery)))
{
Macro::players.at(Macro::selfID).units.at(i).mine("gas", base);
Macro::players.at(Macro::selfID).bases.at(base).gasWorkers++;
break;
}
}
base = Macro::findMiningBase(Macro::players.at(Macro::selfID).units.at(i).unit, "minerals");
if (base > -1 && Macro::players.at(Macro::selfID).bases.at(base).mineralPatches > 0)
{
if (Macro::players.at(Macro::selfID).units.at(i).unit->gather(Macro::players.at(Macro::selfID).bases.at(base).base->getClosestUnit(IsMineralField)))
{
Macro::players.at(Macro::selfID).units.at(i).mine("minerals", base);
Macro::players.at(Macro::selfID).bases.at(base).mineralWorkers++;
}
}
}
else if (Macro::players.at(Macro::selfID).units.at(i).action == "expand")
{
CBase target = CBase(Macro::players.at(Macro::selfID).units.at(i).target);
if (target.isOwned())
{
CBase base = Util::getNextExpand(Macro::selfID);
Macro::players.at(Macro::selfID).units.at(i).target = base.tilePosition;
}
//@TODO make this more flexible in case something is blocking the build location
Macro::players.at(Macro::selfID).units.at(i).unit->build(UnitTypes::Zerg_Hatchery, Macro::players.at(Macro::selfID).units.at(i).target);
}
else if (Macro::players.at(Macro::selfID).units.at(i).action == "build")
{
//if (Military::likelihoodToAttack() < 1)
//if (Macro::players.at(Macro::selfID).units.at(i).targetUnit == UnitTypes::Zerg_Creep_Colony)
{
BuildingPlacement::build(Macro::players.at(Macro::selfID).units.at(i));
}
/*else if (!Macro::players.at(Macro::selfID).units.at(i).unit->build(Macro::players.at(Macro::selfID).units.at(i).targetUnit, Macro::players.at(Macro::selfID).units.at(i).target))
{
TilePosition target = Broodwar->getBuildLocation(Macro::players.at(Macro::selfID).units.at(i).targetUnit, Macro::players.at(Macro::selfID).bases.front().tilePosition, 20, true);
Macro::players.at(Macro::selfID).units.at(i).target = target;
if (Broodwar->self()->minerals() > Macro::players.at(Macro::selfID).units.at(i).targetUnit.mineralPrice() - 10
&& Macro::players.at(Macro::selfID).units.at(i).unit->getOrder() != Orders::PlaceBuilding)
Macro::players.at(Macro::selfID).units.at(i).unit->move(Position(Macro::players.at(Macro::selfID).units.at(i).target));
}*/
}
else if(Macro::players.at(Macro::selfID).units.at(i).action == "scout")
{
if (Macro::players.at(Macro::selfID).units.at(i).unit->isIdle() && Macro::workerScout)
{
Macro::workerScout = false;
Macro::players.at(Macro::selfID).units.at(i).action = "";
}
if (Macro::players.at(Macro::enemyIDs.front()).bases.size() > 0)
{
for (auto b : Macro::players.at(Macro::enemyIDs.front()).bases)
{
if(b.startLocation) Macro::players.at(Macro::selfID).units.at(i).unit->move(Macro::players.at(Macro::selfID).bases.front().position);
}
}
}
else if (Macro::players.at(Macro::selfID).units.at(i).action == "minerals")
{
int miningBase = Macro::players.at(Macro::selfID).units.at(i).miningBase;
if (miningBase > -1)
{
if (Macro::players.at(Macro::selfID).bases.at(miningBase).mineralWorkers > Macro::players.at(Macro::selfID).bases.at(miningBase).mineralPatches * 2)
{
Broodwar << " freeing unit" << std::endl;
Macro::freeUnit(i);
}
}
}
else if (Macro::players.at(Macro::selfID).units.at(i).action == "gas")
{
/*(int miningBase = Macro::players.at(Macro::selfID).units.at(i).miningBase;
if (miningBase > -1)
if (Macro::players.at(Macro::selfID).bases.at(miningBase).gasWorkers > Macro::players.at(Macro::selfID).bases.at(miningBase).gasPatches * 3)
{
Macro::freeUnit(i);
}*/
}
else if (Macro::players.at(Macro::selfID).units.at(i).action == "defend")
{
//@TODO bot doesn't build stuff
int squadIndex = Macro::players.at(Macro::selfID).units.at(i).squadIndex;
if (Military::likelihoodToAttack() < 1 && squadIndex > -1)
{
Macro::squads.at(squadIndex).freeDrones();
}
}
}
//std::chrono::duration<double, std::milli> elapsed = std::chrono::high_resolution_clock::now() - start;
//if(elapsed.count() > 1)
//Broodwar << " time = " << elapsed.count() << " " << Macro::players.at(Macro::selfID).units.at(i).action << std::endl;
}
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Drone) < 60 && !Macro::queueHas(UnitTypes::Zerg_Drone))
{
QueueEntry qe = QueueEntry(UnitTypes::Zerg_Drone, false, 0.0);
Macro::queue.push_back(qe);
}
}
void CheckItem::checkUltraCavern()
{
if (Util::countUnits(Macro::selfID, UnitTypes::Zerg_Ultralisk_Cavern) == 0
&& Util::countUnits(Macro::selfID, UnitTypes::Zerg_Hive) == 1
&& !Macro::queueHas(UnitTypes::Zerg_Ultralisk_Cavern))
{
QueueEntry qe = QueueEntry(UnitTypes::Zerg_Ultralisk_Cavern, false, 0.0);
Macro::queue.push_back(qe);
}
}
void CheckItem::checkUltralisk()
{
if (Util::completedBuilding(UnitTypes::Zerg_Ultralisk_Cavern)
&& !Macro::queueHas(UnitTypes::Zerg_Ultralisk))
{
QueueEntry qe = QueueEntry(UnitTypes::Zerg_Ultralisk, false, 0.0);
Macro::queue.push_back(qe);
}
}
void CheckItem::checkZergling()
{
if (Util::completedBuilding(UnitTypes::Zerg_Spawning_Pool)
&& !Macro::queueHas(UnitTypes::Zerg_Zergling)
&& Broodwar->elapsedTime() >= 180)
{
QueueEntry qe = QueueEntry(UnitTypes::Zerg_Zergling, false, 0.0);
Macro::queue.push_back(qe);
}
}