Search in sources :

Example 1 with Pair

use of org.openbw.bwapi4j.util.Pair in project BWAPI4J by OpenBW.

the class BwemExt method makeBoundingBoxIncludePoint.

// Enlarges the bounding box [topLeft, bottomRight] so that it includes A.
public static Pair<TilePosition, TilePosition> makeBoundingBoxIncludePoint(final TilePosition topLeft, final TilePosition bottomRight, final TilePosition point) {
    int topLeftX = topLeft.getX();
    int topLeftY = topLeft.getY();
    int bottomRightX = bottomRight.getX();
    int bottomRightY = bottomRight.getY();
    if (point.getX() < topLeftX)
        topLeftX = point.getX();
    if (point.getX() > bottomRightX)
        bottomRightX = point.getX();
    if (point.getY() < topLeftY)
        topLeftY = point.getY();
    if (point.getY() > bottomRightY)
        bottomRightY = point.getY();
    return new Pair<>(new TilePosition(topLeftX, topLeftY), new TilePosition(bottomRightX, bottomRightY));
}
Also used : TilePosition(org.openbw.bwapi4j.TilePosition) Pair(org.openbw.bwapi4j.util.Pair)

Example 2 with Pair

use of org.openbw.bwapi4j.util.Pair in project BWAPI4J by OpenBW.

the class Graph method createChokePoints.

