#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 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); } }