/** 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; }