@Override public CoordinateStream stream() { return base.stream().filterBounds(width, height); } }
public CoordinateStream getAreaWithoutGround() { return area.stream().filter((x, y) -> !groundArea.contains(x, y)); } }
/** * Removes the tower at the given position from the grid. * * @param pos * The position of the tower. */ public void removeTowerAndFreeOccupiedArea(ShortPoint2D pos) { // get the tower object and the informations of it. PartitionOccupyingTower tower = occupyingTowers.removeAt(pos); if (tower == null) { return ; } // reduce the tower counter changeTowerCounter(tower.playerId, tower.area.stream(), -1); checkOtherTowersInArea(tower); }
/** * Recalculates the tower counter for the given area. <br> * NOTE: The given area must completely belong to the given player! * * @param tower * @param tower * @param area */ private void recalculateTowerCounter(PartitionOccupyingTower tower, IMapArea area) { area.stream().forEach((x, y) -> towers[x + y * width] = 0); List<Tuple<Integer, PartitionOccupyingTower>> towersInRange = occupyingTowers.getTowersInRange(tower.position, tower.radius, currTower -> currTower.playerId == tower.playerId); stream(towersInRange) .forEach(currTower -> area.stream() .filter(currTower.e2.area::contains) .forEach((x, y) -> towers[x + y * width]++)); }
private void occupyAreaOfTower(PartitionOccupyingTower tower) { // set the tower counter of the groundArea to 0 => the ground area will be occupied tower.groundArea.stream().forEach((x, y) -> towers[x + y * width] = 0); // occupy the area for the new player occupyAreaByTower(tower.playerId, tower.area.stream(), tower.areaBorders); occupyingTowers.add(tower); // recalculate the tower counter for the ground area recalculateTowerCounter(tower, tower.groundArea); }
/** * Changes the player of the tower at given position to the new player. After this operation, the given ground area will always be occupied by the new player. * * @param towerPosition * @param newPlayerId * @return */ public CoordinateStream changePlayerOfTower(ShortPoint2D towerPosition, byte newPlayerId) { // get the tower object and the information of it. PartitionOccupyingTower tower = occupyingTowers.removeAt(towerPosition); if (tower == null) { return CoordinateStream.EMPTY; // return if no tower has been found } // reduce the tower counter changeTowerCounter(tower.playerId, tower.getAreaWithoutGround(), -1); // let the other towers occupy the area checkOtherTowersInArea(tower); PartitionOccupyingTower newTower = new PartitionOccupyingTower(newPlayerId, tower); occupyAreaOfTower(newTower); return newTower.area.stream(); }
/** * Removes all construction marks in the given area. * * @param area * The area to remove the marks * @param notIn * The area of marks that should be skipped. */ private void removeConstructionMarks(IMapArea area, IMapArea notIn) { area.stream() .filterBounds(map.getWidth(), map.getHeight()) .filter((x, y) -> !notIn.contains(x, y)) .forEach((x, y) -> map.setConstructMarking(x, y, false, false, null)); } }
private void selectArea(SelectAreaAction action) { final SelectionSet selectionSet = new SelectionSet(); action.getArea().stream().filterBounds(grid.getWidth(), grid.getHeight()).forEach((x, y) -> { final IGuiMovable movable = grid.getMovable(x, y); if (movable != null && canSelectPlayer(movable.getPlayer().getPlayerId())) { selectionSet.add(movable); } final IBuilding building = grid.getBuildingAt(x, y); if (building != null && canSelectPlayer(building.getPlayer().getPlayerId())) { selectionSet.add(building); } }); setSelection(selectionSet); }
/** * Checks if other towers that intersect the area of the given tower can occupy free positions of the area of the given tower and lets them do so. * * @param tower */ private void checkOtherTowersInArea(PartitionOccupyingTower tower) { // Get the positions that may change their owner (tower counter <= 0) // Save these positions in the list because the list must not change during the loop over the other towers CoordinateStream freedPositions = tower.area.stream().filter((x, y) -> towers[x + y * width] <= 0).freeze(); // if at least one position may change the player // check if other towers occupy the area if (!freedPositions.isEmpty()) { List<Tuple<Integer, PartitionOccupyingTower>> towersInRange = occupyingTowers.getTowersInRange(tower.position, tower.radius, currTower -> currTower.playerId != tower.playerId); // sort the towers by their distance to the removed tower Lists.sort(towersInRange, Tuple.getE1Comparator()); for (Tuple<Integer, PartitionOccupyingTower> curr : towersInRange) { final PartitionOccupyingTower currTower = curr.e2; final IMapArea currArea = currTower.area; CoordinateStream area = freedPositions.filter(currArea::contains); occupyAreaByTower(currTower.playerId, area, currTower.areaBorders); PartitionsListingBorderVisitor borderVisitor = new PartitionsListingBorderVisitor(this, blockingProvider); final FreeMapArea groundArea = currTower.groundArea; ShortPoint2D upperLeftGroundAreaPosition = groundArea.getUpperLeftPosition(); BorderTraversingAlgorithm.traverseBorder(groundArea::contains, upperLeftGroundAreaPosition, borderVisitor, true); checkMergesAndDividesOnPartitionsList(currTower.playerId, getPartitionIdAt(upperLeftGroundAreaPosition.x, upperLeftGroundAreaPosition.y), borderVisitor.getPartitionsList()); } } }