/** Computes the scores for all features on the board. */ public List<FeatureScore> computeFinalScores() { // we use this set to track which claim groups we've already processed Set<Integer> processedClaims = Sets.newHashSet(); // check all features on all tiles for potential scores List<FeatureScore> scores = Lists.newArrayList(); for (Placement play : _plays.values()) { Claim claim = getClaim(play); for (Feature f : play.tile.terrain.features) { // ignore features that aren't completable (e.g. GRASS) if (!COMPLETABLES.contains(f.type)) continue; // determine whether or not we've already processed this claim int group = claim.getClaimGroup(f); if (processedClaims.contains(group)) continue; processedClaims.add(group); // determine who will earn points for this claim Set<Integer> scorers = getScorers(group); // if we have no scorers, the feature is unclaimed; skip it if (scorers.isEmpty()) continue; // if we made it this far, we may have something to report int score = computeFeatureScore(play, f); if (score != 0) { scores.add(new FeatureScore(f, scorers, score, getPiecens(group))); } } } return scores; }
/** Computes the scores for all features involved in the supplied placement. */ public List<FeatureScore> computeScores(Placement play) { List<FeatureScore> scores = Lists.newArrayList(); Claim claim = getClaim(play); // check all of the features on this tile for potential scores Set<Integer> groups = Sets.newHashSet(); for (Feature f : play.tile.terrain.features) { // ignore features that aren't completed in this way (e.g. GRASS) if (!COMPLETABLES.contains(f.type)) continue; // make sure we haven't already scored this group; some tiles have disconnected // features that can be linked into the same group int group = claim.getClaimGroup(f); if (groups.contains(group)) continue; groups.add(group); // see who should score this feature Set<Integer> scorers = getScorers(group); // if we have no scorers, the feature is unclaimed; skip it if (scorers.isEmpty()) continue; // if we made it this far, we may have something to report int score = computeFeatureScore(play, f); if (score != 0) { scores.add(new FeatureScore(f, scorers, score, getPiecens(group))); } } // we may have also completed a cloister, so we check that as well for (Location nloc : play.loc.neighborhood()) { Placement nplay = _plays.get(nloc); if (nplay == null) continue; // check whether this tile has a piecen upon't Piecen p = _piecens.get(nloc); if (p == null) continue; // check whether this tile contains a cloister feature Feature cf = null; for (Feature f : nplay.tile.terrain.features) { if (f.type == Feature.Type.CLOISTER) { cf = f; break; } } if (cf == null) continue; // make sure the piecen is on the cloister if (_piecenGroups.get(p.loc) != getClaim(nplay).getClaimGroup(cf)) continue; // finally, score the cloister, which will always have only one scorer, one involved // piecen, and a non-zero score (simple!) scores.add( new FeatureScore( cf, Collections.singleton(p.ownerIdx), computeFeatureScore(nplay, cf), Collections.singletonList(p))); } return scores; }