Open GoogleCodeExporter opened 8 years ago
I’ve made my own solution for the problem:
GENERAL IDEA:
Once refinery is destroyed (*g)->isCompleted() becomes permanently False, AI
ignores
geyser and will never send workers to it again.
We can get around this by assigning the workers to the refinery instead (not the
geyser), since desiredWorkerCount applies to units, not resources.
It still stands the isCompleted() behaviour for geysers may be incorrect?
And that this is merely a “hacked” solution in BWSAL for something that
should really
be fixed in BWAPI.
ORIGINAL CODE SECTION – BWSAL 0.9.7
set<Unit*> baseGeysers = (*b)->getGeysers();
//
for(set<Unit*>::iterator g = baseGeysers.begin(); g != baseGeysers.end(); g++)
{
resourceBase[*g] = *b;
desiredWorkerCount[*g]=0;
optimalWorkerCount+=3;
if ((*g)->getType().isRefinery() && (*g)->getPlayer()==Broodwar->self() &&
(*g)->isCompleted())
{
for(int w=0;((w < this->WorkersPerGas) && (remainingWorkers > 0));w++)
{
desiredWorkerCount[*g]++;
remainingWorkers--;
}
}
}
NEW CODE
set<Unit*> baseGeysers = (*b)->getGeysers();
BWAPI::Unit* geyserRefinery = NULL; //Local variable added
BWAPI::TilePosition geyserlocation; //Local variable added
//cycle through geysers
for(set<Unit*>::iterator g = baseGeysers.begin(); g != baseGeysers.end(); g++)
{
resourceBase[*g] = *b;
//REMOVED: desiredWorkerCount[*g]=0;
optimalWorkerCount+=3;
geyserlocation = (*g)->getInitialTilePosition();//get tile location for this geyser
//check for refinery on geyser
std::set<BWAPI::Unit*> unitsOnGeyser =
BWAPI::Broodwar->unitsOnTile(geyserlocation.x(),geyserlocation.y());
//cycle through units on geyser
for(std::set<BWAPI::Unit*>::iterator u = unitsOnGeyser.begin(); u !=
unitsOnGeyser.end(); u++)
{
if ((*u)->getType().isRefinery())//if unit is a refinery
{
geyserRefinery=(*u);
desiredWorkerCount[geyserRefinery]=0;
break;
}
}
//IF geyser has a refinery AND geyser owned by self AND refinery completed
if (geyserRefinery!=NULL && (*g)->getPlayer()==Broodwar->self() &&
(geyserRefinery)->isCompleted())
{
for(int w=0;w < this->WorkersPerGas && remainingWorkers > 0;w++)
{
desiredWorkerCount[geyserRefinery]++;//assign workers to refinery, not geyser
remainingWorkers--;
}
}
}
}
NOTES:
- Workers are freed from destroyed refinerys by the
“desiredWorkerCount.clear();” at
start of rebalanceWorkers().
- “geyserRefinery!=NULL” check means “geyserRefinery->isCompleted()”
will never get
called when refinery is NULL. (prevents program crash)
Original comment by Kali...@gmail.com
on 13 Mar 2010 at 8:51
also when you destroy an enemy refinery it can still be found in
SelectAllEnemy()
Original comment by JoshHil...@gmail.com
on 21 Sep 2010 at 11:07
Original issue reported on code.google.com by
Kali...@gmail.com
on 12 Mar 2010 at 6:57