use of bwem.area.Area in project BWAPI4J by OpenBW.
the class Graph method computeChokePointDistanceMatrix.
// ----------------------------------------------------------------------
// Computes the ground distances between any pair of ChokePoints in pContext
// This is achieved by invoking several times pContext->ComputeDistances,
// which effectively computes the distances from one starting ChokePoint, using Dijkstra's algorithm.
// If Context == Area, Dijkstra's algorithm works on the Tiles inside one Area.
// If Context == Graph, Dijkstra's algorithm works on the GetChokePoints between the AreaS.
public void computeChokePointDistanceMatrix() {
// 1) size the matrix
chokePointDistanceMatrix.clear();
// m_ChokePointDistanceMatrix.resize (chokePoints.size());
for (int i = 0; i < chokePoints.size(); ++i) {
chokePointDistanceMatrix.add(new ArrayList<>());
}
// line.resize (chokePoints.size(), -1);
for (int i = 0; i < chokePointDistanceMatrix.size(); ++i) {
for (int n = 0; n < chokePoints.size(); ++n) {
chokePointDistanceMatrix.get(i).add(-1);
}
}
// m_PathsBetweenChokePoints.resize (chokePoints.size());
pathsBetweenChokePoints.clear();
for (int i = 0; i < chokePoints.size(); ++i) {
pathsBetweenChokePoints.add(new ArrayList<>());
}
// line.resize (chokePoints.size());
for (int i = 0; i < pathsBetweenChokePoints.size(); ++i) {
for (int n = 0; n < chokePoints.size(); ++n) {
pathsBetweenChokePoints.get(i).add(new CPPath());
}
}
// 2) Compute distances inside each Area
for (final Area area : getAreas()) {
computeChokePointDistances(area);
}
// 3) Compute distances through connected areas
computeChokePointDistances(this);
for (final ChokePoint cp : getChokePoints()) {
setDistance(cp, cp, 0);
CPPath cppath = new CPPath();
cppath.add(cp);
setPath(cp, cp, cppath);
}
// 4) Update Area::m_AccessibleNeighbors for each Area
for (final Area area : getAreas()) ((AreaInitializer) area).updateAccessibleNeighbors();
// 5) Update Area::m_groupId for each Area
updateGroupIds();
}
use of bwem.area.Area in project BWAPI4J by OpenBW.
the class Graph method getPath.
public CPPath getPath(final Position a, final Position b, final MutableInt pLength) {
final Area areaA = getNearestArea(a.toWalkPosition());
final Area areaB = getNearestArea(b.toWalkPosition());
if (areaA.equals(areaB)) {
if (pLength != null) {
pLength.setValue(BwemExt.getApproxDistance(a, b));
}
return new CPPath();
}
if (!areaA.isAccessibleFrom(areaB)) {
if (pLength != null) {
pLength.setValue(-1);
}
return new CPPath();
}
int minDistAB = Integer.MAX_VALUE;
ChokePoint pBestCpA = null;
ChokePoint pBestCpB = null;
for (final ChokePoint cpA : areaA.getChokePoints()) {
if (!cpA.isBlocked()) {
final int distACpA = BwemExt.getApproxDistance(a, cpA.getCenter().toPosition());
for (final ChokePoint cpB : areaB.getChokePoints()) {
if (!cpB.isBlocked()) {
final int distBToCPB = BwemExt.getApproxDistance(b, cpB.getCenter().toPosition());
final int distAToB = distACpA + distBToCPB + distance(cpA, cpB);
if (distAToB < minDistAB) {
minDistAB = distAToB;
pBestCpA = cpA;
pBestCpB = cpB;
}
}
}
}
}
// bwem_assert(minDistAB != numeric_limits<int>::max());
if (minDistAB == Integer.MAX_VALUE) {
throw new IllegalStateException();
}
final CPPath path = getPath(pBestCpA, pBestCpB);
if (pLength != null) {
// bwem_assert(Path.size() >= 1);
if (!(path.size() >= 1)) {
throw new IllegalStateException();
}
pLength.setValue(minDistAB);
if (path.size() == 1) {
// bwem_assert(pBestCpA == pBestCpB);
if (!pBestCpA.equals(pBestCpB)) {
throw new IllegalStateException();
}
final Position cpEnd1 = BwemExt.center(pBestCpA.getNodePosition(ChokePoint.Node.END1));
final Position cpEnd2 = BwemExt.center(pBestCpA.getNodePosition(ChokePoint.Node.END2));
if (Utils.intersect(a.getX(), a.getY(), b.getX(), b.getY(), cpEnd1.getX(), cpEnd1.getY(), cpEnd2.getX(), cpEnd2.getY())) {
pLength.setValue(BwemExt.getApproxDistance(a, b));
} else {
for (final ChokePoint.Node node : new ChokePoint.Node[] { ChokePoint.Node.END1, ChokePoint.Node.END2 }) {
final Position c = BwemExt.center(pBestCpA.getNodePosition(node));
final int distAToB = BwemExt.getApproxDistance(a, c) + BwemExt.getApproxDistance(b, c);
if (distAToB < pLength.intValue()) {
pLength.setValue(distAToB);
}
}
}
}
}
return getPath(pBestCpA, pBestCpB);
}
use of bwem.area.Area 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;
}
use of bwem.area.Area in project BWAPI4J by OpenBW.
the class Graph method updateGroupIds.
private void updateGroupIds() {
int nextGroupId = 1;
AreaInitializerImpl.getStaticMarkable().unmarkAll();
for (final Area start : getAreas()) {
if (!((AreaInitializer) start).getMarkable().isMarked()) {
final List<Area> toVisit = new ArrayList<>();
toVisit.add(start);
while (!toVisit.isEmpty()) {
final Area current = toVisit.remove(toVisit.size() - 1);
((AreaInitializer) current).setGroupId(new GroupId(nextGroupId));
for (final Area next : current.getAccessibleNeighbors()) {
if (!((AreaInitializer) next).getMarkable().isMarked()) {
((AreaInitializer) next).getMarkable().setMarked();
toVisit.add(next);
}
}
}
++nextGroupId;
}
}
}
use of bwem.area.Area in project BWAPI4J by OpenBW.
the class Graph method createBases.
public void createBases(final AdvancedData mapAdvancedData) {
this.bases.clear();
for (final Area area : this.areas) {
((AreaInitializer) area).createBases(mapAdvancedData);
this.bases.addAll(area.getBases());
}
}
Aggregations