Second note: if you are in Linux, you also have to set BWEM_USE_WINUTILS to 0 in src/defs.s. This will disable the compilation of the optional utils provided in winutils.h.
The BWEM library consists in C++ source files only. You could create a library project to get a library file (.lib or .dll) from them. In the following though, only the direct approach will be discussed, i.e. adding these files into your C++ project.
First, you should have a starting or an existing project that makes use of the BWAPI library. In the following, I will assume you are using the ExampleAIModule that comes with the BWAPI release. Also, make sure to use the latest version (at least 4.1.2).
Copy the BWEM folder into your project (wherever appropriate). For example, in ExampleAIModule\Source.
Now you have to add the files into your C++ project, just as you would for any other C++ source file.
If you are using Visual Studio, this can be achieved using the solution explorer.
Right-click on your project, then add a new filter "BWEM".
Right-click on that filter, then add an existing item : actually you will browse and select all the files in ExampleAIModule\Source\BWEM\src.
Right-click on the filter once again, then browse and add the files EasyBMP.h and EasyBMP.cpp located in ExampleAIModule\Source\BWEM\src\EasyBMP_1.06.
That's all!
Again, I will assume you are working on the ExampleAIModule. To use the library, we will only modify ExampleAIModule.cpp.
First, modify the first lines so that it shows as:
#include "ExampleAIModule.h" #include "BWEM/src/bwem.h" // update the path if necessary #include <iostream> using namespace BWAPI; using namespace Filter; //using namespace BWEM; //using namespace BWEM::BWAPI_ext; //using namespace BWEM::utils; namespace { auto & theMap = BWEM::Map::Instance(); }The class BWEM::Map is the entry point for almost every thing in BWEM.
You may want to uncomment some or all of the 3 using directives.
The namespace BWEM introduces very few names so bringing them all is probably not a big deal.
The two other namespaces are not direcly related to BWEM functionnality, but you might still want to use some of their stuff.
BWEM::BWAPI_ext contains several helper functions, built on top of the BWAPI library, that prove to be useful while implementing the BWEM library.
BWEM::utils also contains helper functions, but they are more general and do not depend on the BWAPI library.
Before we can use theMap, we need to initialize it. The right place to do this is in ExampleAIModule::onStart(). But first, let's inclose the whole code inside a standard and basic: try-catch handler:
void ExampleAIModule::onStart() { try { // Hello World! // ... } catch (const std::exception & e) { Broodwar << "EXCEPTION: " << e.what() << std::endl; } }This will catch any standard exception, as well as any exception from BWEM. We will do that in the other methods too.
Now, we add the initialization code:
// ... else // if this is not a replay { // Retrieve you and your enemy's races. enemy() will just return the first enemy. // If you wish to deal with multiple enemies then you must use enemies(). if ( Broodwar->enemy() ) // First make sure there is an enemy Broodwar << "The matchup is " << Broodwar->self()->getRace() << " vs " << Broodwar->enemy()->getRace() << std::endl; Broodwar << "Map initialization..." << std::endl; theMap.Initialize(); theMap.EnableAutomaticPathAnalysis(); bool startingLocationsOK = theMap.FindBasesForStartingLocations(); assert(startingLocationsOK); BWEM::utils::MapPrinter::Initialize(&theMap); BWEM::utils::printMap(theMap); // will print the map into the file <StarCraftFolder>bwapi-data/map.bmp BWEM::utils::pathExample(theMap); // add to the printed map a path between two starting locations Broodwar << "gg" << std::endl; } } catch (const std::exception & e)We have correctly initialized BWEM, and we have started using it (see the code in printMap and pathExample, which are good examples).
void ExampleAIModule::onUnitDestroy(BWAPI::Unit unit) { try { if (unit->getType().isMineralField()) theMap.OnMineralDestroyed(unit); else if (unit->getType().isSpecialBuilding()) theMap.OnStaticBuildingDestroyed(unit); } catch (const std::exception & e) { Broodwar << "EXCEPTION: " << e.what() << std::endl; } }As an example, let's use BWEM::utils::drawMap, which provides similar functionality to BWEM::utils::printMap.
void ExampleAIModule::onFrame() { // Called once every game frame try { BWEM::utils::gridMapExample(theMap); BWEM::utils::drawMap(theMap); // Display the game frame rate as text in the upper left area of the screen Broodwar->drawTextScreen(200, 0, "FPS: %d", Broodwar->getFPS() ); Broodwar->drawTextScreen(200, 20, "Average FPS: %f", Broodwar->getAverageFPS() ); // ... } catch (const std::exception & e) { Broodwar << "EXCEPTION: " << e.what() << std::endl; } }(We also called BWEM::utils::gridMapExample, which demonstrates the use of the new class utils::GridMap.)
void ExampleAIModule::onSendText(std::string text) { BWEM::utils::MapDrawer::ProcessCommand(text); // Send the text to the game if it is not being processed. Broodwar->sendText("%s", text.c_str()); // Make sure to use %s and pass the text as a parameter, // otherwise you may run into problems when you use the %(percent) character! }Run your bot. You should now be able select which information you want to show.