diff --git a/Dll.cpp b/Dll.cpp new file mode 100644 index 0000000..6d16604 --- /dev/null +++ b/Dll.cpp @@ -0,0 +1,38 @@ +// +// Don't change anything here. +// + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include +#include +#include + +#include + +#include "ExampleAIModule.h" +namespace BWAPI { Game* Broodwar; } +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + BWAPI::BWAPI_init(); + break; + case DLL_PROCESS_DETACH: + break; + } + + + return TRUE; +} + + extern "C" __declspec(dllexport) BWAPI::AIModule* newAIModule(BWAPI::Game* game) +{ + BWAPI::Broodwar=game; + return new ExampleAIModule(); +} \ No newline at end of file diff --git a/ExampleAIModule.cpp b/ExampleAIModule.cpp new file mode 100644 index 0000000..b2388ff --- /dev/null +++ b/ExampleAIModule.cpp @@ -0,0 +1,425 @@ +#include "ExampleAIModule.h" +using namespace BWAPI; + +bool analyzed; +bool analysis_just_finished; +BWTA::Region* home; +BWTA::Region* enemy_base; + +//This is the startup method. It is called once +//when a new game has been started with the bot. +void ExampleAIModule::onStart() +{ + //Goal test; + //test.addObjective(Terran_Command_Center,1); + + Broodwar->sendText("Hello world!"); + + //BroodWar->sendText("I want to build a"); + //Enable flags + Broodwar->enableFlag(Flag::UserInput); + //Uncomment to enable complete map information + Broodwar->enableFlag(Flag::CompleteMapInformation); + + //Start analyzing map data + BWTA::readMap(); + analyzed=false; + analysis_just_finished=false; + //CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AnalyzeThread, NULL, 0, NULL); //Threaded version + AnalyzeThread(); + + //Send each worker to the mineral field that is closest to it + for(std::set::const_iterator i=Broodwar->self()->getUnits().begin();i!=Broodwar->self()->getUnits().end();i++) + { + if ((*i)->getType().isWorker()) + { + Unit* closestMineral=NULL; + for(std::set::iterator m=Broodwar->getMinerals().begin();m!=Broodwar->getMinerals().end();m++) + { + if (closestMineral==NULL || (*i)->getDistance(*m)<(*i)->getDistance(closestMineral)) + { + closestMineral=*m; + } + } + if (closestMineral!=NULL) + { + (*i)->rightClick(closestMineral); + Broodwar->printf("Send worker %d to mineral %d", (*i)->getID(), closestMineral->getID()); + } + } + } +} + +//Called when a game is ended. +//No need to change this. +void ExampleAIModule::onEnd(bool isWinner) +{ + if (isWinner) + { + Broodwar->sendText("I won!"); + } +} + +//Finds a guard point around the home base. +//A guard point is the center of a chokepoint surrounding +//the region containing the home base. +Position ExampleAIModule::findGuardPoint() +{ + //Get the chokepoints linked to our home region + std::set chokepoints = home->getChokepoints(); + double min_length = 10000; + BWTA::Chokepoint* choke = NULL; + + //Iterate through all chokepoints and look for the one with the smallest gap (least width) + for(std::set::iterator c = chokepoints.begin(); c != chokepoints.end(); c++) + { + double length = (*c)->getWidth(); + if (length < min_length || choke==NULL) + { + min_length = length; + choke = *c; + } + } + + return choke->getCenter(); +} + +//This is the method called each frame. This is where the bot's logic +//shall be called. +void ExampleAIModule::onFrame() +{ + Broodwar->printf("It works"); + //Call every 100:th frame + if (Broodwar->getFrameCount() % 100 == 0) + { + //Order one of our workers to guard our chokepoint. + //Iterate through the list of units. + for(std::set::const_iterator i=Broodwar->self()->getUnits().begin();i!=Broodwar->self()->getUnits().end();i++) + { + //Check if unit is a worker. + if ((*i)->getType().isWorker()) + { + //Find guard point + Position guardPoint = findGuardPoint(); + //Order the worker to move to the guard point + (*i)->rightClick(guardPoint); + //Only send the first worker. + break; + } + } + } + + //Draw lines around regions, chokepoints etc. + if (analyzed) + { + drawTerrainData(); + } +} + +//Is called when text is written in the console window. +//Can be used to toggle stuff on and off. +void ExampleAIModule::onSendText(std::string text) +{ + if (text=="/show players") + { + showPlayers(); + } + else if (text=="/show forces") + { + showForces(); + } + else + { + Broodwar->printf("You typed '%s'!",text.c_str()); + Broodwar->sendText("%s",text.c_str()); + } +} + +//Called when the opponent sends text messages. +//No need to change this. +void ExampleAIModule::onReceiveText(BWAPI::Player* player, std::string text) +{ + Broodwar->printf("%s said '%s'", player->getName().c_str(), text.c_str()); +} + +//Called when a player leaves the game. +//No need to change this. +void ExampleAIModule::onPlayerLeft(BWAPI::Player* player) +{ + Broodwar->sendText("%s left the game.",player->getName().c_str()); +} + +//Called when a nuclear launch is detected. +//No need to change this. +void ExampleAIModule::onNukeDetect(BWAPI::Position target) +{ + if (target!=Positions::Unknown) + { + Broodwar->printf("Nuclear Launch Detected at (%d,%d)",target.x(),target.y()); + } + else + { + Broodwar->printf("Nuclear Launch Detected"); + } +} + +//No need to change this. +void ExampleAIModule::onUnitDiscover(BWAPI::Unit* unit) +{ + //Broodwar->sendText("A %s [%x] has been discovered at (%d,%d)",unit->getType().getName().c_str(),unit,unit->getPosition().x(),unit->getPosition().y()); +} + +//No need to change this. +void ExampleAIModule::onUnitEvade(BWAPI::Unit* unit) +{ + //Broodwar->sendText("A %s [%x] was last accessible at (%d,%d)",unit->getType().getName().c_str(),unit,unit->getPosition().x(),unit->getPosition().y()); +} + +//No need to change this. +void ExampleAIModule::onUnitShow(BWAPI::Unit* unit) +{ + //Broodwar->sendText("A %s [%x] has been spotted at (%d,%d)",unit->getType().getName().c_str(),unit,unit->getPosition().x(),unit->getPosition().y()); +} + +//No need to change this. +void ExampleAIModule::onUnitHide(BWAPI::Unit* unit) +{ + //Broodwar->sendText("A %s [%x] was last seen at (%d,%d)",unit->getType().getName().c_str(),unit,unit->getPosition().x(),unit->getPosition().y()); +} + +//Called when a new unit has been created. +//Note: The event is called when the new unit is built, not when it +//has been finished. +void ExampleAIModule::onUnitCreate(BWAPI::Unit* unit) +{ + if (unit->getPlayer() == Broodwar->self()) + { + Broodwar->sendText("A %s [%x] has been created at (%d,%d)",unit->getType().getName().c_str(),unit,unit->getPosition().x(),unit->getPosition().y()); + } +} + +//Called when a unit has been destroyed. +void ExampleAIModule::onUnitDestroy(BWAPI::Unit* unit) +{ + if (unit->getPlayer() == Broodwar->self()) + { + Broodwar->sendText("My unit %s [%x] has been destroyed at (%d,%d)",unit->getType().getName().c_str(),unit,unit->getPosition().x(),unit->getPosition().y()); + } + else + { + Broodwar->sendText("Enemy unit %s [%x] has been destroyed at (%d,%d)",unit->getType().getName().c_str(),unit,unit->getPosition().x(),unit->getPosition().y()); + } +} + +//Only needed for Zerg units. +//No need to change this. +void ExampleAIModule::onUnitMorph(BWAPI::Unit* unit) +{ + //Broodwar->sendText("A %s [%x] has been morphed at (%d,%d)",unit->getType().getName().c_str(),unit,unit->getPosition().x(),unit->getPosition().y()); +} + +//No need to change this. +void ExampleAIModule::onUnitRenegade(BWAPI::Unit* unit) +{ + //Broodwar->sendText("A %s [%x] is now owned by %s",unit->getType().getName().c_str(),unit,unit->getPlayer()->getName().c_str()); +} + +//No need to change this. +void ExampleAIModule::onSaveGame(std::string gameName) +{ + Broodwar->printf("The game was saved to \"%s\".", gameName.c_str()); +} + +//Analyzes the map. +//No need to change this. +DWORD WINAPI AnalyzeThread() +{ + BWTA::analyze(); + + //Self start location only available if the map has base locations + if (BWTA::getStartLocation(BWAPI::Broodwar->self())!=NULL) + { + home = BWTA::getStartLocation(BWAPI::Broodwar->self())->getRegion(); + } + //Enemy start location only available if Complete Map Information is enabled. + if (BWTA::getStartLocation(BWAPI::Broodwar->enemy())!=NULL) + { + enemy_base = BWTA::getStartLocation(BWAPI::Broodwar->enemy())->getRegion(); + } + analyzed = true; + analysis_just_finished = true; + return 0; +} + +//Prints some stats about the units the player has. +//No need to change this. +void ExampleAIModule::drawStats() +{ + std::set myUnits = Broodwar->self()->getUnits(); + Broodwar->drawTextScreen(5,0,"I have %d units:",myUnits.size()); + std::map unitTypeCounts; + for(std::set::iterator i=myUnits.begin();i!=myUnits.end();i++) + { + if (unitTypeCounts.find((*i)->getType())==unitTypeCounts.end()) + { + unitTypeCounts.insert(std::make_pair((*i)->getType(),0)); + } + unitTypeCounts.find((*i)->getType())->second++; + } + int line=1; + for(std::map::iterator i=unitTypeCounts.begin();i!=unitTypeCounts.end();i++) + { + Broodwar->drawTextScreen(5,16*line,"- %d %ss",(*i).second, (*i).first.getName().c_str()); + line++; + } +} + +//Draws terrain data aroung regions and chokepoints. +//No need to change this. +void ExampleAIModule::drawTerrainData() +{ + //Iterate through all the base locations, and draw their outlines. + for(std::set::const_iterator i=BWTA::getBaseLocations().begin();i!=BWTA::getBaseLocations().end();i++) + { + TilePosition p=(*i)->getTilePosition(); + Position c=(*i)->getPosition(); + //Draw outline of center location + Broodwar->drawBox(CoordinateType::Map,p.x()*32,p.y()*32,p.x()*32+4*32,p.y()*32+3*32,Colors::Blue,false); + //Draw a circle at each mineral patch + for(std::set::const_iterator j=(*i)->getStaticMinerals().begin();j!=(*i)->getStaticMinerals().end();j++) + { + Position q=(*j)->getInitialPosition(); + Broodwar->drawCircle(CoordinateType::Map,q.x(),q.y(),30,Colors::Cyan,false); + } + //Draw the outlines of vespene geysers + for(std::set::const_iterator j=(*i)->getGeysers().begin();j!=(*i)->getGeysers().end();j++) + { + TilePosition q=(*j)->getInitialTilePosition(); + Broodwar->drawBox(CoordinateType::Map,q.x()*32,q.y()*32,q.x()*32+4*32,q.y()*32+2*32,Colors::Orange,false); + } + //If this is an island expansion, draw a yellow circle around the base location + if ((*i)->isIsland()) + { + Broodwar->drawCircle(CoordinateType::Map,c.x(),c.y(),80,Colors::Yellow,false); + } + } + //Iterate through all the regions and draw the polygon outline of it in green. + for(std::set::const_iterator r=BWTA::getRegions().begin();r!=BWTA::getRegions().end();r++) + { + BWTA::Polygon p=(*r)->getPolygon(); + for(int j=0;j<(int)p.size();j++) + { + Position point1=p[j]; + Position point2=p[(j+1) % p.size()]; + Broodwar->drawLine(CoordinateType::Map,point1.x(),point1.y(),point2.x(),point2.y(),Colors::Green); + } + } + //Visualize the chokepoints with red lines + for(std::set::const_iterator r=BWTA::getRegions().begin();r!=BWTA::getRegions().end();r++) + { + for(std::set::const_iterator c=(*r)->getChokepoints().begin();c!=(*r)->getChokepoints().end();c++) + { + Position point1=(*c)->getSides().first; + Position point2=(*c)->getSides().second; + Broodwar->drawLine(CoordinateType::Map,point1.x(),point1.y(),point2.x(),point2.y(),Colors::Red); + } + } +} + +//Show player information. +//No need to change this. +void ExampleAIModule::showPlayers() +{ + std::set players=Broodwar->getPlayers(); + for(std::set::iterator i=players.begin();i!=players.end();i++) + { + Broodwar->printf("Player [%d]: %s is in force: %s",(*i)->getID(),(*i)->getName().c_str(), (*i)->getForce()->getName().c_str()); + } +} + +//Show forces information. +//No need to change this. +void ExampleAIModule::showForces() +{ + std::set forces=Broodwar->getForces(); + for(std::set::iterator i=forces.begin();i!=forces.end();i++) + { + std::set players=(*i)->getPlayers(); + Broodwar->printf("Force %s has the following players:",(*i)->getName().c_str()); + for(std::set::iterator j=players.begin();j!=players.end();j++) + { + Broodwar->printf(" - Player [%d]: %s",(*j)->getID(),(*j)->getName().c_str()); + } + } +} + +//Called when a unit has been completed, i.e. finished built. +void ExampleAIModule::onUnitComplete(BWAPI::Unit *unit) +{ + //Broodwar->sendText("A %s [%x] has been completed at (%d,%d)",unit->getType().getName().c_str(),unit,unit->getPosition().x(),unit->getPosition().y()); +} + + +/* +Axel unt Sweppes klasser + +*/ + +ToBuild::ToBuild() +{ + this->quantity = 0; + this->unitType = NULL; +} + +ToBuild::ToBuild(UnitType *type, int quantity) +{ + this->unitType = type; + this->quantity = quantity; +} + +int ToBuild::getQuantity() const +{ + return this->quantity; +} + +UnitType* ToBuild::getUnitType() const +{ + return this->unitType; +} + +void ToBuild::setQuantity(const int &newQuantity) +{ + this->quantity = newQuantity; +} + +void ToBuild::setUnitType(UnitType *unitType) +{ + if(this->unitType != NULL) + delete this->unitType; + + this->unitType = unitType; +} + +Goal::Goal() +{ + for(int i = 0; i < 5; i++) + { + this->toDo[i] = NULL; + } +} + +void Goal::addObjective(BWAPI::UnitType *unit, int nrOfTypes) +{ + ToBuild test = ToBuild(unit,nrOfTypes); + this->toDo[test]; +} + +string Goal::nextUnitName() const +{ + string test2; + UnitType test; + test = this->toDo[0].getType(); + test2 = test.c_str(); + + return test2; +} \ No newline at end of file diff --git a/ExampleAIModule.h b/ExampleAIModule.h new file mode 100644 index 0000000..aecd0b1 --- /dev/null +++ b/ExampleAIModule.h @@ -0,0 +1,88 @@ +#pragma once +#include + +#include +#include +#include + +extern bool analyzed; +extern bool analysis_just_finished; +extern BWTA::Region* home; +extern BWTA::Region* enemy_base; +DWORD WINAPI AnalyzeThread(); + +using namespace BWAPI; +using namespace BWTA; + +class ExampleAIModule : public BWAPI::AIModule +{ +public: + //Methods inherited from BWAPI:AIModule + virtual void onStart(); + virtual void onEnd(bool isWinner); + virtual void onFrame(); + virtual void onSendText(std::string text); + virtual void onReceiveText(BWAPI::Player* player, std::string text); + virtual void onPlayerLeft(BWAPI::Player* player); + virtual void onNukeDetect(BWAPI::Position target); + virtual void onUnitDiscover(BWAPI::Unit* unit); + virtual void onUnitEvade(BWAPI::Unit* unit); + virtual void onUnitShow(BWAPI::Unit* unit); + virtual void onUnitHide(BWAPI::Unit* unit); + virtual void onUnitCreate(BWAPI::Unit* unit); + virtual void onUnitDestroy(BWAPI::Unit* unit); + virtual void onUnitMorph(BWAPI::Unit* unit); + virtual void onUnitRenegade(BWAPI::Unit* unit); + virtual void onSaveGame(std::string gameName); + virtual void onUnitComplete(BWAPI::Unit *unit); + + //Own methods + void drawStats(); + void drawTerrainData(); + void showPlayers(); + void showForces(); + Position findGuardPoint(); +}; +// +//class General +//{ +//}; +// +//class Agent +//{ +//}; +// +//class ConstructAgent : public Agent +//{ +//}; +// +//class UnitAgent : public Agent +//{ +//}; + +class ToBuild +{ +private: + UnitType* unitType; + int quantity; +public: + ToBuild(UnitType *type,int quantity); + ToBuild(); + int getQuantity() const; + UnitType* getUnitType() const; + + void setQuantity(const int &newQuantity); + void setUnitType(UnitType *unitType); +}; + +class Goal +{ +//array av det som finns +private: + ToBuild[5] toDo; +public: + Goal(); + void addObjective(UnitType *unit, int nrOfTypes); + string nextUnitName() const; +}; +