/** Returns true if the two supplied placements match up (represent a legal board position). */ protected boolean tilesMatch(Placement play1, Placement play2) { // based on the relative positions of the two placements, determine the "natural" edges to // be compared (east/west or north/south) Orient orient1 = play1.loc.directionTo(play2.loc), orient2 = orient1.opposite(); // now rotate those "natural" edges based on the orientations of the placements orient1 = orient1.rotate(-play1.orient.index); orient2 = orient2.rotate(-play2.orient.index); // now make suer those two edges match return play1.tile.terrain.getEdge(orient1) == play2.tile.terrain.getEdge(orient2); }
/** Returns the set of board positions where the supplied tile can be legally played. */ public Set<Location> computeLegalPlays(GameTile tile) { Set<Location> locs = Sets.newHashSet(); // compute the neighbors of all existing tiles for (Placement play : _plays.values()) { locs.addAll(play.loc.neighbors()); } // now go back and remove the occupied tiles for (Placement play : _plays.values()) { locs.remove(play.loc); } // now remove any position that is not a legal play OUTER: for (Iterator<Location> iter = locs.iterator(); iter.hasNext(); ) { Location pos = iter.next(); ORIENT: for (Orient orient : Orient.values()) { Placement play = new Placement(tile, orient, pos); for (Location npos : pos.neighbors()) { Placement neighbor = _plays.get(npos); if (neighbor != null && !tilesMatch(neighbor, play)) { continue ORIENT; // try next orientation } } continue OUTER; // this orientation matches } iter.remove(); // no matches, remove the location } return locs; }
/** * Computes the legal orientations in which the specified tile can be placed at the supplied * location. */ public List<Orient> computeLegalOrients(GameTile tile, Location loc) { List<Orient> orients = Lists.newArrayList(); // fetch the neighbors of this tile List<Placement> neighbors = Lists.newArrayList(); for (Location nloc : loc.neighbors()) { Placement nplay = _plays.get(nloc); if (nplay != null) { neighbors.add(nplay); } } // and validate each candidate orientation against them ORIENT: for (Orient orient : Orient.values()) { Placement play = new Placement(tile, orient, loc); for (Placement nplay : neighbors) { if (!tilesMatch(nplay, play)) continue ORIENT; } orients.add(orient); } return orients; }