use of bwem.unit.Mineral in project BWAPI4J by OpenBW.
the class TestListenerBwem method onFrame.
@Override
public void onFrame() {
try {
// Send idle workers to mine at the closest mineral patch.
for (final Worker worker : workers) {
if (worker.isIdle()) {
MineralPatch closestMineralPatch = null;
for (final MineralPatch mineralPatch : bw.getMineralPatches()) {
if (closestMineralPatch == null) {
closestMineralPatch = mineralPatch;
} else {
if (mineralPatch.getPosition().getDistance(self.getStartLocation().toPosition()) < closestMineralPatch.getPosition().getDistance(self.getStartLocation().toPosition())) {
closestMineralPatch = mineralPatch;
}
}
}
worker.gather(closestMineralPatch);
}
}
/* Train an SCV at every Command Center. */
{
if (self.getRace() == Race.Terran) {
for (final PlayerUnit u : bw.getUnits(self)) {
if (u instanceof CommandCenter) {
final CommandCenter commandCenter = (CommandCenter) u;
if (!commandCenter.isTraining()) {
commandCenter.trainWorker();
}
}
}
}
}
/* Highlight starting locations and possible base locations. */
{
for (final Base base : bwem.getMap().getBases()) {
final boolean isStartingLocation = base.isStartingLocation();
final Color highlightColor = isStartingLocation ? Color.GREEN : Color.YELLOW;
final Position baseLocation = base.getLocation().toPosition();
final Position resourceDepotSize = UnitType.Terran_Command_Center.tileSize().toPosition();
if (isOnScreen(baseLocation)) {
bw.getMapDrawer().drawBoxMap(baseLocation, baseLocation.add(resourceDepotSize), highlightColor);
}
/* Display minerals. */
for (final Mineral mineral : base.getMinerals()) {
if (isOnScreen(mineral.getCenter())) {
bw.getMapDrawer().drawLineMap(mineral.getCenter(), base.getCenter(), Color.CYAN);
}
}
/* Display geysers. */
for (final Geyser geyser : base.getGeysers()) {
if (isOnScreen(geyser.getCenter())) {
bw.getMapDrawer().drawLineMap(geyser.getCenter(), base.getCenter(), Color.GREEN);
}
}
}
}
/* Highlight choke points. */
{
final int chokePointRadius = 8;
final Color chokePointColor = Color.RED;
for (final ChokePoint chokePoint : bwem.getMap().getChokePoints()) {
final Position center = chokePoint.getCenter().toPosition();
if (isOnScreen(center)) {
bw.getMapDrawer().drawCircleMap(center, chokePointRadius, chokePointColor);
bw.getMapDrawer().drawLineMap(center.getX() - chokePointRadius, center.getY(), center.getX() + chokePointRadius, center.getY(), chokePointColor);
bw.getMapDrawer().drawLineMap(center.getX(), center.getY() - chokePointRadius, center.getX(), center.getY() + chokePointRadius, chokePointColor);
}
}
}
/* Highlight workers. */
{
for (final Worker worker : workers) {
final Position tileSize = new TilePosition(worker.tileWidth(), worker.tileHeight()).toPosition();
final Position topLeft = worker.getPosition().subtract(tileSize.divide(new Position(2, 2)));
final Position bottomRight = topLeft.add(tileSize);
if (isOnScreen(topLeft)) {
bw.getMapDrawer().drawBoxMap(topLeft, bottomRight, Color.BROWN);
}
}
}
/* Draw mouse position debug info. */
{
final Position screenPosition = bw.getInteractionHandler().getScreenPosition();
final Position mousePosition = screenPosition.add(bw.getInteractionHandler().getMousePosition());
final String mouseText = "T:" + mousePosition.toTilePosition().toString() + "\nW:" + mousePosition.toWalkPosition().toString() + "\nP:" + mousePosition.toString();
bw.getMapDrawer().drawBoxMap(mousePosition.toTilePosition().toPosition(), mousePosition.toTilePosition().toPosition().add(new TilePosition(1, 1).toPosition()), Color.WHITE);
bw.getMapDrawer().drawTextMap(mousePosition.add(new Position(20, -10)), mouseText);
}
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
use of bwem.unit.Mineral 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));
}
}
}
use of bwem.unit.Mineral 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 bwem.unit.Mineral 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 bwem.unit.Mineral in project BWAPI4J by OpenBW.
the class MapImpl method onMineralDestroyed.
@Override
public void onMineralDestroyed(Unit u) {
for (int i = 0; i < getNeutralData().getMinerals().size(); ++i) {
Mineral mineral = getNeutralData().getMinerals().get(i);
if (mineral.getUnit().equals(u)) {
onMineralDestroyed(mineral);
mineral.simulateCPPObjectDestructor();
/* IMPORTANT! These actions are performed in the "~Neutral" dtor in BWEM 1.4.1 C++. */
getNeutralData().getMinerals().remove(i);
return;
}
}
// bwem_assert(iMineral != minerals.end());
throw new IllegalArgumentException("unit is not a Mineral");
}
Aggregations