Skip to content

Commit

Permalink
Update to SteamHammer 2.4
Browse files Browse the repository at this point in the history
  • Loading branch information
kant2002 committed Sep 4, 2020
1 parent dc90e59 commit 97513d4
Show file tree
Hide file tree
Showing 57 changed files with 1,686 additions and 911 deletions.
7 changes: 5 additions & 2 deletions BOSS/source/BOSSAssert.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ namespace Assert
}
}

// BOSS debugging.
// Can be tured off (see the URL), but may then allow crashes to occur rather than hiding them.
// https://github.com/kant2002/ualbertabot/commit/228d20c6522b0d3f6d00107bc3d5fc871612accc
#define BOSS_ASSERT_ENABLE

#ifdef BOSS_ASSERT_ENABLE
Expand All @@ -40,6 +43,6 @@ namespace Assert
} while(0)

#else
#define SPARCRAFT_ASSERT(cond, msg, ...)
#define SPARCRAFT_ASSERT_STATE(cond, state, filename, msg, ...)
#define BOSS_ASSERT(cond, msg, ...)
#define BOSS_ASSERT_STATE(cond, state, filename, msg, ...)
#endif
131 changes: 68 additions & 63 deletions Steamhammer/Source/Base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,84 +5,89 @@

using namespace UAlbertaBot;

// For setting base.id on initialization.
// The first base gets base id 1.
static int BaseID = 1;

// Is the base one of the map's starting bases?
// The only purpose of this method is to initialize the startingBase flag.
// NOTE This depends on tilePosition, so the startingBase flag must be declared after tilePosition.
bool Base::isStartingBase() const
bool Base::findIsStartingBase() const
{
for (BWAPI::TilePosition tile : BWAPI::Broodwar->getStartLocations())
{
if (tile == tilePosition)
{
return true;
}
}
return false;
for (BWAPI::TilePosition tile : BWAPI::Broodwar->getStartLocations())
{
if (tile == tilePosition)
{
return true;
}
}
return false;
}

// For setting base.id on initialization.
// The first base gets base id 1.
static int BaseID = 1;
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

// Create a base given its position and a set of resources that may belong to it.
// The caller is responsible for eliminating resources which are too small to be worth it.
Base::Base(BWAPI::TilePosition pos, const BWAPI::Unitset availableResources)
: id(BaseID)
, tilePosition(pos)
, distances(pos)
, reserved(false)
, startingBase(isStartingBase())
, workerDanger(false)
, failedPlacements(0)
, resourceDepot(nullptr)
, owner(BWAPI::Broodwar->neutral())
: id(BaseID)
, tilePosition(pos)
, distances(pos)
, reserved(false)
, startingBase(findIsStartingBase())
, workerDanger(false)
, failedPlacements(0)
, resourceDepot(nullptr)
, owner(BWAPI::Broodwar->neutral())
{
++BaseID;
++BaseID;

GridDistances resourceDistances(pos, BaseResourceRange, false);
GridDistances resourceDistances(pos, BaseResourceRange, false);

for (BWAPI::Unit resource : availableResources)
{
if (resource->getInitialTilePosition().isValid() && resourceDistances.getStaticUnitDistance(resource) >= 0)
{
if (resource->getType().isMineralField())
{
minerals.insert(resource);
}
else if (resource->getType() == BWAPI::UnitTypes::Resource_Vespene_Geyser)
{
geysers.insert(resource);
}
}
}
for (BWAPI::Unit resource : availableResources)
{
if (resource->getInitialTilePosition().isValid() && resourceDistances.getStaticUnitDistance(resource) >= 0)
{
if (resource->getType().isMineralField())
{
minerals.insert(resource);
}
else if (resource->getType() == BWAPI::UnitTypes::Resource_Vespene_Geyser)
{
geysers.insert(resource);
}
}
}

// Fill in the set of blockers, destructible neutral units that are very close to the base
// and may interfere with its operation.
// This does not include the minerals to mine!
for (const auto unit : BWAPI::Broodwar->getStaticNeutralUnits())
{
// NOTE Khaydarin crystals are not destructible, and I don't know any way
// to find that out other than to check the name explicitly. Is there a way?
if (!unit->getType().canMove() &&
!unit->isInvincible() &&
unit->isTargetable() &&
!unit->isFlying() &&
unit->getType().getName().find("Khaydarin") == std::string::npos)
{
int dist = resourceDistances.getStaticUnitDistance(unit);
if (dist >= 0 && dist <= 9)
{
blockers.insert(unit);
}
}
}
// Fill in the set of blockers, destructible neutral units that are very close to the base
// and may interfere with its operation.
// This does not include the minerals to mine!
for (BWAPI::Unit unit : BWAPI::Broodwar->getStaticNeutralUnits())
{
// NOTE Khaydarin crystals are not destructible, and I don't know any way
// to find that out other than to check the name explicitly. Is there a way?
if (!unit->getType().canMove() &&
!unit->isInvincible() &&
unit->isTargetable() &&
!unit->isFlying() &&
unit->getType().getName().find("Khaydarin") == std::string::npos)
{
int dist = resourceDistances.getStaticUnitDistance(unit);
if (dist >= 0 && dist <= 9)
{
blockers.insert(unit);
}
}
}
}

// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

// Called from InformationManager to work around a bug related to BWAPI 4.1.2.
// TODO is this still needed and correct?
// Recalculate the base's set of geysers, including refineries (completed or not).
// This only works for visible geysers, so it should be called only for bases we own.
// Called to work around a bug related to BWAPI 4.1.2.
void Base::findGeysers()
{
for (auto unit : BWAPI::Broodwar->getNeutralUnits())
geysers.clear();

for (BWAPI::Unit unit : BWAPI::Broodwar->getAllUnits())
{
if ((unit->getType() == BWAPI::UnitTypes::Resource_Vespene_Geyser || unit->getType().isRefinery()) &&
unit->getPosition().isValid() &&
Expand All @@ -93,7 +98,7 @@ void Base::findGeysers()
}
}

// Return the center of the resource depot.
// Return the center of the resource depot location (whether one is there or not).
const BWAPI::Position Base::getCenter() const
{
return BWAPI::Position(tilePosition) + BWAPI::Position(64, 48);
Expand Down
20 changes: 10 additions & 10 deletions Steamhammer/Source/Base.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,23 @@ class Base
bool workerDanger; // for our own bases only; false for others
int failedPlacements; // count building placements that failed

bool isStartingBase() const; // to initialize the startingBase flag
bool findIsStartingBase() const; // to initialize the startingBase flag

public:

BWAPI::Unit resourceDepot; // hatchery, etc., or null if none
// The resourceDepot pointer is set for a base if the depot has been seen.
// It is possible to infer a base location without seeing the depot.
BWAPI::Unit resourceDepot; // hatchery, etc., or null if none
BWAPI::Player owner; // self, enemy, neutral

int getID() const { return id; };
BWAPI::Unit getDepot() const { return resourceDepot; };
BWAPI::Player getOwner() const { return owner; };
Base(BWAPI::TilePosition pos, const BWAPI::Unitset availableResources);

// The resourceDepot pointer is set for a base if the depot has been seen.
// It is possible to infer a base location without seeing the depot.
int getID() const { return id; };
BWAPI::Unit getDepot() const { return resourceDepot; };
BWAPI::Player getOwner() const { return owner; };
bool isAStartingBase() const { return startingBase; };

Base(BWAPI::TilePosition pos, const BWAPI::Unitset availableResources);

void findGeysers();
void findGeysers();

const BWAPI::TilePosition & getTilePosition() const { return tilePosition; };
const BWAPI::Position getPosition() const { return BWAPI::Position(tilePosition); };
Expand Down
24 changes: 12 additions & 12 deletions Steamhammer/Source/Bases.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,17 @@ void Bases::rememberBaseBlockers()

// During initialization, look for a base to be our natural and remember it.
// startingBase has already been set (of course we need to know that first).
// Make sure it's null if we don't find one.
// Make sure it's null if we don't find a natural.
void Bases::setNaturalBase()
{
Base * bestBase = nullptr;
double bestScore = 0.0;

for (Base * base : bases)
{
if (base == startingBase)
if (base->isAStartingBase())
{
// We or the enemy may already own it.
continue;
}

Expand Down Expand Up @@ -314,7 +315,7 @@ void Bases::updateEnemyStart()
return;
}

// Call only shen enemyStartingBase is unknown (null).
// Call only when enemyStartingBase is unknown (null).
if (inferEnemyBaseFromOverlord())
{
// We were able to deduce the enemy's location by seeing an overlord.
Expand Down Expand Up @@ -389,15 +390,17 @@ void Bases::updateBaseOwners()
BWAPI::Unit depot = nullptr;
for (const auto unit : units)
{
if (unit->getType().isResourceDepot())
if (unit->getType().isResourceDepot() && !unit->isLifted())
{
UAB_ASSERT(unit->getType() != BWAPI::UnitTypes::Zerg_Infested_Command_Center, "infested resource depot");
depot = unit;
break;
}
}
if (depot)
{
// The base is occupied.
// NOTE The player might be the neutral player. That's OK.
base->setOwner(depot, depot->getPlayer());
}
else
Expand Down Expand Up @@ -693,7 +696,7 @@ void Bases::drawBaseOwnership(int x, int y) const

BWAPI::Broodwar->drawTextScreen(x, yy, "%cBases", white);

for (Base * base : bases)
for (const Base * base : bases)
{
yy += 10;

Expand Down Expand Up @@ -906,25 +909,22 @@ int Bases::geyserCount() const

// Current number of completed refineries at my completed bases,
// and number of bare geysers available to be taken.
// Not counted: The number of refineries currently under construction.
void Bases::gasCounts(int & nRefineries, int & nFreeGeysers) const
{
int refineries = 0;
int geysers = 0;

for (Base * base : bases)
{
BWAPI::Unit depot = base->getDepot();

if (base->getOwner() == BWAPI::Broodwar->self() &&
depot && // should never be null, but we check anyway
(depot->isCompleted() || UnitUtil::IsMorphedBuildingType(depot->getType())))
if (base->getOwner() == BWAPI::Broodwar->self() && UnitUtil::IsCompletedResourceDepot(base->getDepot()))
{
// Recalculate the base's geysers every time.
// This is a slow but accurate way to work around the BWAPI geyser bug.
// To save cycles, call findGeysers() only when necessary (e.g. a refinery is destroyed).
base->findGeysers();

for (const auto geyser : base->getGeysers())
for (BWAPI::Unit geyser : base->getGeysers())
{
if (geyser && geyser->exists())
{
Expand Down Expand Up @@ -971,7 +971,7 @@ bool Bases::getEnemyProxy() const
if (myNaturalBase())
{
const int natDist = ui.lastPosition.getApproxDistance(myNaturalBase()->getCenter());
if (zone == naturalZone && natDist <= 24 * 32 || natDist <= 13 * 32)
if (zone == naturalZone && natDist <= 24 * 32 || natDist <= 13 * 32)
{
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion Steamhammer/Source/BuildOrderQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ void BuildOrderQueue::drawQueueInformation(int x, int y, bool outOfBook)
{
prefix = orange;
}
else if (act.getUnitType().groundWeapon() != BWAPI::WeaponTypes::None || act.getUnitType().airWeapon() != BWAPI::WeaponTypes::None)
else if (UnitUtil::TypeCanAttack(act.getUnitType()))
{
prefix = red;
}
Expand Down
Loading

0 comments on commit 97513d4

Please sign in to comment.