use of org.openbw.bwapi4j.WalkPosition in project Ecgberht by Jabbo16.
the class BWMapInitializer method setLowestAltitudeInTile.
// Renamed from "BWMap::SetAltitudeInTile"
private void setLowestAltitudeInTile(final TilePosition t) {
Altitude lowestAltitude = new Altitude(Integer.MAX_VALUE);
for (int dy = 0; dy < 4; ++dy) {
for (int dx = 0; dx < 4; ++dx) {
final Altitude altitude = getData().getMiniTile(((t.toPosition()).toWalkPosition()).add(new WalkPosition(dx, dy)), bwem.util.CheckMode.NO_CHECK).getAltitude();
if (altitude.intValue() < lowestAltitude.intValue()) {
lowestAltitude = altitude;
}
}
}
getData().getTile(t).setLowestAltitude(lowestAltitude);
}
use of org.openbw.bwapi4j.WalkPosition in project Ecgberht by Jabbo16.
the class BWMapInitializer method getDoors.
// ----------------------------------------------------------------------
/**
* 2) Find the doors in border: one door for each connected set of walkable, neighboring
* miniTiles. The searched connected miniTiles all have to be next to some lake or some static
* building, though they can't be part of one.
*/
private List<WalkPosition> getDoors(final List<WalkPosition> border) {
final List<WalkPosition> doors = new ArrayList<>();
while (!border.isEmpty()) {
final WalkPosition door = border.remove(border.size() - 1);
doors.add(door);
final List<WalkPosition> toVisit = new ArrayList<>();
toVisit.add(door);
final List<WalkPosition> visited = new ArrayList<>();
visited.add(door);
while (!toVisit.isEmpty()) {
final WalkPosition current = toVisit.remove(toVisit.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) && !visited.contains(next)) {
if (getData().getMiniTile(next, bwem.util.CheckMode.NO_CHECK).isWalkable()) {
if (getData().getTile((next.toPosition()).toTilePosition(), bwem.util.CheckMode.NO_CHECK).getNeutral() == null) {
if (BwemExt.adjoins8SomeLakeOrNeutral(next, this)) {
toVisit.add(next);
visited.add(next);
}
}
}
}
}
}
border.removeIf(visited::contains);
}
return doors;
}
use of org.openbw.bwapi4j.WalkPosition in project Ecgberht by Jabbo16.
the class BWMapInitializer method getTrueDoors.
/**
* 3) If at least 2 doors, find the true doors in Border: a true door is a door that gives onto an
* area big enough
*/
private List<WalkPosition> getTrueDoors(final List<WalkPosition> doors, final Neutral pCandidate) {
final List<WalkPosition> trueDoors = new ArrayList<>();
if (doors.size() >= 2) {
for (final WalkPosition door : doors) {
final List<WalkPosition> toVisit = new ArrayList<>();
toVisit.add(door);
final List<WalkPosition> visited = new ArrayList<>();
visited.add(door);
final int limit = // TODO: Description for 10 and 400?
(pCandidate instanceof StaticBuilding) ? 10 : 400;
while (!toVisit.isEmpty() && (visited.size() < limit)) {
final WalkPosition current = toVisit.remove(toVisit.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) && !visited.contains(next)) {
if (getData().getMiniTile(next, bwem.util.CheckMode.NO_CHECK).isWalkable()) {
if (getData().getTile(next.toTilePosition(), bwem.util.CheckMode.NO_CHECK).getNeutral() == null) {
toVisit.add(next);
visited.add(next);
}
}
}
}
}
if (visited.size() >= limit) {
trueDoors.add(door);
}
}
}
return trueDoors;
}
use of org.openbw.bwapi4j.WalkPosition 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));
}
}
}
Aggregations