Wiki
Clone wikiBWTA2 / Getting Started
Getting Started
This is an example of how to use BWTA with the ExampleAIModule of BWAPI.
Download
Download the last version of BWTA. It should contain 3 folders:
- include: add the content to your include folder of your project
- lib: add the content to your lib folder of your project
- windows: move the files in your
C:\Windows
folder
We also need to create the folder for the cache files of BWTA in your bwapi-data folder.
Usually C:\StarCraft\bwapi-data\BWTA2
Edit ExampleAIModule Project
BWAPI comes with some project examples to start working. We are going to modify the ExampleAIModule project in order to analyze the map using BWTA
Project Properties
We need to edit the project properties in order to add the new libraries.
Edit ExampleAIModule.h file
We need to include BWTA.h
and windows.h
(to use threads) and declare a couple of new functions.
#pragma once
#include <BWAPI.h>
#include <BWTA.h>
#include <windows.h>
DWORD WINAPI AnalyzeThread();
class ExampleAIModule : public BWAPI::AIModule
{
public:
// Virtual functions for callbacks, leave these as they are.
// ...
// Everything below this line is safe to modify.
void drawTerrainData();
};
Edit ExampleAIModule.cpp file
First we need variables to know if the map analysis is completed.
bool analyzed;
bool analysis_just_finished;
At the end of onStart()
we will read the map information into BWTA so the terrain analysis can be done in another thread.
void ExampleAIModule::onStart()
{
// ...
BWTA::readMap();
analyzed = false;
analysis_just_finished = false;
}
At the beginning of onFrame()
we will call our function to draw the terrain if the analysis have been completed.
void ExampleAIModule::onFrame()
{
//...
// Return if the game is a replay or is paused
if ( Broodwar->isReplay() || Broodwar->isPaused() || !Broodwar->self() )
return;
//BWTA draw
if (analyzed)
drawTerrainData();
if (analysis_just_finished)
{
Broodwar << "Finished analyzing map." << std::endl;;
analysis_just_finished = false;
}
// Prevent spamming by only running our onFrame once every number of latency frames.
// Latency frames are the number of frames before commands are processed.
if ( Broodwar->getFrameCount() % Broodwar->getLatencyFrames() != 0 )
return;
// ...
We modify onSendText()
to detect the text "/analyze" and start the analysis of the map.
void ExampleAIModule::onSendText(std::string text)
{
if (text == "/analyze") {
if (analyzed == false) {
Broodwar << "Analyzing map... this may take a minute" << std::endl;;
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AnalyzeThread, NULL, 0, NULL);
}
} else {
// Send the text to the game if it is not being processed.
Broodwar->sendText("%s", text.c_str());
}
}
Finally we define the functions to start the analysis and to draw the regions and chokepoints detected from BWTA.
DWORD WINAPI AnalyzeThread()
{
BWTA::analyze();
analyzed = true;
analysis_just_finished = true;
return 0;
}
void ExampleAIModule::drawTerrainData()
{
//we will iterate through all the base locations, and draw their outlines.
for (const auto& baseLocation : BWTA::getBaseLocations()) {
TilePosition p = baseLocation->getTilePosition();
//draw outline of center location
Position leftTop(p.x * TILE_SIZE, p.y * TILE_SIZE);
Position rightBottom(leftTop.x + 4 * TILE_SIZE, leftTop.y + 3 * TILE_SIZE);
Broodwar->drawBoxMap(leftTop, rightBottom, Colors::Blue);
//draw a circle at each mineral patch
for (const auto& mineral : baseLocation->getStaticMinerals()) {
Broodwar->drawCircleMap(mineral->getInitialPosition(), 30, Colors::Cyan);
}
//draw the outlines of Vespene geysers
for (const auto& geyser : baseLocation->getGeysers()) {
TilePosition p1 = geyser->getInitialTilePosition();
Position leftTop1(p1.x * TILE_SIZE, p1.y * TILE_SIZE);
Position rightBottom1(leftTop1.x + 4 * TILE_SIZE, leftTop1.y + 2 * TILE_SIZE);
Broodwar->drawBoxMap(leftTop1, rightBottom1, Colors::Orange);
}
//if this is an island expansion, draw a yellow circle around the base location
if (baseLocation->isIsland()) {
Broodwar->drawCircleMap(baseLocation->getPosition(), 80, Colors::Yellow);
}
}
//we will iterate through all the regions and ...
for (const auto& region : BWTA::getRegions()) {
// draw the polygon outline of it in green
BWTA::Polygon p = region->getPolygon();
for (size_t j = 0; j < p.size(); ++j) {
Position point1 = p[j];
Position point2 = p[(j + 1) % p.size()];
Broodwar->drawLineMap(point1, point2, Colors::Green);
}
// visualize the chokepoints with red lines
for (auto const& chokepoint : region->getChokepoints()) {
Position point1 = chokepoint->getSides().first;
Position point2 = chokepoint->getSides().second;
Broodwar->drawLineMap(point1, point2, Colors::Red);
}
}
}
Running
Run StarCraft through ChaosLauncher and start a game. Then send the message /analyze and after a while (the first time it can take 2 minutes) we should be able to see the polygons of the decomposed regions and the chokepoints.
Updated