Search in sources :

Example 1 with Pair

use of bwem.util.Pair in project Ecgberht by Jabbo16.

the class BWMapInitializer method getSortedMiniTilesByDescendingAltitude.

private List<Pair<WalkPosition, MiniTile>> getSortedMiniTilesByDescendingAltitude() {
    final List<Pair<WalkPosition, MiniTile>> miniTilesByDescendingAltitude = new ArrayList<>();
    for (int y = 0; y < getData().getMapData().getWalkSize().getY(); ++y) {
        for (int x = 0; x < getData().getMapData().getWalkSize().getX(); ++x) {
            final WalkPosition w = new WalkPosition(x, y);
            final MiniTile miniTile = getData().getMiniTile(w, bwem.util.CheckMode.NO_CHECK);
            if (miniTile.isAreaIdMissing()) {
                miniTilesByDescendingAltitude.add(new Pair<>(w, miniTile));
            }
        }
    }
    miniTilesByDescendingAltitude.sort(MiniTile.BY_ALTITUDE_ORDER);
    Collections.reverse(miniTilesByDescendingAltitude);
    return miniTilesByDescendingAltitude;
}
Also used : ArrayList(java.util.ArrayList) WalkPosition(org.openbw.bwapi4j.WalkPosition) Pair(bwem.util.Pair)

Example 2 with Pair

use of bwem.util.Pair in project Ecgberht by Jabbo16.

the class BWMapInitializer method computeTempAreas.

private List<TempAreaInfo> computeTempAreas(final List<Pair<WalkPosition, MiniTile>> miniTilesByDescendingAltitude) {
    final List<TempAreaInfo> tempAreaList = new ArrayList<>();
    // tempAreaList[0] left unused, as AreaIds are > 0
    tempAreaList.add(new TempAreaInfo(asserter));
    for (final Pair<WalkPosition, MiniTile> current : miniTilesByDescendingAltitude) {
        final WalkPosition pos = new WalkPosition(current.getLeft().getX(), current.getLeft().getY());
        final MiniTile cur = current.getRight();
        final Pair<AreaId, AreaId> neighboringAreas = findNeighboringAreas(pos);
        if (neighboringAreas.getLeft() == null) {
            // no neighboring area : creates of a new area
            tempAreaList.add(new TempAreaInfo(new AreaId(tempAreaList.size()), cur, pos, asserter));
        } else if (neighboringAreas.getRight() == null) {
            // one neighboring area : adds cur to the existing area
            tempAreaList.get(neighboringAreas.getLeft().intValue()).add(cur);
        } else {
            // two neighboring areas : adds cur to one of them  &  possible merging
            AreaId smaller = neighboringAreas.getLeft();
            AreaId bigger = neighboringAreas.getRight();
            if (tempAreaList.get(smaller.intValue()).getSize() > tempAreaList.get(bigger.intValue()).getSize()) {
                AreaId smallerTmp = smaller;
                smaller = bigger;
                bigger = smallerTmp;
            }
            // Condition for the neighboring areas to merge:
            // any_of(StartingLocations().begin(), StartingLocations().end(),
            // [&pos](const TilePosition & startingLoc)
            // { return dist(TilePosition(pos), startingLoc + TilePosition(2, 1)) <=
            // 3;})
            boolean cppAlgorithmStdAnyOf = getData().getMapData().getStartingLocations().stream().anyMatch(startingLoc -> BwemExt.dist(pos.toTilePosition(), startingLoc.add(new TilePosition(2, 1))) <= 3.0);
            final int curAltitude = cur.getAltitude().intValue();
            final int biggerHighestAltitude = tempAreaList.get(bigger.intValue()).getHighestAltitude().intValue();
            final int smallerHighestAltitude = tempAreaList.get(smaller.intValue()).getHighestAltitude().intValue();
            if ((tempAreaList.get(smaller.intValue()).getSize() < 80) || (smallerHighestAltitude < 80) || ((double) curAltitude / (double) biggerHighestAltitude >= 0.90) || ((double) curAltitude / (double) smallerHighestAltitude >= 0.90) || cppAlgorithmStdAnyOf) {
                // adds cur to the absorbing area:
                tempAreaList.get(bigger.intValue()).add(cur);
                // merges the two neighboring areas:
                replaceAreaIds(tempAreaList.get(smaller.intValue()).getWalkPositionWithHighestAltitude(), bigger);
                tempAreaList.get(bigger.intValue()).merge(tempAreaList.get(smaller.intValue()));
            } else {
                // no merge : cur starts or continues the frontier between the two neighboring
                // areas
                // adds cur to the chosen Area:
                tempAreaList.get(chooseNeighboringArea(smaller, bigger).intValue()).add(cur);
                super.rawFrontier.add(new Pair<>(neighboringAreas, pos));
            }
        }
    }
    // Remove from the frontier obsolete positions
    rawFrontier.removeIf(f -> f.getLeft().getLeft().equals(f.getLeft().getRight()));
    return tempAreaList;
}
Also used : Utils(bwem.util.Utils) List(java.util.List) Unit(org.openbw.bwapi4j.unit.Unit) WalkPosition(org.openbw.bwapi4j.WalkPosition) BW(org.openbw.bwapi4j.BW) BwemExt(bwem.util.BwemExt) Pair(bwem.util.Pair) TilePosition(org.openbw.bwapi4j.TilePosition) Collections(java.util.Collections) ArrayList(java.util.ArrayList) TilePosition(org.openbw.bwapi4j.TilePosition) ArrayList(java.util.ArrayList) WalkPosition(org.openbw.bwapi4j.WalkPosition) Pair(bwem.util.Pair)

