예제 #1
0
 public Feature getFeaturePartOf(Location loc) {
   for (Feature p : features) {
     if (loc.isPartOf(p.getLocation())) {
       return p;
     }
   }
   return null;
 }
예제 #2
0
 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);
   }
 }
예제 #3
0
 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;
 }
예제 #4
0
 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);
 }
예제 #5
0
 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;
 }
예제 #6
0
 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());
     }
   }
 }
예제 #7
0
  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;
  }
예제 #8
0
 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;
 }
예제 #9
0
 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();
   }
 }
예제 #10
0
 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
 }
예제 #12
0
 public Feature getFeature(Location loc) {
   for (Feature p : features) {
     if (p.getLocation().equals(loc)) return p;
   }
   return null;
 }
예제 #13
0
  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);
      }
    }
  }
예제 #14
0
 public void undeploy(boolean checkForLonelyBuilderOrPig) {
   assert location != null && location != Location.PRISON;
   game.post(new MeepleEvent(MeepleEvent.UNDEPLOY, this));
   feature.removeMeeple(this);
   clearDeployment();
 }