use of org.openbw.bwapi4j.TilePosition 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;
}
use of org.openbw.bwapi4j.TilePosition in project BWAPI4J by OpenBW.
the class AreaInitializerImpl method validateBaseLocation.
@Override
public boolean validateBaseLocation(final AdvancedData mapAdvancedData, final TilePosition location, final List<Mineral> blockingMinerals) {
final TilePosition dimCC = UnitType.Terran_Command_Center.tileSize();
blockingMinerals.clear();
for (int dy = -3; dy < dimCC.getY() + 3; ++dy) for (int dx = -3; dx < dimCC.getX() + 3; ++dx) {
final TilePosition deltaLocation = location.add(new TilePosition(dx, dy));
if (mapAdvancedData.getMapData().isValid(deltaLocation)) {
final Tile deltaTile = mapAdvancedData.getTile(deltaLocation, CheckMode.NO_CHECK);
final Neutral deltaTileNeutral = deltaTile.getNeutral();
if (deltaTileNeutral != null) {
if (deltaTileNeutral instanceof Geyser) {
return false;
} else if (deltaTileNeutral instanceof Mineral) {
final Mineral deltaTileMineral = (Mineral) deltaTileNeutral;
if (deltaTileMineral.getInitialAmount() <= 8) {
blockingMinerals.add(deltaTileMineral);
} else {
return false;
}
}
}
}
}
// checks the distance to the bases already created:
for (final Base base : getBases()) {
if (BwemExt.roundedDist(base.getLocation(), location) < BwemExt.min_tiles_between_Bases) {
return false;
}
}
return true;
}
use of org.openbw.bwapi4j.TilePosition 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));
}
}
use of org.openbw.bwapi4j.TilePosition 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;
}
use of org.openbw.bwapi4j.TilePosition in project Ecgberht by Jabbo16.
the class AreaInitializer method computeDistances.
private int[] computeDistances(final TilePosition start, final List<TilePosition> targets) {
final int[] distances = new int[targets.size()];
Tile.getStaticMarkable().unmarkAll();
final Queue<Pair<Integer, TilePosition>> toVisit = new PriorityQueue<>(Comparator.comparingInt(// a priority queue holding the tiles to visit ordered by their
Pair::getLeft));
// distance to start.
toVisit.offer(new Pair<>(0, start));
int remainingTargets = targets.size();
while (!toVisit.isEmpty()) {
final Pair<Integer, TilePosition> distanceAndTilePosition = toVisit.poll();
final int currentDist = distanceAndTilePosition.getLeft();
final TilePosition current = distanceAndTilePosition.getRight();
final Tile currentTile = this.map.getData().getTile(current, CheckMode.NO_CHECK);
if (!(currentTile.getInternalData() == currentDist)) {
map.asserter.throwIllegalStateException("currentTile.InternalData().intValue()=" + currentTile.getInternalData() + ", currentDist=" + currentDist);
}
currentTile.setInternalData(// resets Tile::m_internalData for future usage
0);
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 (this.map.getData().getMapData().isValid(next)) {
final Tile nextTile = this.map.getData().getTile(next, CheckMode.NO_CHECK);
if (nextTile.getMarkable().isUnmarked()) {
if (nextTile.getInternalData() != 0) {
// next already in toVisit
if (newNextDist < nextTile.getInternalData()) {
// nextNewDist < nextOldDist
// To update next's distance, we need to remove-insert it from toVisit:
final boolean removed = toVisit.remove(new Pair<>(nextTile.getInternalData(), next));
if (!removed) {
map.asserter.throwIllegalStateException("");
}
nextTile.setInternalData(newNextDist);
toVisit.offer(new Pair<>(newNextDist, next));
}
} else if ((nextTile.getAreaId().equals(getId())) || (nextTile.getAreaId().equals(UNINITIALIZED))) {
nextTile.setInternalData(newNextDist);
toVisit.offer(new Pair<>(newNextDist, next));
}
}
}
}
}
if (!(remainingTargets == 0)) {
map.asserter.throwIllegalStateException("");
}
for (final Pair<Integer, TilePosition> distanceAndTilePosition : toVisit) {
final Tile tileToUpdate = this.map.getData().getTile(distanceAndTilePosition.getRight(), CheckMode.NO_CHECK);
tileToUpdate.setInternalData(0);
}
return distances;
}
Aggregations