BWAPI
Public Member Functions | Private Member Functions | Private Attributes
TerrainAnaysisClass Class Reference

#include <TerrainAnaysis.h>

Collaboration diagram for TerrainAnaysisClass:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 TerrainAnaysisClass ()
void analyseBasesAndTerrain ()
void finaliseConnectivity ()
const std::set< Region > & getRegions () const
const std::set< Chokepoint > & getChokepoints () const
const RegiongetRegion (TilePosition tile) const
const RegiongetRegion (Position pos) const
const RegiongetRegion (WalkPosition tile) const
const RegiongetRegion (int x, int y) const
int getWalkClearance (WalkPosition currentTile)
int getWalkClearance (int x, int y)
int getWalkConnectivity (WalkPosition currentTile)
int getWalkConnectivity (int x, int y)

Private Member Functions

void calculateConnectivity ()
void calculateWalkTileClearance ()
void createRegions ()
void createBases ()
std::pair< WalkPosition,
WalkPosition
findChokePoint (WalkPosition center)
void removeChokepoint (Chokepoint chokeToRemove)

Private Attributes

std::set< ChokepointmChokepoints
std::set< RegionmRegions
RectangleArray< RegionmTileToRegion
RectangleArray< int > mTileConnectivity
std::set< int > mSmallObstacles
RectangleArray< int > mTileClearance
RectangleArray< WalkPositionmTileClosestObstacle

Detailed Description

Definition at line 10 of file TerrainAnaysis.h.


Constructor & Destructor Documentation

Definition at line 15 of file TerrainAnaysis.cpp.

{
}

Member Function Documentation

Definition at line 237 of file TerrainAnaysis.cpp.

References BWAPI::Broodwar, BWAPI::Game::isWalkable(), BWAPI::Game::mapHeight(), BWAPI::Game::mapWidth(), mSmallObstacles, mTileConnectivity, and RectangleArray< T >::resize().

Referenced by analyseBasesAndTerrain().

