Browse Source

Allow cardinal directions in Rectangle.Util.getCorner(Rectangle, Direction) + add convenience implementations of size() and contains(int, int) in Zone.Skeleton + document how to proceed to implement a Zone correctly

smelc 7 years ago
parent
commit
7fe090df18

+ 10 - 9
squidlib-util/src/main/java/squidpony/squidgrid/mapping/Rectangle.java

@@ -189,13 +189,12 @@ public interface Rectangle extends Zone {
 
 		/**
 		 * @param r
-         * @param diagonal A diagonal direction.
-		 * @return The coord at the corner identified by {@code diagonal} in
+		 * @param dir
+		 * @return The coord at the corner identified by {@code dir} in
 		 *         {@code r}.
 		 */
-		public static Coord getCorner(Rectangle r, Direction diagonal) {
-			assert diagonal.isDiagonal();
-			switch (diagonal) {
+		public static Coord getCorner(Rectangle r, Direction dir) {
+			switch (dir) {
 			case DOWN_LEFT:
 				return r.getBottomLeft();
 			case DOWN_RIGHT:
@@ -206,15 +205,17 @@ public interface Rectangle extends Zone {
 			case UP_RIGHT:
 				/* -y because in SquidLib higher y is smaller */
 				return r.getBottomLeft().translate(r.getWidth() - 1, -(r.getHeight() - 1));
+			case NONE:
+				return r.getCenter();
 			case DOWN:
 			case LEFT:
-			case NONE:
 			case RIGHT:
 			case UP:
-				throw new IllegalStateException(
-						"Expected a diagonal direction in Rectangle.Utils::getCorner. Received: " + diagonal);
+				final Coord c1 = getCorner(r, dir.clockwise());
+				final Coord c2 = getCorner(r, dir.counterClockwise());
+				return Coord.get((c1.x + c2.x) / 2, (c1.y + c2.y) / 2);
 			}
-			throw new IllegalStateException("Unmatched direction in Rectangle.Utils::getCorner: " + diagonal);
+			throw new IllegalStateException("Unmatched direction in Rectangle.Utils::getCorner: " + dir);
 		}
 
 		/**

+ 26 - 0
squidlib-util/src/main/java/squidpony/squidgrid/zone/Zone.java

@@ -37,6 +37,16 @@ import java.util.List;
  * planned), GreasedRegion is mutable for performance reasons, and may need copies
  * to be created if you want to keep around older GreasedRegions.
  * </p>
+ * 
+ * <p>
+ * The correct method to implement a {@link Zone} efficiently is to first try
+ * implementing the interface directly, looking at each method and thinking
+ * whether you can do something smart for it. Once you've inspected all methods,
+ * then extend {@link Zone.Skeleton} (instead of Object in the first place) so
+ * that it'll fill for you the methods for which you cannot provide a smart
+ * implementation.
+ * </p>
+ * 
  * @author smelC
  * @see squidpony.squidmath.CoordPacker
  * @see squidpony.squidmath.GreasedRegion
@@ -159,6 +169,22 @@ public interface Zone extends Serializable, Iterable<Coord> {
 
 		private static final long serialVersionUID = 4436698111716212256L;
 
+		@Override
+		/* Convenience implementation, feel free to override */
+		public int size() {
+			return getAll().size();
+		}
+
+		@Override
+		/* Convenience implementation, feel free to override */
+		public boolean contains(int x, int y) {
+			for (Coord in : this) {
+				if (in.x == x && in.y == y)
+					return true;
+			}
+			return false;
+		}
+
 		@Override
 		/* Convenience implementation, feel free to override */
 		public boolean contains(Coord c) {