-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
72 changed files
with
3,173 additions
and
1,362 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
#include "BOSimulator.h" | ||
|
||
using namespace UAlbertaBot; | ||
|
||
// TODO unfinished! this is work in progress | ||
|
||
// Simulate a given build order to estimate its duration and its final gas and minerals. | ||
// This is meant to be a low-level tool to compare build orders, to help in making | ||
// dynamic decisions during games. | ||
|
||
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
|
||
// Minerals mined over the given (short) duration. The worker count is constant. | ||
// NOTE This is a simplified estimate. The same is used in WorkerManager. | ||
int BOSimulator::mineralsMined(int duration) const | ||
{ | ||
return int(std::round(duration * nWorkers * mineralRate)); | ||
} | ||
|
||
// TODO unimplemented | ||
int BOSimulator::gasMined(int duration) const | ||
{ | ||
return 0; | ||
} | ||
|
||
// When will we have enough resources to produce the item? | ||
// NOTE This doesn't check supply or prerequisites, only resources. | ||
int BOSimulator::findItemFrame(const MacroAct & act) const | ||
{ | ||
if (act.isUnit()) | ||
{ | ||
int mineralsNeeded = act.getUnitType().mineralPrice() - minerals; | ||
int gasNeeded = act.getUnitType().gasPrice() - gas; | ||
|
||
if (mineralsNeeded > 0) | ||
{ | ||
return frame + int(std::round(mineralsNeeded / (nWorkers * mineralRate))); | ||
} | ||
// Otherwise we already have enough and can fall through. | ||
} | ||
|
||
return frame; | ||
} | ||
|
||
// The next in-progress item is now completing. | ||
void BOSimulator::doInProgressItem() | ||
{ | ||
int nextFrame = inProgress.top().first; | ||
const MacroAct * act = inProgress.top().second; // do not alter inProgress until the end | ||
|
||
int duration = nextFrame - frame; | ||
minerals += mineralsMined(duration); | ||
gas += gasMined(duration); | ||
|
||
if (act->isUnit()) | ||
{ | ||
BWAPI::UnitType type = act->getUnitType(); | ||
completedUnits[type] += 1; | ||
supply += type.supplyProvided(); | ||
if (type.isWorker()) | ||
{ | ||
++nWorkers; | ||
} | ||
} | ||
|
||
frame = nextFrame; | ||
inProgress.pop(); | ||
} | ||
|
||
void BOSimulator::doBuildItem(int nextFrame) | ||
{ | ||
int duration = nextFrame - frame; | ||
minerals += mineralsMined(duration); | ||
gas += gasMined(duration); | ||
|
||
const MacroAct & act = buildOrder[boindex]; | ||
if (act.isUnit()) | ||
{ | ||
BWAPI::UnitType type = act.getUnitType(); | ||
minerals -= type.mineralPrice(); | ||
gas -= type.gasPrice(); | ||
inProgress.push(std::pair<int, const MacroAct *>(nextFrame + type.buildTime(), &act)); | ||
} | ||
|
||
UAB_ASSERT(minerals >= 0 && gas >= 0, "resources out of bounds"); | ||
|
||
++boindex; | ||
} | ||
|
||
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
|
||
BOSimulator::BOSimulator(const std::vector<MacroAct> & bo) | ||
: buildOrder(bo) | ||
, boindex(0) | ||
, frame(BWAPI::Broodwar->getFrameCount()) | ||
, startFrame(BWAPI::Broodwar->getFrameCount()) | ||
, nWorkers(4) // start of game | ||
, minerals(BWAPI::Broodwar->self()->minerals()) | ||
, gas(BWAPI::Broodwar->self()->gas()) | ||
, supply(BWAPI::Broodwar->self()->supplyTotal()) | ||
{ | ||
// TODO find pending research, etc. | ||
|
||
run(); | ||
} | ||
|
||
bool BOSimulator::done() const | ||
{ | ||
return | ||
deadlock || | ||
boindex >= buildOrder.size() && inProgress.empty(); | ||
} | ||
|
||
bool BOSimulator::deadlocked() const | ||
{ | ||
return deadlock; | ||
} | ||
|
||
void BOSimulator::step() | ||
{ | ||
UAB_ASSERT(!done(), "simulation over"); | ||
|
||
// 1. Is the next item a build order item, or the completion of an in-progress item? | ||
bool nextIsInProgress; | ||
int boFrame = -1; | ||
|
||
if (boindex >= buildOrder.size()) | ||
{ | ||
nextIsInProgress = true; | ||
} | ||
else | ||
{ | ||
const MacroAct & act = buildOrder.at(boindex); | ||
boFrame = findItemFrame(act); | ||
if (inProgress.empty()) | ||
{ | ||
nextIsInProgress = false; | ||
} | ||
else | ||
{ | ||
// Within a frame, do in progress items before build items. | ||
int inProgressFrame = inProgress.top().first; | ||
nextIsInProgress = inProgressFrame <= boFrame; | ||
} | ||
} | ||
|
||
// 2. Execute the next item. | ||
if (nextIsInProgress) | ||
{ | ||
doInProgressItem(); | ||
} | ||
else | ||
{ | ||
doBuildItem(boFrame); | ||
} | ||
} | ||
|
||
|
||
void BOSimulator::run() | ||
{ | ||
while (!done()) | ||
{ | ||
step(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#pragma once | ||
|
||
#include <queue> | ||
#include "MacroAct.h" | ||
|
||
namespace UAlbertaBot | ||
{ | ||
|
||
class BOSimulator | ||
{ | ||
private: | ||
const std::vector<MacroAct> & buildOrder; | ||
|
||
size_t boindex; // how far into the simulation? | ||
int frame; // simulated time | ||
|
||
int startFrame; | ||
int nWorkers; | ||
int minerals; | ||
int gas; | ||
int supply; | ||
|
||
bool deadlock; | ||
|
||
// Assumed rate at which 1 worker can mine minerals. | ||
const double mineralRate = 0.045; | ||
|
||
// Completed items. | ||
std::map<BWAPI::UnitType, int> completedUnits; | ||
|
||
// The finishing time of items that are started and take time to complete. | ||
std::priority_queue< | ||
std::pair<int, const MacroAct *>, | ||
std::vector< std::pair<int, const MacroAct *> >, | ||
std::greater< std::pair<int, const MacroAct *> > | ||
> inProgress; | ||
|
||
int mineralsMined(int duration) const; | ||
int gasMined(int duration) const; | ||
|
||
bool canBuildItem(const MacroAct & act) const; | ||
int findItemFrame(const MacroAct & act) const; | ||
void doInProgressItem(); | ||
void doBuildItem(int nextFrame); | ||
|
||
public: | ||
BOSimulator(const std::vector<MacroAct> & bo); | ||
|
||
int getStartFrame() const { return startFrame; }; | ||
int getFrame() const { return frame; }; | ||
int getMinerals() const { return minerals; }; | ||
int getGas() const { return gas; }; | ||
|
||
int getDuration() const { return frame - startFrame; }; | ||
|
||
bool done() const; // the simulation is completed (or deadlocked) | ||
bool deadlocked() const; // the simulation cannot continue (and is therefore done) | ||
void step(); // execute one simulation step | ||
void run(); // run the simulation to its end | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.