{
        int mapWidth = BWAPI::Broodwar->mapWidth() * 4;
        int mapHeight = BWAPI::Broodwar->mapHeight() * 4;

        int currentRegion = 1;
        mTileConnectivity.resize(mapWidth, mapHeight, 0);
        for(int x = 0; x < mapWidth; ++x)
        {
                for(int y = 0; y < mapHeight; ++y)
                {
                        if(mTileConnectivity[x][y] != 0)
                                continue;

                        bool walkable = BWAPI::Broodwar->isWalkable(x, y);
                        int tileCount = 0;

                        std::set<WalkPosition> unvisitedTiles;
                        unvisitedTiles.insert(WalkPosition(x, y));

                        while(!unvisitedTiles.empty())
                        {
                                const std::set<WalkPosition>::iterator &tile = unvisitedTiles.begin();

                                ++tileCount;
                                mTileConnectivity[tile->x][tile->y] = currentRegion;

                                if(tile->x > 0 && BWAPI::Broodwar->isWalkable(tile->x-1, tile->y) == walkable && mTileConnectivity[tile->x-1][tile->y] == 0)
                                        unvisitedTiles.insert(WalkPosition(tile->x-1, tile->y));
                                if(tile->y > 0 && BWAPI::Broodwar->isWalkable(tile->x, tile->y-1) == walkable && mTileConnectivity[tile->x][tile->y-1] == 0)
                                        unvisitedTiles.insert(WalkPosition(tile->x, tile->y-1));

                                if(tile->x < mapWidth-1 && BWAPI::Broodwar->isWalkable(tile->x+1, tile->y) == walkable && mTileConnectivity[tile->x+1][tile->y] == 0)
                                        unvisitedTiles.insert(WalkPosition(tile->x+1, tile->y));
                                if(tile->y < mapHeight-1 && BWAPI::Broodwar->isWalkable(tile->x, tile->y+1) == walkable && mTileConnectivity[tile->x][tile->y+1] == 0)
                                        unvisitedTiles.insert(WalkPosition(tile->x, tile->y+1));

                                unvisitedTiles.erase(tile);
                        }

                        if(!walkable && tileCount < 200)
                                mSmallObstacles.insert(currentRegion);

                        ++currentRegion;
                }
        }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 72 of file TerrainAnaysis.cpp.

References BWAPI::Broodwar, Heap< Key, Val >::empty(), BWAPI::Game::mapHeight(), BWAPI::Game::mapWidth(), mSmallObstacles, mTileClearance, mTileClosestObstacle, mTileConnectivity, Heap< Key, Val >::pop(), RectangleArray< T >::resize(), Heap< Key, Val >::set(), Heap< Key, Val >::top(), WalkPosition::x, and WalkPosition::y.

Referenced by analyseBasesAndTerrain().

{
        int mapWidth = BWAPI::Broodwar->mapWidth() * 4;
        int mapHeight = BWAPI::Broodwar->mapHeight() * 4;

        mTileClearance.resize(mapWidth, mapHeight, -1);
        mTileClosestObstacle.resize(mapWidth, mapHeight);

        Heap<WalkPosition, int> unvisitedTiles(true);
        for(int x = 0; x < mapWidth; ++x)
        {
                for(int y = 0; y < mapHeight; ++y)
                {
                        if(!BWAPI::Broodwar->isWalkable(x, y))
                        {
                                mTileClearance[x][y] = 0;
                                mTileClosestObstacle[x][y] = WalkPosition(x, y);
                                if(mSmallObstacles.count(mTileConnectivity[x][y]) == 0)
                                        unvisitedTiles.set(WalkPosition(x, y), 0);
                        }
                        else if(x == 0 || y == 0 || x == mapWidth-1 || y == mapHeight-1)
                        {
                                mTileClearance[x][y] = 10;
                                mTileClosestObstacle[x][y] = WalkPosition((x == 0 ? -1 : (x == mapWidth-1 ? mapWidth : x)), (y == 0 ? -1 : (y == mapHeight-1 ? mapHeight : y)));
                                unvisitedTiles.set(WalkPosition(x, y), 10);
                        }
                }
        }

        while(!unvisitedTiles.empty())
        {
                WalkPosition tile = unvisitedTiles.top().first;
                const int distance = unvisitedTiles.top().second + 10;
                const int diagDistance = distance + 4;
                unvisitedTiles.pop();

                const int west = tile.x - 1;
                const int north = tile.y - 1;
                const int east = tile.x + 1;
                const int south = tile.y + 1;

                const bool canGoWest = west >= 0;
                const bool canGoNorth = north >= 0;
                const bool canGoEast = east < mapWidth;
                const bool canGoSouth = south < mapHeight;

                const WalkPosition &currentParent = mTileClosestObstacle[tile.x][tile.y];

                if(canGoWest && (mTileClearance[west][tile.y] == -1 || distance < mTileClearance[west][tile.y]))
                {
                        mTileClearance[west][tile.y] = distance;
                        mTileClosestObstacle[west][tile.y] = currentParent;
                        unvisitedTiles.set(WalkPosition(west, tile.y), distance);
                }

                if(canGoNorth && (mTileClearance[tile.x][north] == -1 || distance < mTileClearance[tile.x][north]))
                {
                        mTileClearance[tile.x][north] = distance;
                        mTileClosestObstacle[tile.x][north] = currentParent;
                        unvisitedTiles.set(WalkPosition(tile.x, north), distance);
                }

                if(canGoEast && (mTileClearance[east][tile.y] == -1 || distance < mTileClearance[east][tile.y]))
                {
                        mTileClearance[east][tile.y] = distance;
                        mTileClosestObstacle[east][tile.y] = currentParent;
                        unvisitedTiles.set(WalkPosition(east, tile.y), distance);
                }

                if(canGoSouth && (mTileClearance[tile.x][south] == -1 || distance < mTileClearance[tile.x][south]))
                {
                        mTileClearance[tile.x][south] = distance;
                        mTileClosestObstacle[tile.x][south] = currentParent;
                        unvisitedTiles.set(WalkPosition(tile.x, south), distance);
                }

                if(canGoWest && canGoNorth && (mTileClearance[west][north] == -1 || diagDistance < mTileClearance[west][north]))
                {
                        mTileClearance[west][north] = diagDistance;
                        mTileClosestObstacle[west][north] = currentParent;
                        unvisitedTiles.set(WalkPosition(west, north), diagDistance);
                }

                if(canGoEast && canGoSouth && (mTileClearance[east][south] == -1 || diagDistance < mTileClearance[east][south]))
                {
                        mTileClearance[east][south] = diagDistance;
                        mTileClosestObstacle[east][south] = currentParent;
                        unvisitedTiles.set(WalkPosition(east, south), diagDistance);
                }

                if(canGoEast && canGoNorth && (mTileClearance[east][north] == -1 || diagDistance < mTileClearance[east][north]))
                {
                        mTileClearance[east][north] = diagDistance;
                        mTileClosestObstacle[east][north] = currentParent;
                        unvisitedTiles.set(WalkPosition(east, north), diagDistance);
                }

                if(canGoWest && canGoSouth && (mTileClearance[west][south] == -1 || diagDistance < mTileClearance[west][south]))
                {
                        mTileClearance[west][south] = diagDistance;
                        mTileClosestObstacle[west][south] = currentParent;
                        unvisitedTiles.set(WalkPosition(west, south), diagDistance);
                }
        }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 594 of file TerrainAnaysis.cpp.

References UnitGroup::begin(), BWAPI::Broodwar, UnitGroup::end(), BWAPI::Position::getApproxDistance(), UnitGroup::getCenter(), UnitHelper::getClusters(), Singleton< T >::Instance(), BWAPI::Game::mapHeight(), BWAPI::Game::mapWidth(), mRegions, mTileToRegion, MapHelper::spiralSearch(), BWAPI::TilePosition::x(), and BWAPI::TilePosition::y().

Referenced by analyseBasesAndTerrain().

{
        //Create a set of all Geysers and all mineral patches with more than 200 minerals
        UnitGroup resources = UnitTracker::Instance().getGeysers();
        for each(Unit mineral in UnitTracker::Instance().getMinerals())
        {
                if(mineral->getResources() > 200)
                        resources.insert(mineral);
        }

        //Group them into clusters
        std::vector<UnitGroup> resourceClusters = UnitHelper::getClusters(resources, 260, 3);

        //TODO: create the bases on the fly rather then collect information then create
        std::set<TilePosition> basesToCreate;
        std::map<TilePosition, UnitGroup> baseToCreateToMineral;
        std::map<TilePosition, bool> baseIsRegionBase;
        std::map<TilePosition, bool> baseToCreateIsStartLocation;
        std::map<TilePosition, Region> baseToRegion;
        std::map<Region, std::set<TilePosition>> baseToCreateFromRegion;

        for each(UnitGroup resourceCluster in resourceClusters)
        {
                TilePosition baseLocation;
                PossibleLocationCompare locationCompare(&resourceCluster, &baseLocation);
                MapHelper::spiralSearch(TilePosition(resourceCluster.getCenter()), locationCompare, 18);

                bool addedToOther = false;
                for(std::map<TilePosition, UnitGroup>::iterator it = baseToCreateToMineral.begin(); it != baseToCreateToMineral.end(); ++it)
                {
                        int dx = abs(baseLocation.x() - it->first.x());
                        int dy = abs(baseLocation.y() - it->first.y());

                        if(dx <= 4 && dy <= 3)
                        {
                                it->second.insert(resourceCluster.begin(), resourceCluster.end());
                                addedToOther = true;
                                break;
                        }
                }

                if(!addedToOther)
                {
                        basesToCreate.insert(baseLocation);
                        baseToCreateToMineral[baseLocation] = resourceCluster;
                }
        }

        for each(TilePosition base in basesToCreate)
        {
                Region region = mTileToRegion[base.x() * 4][base.y() * 4];
                if(region)
                {
                        baseToCreateFromRegion[region].insert(base);
                        baseToRegion[base] = region;
                }
        }

        RectangleArray<TilePosition> tileToBase(BWAPI::Broodwar->mapWidth(), BWAPI::Broodwar->mapHeight());
        std::map<TilePosition, std::set<TilePosition>> baseToTiles;

        for(int x = 0; x < BWAPI::Broodwar->mapWidth(); ++x)
        {
                for(int y = 0; y < BWAPI::Broodwar->mapHeight(); ++y)
                {
                        Region region = mTileToRegion[x*4][y*4];

                        //This isn't a region, so find the closest Region
                        if(!region || region->getClearance() < 80)
                        {
                                int distance = std::numeric_limits<int>::max();
                                for each(Region reg in mRegions)
                                {
                                        if(reg->getClearance() < 80)
                                                continue;

                                        int thisDistance = reg->getCenter().getApproxDistance(Position(x*32, y*32));
                                        if(thisDistance < distance)
                                        {
                                                distance = thisDistance;
                                                region = reg;
                                        }
                                }
                        }

                        // Still hasn't got a region? something must be wrong with the analysis
                        if(!region)
                                return;
                        
                        // Dont already have a base for this region
                        if(baseToCreateFromRegion.count(region) == 0)
                        {
                                TilePosition newBase = TilePosition(region->getCenter());

                                basesToCreate.insert(newBase);
                                baseToCreateFromRegion[region].insert(newBase);
                                baseToRegion[newBase] = region;

                                tileToBase[x][y] = newBase;
                                baseToTiles[newBase].insert(TilePosition(x, y));
                                baseIsRegionBase[newBase] = true;
                        }
                        // Have 1 base exactly, use it
                        else if(baseToCreateFromRegion[region].size() == 1)
                        {
                                TilePosition base = *baseToCreateFromRegion[region].begin();
                                tileToBase[x][y] = base;
                                baseToTiles[base].insert(TilePosition(x, y));
                        }
                        // Find the closest from the possibilities
                        else
                        {
                                TilePosition baseToUse;
                                int distance = std::numeric_limits<int>::max();

                                for each(TilePosition base in baseToCreateFromRegion[region])
                                {
                                        int thisDistance = Position(base).getApproxDistance(Position(x*32, y*32));
                                        if(thisDistance < distance)
                                        {
                                                distance = thisDistance;
                                                baseToUse = base;
                                        }
                                }

                                tileToBase[x][y] = baseToUse;
                                baseToTiles[baseToUse].insert(TilePosition(x, y));
                        }
                }
        }

        for each(TilePosition startLocation in BWAPI::Broodwar->getStartLocations())
        {
                baseToCreateIsStartLocation[tileToBase[startLocation.x()][startLocation.y()]] = true;
        }

        for each(TilePosition base in basesToCreate)
        {
                Base newBase;
                if(baseIsRegionBase[base])
                        newBase = BaseTracker::Instance().createBase(baseToTiles[base], baseToRegion[base], baseToCreateIsStartLocation[base]);
                else
                        newBase = BaseTracker::Instance().createBase(baseToTiles[base], baseToRegion[base], baseToCreateIsStartLocation[base], base, baseToCreateToMineral[base]);

                newBase->getRegion()->addBase(newBase);
        }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 285 of file TerrainAnaysis.cpp.

References BWAPI::Broodwar, Heap< Key, Val >::empty(), Heap< Key, Val >::erase(), findChokePoint(), WalkPosition::getCenterPosition(), getRegions(), Singleton< T >::Instance(), LOGMESSAGEWARNING, BWAPI::CoordinateType::Map, BWAPI::Game::mapHeight(), BWAPI::Game::mapWidth(), mChokepoints, mRegions, mTileClearance, mTileToRegion, Heap< Key, Val >::pop(), BWAPI::Colors::Red, removeChokepoint(), RectangleArray< T >::resize(), Heap< Key, Val >::set(), Heap< Key, Val >::top(), WalkPosition::x, and WalkPosition::y.

Referenced by analyseBasesAndTerrain().

{
        int mapWidth = BWAPI::Broodwar->mapWidth() * 4;
        int mapHeight = BWAPI::Broodwar->mapHeight() * 4;

        // This comment is self explanatory.
        mTileToRegion.resize(mapWidth, mapHeight);
        std::map<WalkPosition, Chokepoint> chokeTiles;

        for(;;)
        {
                int currentRegionClearance = 0;
                WalkPosition currentRegionTile;

                for(int x = 0; x < mapWidth; ++x)
                {
                        for(int y = 0; y < mapHeight; ++y)
                        {
                                if(mTileToRegion[x][y])
                                        continue;

                                if(chokeTiles.count(WalkPosition(x, y)) != 0)
                                        continue;

                                const int localMaximaValue = mTileClearance[x][y];
                                if(localMaximaValue > currentRegionClearance)
                                {
                                        currentRegionClearance = localMaximaValue;
                                        currentRegionTile.x = x;
                                        currentRegionTile.y = y;
                                }
                        }
                }

                if(currentRegionClearance == 0)
                        break;

                Region currentRegion(new RegionClass(currentRegionTile.getCenterPosition(), currentRegionClearance));
                mRegions.insert(currentRegion);

                std::map<WalkPosition, WalkPosition> tileToLastMinima;
                std::map<WalkPosition, std::vector<WalkPosition>> tileToChildren;

                Heap<WalkPosition, int> unvisitedTiles(false);

                unvisitedTiles.set(currentRegionTile, currentRegionClearance);
                tileToLastMinima[currentRegionTile] = currentRegionTile;

                while(!unvisitedTiles.empty())
                {
                        WalkPosition currentTile = unvisitedTiles.top().first;
                        int currentTileClearance = unvisitedTiles.top().second;
                        unvisitedTiles.pop();

                        if(chokeTiles.count(currentTile) != 0)
                        {
                                if(chokeTiles[currentTile]->getRegions().second && chokeTiles[currentTile]->getRegions().second != currentRegion)
                                {
                                        DrawBuffer::Instance().drawBufferedBox(BWAPI::CoordinateType::Map, currentTile.x * 8, currentTile.y * 8, currentTile.x * 8 + 8, currentTile.y * 8 + 8, 999999, BWAPI::Colors::Red);
                                        LOGMESSAGEWARNING("Touched a choke saved to anouther region");
                                }
                                else if(chokeTiles[currentTile]->getRegions().first != currentRegion)
                                {
                                        currentRegion->addChokepoint(chokeTiles[currentTile]);
                                        chokeTiles[currentTile]->setRegion2(currentRegion);
                                }

                                continue;
                        }

                        if(mTileToRegion[currentTile.x][currentTile.y])
                        {
                                LOGMESSAGEWARNING("2 regions possibly connected without a choke");
                                continue;
                        }

                        WalkPosition lastMinima = tileToLastMinima[currentTile];
                        const int chokeSize = mTileClearance[lastMinima.x][lastMinima.y];

                        bool foundChokepoint = false;
                        if(chokeSize < int(float(currentRegionClearance)*0.90f) && chokeSize < int(float(currentTileClearance)*0.80f))
                                foundChokepoint = true;

                        if(foundChokepoint)
                        {
                                const int minDistance = 32;
                                if((abs(currentRegionTile.x - lastMinima.x) + abs(currentRegionTile.y - lastMinima.y)) < minDistance)
                                        foundChokepoint = false;
                                else if((abs(currentTile.x - lastMinima.x) + abs(currentTile.y - lastMinima.y)) < minDistance)
                                        foundChokepoint = false;
                                else if(currentTileClearance < 120)
                                        foundChokepoint = false;
                        }

                        if(foundChokepoint)
                        {
                                const std::pair<WalkPosition, WalkPosition> &chokeSides = findChokePoint(lastMinima);

                                Chokepoint currentChokepoint(new ChokepointClass(chokeSides.first.getCenterPosition(), chokeSides.second.getCenterPosition(), chokeSize));
                                mChokepoints.insert(currentChokepoint);

                                currentChokepoint->setRegion1(currentRegion);
                                currentRegion->addChokepoint(currentChokepoint);

                                int x0 = chokeSides.second.x;
                                int y0 = chokeSides.second.y;

                                int x1 = chokeSides.first.x;
                                int y1 = chokeSides.first.y;

                                int dx = abs(x1 - x0);
                                int dy = abs(y1 - y0);

                                int sx = x0 < x1 ? 1 : -1;
                                int sy = y0 < y1 ? 1 : -1;

                                int error = dx - dy;

                                std::set<WalkPosition> chokeChildren;

                                for(;;)
                                {
                                        if(x0 >= 0 && y0 >= 0 && x0 < mapWidth && y0 < mapHeight && mTileClearance[x0][y0] != 0 && !mTileToRegion[x0][y0])
                                        {
                                                const WalkPosition thisChokeTile(x0, y0);

                                                tileToChildren[currentRegionTile].push_back(thisChokeTile);
                                                chokeTiles[thisChokeTile] = currentChokepoint;
                                                chokeChildren.insert(thisChokeTile);
                                        }

                                        if(x0 == x1 && y0 == y1)
                                                break;

                                        int e2 = error*2;
                                        if(e2 > -dy)
                                        {
                                                error -= dy;
                                                x0 += sx;
                                        }
                                        if(e2 < dx)
                                        {
                                                error += dx;
                                                y0 += sy;
                                        }
                                }

                                while(!chokeChildren.empty())
                                {
                                        std::set<WalkPosition>::iterator currentTile = chokeChildren.begin();

                                        tileToLastMinima.erase(*currentTile);
                                        unvisitedTiles.erase(*currentTile);

                                        for each(WalkPosition nextTile in tileToChildren[*currentTile])
                                        {
                                                chokeChildren.insert(nextTile);
                                        }
                                        tileToChildren.erase(*currentTile);

                                        chokeChildren.erase(currentTile);
                                }
                        }
                        else
                        {
                                if(mTileClearance[currentTile.x][currentTile.y] < chokeSize)
                                        lastMinima = currentTile;

                                for(int i = 0; i < 4; ++i)
                                {
                                        int x = (i == 0 ? currentTile.x-1 : (i == 1 ? currentTile.x+1 : currentTile.x));
                                        int y = (i == 2 ? currentTile.y-1 : (i == 3 ? currentTile.y+1 : currentTile.y));

                                        if(x < 0 || y < 0 || x >= mapWidth || y >= mapHeight)
                                                continue;

                                        if(mTileClearance[x][y] == 0)
                                                continue;

                                        const WalkPosition nextTile(x, y);
                                        if(tileToLastMinima.count(nextTile) == 0)
                                        {
                                                tileToLastMinima[nextTile] = lastMinima;
                                                tileToChildren[currentTile].push_back(nextTile);

                                                unvisitedTiles.set(nextTile, mTileClearance[x][y]);
                                        }
                                }
                        }
                }

                std::set<WalkPosition> tileSteps;
                tileSteps.insert(currentRegionTile);
                int regionSize = 1;

                while(!tileSteps.empty())
                {
                        std::set<WalkPosition>::iterator currentTile = tileSteps.begin();
                        ++regionSize;

                        for each(WalkPosition nextTile in tileToChildren[*currentTile])
                        {
                                tileSteps.insert(nextTile);
                        }

                        mTileToRegion[currentTile->x][currentTile->y] = currentRegion;

                        tileSteps.erase(currentTile);
                }

                currentRegion->setSize(regionSize);
        }

        for(std::set<Chokepoint>::iterator it = mChokepoints.begin(); it != mChokepoints.end();)
        {
                if(!(*it)->getRegions().first || !(*it)->getRegions().second || (*it)->getRegions().first == (*it)->getRegions().second)
                        removeChokepoint(*(it++));
                else
                        ++it;
        }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 56 of file TerrainAnaysis.cpp.

References mChokepoints, mRegions, and MapHelper::spiralSearch().

Referenced by analyseBasesAndTerrain().

{
        for each(Region region in mRegions)
        {
                WalkInRegionComp goCompare(region);

                for each(Chokepoint chokepoint in mChokepoints)
                {
                        TilePosition pos = MapHelper::spiralSearch(TilePosition(chokepoint->getCenter()), goCompare, 24);

                        region->addChokepointTile(chokepoint, pos);
                        chokepoint->addChokepointTile(region, pos);
                }
        }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 178 of file TerrainAnaysis.cpp.

References BWAPI::Broodwar, Vector::dotProduct(), BWAPI::Game::mapHeight(), BWAPI::Game::mapWidth(), mTileClosestObstacle, Vector::normalise(), WalkPosition::x, and WalkPosition::y.

Referenced by createRegions().

{
        WalkPosition side1 = mTileClosestObstacle[center.x][center.y];

        if(side1 == center)
                return std::make_pair(side1, side1);

        Vector side1Direction(side1.x - center.x, side1.y - center.y);
        side1Direction.normalise();

        int mapWidth = BWAPI::Broodwar->mapWidth() * 4;
        int mapHeight = BWAPI::Broodwar->mapHeight() * 4;

        int x0 = side1.x;
        int y0 = side1.y;

        int x1 = center.x;
        int y1 = center.y;

        int dx = abs(x1 - x0);
        int dy = abs(y1 - y0);

        int sx = x0 < x1 ? 1 : -1;
        int sy = y0 < y1 ? 1 : -1;

        x0 = x1;
        y0 = y1;

        int error = dx - dy;

        for(;;)
        {
                if(x0 < 0 || y0 < 0 || x0 >= mapWidth || y0 >= mapHeight || !BWAPI::Broodwar->isWalkable(x0, y0))
                        return std::make_pair(side1, WalkPosition(x0, y0));

                WalkPosition side2 = mTileClosestObstacle[x0][y0];

                Vector side2Direction(side2.x - center.x, side2.y - center.y);
                side2Direction.normalise();

                float dot = side2Direction.dotProduct(side1Direction);
                float angle = acos(dot);
                if(angle > 2.0f)
                        return std::make_pair(side1, side2);

                int e2 = error*2;
                if(e2 > -dy)
                {
                        error -= dy;
                        x0 += sx;
                }
                if(e2 < dx)
                {
                        error += dx;
                        y0 += sy;
                }
        }
}

Here is the call graph for this function:

Here is the caller graph for this function:

const std::set<Chokepoint>& TerrainAnaysisClass::getChokepoints ( ) const [inline]

Definition at line 19 of file TerrainAnaysis.h.

References mChokepoints.

{ return mChokepoints; }
const Region& TerrainAnaysisClass::getRegion ( TilePosition  tile) const [inline]

Definition at line 21 of file TerrainAnaysis.h.

References mTileToRegion, BWAPI::TilePosition::x(), and BWAPI::TilePosition::y().

{ return mTileToRegion[tile.x()*4][tile.y()*4]; }

Here is the call graph for this function:

const Region& TerrainAnaysisClass::getRegion ( Position  pos) const [inline]

Definition at line 22 of file TerrainAnaysis.h.

References mTileToRegion, BWAPI::Position::x(), and BWAPI::Position::y().

{ return mTileToRegion[pos.x()/8][pos.y()/8]; }

Here is the call graph for this function:

const Region& TerrainAnaysisClass::getRegion ( WalkPosition  tile) const [inline]

Definition at line 23 of file TerrainAnaysis.h.

References mTileToRegion, WalkPosition::x, and WalkPosition::y.

{ return mTileToRegion[tile.x][tile.y]; }
const Region& TerrainAnaysisClass::getRegion ( int  x,
int  y 
) const [inline]

Definition at line 24 of file TerrainAnaysis.h.

References mTileToRegion.

{ return mTileToRegion[x][y]; }
const std::set<Region>& TerrainAnaysisClass::getRegions ( ) const [inline]

Definition at line 18 of file TerrainAnaysis.h.

References mRegions.

Referenced by createRegions().

{ return mRegions; }

Here is the caller graph for this function:

int TerrainAnaysisClass::getWalkClearance ( WalkPosition  currentTile) [inline]

Definition at line 26 of file TerrainAnaysis.h.

References mTileClearance, WalkPosition::x, and WalkPosition::y.

{ return mTileClearance[currentTile.x][currentTile.y]; }
int TerrainAnaysisClass::getWalkClearance ( int  x,
int  y 
) [inline]

Definition at line 27 of file TerrainAnaysis.h.

References mTileClearance.

{ return mTileClearance[x][y]; }

Definition at line 29 of file TerrainAnaysis.h.

References mTileConnectivity, WalkPosition::x, and WalkPosition::y.

{ return mTileConnectivity[currentTile.x][currentTile.y]; }
int TerrainAnaysisClass::getWalkConnectivity ( int  x,
int  y 
) [inline]

Definition at line 30 of file TerrainAnaysis.h.

References mTileConnectivity.

{ return mTileConnectivity[x][y]; }
void TerrainAnaysisClass::removeChokepoint ( Chokepoint  chokeToRemove) [private]

Definition at line 742 of file TerrainAnaysis.cpp.

References LOGMESSAGEWARNING.

Referenced by createRegions().

{
        //Removes a chokepoint and if its a real one will merge the 2 regions

        Region reg1 = chokeToRemove->getRegions().first;
        Region reg2 = chokeToRemove->getRegions().second;

        if(reg1)
                reg1->removeChokepoint(chokeToRemove);

        if(reg2 && reg2 != reg1)
                reg2->removeChokepoint(chokeToRemove);

        // choke is real, need to merge the regions
        if(reg1 && reg2 && reg1 != reg2)
        {
                LOGMESSAGEWARNING("Tries to Merge 2 regions but is not implemented");
        }
}

Here is the caller graph for this function:


Member Data Documentation

Definition at line 33 of file TerrainAnaysis.h.

Referenced by createRegions(), finaliseConnectivity(), and getChokepoints().

Definition at line 34 of file TerrainAnaysis.h.

Referenced by createBases(), createRegions(), finaliseConnectivity(), and getRegions().

std::set<int> TerrainAnaysisClass::mSmallObstacles [private]

Definition at line 38 of file TerrainAnaysis.h.

Referenced by calculateConnectivity(), and calculateWalkTileClearance().

Definition at line 40 of file TerrainAnaysis.h.

Referenced by calculateWalkTileClearance(), createRegions(), and getWalkClearance().

Definition at line 41 of file TerrainAnaysis.h.

Referenced by calculateWalkTileClearance(), and findChokePoint().

Definition at line 35 of file TerrainAnaysis.h.

Referenced by createBases(), createRegions(), and getRegion().


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines