public Feature getFeaturePartOf(Location loc) { for (Feature p : features) { if (loc.isPartOf(p.getLocation())) { return p; } } return null; }
private void undeployed(MeepleEvent ev) { if (ev.getFrom() == null) return; Feature f = getBoard().get(ev.getFrom()); if (f instanceof Castle) { Castle castle = (Castle) f.getMaster(); scoreableCastleVicinity.remove(castle); emptyCastles.add(castle); } }
public Set<Location> getPlayerFeatures(Player player, Class<? extends Feature> featureClass) { Set<Location> locations = new HashSet<>(); for (Feature f : features) { if (!featureClass.isInstance(f)) continue; if (f.walk(new IsOccupied().with(player).with(Follower.class))) { locations.add(f.getLocation()); } } return locations; }
private MeeplePositionedImage createMeepleImage( Class<? extends Meeple> type, Color c, FeaturePointer fp) { Feature feature = getGame().getBoard().get(fp); ImmutablePoint offset = getClient() .getResourceManager() .getMeeplePlacement(feature.getTile(), type, fp.getLocation()); Image image = getClient().getFigureTheme().getFigureImage(type, c, getExtraDecoration(type, fp)); if (fp.getLocation() == Location.ABBOT) { image = rotate(image, 90); } return new MeeplePositionedImage(type, fp, offset, image, feature instanceof Bridge); }
public Set<Location> getUnoccupiedScoreables(boolean excludeCompleted) { Set<Location> locations = new HashSet<>(); for (Feature f : features) { // if (f instanceof Farm && !game.hasCapability(Capability.FARM_PLACEMENT)) continue; if (f instanceof Scoreable) { IsOccupied visitor; if (excludeCompleted && f instanceof Completable) { visitor = new IsOccupiedOrCompleted(); } else { visitor = new IsOccupied(); } if (f.walk(visitor)) continue; locations.add(f.getLocation()); } } return locations; }
private void addAdjoiningCompletedCities(Feature[] adjoiningCities) { for (Feature feature : adjoiningCities) { if (feature instanceof City) { City c = (City) feature; CityScoreContext ctx = cityCache.get(c); if (ctx == null) { ctx = c.getScoreContext(); ctx.setCityCache(cityCache); c.walk(ctx); } if (ctx.isCompleted()) { adjoiningCompletedCities.put((City) ctx.getMasterFeature(), ctx); } } else if (feature instanceof Castle) { adjoiningCastles.add((Castle) feature.getMaster()); } } }
private Castle replaceCityWithCastle(Tile tile, Location loc) { ListIterator<Feature> iter = tile.getFeatures().listIterator(); City city = null; while (iter.hasNext()) { Feature feature = iter.next(); if (feature.getLocation() == loc) { city = (City) feature; break; } } List<Meeple> meeples = new ArrayList<>(city.getMeeples()); // collection copy required!!! undeploy modify it for (Meeple m : meeples) { m.undeploy(); } Castle castle = new Castle(); castle.setTile(tile); castle.setId(game.idSequnceNextVal()); castle.setLocation(loc.rotateCCW(tile.getRotation())); iter.set(castle); for (Feature f : tile.getFeatures()) { // replace also city references if (f instanceof Farm) { Farm farm = (Farm) f; Feature[] adjoining = farm.getAdjoiningCities(); if (adjoining != null) { for (int i = 0; i < adjoining.length; i++) { if (adjoining[i] == city) { adjoining[i] = castle; break; } } } } } FeaturePointer fp = new FeaturePointer(tile.getPosition(), loc); for (Meeple m : meeples) { if (m.getPlayer() == game.getActivePlayer() && m.isDeploymentAllowed(castle).result) { m.deploy(fp); } } return castle; }
private static TileSymmetry countBaseSymmetry(Tile tile) { for (Feature piece : tile.getFeatures()) { if (piece instanceof Road || piece instanceof City) { Feature opposite = tile.getFeature(piece.getLocation().rev()); if (opposite == null || !opposite.getClass().equals(piece.getClass())) { return TileSymmetry.NONE; } } } for (Feature piece : tile.getFeatures()) { if (piece instanceof Road || piece instanceof City) { Feature opposite = tile.getFeature(piece.getLocation().rotateCW(Rotation.R90)); if (opposite == null || !opposite.getClass().equals(piece.getClass())) { return TileSymmetry.S2; } } } return TileSymmetry.S4; }
public void tileEvent(TileEvent ev) { Tile tile = ev.getTile(); if (ev.getType() == TileEvent.PLACEMENT) { ResourceManager resourceManager = getClient().getResourceManager(); Set<Location> farmLocations = new HashSet<>(); for (Feature f : tile.getFeatures()) { if (f instanceof Farm) { farmLocations.add(f.getLocation()); } } if (farmLocations.isEmpty()) return; Map<Location, Area> tAreas = resourceManager.getFeatureAreas(tile, FULL_SIZE, farmLocations); areas.put(tile, tAreas); refreshHints(); } if (ev.getType() == TileEvent.REMOVE) { areas.remove(tile); refreshHints(); } }
protected void deploy(Tile tile, Location loc, Feature feature) { DeploymentCheckResult check = isDeploymentAllowed(feature); if (!check.result) { throw new IllegalArgumentException(check.error); } feature.addMeeple(this); setPosition(tile.getPosition()); setLocation(loc); setFeature(feature); game.post(new MeepleEvent(MeepleEvent.DEPLOY, this)); }
@Override public boolean visit(Feature feature) { Meeple m = feature.getMeeple(); if (m == null || m.getPlayer() != player) { return true; } if (m instanceof Builder || m instanceof Pig) { toRemove = (Special) m; return true; } if (m instanceof Follower) { // another follower exists toRemove = null; return false; } return true; // some special case like Barn }
public Feature getFeature(Location loc) { for (Feature p : features) { if (p.getLocation().equals(loc)) return p; } return null; }
private void fillHints() { hints.clear(); final Set<Feature> processed = new HashSet<>(); for (Entry<Tile, Map<Location, Area>> entry : areas.entrySet()) { for (Feature f : entry.getKey().getFeatures()) { if (!(f instanceof Farm)) continue; if (processed.contains(f)) continue; FarmHint fh = f.walk( new FeatureVisitor<FarmHint>() { FarmHint result = new FarmHint(new Area(), null); int x = Integer.MAX_VALUE; int y = Integer.MAX_VALUE; int size = 0; boolean hasCity = false; int[] power = new int[getGame().getAllPlayers().length]; @Override public boolean visit(Feature feature) { Farm f = (Farm) feature; processed.add(f); size++; hasCity = hasCity || f.getAdjoiningCities() != null || f.isAdjoiningCityOfCarcassonne(); for (Meeple m : f.getMeeples()) { if (m instanceof Follower) { power[m.getPlayer().getIndex()] += ((Follower) m).getPower(); } if (m instanceof Barn) { power[m.getPlayer().getIndex()] += 1; } } Position pos = f.getTile().getPosition(); if (pos.x < x) { if (x != Integer.MAX_VALUE) result.area.transform( AffineTransform.getTranslateInstance(FULL_SIZE * (x - pos.x), 0)); x = pos.x; } if (pos.y < y) { if (y != Integer.MAX_VALUE) result.area.transform( AffineTransform.getTranslateInstance(0, FULL_SIZE * (y - pos.y))); y = pos.y; } Map<Location, Area> tileAreas = areas.get(f.getTile()); if (tileAreas != null) { // sync issue, feature can be extended in other thread, so it is // not registered in areas yet Area featureArea = new Area(tileAreas.get(f.getLocation())); featureArea.transform( AffineTransform.getTranslateInstance( FULL_SIZE * (pos.x - x), FULL_SIZE * (pos.y - y))); result.area.add(featureArea); } return true; } @Override public FarmHint getResult() { result.position = new Position(x, y); int bestPower = 0; List<Integer> bestPlayerIndexes = new ArrayList<>(); for (int i = 0; i < power.length; i++) { if (power[i] == bestPower) { bestPlayerIndexes.add(i); } if (power[i] > bestPower) { bestPower = power[i]; bestPlayerIndexes.clear(); bestPlayerIndexes.add(i); } } if (bestPower == 0) { if (size < 2 || !hasCity) return null; // don't display unimportant farms result.colors = new Color[] {Color.DARK_GRAY}; } else { result.colors = new Color[bestPlayerIndexes.size()]; int i = 0; for (Integer index : bestPlayerIndexes) { result.colors[i++] = getGame().getPlayer(index).getColors().getMeepleColor(); } } return result; } }); if (fh == null) continue; // to small farm hints.add(fh); } } }
public void undeploy(boolean checkForLonelyBuilderOrPig) { assert location != null && location != Location.PRISON; game.post(new MeepleEvent(MeepleEvent.UNDEPLOY, this)); feature.removeMeeple(this); clearDeployment(); }