// ----------------------------------------------------------------------
// //////////////////////////////////////////////////////////////////////
// Creates a new Area for each pair (top, miniTiles) in AreasList (See Area::top() and Area::miniTiles())
public void createChokePoints(final List<StaticBuilding> staticBuildings, final List<Mineral> minerals, final List<MutablePair<MutablePair<AreaId, AreaId>, WalkPosition>> rawFrontier) {
    Index newIndex = new Index(0);
    final List<Neutral> blockingNeutrals = new ArrayList<>();
    for (final StaticBuilding s : staticBuildings) {
        if (s.isBlocking()) {
            blockingNeutrals.add(s);
        }
    }
    for (final Mineral m : minerals) {
        if (m.isBlocking()) {
            blockingNeutrals.add(m);
        }
    }
    // Note: pseudoChokePointsToCreate is only used for pre-allocating the GetChokePoints array size.
    // This number will highly likely be very small. There is no reason to set a minimum size.
    // int pseudoChokePointsToCreate = 0;
    // for (final Neutral blockingNeutral : blockingNeutrals) {
    // if (blockingNeutral.getNextStacked() == null) {
    // ++pseudoChokePointsToCreate;
    // }
    // }
    // 1) size the matrix
    initializeChokePointsMatrix(this.chokePointsMatrix, getAreaCount());
    // 2) Dispatch the global raw frontier between all the relevant pairs of areas:
    final java.util.Map<MutablePair<AreaId, AreaId>, List<WalkPosition>> rawFrontierByAreaPair = createRawFrontierByAreaPairMap(rawFrontier);
    // 3) For each pair of areas (A, B):
    for (final java.util.Map.Entry<MutablePair<AreaId, AreaId>, List<WalkPosition>> entry : rawFrontierByAreaPair.entrySet()) {
        MutablePair<AreaId, AreaId> rawleft = entry.getKey();
        final List<WalkPosition> rawFrontierAB = entry.getValue();
        // Because our dispatching preserved order,
        // and because Map::m_RawFrontier was populated in descending order of the altitude (see Map::computeAreas),
        // we know that rawFrontierAB is also ordered the same way, but let's check it:
        {
            final List<Altitude> altitudes = new ArrayList<>();
            for (final WalkPosition w : rawFrontierAB) {
                altitudes.add(getMap().getData().getMiniTile(w).getAltitude());
            }
            // bwem_assert(is_sorted(altitudes.rbegin(), altitudes.rend()));
            for (int i = 1; i < altitudes.size(); ++i) {
                final int prev = altitudes.get(i - 1).intValue();
                final int curr = altitudes.get(i).intValue();
                if (prev < curr) {
                    throw new IllegalStateException();
                }
            }
        }
        // 3.1) Use that information to efficiently cluster rawFrontierAB in one or several chokepoints.
        // Each cluster will be populated starting with the center of a chokepoint (max altitude)
        // and finishing with the ends (min altitude).
        final int clusterMinDist = (int) Math.sqrt(BwemExt.lake_max_miniTiles);
        final List<List<WalkPosition>> clusters = new ArrayList<>();
        for (final WalkPosition w : rawFrontierAB) {
            boolean added = false;
            for (final List<WalkPosition> cluster : clusters) {
                final int distToFront = BwemExt.queenWiseDist(cluster.get(0), w);
                final int distToBack = BwemExt.queenWiseDist(cluster.get(cluster.size() - 1), w);
                if (Math.min(distToFront, distToBack) <= clusterMinDist) {
                    if (distToFront < distToBack) {
                        cluster.add(0, w);
                    } else {
                        cluster.add(w);
                    }
                    added = true;
                    break;
                }
            }
            if (!added) {
                final List<WalkPosition> list = new ArrayList<>();
                list.add(w);
                clusters.add(list);
            }
        }
        // 3.2) Create one Chokepoint for each cluster:
        final AreaId a = rawleft.getLeft();
        final AreaId b = rawleft.getRight();
        // getChokePoints(a, b).reserve(clusters.size() + pseudoChokePointsToCreate);
        for (final List<WalkPosition> cluster : clusters) {
            getChokePoints(a, b).add(new ChokePointImpl(this, newIndex, getArea(a), getArea(b), cluster));
            newIndex = newIndex.add(1);
        }
    }
    // 4) Create one Chokepoint for each pair of blocked areas, for each blocking Neutral:
    for (final Neutral blockingNeutral : blockingNeutrals) {
        if (blockingNeutral.getNextStacked() == null) {
            // in the case where several neutrals are stacked, we only consider the top
            final List<Area> blockedAreas = blockingNeutral.getBlockedAreas();
            for (final Area blockedAreaA : blockedAreas) for (final Area blockedAreaB : blockedAreas) {
                if (blockedAreaB.equals(blockedAreaA)) {
                    // breaks symmetry
                    break;
                }
                final WalkPosition center = getMap().breadthFirstSearch(blockingNeutral.getCenter().toWalkPosition(), // findCond
                args -> {
                    Object ttile = args[0];
                    if (!(ttile instanceof MiniTile)) {
                        throw new IllegalArgumentException();
                    }
                    MiniTile miniTile = (MiniTile) ttile;
                    return miniTile.isWalkable();
                }, // visitCond
                args -> true);
                final List<WalkPosition> list = new ArrayList<>();
                list.add(center);
                getChokePoints(blockedAreaA, blockedAreaB).add(new ChokePointImpl(this, newIndex, blockedAreaA, blockedAreaB, list, blockingNeutral));
                newIndex = newIndex.add(1);
            }
        }
    }
    // 5) Set the references to the freshly created Chokepoints:
    for (int loopA = 1; loopA <= getAreaCount(); ++loopA) for (int loopB = 1; loopB < loopA; ++loopB) {
        final AreaId a = new AreaId(loopA);
        final AreaId b = new AreaId(loopB);
        if (!getChokePoints(a, b).isEmpty()) {
            ((AreaInitializer) getArea(a)).addChokePoints(getArea(b), getChokePoints(a, b));
            ((AreaInitializer) getArea(b)).addChokePoints(getArea(a), getChokePoints(a, b));
            this.chokePoints.addAll(getChokePoints(a, b));
        }
    }
}
Also used : StaticBuilding(bwem.unit.StaticBuilding) Utils(bwem.util.Utils) Altitude(bwem.typedef.Altitude) MutableInt(org.apache.commons.lang3.mutable.MutableInt) PriorityQueue(java.util.PriorityQueue) Map(bwem.map.Map) HashMap(java.util.HashMap) TilePosition(org.openbw.bwapi4j.TilePosition) Pair(org.openbw.bwapi4j.util.Pair) ArrayList(java.util.ArrayList) Area(bwem.area.Area) MutablePair(org.apache.commons.lang3.tuple.MutablePair) GroupId(bwem.area.typedef.GroupId) AreaId(bwem.area.typedef.AreaId) CPPath(bwem.typedef.CPPath) Index(bwem.typedef.Index) AdvancedData(bwem.map.AdvancedData) StaticBuilding(bwem.unit.StaticBuilding) Position(org.openbw.bwapi4j.Position) Tile(bwem.tile.Tile) Neutral(bwem.unit.Neutral) AreaInitializer(bwem.area.AreaInitializer) WalkPosition(org.openbw.bwapi4j.WalkPosition) Mineral(bwem.unit.Mineral) TileImpl(bwem.tile.TileImpl) List(java.util.List) Geyser(bwem.unit.Geyser) AreaInitializerImpl(bwem.area.AreaInitializerImpl) BwemExt(bwem.util.BwemExt) Queue(java.util.Queue) Comparator(java.util.Comparator) MiniTile(bwem.tile.MiniTile) Neutral(bwem.unit.Neutral) ArrayList(java.util.ArrayList) AreaId(bwem.area.typedef.AreaId) MiniTile(bwem.tile.MiniTile) Index(bwem.typedef.Index) MutablePair(org.apache.commons.lang3.tuple.MutablePair) ArrayList(java.util.ArrayList) List(java.util.List) Mineral(bwem.unit.Mineral) Area(bwem.area.Area) WalkPosition(org.openbw.bwapi4j.WalkPosition) Map(bwem.map.Map) HashMap(java.util.HashMap)

