void ProbeUnit::check() { if (backUpMineral == NULL || !backUpMineral->exists()) { if (Broodwar->getFrameCount() < 10*24*60) { BWTA::BaseLocation* b = BWTA::getStartLocation(Broodwar->self()); if (b != NULL && !b->getMinerals().empty()) backUpMineral = *(b->getMinerals().begin()); if (backUpMineral == NULL || !backUpMineral->exists()) backUpMineral = NULL; } } }
// Get a sunken position depending on whether or not we have an expansion. BWAPI::TilePosition BuildingManager::getSunkenPosition() { BWAPI::UnitType sunk = BWAPI::UnitTypes::Zerg_Creep_Colony; // Always make sunkens at natural expansion if you can. if (createdHatcheriesSet.size() >= 1) { BWAPI::TilePosition hatchPosition = createdHatcheriesVector[0]; BWAPI::Unit pExpansion = BWAPI::Broodwar->getClosestUnit(BWAPI::Position(hatchPosition), BWAPI::Filter::IsResourceDepot); BWAPI::Unitset myUnits = pExpansion->getUnitsInRadius(200); BWAPI::UnitType larva = BWAPI::UnitTypes::Zerg_Larva; BWAPI::UnitType egg = BWAPI::UnitTypes::Zerg_Egg; std::set<BWAPI::TilePosition> stuffBlocking; for (BWAPI::Unit p : myUnits) { if (p->getType() == larva || p->getType() == egg) { stuffBlocking.insert(p->getTilePosition()); } } while (buildableSunkenTilePositions.size() >= 1) { std::set<BWAPI::TilePosition>::iterator it = buildableSunkenTilePositions.begin(); BWAPI::TilePosition mySunkPosition = *it; Building z(sunk, mySunkPosition); if (!isCreepStarted()) { if (BWAPI::Broodwar->hasCreep(mySunkPosition) && createdBuilding.find(mySunkPosition) == createdBuilding.end() && stuffBlocking.find(mySunkPosition) == stuffBlocking.end()) { return *it; } else { buildableSunkenTilePositions.erase(*it); } } else { if (BWAPI::Broodwar->hasCreep(mySunkPosition) && BuildingPlacer::Instance().canBuildHere(mySunkPosition, z) && createdBuilding.find(mySunkPosition) == createdBuilding.end() && stuffBlocking.find(mySunkPosition) == stuffBlocking.end()) { return *it; } else { buildableSunkenTilePositions.erase(*it); } } } //BWAPI::Position hatchPositionBWP = BWAPI::Position(hatchPosition); BWAPI::TilePosition sunkPosition; const std::set<BWTA::BaseLocation*, std::less<BWTA::BaseLocation*>> locations = BWTA::getBaseLocations(); BWTA::BaseLocation *myLocation; for (BWTA::BaseLocation *p : locations) { BWAPI::TilePosition z = p->getTilePosition(); if (z == hatchPosition){ // This is the BWTA::Location of the first hatchery. myLocation = p; } } // Get the set of mineral patches closest to BWTA::Location of the hatchery(it will return like 8 mineral patches usually in the set) const BWAPI::Unitset mineralSet = myLocation->getMinerals(); //const std::set<BWAPI::Unit*> mineralSet = myLocation->getMinerals(); int counter3 = 0; int theX = 0; int theY = 0; for (BWAPI::Unit p : mineralSet) { // Calculate the difference between LeftMostMineralPatch.x - ExpansionHatchery.x and store it in theX theX = p->getTilePosition().x - hatchPosition.x; // Calculate the difference between LeftMostMineralPatch.y - ExpansionHatchery.y and store it in theY theY = p->getTilePosition().y - hatchPosition.y; break; } int gasX = 0; int gasY = 0; int counter4 = 0; //Get all geysers near the expansion -- it should only return 1 for every map we play.. const BWAPI::Unitset gasSet = myLocation->getGeysers(); for (BWAPI::Unit p : gasSet) { // Calculate the difference between Geyser.x- ExpansionHatchery.x and store it in gasX gasX = p->getTilePosition().x - hatchPosition.x; // Calculate the difference between Geyser.y- ExpansionHatchery.y and store it in gasY gasY = p->getTilePosition().y - hatchPosition.y; break; } int newx, newy; int outercounter = 0; int counter = 0; newx = hatchPosition.x; newy = hatchPosition.y; int beginX = hatchPosition.x; int beginY = hatchPosition.y; //sunkPosition = BWAPI::TilePosition(newx, newy); //test4 = BuildingPlacer::Instance().canBuildHere(sunkPosition, b); // Form a new sunken position that starts at the hatchery positive. std::vector<bool> incrementDecrement(8); bool useGasX = false; bool useGasY = false; bool useMinX = false; bool useMinY = false; if (abs(gasX) > abs(gasY)) { useGasX = true; } else { useGasY = true; } if (abs(theX) > abs(theY)) { useMinX = true; } else { useMinY = true; } // Gas differences is probably more reliable than mineral differences. if (useGasX && useMinX) { useMinX = false; useMinY = true; } // Gas differences is probably more reliable than mineral differences. if (useGasY && useMinY) { useMinY = false; useMinX = true; } // This is where we decide which directions we can make sunkens in // It is based on X and Y differences in LeftMostMineral - Hatchery and Geyser - Hatchery // It is not very good right now because we only use two variables. We should use four variables for better dection : theX, theY, gasX, gasY // If the difference between LeftMostMineral.y - Hatchery.y is negative : It means the mierals are North of the hatchery // If the difference between Geyser.X - Hatchery.X is negative : It means that the geyser is Left of the Hatchery if (useMinY && useGasX) { if (theY < 0 && gasX < 0) { /* Allow the following directions for sunken to be built : Increase X & Keep Y the same (East) Increase X & Increase Y (Go South East) Decrease X & Increase Y (Go South West) Keep X Same, Increase Y (Go South) Go NORTHEAST **Test** */ incrementDecrement = { true, false, true, true, false, false, true, false }; } // If the difference between LeftMostMineral.y - Hatchery.y is positive : It means the mierals are South of the hatchery // If the difference between Geyser.X - Hatchery.X is negative : It means that the geyser is Left of the Hatchery else if (gasX < 0 && theY > 0) { /* Allow the following directions for sunken to be built : Increase X & Keep Y the same (East) Increase X & Decrease Y (Go North East) Decrease X & Decrease Y (Go North West) Keep X Same, Decrease Y (Go North) GO SOUTHEAST --> Test */ incrementDecrement = { false, true, true, false, true, false, false, true }; } // If the difference between LeftMostMineral.y - Hatchery.y is negative : It means the mierals are North of the hatchery // If the difference between Geyser.X - Hatchery.X is positive : It means that the geyser is Right or East of the Hatchery else if (gasX > 0 && theY < 0) { /* Allow the following directions for sunken to be built : Decrease X & Keep Y the same (West) Decrease X & Increase Y (Go South West) Increase X & Increase Y (Go South East) Keep X Same, Increase Y (Go South) Go Northwest */ incrementDecrement = { true, false, false, true, false, true, true, false }; } // If the difference between LeftMostMineral.y - Hatchery.y is positive : It means the mierals are South of the hatchery // If the difference between Geyser.X - Hatchery.X is positive : It means that the geyser is Right or East of the Hatchery else if (theY > 0 && gasX > 0) { /* Decrease X & Keep Y the same (West) Decrease X & Decrease Y (Go North West) Increase X & Decrease Y (Go North East) Don't change X Decrease y (Go North) Go Southwest */ incrementDecrement = { false, true, false, false, true, true, false, true }; } } else if (useMinX && useGasY) { // If the difference between LeftMostMineral.x - Hatchery.x is positive : It means the mierals are East of the hatchery // If the difference between Geyser.Y - Hatchery.Y is negative : It means that the geyser is North of the Hatchery if (gasY < 0 && theX > 0) { /* Decrease X(Go West) Increase Y(Go South) Decrease X, Increase Y(Go South West) Decrease X, Decrease Y(Go North West) I think can try SouthEast ? */ incrementDecrement = { false, false, false, true, true, true, true, false }; } // If the difference between LeftMostMineral.x - Hatchery.x is positive : It means the mierals are East of the hatchery // If the difference between Geyser.Y - Hatchery.Y is positive : It means that the geyser is South of the Hatchery else if (theX > 0 && gasY > 0) { /* Decrease X(Go West) Decrease Y(Go North) Decrease X, INcrease Y(Go SOuth West) Decrease X, Decrease Y(Go North West) I think can try NOrthEast? */ incrementDecrement = { false, false, false, true, true, true, false, true }; } // If the difference between LeftMostMineral.x - Hatchery.x is negative : It means the minerals are West of the hatchery // If the difference between Geyser.Y - Hatchery.Y is negative : It means that the geyser is North of the Hatchery else if (gasY < 0 && theX < 0) { /* Increase X(Go East) Increase Y(Go South) Increase X, Increase Y(Go South East) Increase X, Decrease Y(Go North East) I think maybe Southwest is okay?.. Even NW might be okay */ incrementDecrement = { true, true, true, false, false, false, true, false }; } // If the difference between LeftMostMineral.x - Hatchery.x is negative : It means the minerals are West of the hatchery // If the difference between Geyser.Y - Hatchery.Y is positive : It means that the geyser is South of the Hatchery else if (gasY > 0 && theX < 0) { incrementDecrement = { true, true, true, false, false, false, false, true }; /* Increase X(Go East) Decrease Y(Go North) Increase X, Increase Y(Go South East) Increase X, Decrease Y(Go North East) I think maybe Northwest is okay? */ } } beginX = hatchPosition.x; beginY = hatchPosition.y; std::vector<std::pair<int, int> > myVec; std::pair<int, int> p1; for (int i = 0; i < 8; i++) { if (incrementDecrement[i]) { if (i == 0) { p1.first = 1; p1.second = 1; } else if (i == 1) { p1.first = 1; p1.second = -1; } else if (i == 2) { p1.first = 1; p1.second = 0; } else if (i == 3) { p1.first = -1; p1.second = 1; } else if (i == 4) { p1.first = -1; p1.second = -1; } else if (i == 5) { p1.first = -1; p1.second = 0; } else if (i == 6) { p1.first = 0; p1.second = 1; } else if (i == 7) { p1.first = 0; p1.second = -1; } myVec.push_back(p1); } } for (int i = 0; i < 30; i++) for (int j = 0; j < 30; j++) for (int k = 0; k < 30; k++) for (int l = 0; l < 30; l++) { int xChange = beginX; int yChange = beginY; xChange += i * myVec[0].first; yChange += i * myVec[0].second; xChange += j * myVec[1].first; yChange += j * myVec[1].second; xChange += k * myVec[2].first; yChange += k * myVec[2].second; xChange += l * myVec[3].first; yChange += l * myVec[3].second; /* if (beginX + 1 == xChange) { if (yChange == beginY) { BWAPI::Broodwar->printf("%d", xChange); } } */ sunkPosition = BWAPI::TilePosition(xChange, yChange); Building b(sunk, sunkPosition); if (!isCreepStarted()) { if (BWAPI::Broodwar->hasCreep(sunkPosition) && stuffBlocking.find(sunkPosition) == stuffBlocking.end() && createdBuilding.find(sunkPosition) == createdBuilding.end()) { buildableSunkenTilePositions.insert(sunkPosition); } } else { if (BWAPI::Broodwar->hasCreep(sunkPosition) && BuildingPlacer::Instance().canBuildHere(sunkPosition, b) && stuffBlocking.find(sunkPosition) == stuffBlocking.end() && createdBuilding.find(sunkPosition) == createdBuilding.end()) { buildableSunkenTilePositions.insert(sunkPosition); } } } if (buildableSunkenTilePositions.size() != 0) { std::set<BWAPI::TilePosition>::iterator it = buildableSunkenTilePositions.begin(); return *it; } else { return BWAPI::TilePositions::None; } } }
// STEP 6: CHECK FOR COMPLETED BUILDINGS void BuildingManager::checkForCompletedBuildings() { std::vector<Building> toRemove; // for each of our buildings under construction for (auto & b : _buildings) { if (b.status != BuildingStatus::UnderConstruction) { continue; } // if the unit has completed if (b.buildingUnit->isCompleted()) { if (BWAPI::Broodwar->self()->getRace() == BWAPI::Races::Zerg) { if (b.buildingUnit->getType() == BWAPI::UnitTypes::Zerg_Creep_Colony) { //b.buildingUnit->upgrade(b.buildingUnit->getUpgrade()); //b.buildingUnit->buildAddon(BWAPI::UnitTypes::Zerg_Sunken_Colony); // MAKE SUNKEN //b.buildingUnit->morph(BWAPI::UnitTypes::Zerg_Sunken_Colony); MetaType type(BWAPI::UnitTypes::Zerg_Sunken_Colony); //ProductionManager::Instance()._queue.queueAsHighestPriority(type, true); } if (b.buildingUnit->getType() == BWAPI::UnitTypes::Zerg_Hatchery) { createdHatchery = true; } /* if (b.buildingUnit->getType() == BWAPI::UnitTypes::Zerg_Hatchery) { for (BWAPI::Unit p : BWAPI::Broodwar->self()->getUnits()) { if (!madeFirstSunken && p->getType().isWorker() && p->getPosition() == firstHatcheryPosition) { //BWAPI::Position tempPosition; //tempPosition.x = b.finalPosition.x + 3; //tempPosition.y = b.finalPosition.y + 3; MetaType type(BWAPI::UnitTypes::Zerg_Creep_Colony); ProductionManager::Instance()._queue.queueAsHighestPriority(type, true); /* BWAPI::TilePosition sunkPos = getSunkenPosition(); createdSunkenSet.insert(sunkPos); createdSunkenVector.push_back(sunkPos); createdBuilding.insert(sunkPos); p->build(BWAPI::UnitTypes::Zerg_Hatchery, sunkPos); madeFirstSunken = true; BWAPI::TilePosition sunkPos2 = getSunkenPosition(); createdSunkenSet.insert(sunkPos2); createdSunkenVector.push_back(sunkPos2); createdBuilding.insert(sunkPos2); p->build(BWAPI::UnitTypes::Zerg_Hatchery, sunkPos2); //b.builderUnit->build(b.type, b.finalPosition); break; //candidateProducers.insert(p); } } } */ } // if we are terran, give the worker back to worker manager if (BWAPI::Broodwar->self()->getRace() == BWAPI::Races::Terran) { if (b.isGasSteal) { ScoutManager::Instance().setWorkerScout(b.builderUnit); } // otherwise tell the worker manager we're finished with this unit else { WorkerManager::Instance().finishedWithWorker(b.builderUnit); } } // remove this unit from the under construction vector toRemove.push_back(b); } else { if (b.type == 131 && b.buildingUnit->getHitPoints() >= 1050 && !transferredDrones) { //BWAPI::Broodwar->printf("Send Drone"); //BWAPI::Unitset candidateProducers; BWAPI::UnitType sunk = BWAPI::UnitTypes::Zerg_Creep_Colony; Building z(sunk, createdHatcheriesVector[0]); //BWAPI::Unit workerToAssign = WorkerManager::Instance().getMoveWorker(BWAPI::Position(createdHatcheriesVector[0])); //BWAPI::Unit workerToAssign2 = WorkerManager::Instance().getMoveWorker(BWAPI::Position(createdHatcheriesVector[0])); //WorkerManager::Instance().setMoveWorker(0, 0, BWAPI::Position(createdHatcheriesVector[0])); //WorkerManager::Instance().setMoveWorker(0, 0, BWAPI::Position(createdHatcheriesVector[0])); //_reservedMinerals += 75; BWAPI::Unit workerToAssign = WorkerManager::Instance().getBuilder(z); BWAPI::Unit workerToAssign2 = WorkerManager::Instance().getBuilder(z); //WorkerData m; //m.setWorkerJob(workerToAssign, WorkerData::Minerals, b.type); /* for (BWAPI::Unit p : BWAPI::Broodwar->self()->getUnits()) { WorkerData k; WorkerData::WorkerJob j = k.getWorkerJob(p); if (p->getType().isWorker() && j != WorkerData::Scout) { */ const std::set<BWTA::BaseLocation*, std::less<BWTA::BaseLocation*>> locations = BWTA::getBaseLocations(); BWTA::BaseLocation *myLocation; for (BWTA::BaseLocation *p : locations) { BWAPI::TilePosition z = p->getTilePosition(); if (z == createdHatcheriesVector[0]){ // This is the BWTA::Location of the first hatchery. myLocation = p; } } // Get the set of mineral patches closest to BWTA::Location of the hatchery(it will return like 8 mineral patches usually in the set) const BWAPI::Unitset mineralSet = myLocation->getMinerals(); BWAPI::Unit myMineral; for (BWAPI::Unit p : mineralSet) { myMineral = p; // Calculate the difference between LeftMostMineralPatch.x - ExpansionHatchery.x and store it in theX //theX = p->getTilePosition().x - hatchPosition.x; // Calculate the difference between LeftMostMineralPatch.y - ExpansionHatchery.y and store it in theY //theY = p->getTilePosition().y - hatchPosition.y; break; } workerToAssign->gather(myMineral); workerToAssign2->gather(myMineral); sunkenUnit = workerToAssign; sunkenUnit2 = workerToAssign2; //sunkenID = workerToAssign->getID(); transferredDrones = true; } if (b.type == 131 && b.buildingUnit->getHitPoints() >= 1225 && !sentFirstDroneForSunken) { MetaType type(BWAPI::UnitTypes::Zerg_Creep_Colony); ProductionManager::Instance()._queue.queueAsHighestPriority(type, true); //sunkenID2 = workerToAssign2->getID(); //BWAPI::TilePosition tempPosition; //tempPosition.x = b.finalPosition.x+4; //tempPosition.y = b.finalPosition.y+4; //Micro::SmartMove(p, BWAPI::Position(tempPosition)); //Micro::SmartMove(p, BWAPI::Position(tempPosition)); //p->move(BWAPI::Position(tempPosition)); //p->move(BWAPI::Position(tempPosition)); //break; //candidateProducers.insert(p); //MetaType type(BWAPI::UnitTypes::Zerg_Creep_Colony); //ProductionManager::Instance()._queue.queueAsHighestPriority(type, true); sentFirstDroneForSunken = true; } } } removeBuildings(toRemove); }
// STEP 6: CHECK FOR COMPLETED BUILDINGS void BuildingManager::checkForCompletedBuildings() { std::vector<Building> toRemove; // for each of our buildings under construction for (auto & b : _buildings) { if (b.status != BuildingStatus::UnderConstruction) { continue; } // if the unit has completed if (b.buildingUnit->isCompleted()) { if (BWAPI::Broodwar->self()->getRace() == BWAPI::Races::Zerg) { if (b.buildingUnit->getType() == BWAPI::UnitTypes::Zerg_Creep_Colony) { //b.buildingUnit->upgrade(b.buildingUnit->getUpgrade()); //b.buildingUnit->buildAddon(BWAPI::UnitTypes::Zerg_Sunken_Colony); // MAKE SUNKEN //b.buildingUnit->morph(BWAPI::UnitTypes::Zerg_Sunken_Colony); //MetaType type(BWAPI::UnitTypes::Zerg_Sunken_Colony); //ProductionManager::Instance()._queue.queueAsHighestPriority(type, true); } if (b.buildingUnit->getType() == BWAPI::UnitTypes::Zerg_Hatchery) { MetaType type(BWAPI::UnitTypes::Zerg_Creep_Colony); ProductionManager::Instance()._queue.queueAsHighestPriority(type, true); createdHatchery = true; } /* for (BWAPI::Unit p : BWAPI::Broodwar->self()->getUnits()) { if (!madeFirstSunken && p->getType().isWorker() && p->getPosition() == firstHatcheryPosition) { //BWAPI::Position tempPosition; //tempPosition.x = b.finalPosition.x + 3; //tempPosition.y = b.finalPosition.y + 3; /* BWAPI::TilePosition sunkPos = getSunkenPosition(); createdSunkenSet.insert(sunkPos); createdSunkenVector.push_back(sunkPos); createdBuilding.insert(sunkPos); p->build(BWAPI::UnitTypes::Zerg_Hatchery, sunkPos); madeFirstSunken = true; BWAPI::TilePosition sunkPos2 = getSunkenPosition(); createdSunkenSet.insert(sunkPos2); createdSunkenVector.push_back(sunkPos2); createdBuilding.insert(sunkPos2); p->build(BWAPI::UnitTypes::Zerg_Hatchery, sunkPos2); //b.builderUnit->build(b.type, b.finalPosition); break; //candidateProducers.insert(p); } } } */ } // if we are terran, give the worker back to worker manager if (BWAPI::Broodwar->self()->getRace() == BWAPI::Races::Terran) { if (b.isGasSteal) { ScoutManager::Instance().setWorkerScout(b.builderUnit); } // otherwise tell the worker manager we're finished with this unit else { WorkerManager::Instance().finishedWithWorker(b.builderUnit); } } // remove this unit from the under construction vector toRemove.push_back(b); } else { if (b.type == 131 && b.buildingUnit->getHitPoints() >= 1050 && !sentFirstDroneForSunken) { BWAPI::UnitType sunk = BWAPI::UnitTypes::Zerg_Creep_Colony; Building z(sunk, createdHatcheriesVector[0]); BWAPI::Unit workerToAssign = WorkerManager::Instance().getBuilder(z); BWAPI::Unit workerToAssign2 = WorkerManager::Instance().getBuilder(z); const std::set<BWTA::BaseLocation*, std::less<BWTA::BaseLocation*>> locations = BWTA::getBaseLocations(); BWTA::BaseLocation *myLocation; for (BWTA::BaseLocation *p : locations) { BWAPI::TilePosition z = p->getTilePosition(); if (z == createdHatcheriesVector[0]){ // This is the BWTA::Location of the first hatchery. myLocation = p; } } // Get the set of mineral patches closest to BWTA::Location of the hatchery(it will return like 8 mineral patches usually in the set) const BWAPI::Unitset mineralSet = myLocation->getMinerals(); BWAPI::Unit myMineral; for (BWAPI::Unit p : mineralSet) { myMineral = p; break; } workerToAssign->gather(myMineral); workerToAssign2->gather(myMineral); sunkenUnit = workerToAssign; sunkenUnit2 = workerToAssign2; sentFirstDroneForSunken = true; } int x = 0; } } removeBuildings(toRemove); }