Example 3 with Pair

use of bwem.util.Pair in project Ecgberht by Jabbo16.

the class BWMapInitializer method replaceAreaIds.

private void replaceAreaIds(final WalkPosition p, final AreaId newAreaId) {
    final MiniTile origin = getData().getMiniTile(p, bwem.util.CheckMode.NO_CHECK);
    final AreaId oldAreaId = origin.getAreaId();
    origin.replaceAreaId(newAreaId);
    List<WalkPosition> toSearch = new ArrayList<>();
    toSearch.add(p);
    while (!toSearch.isEmpty()) {
        final WalkPosition current = toSearch.remove(toSearch.size() - 1);
        final WalkPosition[] deltas = { new WalkPosition(0, -1), new WalkPosition(-1, 0), new WalkPosition(+1, 0), new WalkPosition(0, +1) };
        for (final WalkPosition delta : deltas) {
            final WalkPosition next = current.add(delta);
            if (getData().getMapData().isValid(next)) {
                final MiniTile miniTile = getData().getMiniTile(next, bwem.util.CheckMode.NO_CHECK);
                if (miniTile.getAreaId().equals(oldAreaId)) {
                    toSearch.add(next);
                    miniTile.replaceAreaId(newAreaId);
                }
            }
        }
    }
    // also replaces references of oldAreaId by newAreaId in getRawFrontier:
    if (newAreaId.intValue() > 0) {
        for (final Pair<Pair<AreaId, AreaId>, WalkPosition> f : super.rawFrontier) {
            if (f.getLeft().getLeft().equals(oldAreaId)) {
                f.getLeft().setLeft(newAreaId);
            }
            if (f.getLeft().getRight().equals(oldAreaId)) {
                f.getLeft().setRight(newAreaId);
            }
        }
    }
}
Also used : WalkPosition(org.openbw.bwapi4j.WalkPosition) ArrayList(java.util.ArrayList) Pair(bwem.util.Pair)

Example 4 with Pair

use of bwem.util.Pair in project Ecgberht by Jabbo16.

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<Pair<Pair<AreaId, AreaId>, WalkPosition>> rawFrontier) {
    int newIndex = 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();
    // 2) Dispatch the global raw frontier between all the relevant pairs of areas:
    final Map<Pair<AreaId, AreaId>, List<WalkPosition>> rawFrontierByAreaPair = createRawFrontierByAreaPairMap(rawFrontier);
    // 3) For each pair of areas (A, B):
    for (final Map.Entry<Pair<AreaId, AreaId>, List<WalkPosition>> entry : rawFrontierByAreaPair.entrySet()) {
        Pair<AreaId, AreaId> rawleft = entry.getKey();
        final List<WalkPosition> rawFrontierAB = entry.getValue();
        // Because our dispatching preserved order,
        // and because BWMap::m_RawFrontier was populated in descending order of the altitude (see
        // BWMap::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());
            }
            // Check if the altitudes array is sorted in descending order.
            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) {
                    map.asserter.throwIllegalStateException("");
                }
            }
        }
        // 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_MINI_TILES);
        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();
        for (final List<WalkPosition> cluster : clusters) {
            getChokePoints(a, b).add(new ChokePoint(this, newIndex, getArea(a), getArea(b), cluster));
            newIndex++;
        }
    }
    // 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
                (MiniTile miniTile, WalkPosition unused) -> miniTile.isWalkable(), // visitCond
                Pred.accept());
                final List<WalkPosition> list = new ArrayList<>();
                list.add(center);
                getChokePoints(blockedAreaA, blockedAreaB).add(new ChokePoint(this, newIndex, blockedAreaA, blockedAreaB, list, blockingNeutral));
                newIndex++;
            }
        }
    }
    // 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 : WalkPosition(org.openbw.bwapi4j.WalkPosition) Pair(bwem.util.Pair)

Aggregations

Pair (bwem.util.Pair)4 WalkPosition (org.openbw.bwapi4j.WalkPosition)4 ArrayList (java.util.ArrayList)3 BwemExt (bwem.util.BwemExt)1 Utils (bwem.util.Utils)1 Collections (java.util.Collections)1 List (java.util.List)1 BW (org.openbw.bwapi4j.BW)1 TilePosition (org.openbw.bwapi4j.TilePosition)1 Unit (org.openbw.bwapi4j.unit.Unit)1