package inf101.v18.grid; import java.util.List; import java.util.stream.Stream; /** * Representation of a two-dimensional area. *

* This describes the coordinate system of the area and defines the set of valid * locations within the area. *

* See {@link #location(int, int)} to covert (x,y)-coordinates to * {@link ILocation}s. *

* An {@link IArea} does not store anything, it just defines valid * storage locations (e.g., for an {@link IGrid}), and the relationships between * locations (e.g., how to find neighbours of a given location). * * @author Anya Helene Bagge, UiB */ public interface IArea extends Iterable { /** * Check if a (x,y) is inside the area. * * @param x * X-coordinate * @param y * Y-coordinate * @return True if the (x,y) position lies within the area */ boolean contains(int x, int y); /** * Check if a position is inside the area. * * @param pos * A position * @return True if the position lies within the area */ boolean contains(IPosition pos); @Override boolean equals(Object other); /** * Get a location object corresponding to (x,y) * * @param x * X-coordinate * @param y * Y-coordinate * @return The location object associated with (x,y) * @throws IndexOutOfBoundsException * if {@link #contains(int, int)} returns false for (x,y) */ ILocation location(int x, int y); /** @return Height of the area */ int getHeight(); /** * Returns the number of legal positions in the area * * @return Same as getWidth()*getHeight() */ int getSize(); /** @return Width of the area */ int getWidth(); @Override int hashCode(); /** * Return an object for iterating over all the neighbours of the given position, * suitable for use in a new-style for-loop. *

* The iterator will yield up to eight positions (less if the given position is * at the edge of the area, and the coordinates are not wrapped). E.g., for a * 1x1 area, the iterator will yield nothing (if the area is not wrapped), or * the same position two or eight times (if the area is wrapped horizontally, * vertically or both). * * @param pos * A position in the area * @return An iterable over positions, with {@link #contains(ILocation)} being * true for each position. * @see #wrapsHorizontally(), {@link #wrapsVertically()} * @throws IndexOutOfBoundsException * if !contains(pos) */ Iterable neighboursOf(ILocation pos); @Override String toString(); /** * If the area wraps horizontally, then x will be the same as x+(k*getWidth()) * for any k – i.e., it will be as if the 2D area is projected on a cylinder or * torus in 3D-space. *

* With no wrapping, accessing positions outside (0,0)–(getWidth(),getHeight()) * is illegal. * * @return True if the area wraps around horizontally */ boolean wrapsHorizontally(); /** * If the area wraps vertically, then y will be the same as y+(k*getHeight()) * for any k – i.e., it will be as if the 2D area is projected on a cylinder or * torus in 3D-space. *

* With no wrapping, accessing positions outside (0,0)–(getWidth(),getHeight()) * is illegal. * * @return True if the area wraps around vertically */ boolean wrapsVertically(); /** @return A {@link Stream} of all locations in the area */ Stream stream(); /** @return A (possibly) parallel {@link Stream} of all locations in the area */ Stream parallelStream(); /** * Convert a 2D coordinate to 1D * * @param x * X-coordinate * @param y * Y-coordinate * @return x + y*getWidth() */ int toIndex(int x, int y); /** * Convert a 1D coordinate to a location *

* Returns a location l = fromIndex(i) such that * toIndex(l.getX(), l.getY()) == i. * * @param i * @return A location */ ILocation fromIndex(int i); /** * Get all locations in area *

* Since IArea is @{@link Iterable}, you can also use directly in a for-loop to * iterate over the locations. *

* All locations in the list are guaranteed to be valid * according to {@link #isValid(ILocation)}. The returned list cannot be modified. * * @return An unmodifiable list with all the locations in the area */ List locations(); }