Search in sources :

Example 1 with BaseImpl

use of bwem.BaseImpl in project BWAPI4J by OpenBW.

the class AreaInitializerImpl method createBases.

@Override
public void createBases(final AdvancedData mapAdvancedData) {
    final TilePosition resourceDepotDimensions = UnitType.Terran_Command_Center.tileSize();
    final List<Resource> remainingResources = new ArrayList<>();
    for (final Mineral mineral : getMinerals()) {
        if ((mineral.getInitialAmount() >= 40) && !mineral.isBlocking()) {
            remainingResources.add(mineral);
        }
    }
    for (final Geyser geyser : getGeysers()) {
        if ((geyser.getInitialAmount() >= 300) && !geyser.isBlocking()) {
            remainingResources.add(geyser);
        }
    }
    while (!remainingResources.isEmpty()) {
        // 1) Calculate the SearchBoundingBox (needless to search too far from the remainingResources):
        TilePosition topLeftResources = new TilePosition(Integer.MAX_VALUE, Integer.MAX_VALUE);
        TilePosition bottomRightResources = new TilePosition(Integer.MIN_VALUE, Integer.MIN_VALUE);
        for (final Resource r : remainingResources) {
            final Pair<TilePosition, TilePosition> pair1 = BwemExt.makeBoundingBoxIncludePoint(topLeftResources, bottomRightResources, r.getTopLeft());
            topLeftResources = pair1.getFirst();
            bottomRightResources = pair1.getSecond();
            final Pair<TilePosition, TilePosition> pair2 = BwemExt.makeBoundingBoxIncludePoint(topLeftResources, bottomRightResources, r.getBottomRight());
            topLeftResources = pair2.getFirst();
            bottomRightResources = pair2.getSecond();
        }
        final TilePosition dimensionsBetweenResourceDepotAndResources = new TilePosition(BwemExt.MAX_TILES_BETWEEN_COMMAND_CENTER_AND_RESOURCES, BwemExt.MAX_TILES_BETWEEN_COMMAND_CENTER_AND_RESOURCES);
        TilePosition topLeftSearchBoundingBox = topLeftResources.subtract(resourceDepotDimensions).subtract(dimensionsBetweenResourceDepotAndResources);
        TilePosition bottomRightSearchBoundingBox = bottomRightResources.add(new TilePosition(1, 1)).add(dimensionsBetweenResourceDepotAndResources);
        topLeftSearchBoundingBox = BwemExt.makePointFitToBoundingBox(topLeftSearchBoundingBox, getTopLeft(), getBottomRight().subtract(resourceDepotDimensions).add(new TilePosition(1, 1)));
        bottomRightSearchBoundingBox = BwemExt.makePointFitToBoundingBox(bottomRightSearchBoundingBox, getTopLeft(), getBottomRight().subtract(resourceDepotDimensions).add(new TilePosition(1, 1)));
        // 2) Mark the Tiles with their distances from each remaining Resource (Potential Fields >= 0)
        for (final Resource r : remainingResources) for (int dy = -resourceDepotDimensions.getY() - BwemExt.MAX_TILES_BETWEEN_COMMAND_CENTER_AND_RESOURCES; dy < r.getSize().getY() + resourceDepotDimensions.getY() + BwemExt.MAX_TILES_BETWEEN_COMMAND_CENTER_AND_RESOURCES; ++dy) for (int dx = -resourceDepotDimensions.getX() - BwemExt.MAX_TILES_BETWEEN_COMMAND_CENTER_AND_RESOURCES; dx < r.getSize().getX() + resourceDepotDimensions.getX() + BwemExt.MAX_TILES_BETWEEN_COMMAND_CENTER_AND_RESOURCES; ++dx) {
            final TilePosition deltaTilePosition = r.getTopLeft().add(new TilePosition(dx, dy));
            if (mapAdvancedData.getMapData().isValid(deltaTilePosition)) {
                final Tile tile = mapAdvancedData.getTile(deltaTilePosition, CheckMode.NO_CHECK);
                int dist = (BwemExt.distToRectangle(BwemExt.center(deltaTilePosition), r.getTopLeft().toPosition(), r.getSize().toPosition()) + (TilePosition.SIZE_IN_PIXELS / 2)) / TilePosition.SIZE_IN_PIXELS;
                int score = Math.max(BwemExt.MAX_TILES_BETWEEN_COMMAND_CENTER_AND_RESOURCES + 3 - dist, 0);
                if (r instanceof Geyser) {
                    // somewhat compensates for Geyser alone vs the several minerals
                    score *= 3;
                }
                if (tile.getAreaId().equals(getId())) {
                    // note the additive effect (assume tile.InternalData() is 0 at the beginning)
                    ((TileImpl) tile).setInternalData(((TileImpl) tile).getInternalData() + score);
                }
            }
        }
        // 3) Invalidate the 7 x 7 Tiles around each remaining Resource (Starcraft rule)
        for (final Resource r : remainingResources) for (int dy = -3; dy < r.getSize().getY() + 3; ++dy) for (int dx = -3; dx < r.getSize().getX() + 3; ++dx) {
            final TilePosition deltaTilePosition = r.getTopLeft().add(new TilePosition(dx, dy));
            if (mapAdvancedData.getMapData().isValid(deltaTilePosition)) {
                final Tile tileToUpdate = mapAdvancedData.getTile(deltaTilePosition, CheckMode.NO_CHECK);
                ((TileImpl) tileToUpdate).setInternalData(-1);
            }
        }
        // 4) Search the best location inside the SearchBoundingBox:
        TilePosition bestLocation = null;
        int bestScore = 0;
        final List<Mineral> blockingMinerals = new ArrayList<>();
        for (int y = topLeftSearchBoundingBox.getY(); y <= bottomRightSearchBoundingBox.getY(); ++y) for (int x = topLeftSearchBoundingBox.getX(); x <= bottomRightSearchBoundingBox.getX(); ++x) {
            final int score = computeBaseLocationScore(mapAdvancedData, new TilePosition(x, y));
            if (score > bestScore) {
                if (validateBaseLocation(mapAdvancedData, new TilePosition(x, y), blockingMinerals)) {
                    bestScore = score;
                    bestLocation = new TilePosition(x, y);
                }
            }
        }
        // 5) Clear Tile::m_internalData (required due to our use of Potential Fields: see comments in 2))
        for (Resource r : remainingResources) {
            for (int dy = -resourceDepotDimensions.getY() - BwemExt.MAX_TILES_BETWEEN_COMMAND_CENTER_AND_RESOURCES; dy < r.getSize().getY() + resourceDepotDimensions.getY() + BwemExt.MAX_TILES_BETWEEN_COMMAND_CENTER_AND_RESOURCES; ++dy) for (int dx = -resourceDepotDimensions.getX() - BwemExt.MAX_TILES_BETWEEN_COMMAND_CENTER_AND_RESOURCES; dx < r.getSize().getX() + resourceDepotDimensions.getX() + BwemExt.MAX_TILES_BETWEEN_COMMAND_CENTER_AND_RESOURCES; ++dx) {
                final TilePosition deltaTilePosition = r.getTopLeft().add(new TilePosition(dx, dy));
                if (mapAdvancedData.getMapData().isValid(deltaTilePosition)) {
                    final Tile tileToUpdate = mapAdvancedData.getTile(deltaTilePosition, CheckMode.NO_CHECK);
                    ((TileImpl) tileToUpdate).setInternalData(0);
                }
            }
        }
        if (bestScore == 0) {
            break;
        }
        // 6) Create a new Base at bestLocation, assign to it the relevant resources and remove them from RemainingResources:
        final List<Resource> assignedResources = new ArrayList<>();
        for (final Resource r : remainingResources) {
            if (BwemExt.distToRectangle(r.getCenter(), bestLocation.toPosition(), resourceDepotDimensions.toPosition()) + 2 <= BwemExt.MAX_TILES_BETWEEN_COMMAND_CENTER_AND_RESOURCES * TilePosition.SIZE_IN_PIXELS) {
                assignedResources.add(r);
            }
        }
        // for (int i = 0; i < remainingResources.size(); ++i) {
        // Resource r = remainingResources.get(i);
        // if (assignedResources.contains(r)) {
        // remainingResources.remove(i--);
        // }
        // }
        remainingResources.removeIf(assignedResources::contains);
        if (assignedResources.isEmpty()) {
            break;
        }
        super.bases.add(new BaseImpl(this, bestLocation, assignedResources, blockingMinerals));
    }
}
Also used : Mineral(bwem.unit.Mineral) TileImpl(bwem.tile.TileImpl) Resource(bwem.unit.Resource) ArrayList(java.util.ArrayList) BaseImpl(bwem.BaseImpl) Tile(bwem.tile.Tile) MiniTile(bwem.tile.MiniTile) ChokePoint(bwem.ChokePoint) Geyser(bwem.unit.Geyser) TilePosition(org.openbw.bwapi4j.TilePosition)

Aggregations

BaseImpl (bwem.BaseImpl)1 ChokePoint (bwem.ChokePoint)1 MiniTile (bwem.tile.MiniTile)1 Tile (bwem.tile.Tile)1 TileImpl (bwem.tile.TileImpl)1 Geyser (bwem.unit.Geyser)1 Mineral (bwem.unit.Mineral)1 Resource (bwem.unit.Resource)1 ArrayList (java.util.ArrayList)1 TilePosition (org.openbw.bwapi4j.TilePosition)1