Example 3 with Pair

use of org.openbw.bwapi4j.util.Pair in project BWAPI4J by OpenBW.

the class AreaInitializerImpl method computeDistances.

@Override
public int[] computeDistances(final TilePosition start, final List<TilePosition> targets) {
    final int[] distances = new int[targets.size()];
    TileImpl.getStaticMarkable().unmarkAll();
    // a priority queue holding the tiles to visit ordered by their distance to start.
    final Queue<Pair<Integer, TilePosition>> toVisit = new PriorityQueue<>(Comparator.comparingInt(Pair::getFirst));
    toVisit.offer(new Pair<>(0, start));
    int remainingTargets = targets.size();
    while (!toVisit.isEmpty()) {
        final Pair<Integer, TilePosition> distanceAndTilePosition = toVisit.poll();
        final int currentDist = distanceAndTilePosition.getFirst();
        final TilePosition current = distanceAndTilePosition.getSecond();
        final Tile currentTile = getMap().getData().getTile(current, CheckMode.NO_CHECK);
        // bwem_assert(currentTile.InternalData() == currentDist);
        if (!(((TileImpl) currentTile).getInternalData() == currentDist)) {
            throw new IllegalStateException("currentTile.InternalData().intValue()=" + ((TileImpl) currentTile).getInternalData() + ", currentDist=" + currentDist);
        }
        // resets Tile::m_internalData for future usage
        ((TileImpl) currentTile).setInternalData(0);
        ((TileImpl) currentTile).getMarkable().setMarked();
        for (int i = 0; i < targets.size(); ++i) {
            if (current.equals(targets.get(i))) {
                distances[i] = (int) Math.round(currentDist * 32.0 / 10000.0);
                --remainingTargets;
            }
        }
        if (remainingTargets == 0) {
            break;
        }
        final TilePosition[] deltas = { new TilePosition(-1, -1), new TilePosition(0, -1), new TilePosition(+1, -1), new TilePosition(-1, 0), new TilePosition(+1, 0), new TilePosition(-1, +1), new TilePosition(0, +1), new TilePosition(+1, +1) };
        for (final TilePosition delta : deltas) {
            final boolean diagonalMove = (delta.getX() != 0) && (delta.getY() != 0);
            final int newNextDist = currentDist + (diagonalMove ? 14142 : 10000);
            final TilePosition next = current.add(delta);
            if (getMap().getData().getMapData().isValid(next)) {
                final Tile nextTile = getMap().getData().getTile(next, CheckMode.NO_CHECK);
                if (!((TileImpl) nextTile).getMarkable().isMarked()) {
                    if (((TileImpl) nextTile).getInternalData() != 0) {
                        // next already in toVisit
                        if (newNextDist < ((TileImpl) nextTile).getInternalData()) {
                            // nextNewDist < nextOldDist
                            // To update next's distance, we need to remove-insert it from toVisit:
                            // bwem_assert(iNext != range.second);
                            final boolean removed = toVisit.remove(new Pair<>(((TileImpl) nextTile).getInternalData(), next));
                            if (!removed) {
                                throw new IllegalStateException();
                            }
                            ((TileImpl) nextTile).setInternalData(newNextDist);
                            toVisit.offer(new Pair<>(newNextDist, next));
                        }
                    } else if ((nextTile.getAreaId().equals(getId())) || (nextTile.getAreaId().equals(UNINITIALIZED))) {
                        ((TileImpl) nextTile).setInternalData(newNextDist);
                        toVisit.offer(new Pair<>(newNextDist, next));
                    }
                }
            }
        }
    }
    // bwem_assert(!remainingTargets);
    if (!(remainingTargets == 0)) {
        throw new IllegalStateException();
    }
    for (final Pair<Integer, TilePosition> distanceAndTilePosition : toVisit) {
        final TileImpl tileToUpdate = ((TileImpl) getMap().getData().getTile(distanceAndTilePosition.getSecond(), CheckMode.NO_CHECK));
        tileToUpdate.setInternalData(0);
    }
    return distances;
}
Also used : TileImpl(bwem.tile.TileImpl) Tile(bwem.tile.Tile) MiniTile(bwem.tile.MiniTile) PriorityQueue(java.util.PriorityQueue) ChokePoint(bwem.ChokePoint) TilePosition(org.openbw.bwapi4j.TilePosition) Pair(org.openbw.bwapi4j.util.Pair)

Example 4 with Pair

use of org.openbw.bwapi4j.util.Pair in project BWAPI4J by OpenBW.

the class Graph method computeDistances.

// //////////////////////////////////////////////////////////////////////
// Returns Distances such that Distances[i] == ground_distance(start, targets[i]) in pixels
// Any Distances[i] may be 0 (meaning targets[i] is not reachable).
// This may occur in the case where start and targets[i] leave in different continents or due to Bloqued intermediate ChokePoint(s).
// For each reached target, the shortest path can be derived using
// the backward trace set in cp->getPathBackTrace() for each intermediate ChokePoint cp from the target.
// Note: same algo than Area::computeDistances (derived from Dijkstra)
private int[] computeDistances(final ChokePoint start, final List<ChokePoint> targets) {
    final int[] distances = new int[targets.size()];
    TileImpl.getStaticMarkable().unmarkAll();
    final Queue<Pair<Integer, ChokePoint>> toVisit = new PriorityQueue<>(Comparator.comparingInt(a -> a.first));
    toVisit.offer(new Pair<>(0, start));
    int remainingTargets = targets.size();
    while (!toVisit.isEmpty()) {
        final Pair<Integer, ChokePoint> distanceAndChokePoint = toVisit.poll();
        final int currentDist = distanceAndChokePoint.first;
        final ChokePoint current = distanceAndChokePoint.second;
        final Tile currentTile = getMap().getData().getTile(current.getCenter().toTilePosition(), CheckMode.NO_CHECK);
        // bwem_assert(currentTile.InternalData() == currentDist);
        if (!(((TileImpl) currentTile).getInternalData() == currentDist)) {
            throw new IllegalStateException();
        }
        // resets Tile::m_internalData for future usage
        ((TileImpl) currentTile).setInternalData(0);
        ((TileImpl) currentTile).getMarkable().setMarked();
        for (int i = 0; i < targets.size(); ++i) {
            if (current == targets.get(i)) {
                distances[i] = currentDist;
                --remainingTargets;
            }
        }
        if (remainingTargets == 0) {
            break;
        }
        if (current.isBlocked() && (!current.equals(start))) {
            continue;
        }
        for (final Area pArea : new Area[] { current.getAreas().getFirst(), current.getAreas().getSecond() }) {
            for (final ChokePoint next : pArea.getChokePoints()) {
                if (!next.equals(current)) {
                    final int newNextDist = currentDist + distance(current, next);
                    final Tile nextTile = getMap().getData().getTile(next.getCenter().toTilePosition(), CheckMode.NO_CHECK);
                    if (!((TileImpl) nextTile).getMarkable().isMarked()) {
                        if (((TileImpl) nextTile).getInternalData() != 0) {
                            // next already in toVisit
                            if (newNextDist < ((TileImpl) nextTile).getInternalData()) {
                                // nextNewDist < nextOldDist
                                // To update next's distance, we need to remove-insert it from toVisit:
                                // bwem_assert(iNext != range.second);
                                final boolean removed = toVisit.remove(new Pair<>(((TileImpl) nextTile).getInternalData(), next));
                                if (!removed) {
                                    throw new IllegalStateException();
                                }
                                ((TileImpl) nextTile).setInternalData(newNextDist);
                                ((ChokePointImpl) next).setPathBackTrace(current);
                                toVisit.offer(new Pair<>(newNextDist, next));
                            }
                        } else {
                            ((TileImpl) nextTile).setInternalData(newNextDist);
                            ((ChokePointImpl) next).setPathBackTrace(current);
                            toVisit.offer(new Pair<>(newNextDist, next));
                        }
                    }
                }
            }
        }
    }
    // reset Tile::m_internalData for future usage
    for (Pair<Integer, ChokePoint> distanceToChokePoint : toVisit) {
        ((TileImpl) getMap().getData().getTile(distanceToChokePoint.second.getCenter().toTilePosition(), CheckMode.NO_CHECK)).setInternalData(0);
    }
    return distances;
}
Also used : Utils(bwem.util.Utils) Altitude(bwem.typedef.Altitude) MutableInt(org.apache.commons.lang3.mutable.MutableInt) PriorityQueue(java.util.PriorityQueue) Map(bwem.map.Map) HashMap(java.util.HashMap) TilePosition(org.openbw.bwapi4j.TilePosition) Pair(org.openbw.bwapi4j.util.Pair) ArrayList(java.util.ArrayList) Area(bwem.area.Area) MutablePair(org.apache.commons.lang3.tuple.MutablePair) GroupId(bwem.area.typedef.GroupId) AreaId(bwem.area.typedef.AreaId) CPPath(bwem.typedef.CPPath) Index(bwem.typedef.Index) AdvancedData(bwem.map.AdvancedData) StaticBuilding(bwem.unit.StaticBuilding) Position(org.openbw.bwapi4j.Position) Tile(bwem.tile.Tile) Neutral(bwem.unit.Neutral) AreaInitializer(bwem.area.AreaInitializer) WalkPosition(org.openbw.bwapi4j.WalkPosition) Mineral(bwem.unit.Mineral) TileImpl(bwem.tile.TileImpl) List(java.util.List) Geyser(bwem.unit.Geyser) AreaInitializerImpl(bwem.area.AreaInitializerImpl) BwemExt(bwem.util.BwemExt) Queue(java.util.Queue) Comparator(java.util.Comparator) MiniTile(bwem.tile.MiniTile) TileImpl(bwem.tile.TileImpl) Tile(bwem.tile.Tile) MiniTile(bwem.tile.MiniTile) PriorityQueue(java.util.PriorityQueue) Area(bwem.area.Area) Pair(org.openbw.bwapi4j.util.Pair) MutablePair(org.apache.commons.lang3.tuple.MutablePair)

Aggregations

TilePosition (org.openbw.bwapi4j.TilePosition)4 Pair (org.openbw.bwapi4j.util.Pair)4 MiniTile (bwem.tile.MiniTile)3 Tile (bwem.tile.Tile)3 TileImpl (bwem.tile.TileImpl)3 PriorityQueue (java.util.PriorityQueue)3 Area (bwem.area.Area)2 AreaInitializer (bwem.area.AreaInitializer)2 AreaInitializerImpl (bwem.area.AreaInitializerImpl)2 AreaId (bwem.area.typedef.AreaId)2 GroupId (bwem.area.typedef.GroupId)2 AdvancedData (bwem.map.AdvancedData)2 Map (bwem.map.Map)2 Altitude (bwem.typedef.Altitude)2 CPPath (bwem.typedef.CPPath)2 Index (bwem.typedef.Index)2 Geyser (bwem.unit.Geyser)2 Mineral (bwem.unit.Mineral)2 Neutral (bwem.unit.Neutral)2 StaticBuilding (bwem.unit.StaticBuilding)2