Explorar el Código

Remove IColorCenter reference from SquidPanel. I do it externally.

smelc hace 7 años
padre
commit
a802a88fb6

+ 0 - 10
squidlib-util/src/main/java/squidpony/panel/ISquidPanel.java

@@ -1,7 +1,5 @@
 package squidpony.panel;
 
-import squidpony.IColorCenter;
-
 /**
  * The abstraction of {@code SquidPanel}s, to abstract from the UI
  * implementation (i.e. whether it's awt or libgdx doesn't matter here).
@@ -134,14 +132,6 @@ public interface ISquidPanel<T> {
 	 */
 	T getDefaultForegroundColor();
 
-	/**
-	 * Method to change the backing {@link IColorCenter}.
-	 * 
-	 * @param icc
-	 * @return {@code this}
-	 */
-	ISquidPanel<T> setColorCenter(IColorCenter<T> icc);
-
 	/**
 	 * @return The panel doing the real job, i.e. an instance of {@code SquidPanel}.
 	 *         The type of colors is unspecified, as some clients have forwarding

+ 512 - 419
squidlib-util/src/main/java/squidpony/squidmath/Coord.java

@@ -1,16 +1,16 @@
 package squidpony.squidmath;
 
-import squidpony.squidgrid.Direction;
-
 import java.io.Serializable;
 
+import squidpony.squidgrid.Direction;
+
 /**
  * A 2D coordinate.
  * 
  * Created by Tommy Ettinger on 8/12/2015.
  */
 public class Coord implements Serializable {
-    private static final long serialVersionUID = 300L;
+	private static final long serialVersionUID = 300L;
 
 	/** The x-coordinate. */
 	public final int x;
@@ -18,26 +18,29 @@ public class Coord implements Serializable {
 	/** The y-coordinate (the ordinate) */
 	public final int y;
 
-    protected Coord()
-    {
-        this(0, 0);
-    }
-    protected Coord(int x, int y)
-    {
-        this.x = x;
-        this.y = y;
-    }
-    public static Coord get(int x, int y)
-    {
-        if(x >= -3 && y >= -3 && x < POOL.length - 3 && y < POOL[x + 3].length - 3)
-            return POOL[x + 3][y + 3];
-        else return new Coord(x, y);
-    }
-
-	/**
-     * Gets the angle in degrees to go between two Coords; 0 is up.
-	 * @param from the starting Coord to measure from
-	 * @param to the ending Coord to measure to
+	protected Coord() {
+		this(0, 0);
+	}
+
+	protected Coord(int x, int y) {
+		this.x = x;
+		this.y = y;
+	}
+
+	public static Coord get(int x, int y) {
+		if (x >= -3 && y >= -3 && x < POOL.length - 3 && y < POOL[x + 3].length - 3)
+			return POOL[x + 3][y + 3];
+		else
+			return new Coord(x, y);
+	}
+
+	/**
+	 * Gets the angle in degrees to go between two Coords; 0 is up.
+	 * 
+	 * @param from
+	 *            the starting Coord to measure from
+	 * @param to
+	 *            the ending Coord to measure to
 	 * @return The degree from {@code from} to {@code to}; 0 is up
 	 */
 	public static double degrees(Coord from, Coord to) {
@@ -50,195 +53,247 @@ public class Coord implements Serializable {
 		return degree;
 	}
 
-    /**
-     * Provided for compatibility with earlier code that used the AWT Point API.
-     * @return this Coord, without changes
-     */
-    public Coord getLocation()
-    {
-        return this;
-    }
-
-    /**
-     * Takes this Coord, adds x to its x and y to its y, and returns the Coord at that position.
-     * @param x the amount of x distance to move
-     * @param y the amount of y distance to move
-     * @return a Coord (usually cached and not a new instance) that has been moved the specified distance
-     */
-    public Coord translate(int x, int y)
-    {
-        return get(this.x + x, this.y + y);
-    }
-    /**
-     * Takes this Coord, adds x to its x and y to its y, limiting x from 0 to width and limiting y from 0 to height,
-     * and returns the Coord at that position.
-     * @param x the amount of x distance to move
-     * @param y the amount of y distance to move
-     * @param width one higher than the maximum x value this can use; typically the length of an array
-     * @param height one higher than the maximum y value this can use; typically the length of an array
-     * @return a Coord (usually cached and not a new instance) that has been moved the specified distance
-     */
-    public Coord translateCapped(int x, int y, int width, int height)
-    {
-        return get(Math.min(Math.max(0, this.x + x), width - 1), Math.min(Math.max(0, this.y + y), height - 1));
-    }
-
-    /**
-     * Separately combines the x and y positions of this Coord and other, producing a different Coord as their "sum."
-     * @param other another Coord
-     * @return a Coord (usually cached and not a new instance) with {@code x = this.x + other.x; y = this.y + other.y}
-     */
-    public Coord add(Coord other)
-    {
-        return get(x + other.x, y + other.y);
-    }
-
-    /**
-     * Separately adds the x and y positions of this Coord to operand, producing a different Coord as their
-     * "sum."
-     * @param operand a value to add each of x and y to
-     * @return a Coord (usually cached and not a new instance) with {@code x = this.x + operand; y = this.y + operand}
-     */
-    public Coord add(int operand)
-    {
-        return get(x + operand, y + operand);
-    }
-
-    /**
-     * Separately adds the x and y positions of this Coord to operand, rounding to the nearest int for each of x
-     * and y and producing a different Coord as their "sum."
-     * @param operand a value to add each of x and y to
-     * @return a Coord (usually cached and not a new instance) with {@code x = this.x + operand; y = this.y +
-     *          operand}, with both x and y rounded accordingly
-     */
-    public Coord add(double operand)
-    {
-        return get((int)Math.round(x + operand), (int)Math.round(y + operand));
-    }
-
-    /**
-     * Separately subtracts the x and y positions of other from this Coord, producing a different Coord as their
-     * "difference."
-     * @param other another Coord
-     * @return a Coord (usually cached and not a new instance) with {@code x = this.x - other.x; y = this.y - other.y}
-     */
-    public Coord subtract(Coord other)
-    {
-        return get(x - other.x, y - other.y);
-    }
-
-    /**
-     * Separately subtracts operand from the x and y positions of this Coord, producing a different Coord as their
-     * "difference."
-     * @param operand a value to subtract from each of x and y
-     * @return a Coord (usually cached and not a new instance) with {@code x = this.x - operand; y = this.y - operand}
-     */
-    public Coord subtract(int operand)
-    {
-        return get(x - operand, y - operand);
-    }
-
-    /**
-     * Separately subtracts operand from the x and y positions of this Coord, rounding to the nearest int for each of x
-     * and y and producing a different Coord as their "difference."
-     * @param operand a value to subtract from each of x and y
-     * @return a Coord (usually cached and not a new instance) with {@code x = this.x - operand; y = this.y -
-     *          operand}, with both x and y rounded accordingly
-     */
-    public Coord subtract(double operand)
-    {
-        return get((int)Math.round(x - operand), (int)Math.round(y - operand));
-    }
-    /**
-     * Separately multiplies the x and y positions of other from this Coord, producing a different Coord as their
-     * "product."
-     * @param other another Coord
-     * @return a Coord (usually cached and not a new instance) with {@code x = this.x * other.x; y = this.y * other.y}
-     */
-    public Coord multiply(Coord other)
-    {
-        return get(x * other.x, y * other.y);
-    }
-    /**
-     * Separately multiplies the x and y positions of this Coord by operand, producing a different Coord as their
-     * "product."
-     * @param operand a value to multiply each of x and y by
-     * @return a Coord (usually cached and not a new instance) with {@code x = this.x * operand; y = this.y * operand}
-     */
-    public Coord multiply(int operand)
-    {
-        return get(x * operand, y * operand);
-    }
-
-    /**
-     * Separately multiplies the x and y positions of this Coord by operand, rounding to the nearest int for each of x
-     * and y and producing a different Coord as their "product."
-     * @param operand a value to multiply each of x and y by
-     * @return a Coord (usually cached and not a new instance) with {@code x = this.x * operand; y = this.y *
-     *          operand}, with both x and y rounded accordingly
-     */
-    public Coord multiply(double operand)
-    {
-        return get((int)Math.round(x * operand), (int)Math.round(y * operand));
-    }
-
-    /**
-     * Separately divides the x and y positions of this Coord by other, producing a different Coord as their
-     * "quotient." If other has 0 for x or y, this will throw an exception, as dividing by 0 is expected to do.
-     * @param other another Coord
-     * @return a Coord (usually cached and not a new instance) with {@code x = this.x / other.x; y = this.y / other.y}
-     */
-    public Coord divide(Coord other)
-    {
-        return get(x / other.x, y / other.y);
-    }
-    /**
-     * Separately divides the x and y positions of this Coord by operand, producing a different Coord as their
-     * "quotient." If operand is 0, this will throw an exception, as dividing by 0 is expected to do.
-     * @param operand a value to divide each of x and y by
-     * @return a Coord (usually cached and not a new instance) with {@code x = this.x / operand; y = this.y / operand}
-     */
-    public Coord divide(int operand)
-    {
-        return get(x / operand, y / operand);
-    }
-
-    /**
-     * Separately divides the x and y positions of this Coord by operand, flooring to a lower int for each of x and
-     * y and producing a different Coord as their "quotient." If operand is 0.0, expect strange results (infinity and
-     * NaN are both possibilities).
-     * @param operand a value to divide each of x and y by
-     * @return a Coord (usually cached and not a new instance) with {@code x = this.x / operand; y = this.y /
-     *          operand}, with both x and y rounded accordingly
-     */
-    public Coord divide(double operand)
-    {
-        return get((int)(x / operand), (int)(y / operand));
-    }
-
-    /**
-     * Separately divides the x and y positions of this Coord by operand, rounding to the nearest int for each of x and
-     * y and producing a different Coord as their "quotient." If operand is 0.0, expect strange results (infinity and
-     * NaN are both possibilities).
-     * @param operand a value to divide each of x and y by
-     * @return a Coord (usually cached and not a new instance) with {@code x = this.x / operand; y = this.y /
-     *          operand}, with both x and y rounded accordingly
-     */
-    public Coord divideRounding(double operand)
-    {
-        return get((int)Math.round(x / operand), (int)Math.round(y / operand));
-    }
-
-    /**
-     * Separately averages the x and y positions of this Coord with other, producing a different Coord as their
-     * "midpoint."
-     * @param other another Coord
-     * @return a Coord (usually cached and not a new instance) halfway between this and other, rounded nearest.
-     */
-    public Coord average(Coord other)
-    {
-        return get(Math.round((x + other.x) / 2.0f), Math.round((y + other.y) / 2.0f));
-    }
+	/**
+	 * Provided for compatibility with earlier code that used the AWT Point API.
+	 * 
+	 * @return this Coord, without changes
+	 */
+	public Coord getLocation() {
+		return this;
+	}
+
+	/**
+	 * Takes this Coord, adds x to its x and y to its y, and returns the Coord at
+	 * that position.
+	 * 
+	 * @param tx
+	 *            the amount of x distance to move
+	 * @param ty
+	 *            the amount of y distance to move
+	 * @return a Coord (usually cached and not a new instance) that has been moved
+	 *         the specified distance
+	 */
+	public Coord translate(int tx, int ty) {
+		return get(this.x + tx, this.y + ty);
+	}
+
+	/**
+	 * Takes this Coord, adds x to its x and y to its y, limiting x from 0 to width
+	 * and limiting y from 0 to height, and returns the Coord at that position.
+	 * 
+	 * @param tx
+	 *            the amount of x distance to move
+	 * @param ty
+	 *            the amount of y distance to move
+	 * @param width
+	 *            one higher than the maximum x value this can use; typically the
+	 *            length of an array
+	 * @param height
+	 *            one higher than the maximum y value this can use; typically the
+	 *            length of an array
+	 * @return a Coord (usually cached and not a new instance) that has been moved
+	 *         the specified distance
+	 */
+	public Coord translateCapped(int tx, int ty, int width, int height) {
+		return get(Math.min(Math.max(0, this.x + tx), width - 1), Math.min(Math.max(0, this.y + ty), height - 1));
+	}
+
+	/**
+	 * Separately combines the x and y positions of this Coord and other, producing
+	 * a different Coord as their "sum."
+	 * 
+	 * @param other
+	 *            another Coord
+	 * @return a Coord (usually cached and not a new instance) with
+	 *         {@code x = this.x + other.x; y = this.y + other.y}
+	 */
+	public Coord add(Coord other) {
+		return get(x + other.x, y + other.y);
+	}
+
+	/**
+	 * Separately adds the x and y positions of this Coord to operand, producing a
+	 * different Coord as their "sum."
+	 * 
+	 * @param operand
+	 *            a value to add each of x and y to
+	 * @return a Coord (usually cached and not a new instance) with
+	 *         {@code x = this.x + operand; y = this.y + operand}
+	 */
+	public Coord add(int operand) {
+		return get(x + operand, y + operand);
+	}
+
+	/**
+	 * Separately adds the x and y positions of this Coord to operand, rounding to
+	 * the nearest int for each of x and y and producing a different Coord as their
+	 * "sum."
+	 * 
+	 * @param operand
+	 *            a value to add each of x and y to
+	 * @return a Coord (usually cached and not a new instance) with
+	 *         {@code x = this.x + operand; y = this.y +
+	 *          operand}, with both x and y rounded accordingly
+	 */
+	public Coord add(double operand) {
+		return get((int) Math.round(x + operand), (int) Math.round(y + operand));
+	}
+
+	/**
+	 * Separately subtracts the x and y positions of other from this Coord,
+	 * producing a different Coord as their "difference."
+	 * 
+	 * @param other
+	 *            another Coord
+	 * @return a Coord (usually cached and not a new instance) with
+	 *         {@code x = this.x - other.x; y = this.y - other.y}
+	 */
+	public Coord subtract(Coord other) {
+		return get(x - other.x, y - other.y);
+	}
+
+	/**
+	 * Separately subtracts operand from the x and y positions of this Coord,
+	 * producing a different Coord as their "difference."
+	 * 
+	 * @param operand
+	 *            a value to subtract from each of x and y
+	 * @return a Coord (usually cached and not a new instance) with
+	 *         {@code x = this.x - operand; y = this.y - operand}
+	 */
+	public Coord subtract(int operand) {
+		return get(x - operand, y - operand);
+	}
+
+	/**
+	 * Separately subtracts operand from the x and y positions of this Coord,
+	 * rounding to the nearest int for each of x and y and producing a different
+	 * Coord as their "difference."
+	 * 
+	 * @param operand
+	 *            a value to subtract from each of x and y
+	 * @return a Coord (usually cached and not a new instance) with
+	 *         {@code x = this.x - operand; y = this.y -
+	 *          operand}, with both x and y rounded accordingly
+	 */
+	public Coord subtract(double operand) {
+		return get((int) Math.round(x - operand), (int) Math.round(y - operand));
+	}
+
+	/**
+	 * Separately multiplies the x and y positions of other from this Coord,
+	 * producing a different Coord as their "product."
+	 * 
+	 * @param other
+	 *            another Coord
+	 * @return a Coord (usually cached and not a new instance) with
+	 *         {@code x = this.x * other.x; y = this.y * other.y}
+	 */
+	public Coord multiply(Coord other) {
+		return get(x * other.x, y * other.y);
+	}
+
+	/**
+	 * Separately multiplies the x and y positions of this Coord by operand,
+	 * producing a different Coord as their "product."
+	 * 
+	 * @param operand
+	 *            a value to multiply each of x and y by
+	 * @return a Coord (usually cached and not a new instance) with
+	 *         {@code x = this.x * operand; y = this.y * operand}
+	 */
+	public Coord multiply(int operand) {
+		return get(x * operand, y * operand);
+	}
+
+	/**
+	 * Separately multiplies the x and y positions of this Coord by operand,
+	 * rounding to the nearest int for each of x and y and producing a different
+	 * Coord as their "product."
+	 * 
+	 * @param operand
+	 *            a value to multiply each of x and y by
+	 * @return a Coord (usually cached and not a new instance) with
+	 *         {@code x = this.x * operand; y = this.y *
+	 *          operand}, with both x and y rounded accordingly
+	 */
+	public Coord multiply(double operand) {
+		return get((int) Math.round(x * operand), (int) Math.round(y * operand));
+	}
+
+	/**
+	 * Separately divides the x and y positions of this Coord by other, producing a
+	 * different Coord as their "quotient." If other has 0 for x or y, this will
+	 * throw an exception, as dividing by 0 is expected to do.
+	 * 
+	 * @param other
+	 *            another Coord
+	 * @return a Coord (usually cached and not a new instance) with
+	 *         {@code x = this.x / other.x; y = this.y / other.y}
+	 */
+	public Coord divide(Coord other) {
+		return get(x / other.x, y / other.y);
+	}
+
+	/**
+	 * Separately divides the x and y positions of this Coord by operand, producing
+	 * a different Coord as their "quotient." If operand is 0, this will throw an
+	 * exception, as dividing by 0 is expected to do.
+	 * 
+	 * @param operand
+	 *            a value to divide each of x and y by
+	 * @return a Coord (usually cached and not a new instance) with
+	 *         {@code x = this.x / operand; y = this.y / operand}
+	 */
+	public Coord divide(int operand) {
+		return get(x / operand, y / operand);
+	}
+
+	/**
+	 * Separately divides the x and y positions of this Coord by operand, flooring
+	 * to a lower int for each of x and y and producing a different Coord as their
+	 * "quotient." If operand is 0.0, expect strange results (infinity and NaN are
+	 * both possibilities).
+	 * 
+	 * @param operand
+	 *            a value to divide each of x and y by
+	 * @return a Coord (usually cached and not a new instance) with
+	 *         {@code x = this.x / operand; y = this.y /
+	 *          operand}, with both x and y rounded accordingly
+	 */
+	public Coord divide(double operand) {
+		return get((int) (x / operand), (int) (y / operand));
+	}
+
+	/**
+	 * Separately divides the x and y positions of this Coord by operand, rounding
+	 * to the nearest int for each of x and y and producing a different Coord as
+	 * their "quotient." If operand is 0.0, expect strange results (infinity and NaN
+	 * are both possibilities).
+	 * 
+	 * @param operand
+	 *            a value to divide each of x and y by
+	 * @return a Coord (usually cached and not a new instance) with
+	 *         {@code x = this.x / operand; y = this.y /
+	 *          operand}, with both x and y rounded accordingly
+	 */
+	public Coord divideRounding(double operand) {
+		return get((int) Math.round(x / operand), (int) Math.round(y / operand));
+	}
+
+	/**
+	 * Separately averages the x and y positions of this Coord with other, producing
+	 * a different Coord as their "midpoint."
+	 * 
+	 * @param other
+	 *            another Coord
+	 * @return a Coord (usually cached and not a new instance) halfway between this
+	 *         and other, rounded nearest.
+	 */
+	public Coord average(Coord other) {
+		return get(Math.round((x + other.x) / 2.0f), Math.round((y + other.y) / 2.0f));
+	}
+
 	/**
 	 * @param d
 	 *            A non-{@code null} direction.
@@ -248,6 +303,16 @@ public class Coord implements Serializable {
 		return Coord.get(x + d.deltaX, y + d.deltaY);
 	}
 
+	/**
+	 * @param dir
+	 *            A non-{@code null} direction.
+	 * @param n
+	 * @return {@code this} translated by {@code dir} {@code n} times.
+	 */
+	public Coord translate(Direction dir, int n) {
+		return get(this.x + (dir.deltaX * n), this.y + (dir.deltaY * n));
+	}
+
 	/**
 	 * @param i
 	 * @return {@code (x*i,y*i)}.
@@ -264,27 +329,26 @@ public class Coord implements Serializable {
 		return Coord.get(x * i, y * j);
 	}
 
-    public double distance(double x2, double y2)
-    {
-        return Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y));
-    }
-    public double distance(Coord co)
-    {
-        return Math.sqrt((co.x - x) * (co.x - x) + (co.y - y) * (co.y - y));
-    }
-    public double distanceSq(double x2, double y2)
-    {
-        return (x2 - x) * (x2 - x) + (y2 - y) * (y2 - y);
-    }
-    public double distanceSq(Coord co)
-    {
-        return (co.x - x) * (co.x - x) + (co.y - y) * (co.y - y);
-    }
+	public double distance(double x2, double y2) {
+		return Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y));
+	}
+
+	public double distance(Coord co) {
+		return Math.sqrt((co.x - x) * (co.x - x) + (co.y - y) * (co.y - y));
+	}
+
+	public double distanceSq(double x2, double y2) {
+		return (x2 - x) * (x2 - x) + (y2 - y) * (y2 - y);
+	}
+
+	public double distanceSq(Coord co) {
+		return (co.x - x) * (co.x - x) + (co.y - y) * (co.y - y);
+	}
 
 	/**
 	 * @param c
-	 * @return Whether {@code this} is adjacent to {@code c}. Not that a cell is
-	 *         not adjacent to itself with this method.
+	 * @return Whether {@code this} is adjacent to {@code c}. Not that a cell is not
+	 *         adjacent to itself with this method.
 	 */
 	public boolean isAdjacent(Coord c) {
 		switch (Math.abs(x - c.x)) {
@@ -304,9 +368,9 @@ public class Coord implements Serializable {
 	 * @param adjacent
 	 *            A {@link Coord} that is {@link #isAdjacent(Coord) adjacent} to
 	 *            {@code this}.
-	 * @return The direction to go from {@code this} to {@code adjacent} i.e.
-	 *         the direction {@code d} such that {@code translate(this, d)}
-	 *         yields {@code adjacent}.
+	 * @return The direction to go from {@code this} to {@code adjacent} i.e. the
+	 *         direction {@code d} such that {@code translate(this, d)} yields
+	 *         {@code adjacent}.
 	 * @throws IllegalStateException
 	 *             If {@code this} isn't adjacent to {@code adjacent}.
 	 */
@@ -321,190 +385,219 @@ public class Coord implements Serializable {
 		throw new IllegalStateException(this + " is not adjacent to " + adjacent);
 	}
 
-    /**
-     * Returns true if x is between 0 (inclusive) and width (exclusive) and y is between 0 (inclusive) and height
-     * (exclusive), false otherwise.
-     * @param width the upper limit on x to check, exclusive
-     * @param height the upper limit on y to check, exclusive
-     * @return true if this Coord is within the limits of width and height and has non-negative x and y
-     */
-    public boolean isWithin(int width, int height)
-    {
-        return x >= 0 && y >= 0 && x < width && y < height;
-    }
-    /**
-     * Returns true if x is between minX (inclusive) and maxX (exclusive) and y is between minY (inclusive) and maxY
-     * (exclusive), false otherwise.
-     * @param minX the lower limit on x to check, inclusive
-     * @param minY the lower limit on y to check, inclusive
-     * @param maxX the upper limit on x to check, exclusive
-     * @param maxY the upper limit on y to check, exclusive
-     * @return true if this Coord is within the limits of the given parameters
-     */
-    public boolean isWithinRectangle(int minX, int minY, int maxX, int maxY)
-    {
-        return x >= minX && y >= minY && x < maxX && y < maxY;
-    }
-    public int getX() {
-        return x;
-    }
-
-    public Coord setX(int x) {
-        return get(x, y);
-    }
-
-    public int getY() {
-        return y;
-    }
-
-    public Coord setY(int y) {
-        return get(x, y);
-    }
-
-    @Override
-    public String toString()
-    {
-        return "(" + x + "," + y + ")";
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = 7;
-        hash = 113 * hash + x;
-        hash = 113 * hash + y;
-        return hash;
-    }
-
-    /**
-     * Something like hashCode(), but reversible with {@code Coord.decode()}. Works for Coords between roughly -256 and
-     * 32000 in each of x and y, but will probably only decode to pooled Coords if x and y are both between -3 and 255
-     * (inclusive for both).
-     * @return an int as a unique code for this Coord
-     */
-    public int encode()
-    {
-        return ((x + 256) << 16) ^ (y + 256);
-    }
-
-    /**
-     * An alternative to getting a Coord with Coord.get() only to encode() it as the next step. This doesn't create a
-     * Coord in the middle step. Can be decoded with Coord.decode() to get the (x,y) Coord.
-     * @param x the x position to encode
-     * @param y the y position to encode
-     * @return the coded int that a Coord at (x,y) would produce with encode()
-     */
-    public static int pureEncode(int x, int y)
-    {
-        return ((x + 256) << 16) ^ (y + 256);
-    }
-    /**
-     * This can take an int produced by {@code someCoord.encode()} and get the original Coord back out of it. It
-     * works for all pooled Coords where the pool hasn't been expanded past about 32,000 in either dimension. It even
-     * works for Coords with negative x or y as well, if they are no lower than -256 in either dimension. This will
-     * almost certainly fail (producing a gibberish Coord that probably won't be pooled) on hashes produced by any other
-     * class, including subclasses of Coord.
-     * @param code an encoded int from a Coord, but not a subclass of Coord
-     * @return the Coord that gave hash as its hashCode()
-     */
-    public static Coord decode(int code)
-    {
-        return get((code >>> 16) - 256, (code & 0xFFFF) - 256);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (o instanceof Coord) {
-            Coord other = (Coord) o;
-            return x == other.x && y == other.y;
-        } else {
-            return false;
-        }
-    }
-    private static Coord[][] POOL = new Coord[259][259];
-    static {
-        int width = POOL.length, height = POOL[0].length;
-        for (int i = 0; i < width; i++) {
-            for (int j = 0; j < height; j++) {
-                POOL[i][j] = new Coord(i - 3, j - 3);
-            }
-        }
-    }
-
-    /**
-     * Gets the width of the pool used as a cache for Coords, not including negative Coords.
-     * Unless expandPool() has been called, this should be 256.
-     * Useful for finding the upper (exclusive) bound for x values that can be used efficiently in Coords.
-     * Requesting a Coord with a x greater than or equal to this value will result in a new Coord being allocated and
-     * not cached, which may cause problems with code that expects the normal reference equality of Coords to be upheld
-     * and in extreme cases may require more time garbage collecting than is normally necessary.
-     * @return the width of the Coord cache, disregarding negative Coords
-     */
-    public static int getCacheWidth()
-    {
-        return POOL.length - 3;
-    }
-
-    /**
-     * Gets the height of the pool used as a cache for Coords, not including negative Coords.
-     * Unless expandPool() has been called, this should be 256.
-     * Useful for finding the upper (exclusive) bound for y values that can be used efficiently in Coords.
-     * Requesting a Coord with a y greater than or equal to this value will result in a new Coord being allocated and
-     * not cached, which may cause problems with code that expects the normal reference equality of Coords to be upheld
-     * and in extreme cases may require more time garbage collecting than is normally necessary.
-     * @return the height of the Coord cache, disregarding negative Coords
-     */
-    public static int getCacheHeight()
-    {
-        return POOL[0].length - 3;
-    }
-
-    /**
-     * Enlarges the pool of cached Coords to the given width and height, and doesn't change
-     * a dimension if it would be reduced in size.
-     * Cached Coord values will be reused by Coord.get instead of re-allocated each time.
-     * The default pool allows Coords with x and y each between -3 and 255, inclusive, to
-     * be cached, and is considered to have width and height of 256 to begin with. Giving a
-     * width greater than 256 will allow Coords with x greater than 255 to be cached;
-     * likewise for height. If width or height is smaller than the current cache width or
-     * height, that dimension will not change, but the other still may if it is valid. You
-     * cannot shrink the pool size.
-     * @param width the new width for the pool of cached Coords; will be ignored if smaller than the current width
-     * @param height the new height for the pool of cached Coords; will be ignored if smaller than the current height
-     */
-    public static void expandPoolTo(int width, int height)
-    {
-        expandPool(Math.max(0, width + 3 - POOL.length), Math.max(0, height + 3 - POOL[0].length));
-    }
-
-    /**
-     * Enlarges the pool of cached Coords by the given amount of expansion for x and y.
-     * Cached Coord values will be reused by Coord.get instead of re-allocated each time.
-     * The default pool allows Coords with x and y each between -3 and 255, inclusive, to
-     * be cached, and this can increase the size in the positive direction. If either
-     * xIncrease or yIncrease is negative, this method returns immediately and does nothing
-     * else; the same is true of both arguments are zero. You cannot shrink the pool size.
-     * @param xIncrease the amount to increase cache's width by
-     * @param yIncrease the amount to increase cache's height by
-     */
-    public static void expandPool(int xIncrease, int yIncrease)
-    {
-        if(xIncrease < 0 || yIncrease < 0 || (xIncrease | yIncrease) == 0 )
-            return;
-        int width = POOL.length, height = POOL[0].length;
-        Coord[][] POOL2 = new Coord[width + xIncrease][height + yIncrease];
-        for (int i = 0; i < width; i++) {
-            POOL2[i] = new Coord[height + yIncrease];
-            System.arraycopy(POOL[i], 0, POOL2[i], 0, height);
-            for (int j = 0; j < height + yIncrease; j++) {
-                if(POOL2[i][j] == null) POOL2[i][j] = new Coord(i - 3, j - 3);
-            }
-        }
-        for (int i = width; i < width + xIncrease; i++) {
-            POOL2[i] = new Coord[height + yIncrease];
-            for (int j = 0; j < height + yIncrease; j++) {
-                POOL2[i][j] = new Coord(i - 3, j - 3);
-            }
-        }
-        POOL = POOL2;
-    }
+	/**
+	 * Returns true if x is between 0 (inclusive) and width (exclusive) and y is
+	 * between 0 (inclusive) and height (exclusive), false otherwise.
+	 * 
+	 * @param width
+	 *            the upper limit on x to check, exclusive
+	 * @param height
+	 *            the upper limit on y to check, exclusive
+	 * @return true if this Coord is within the limits of width and height and has
+	 *         non-negative x and y
+	 */
+	public boolean isWithin(int width, int height) {
+		return x >= 0 && y >= 0 && x < width && y < height;
+	}
+
+	/**
+	 * Returns true if x is between minX (inclusive) and maxX (exclusive) and y is
+	 * between minY (inclusive) and maxY (exclusive), false otherwise.
+	 * 
+	 * @param minX
+	 *            the lower limit on x to check, inclusive
+	 * @param minY
+	 *            the lower limit on y to check, inclusive
+	 * @param maxX
+	 *            the upper limit on x to check, exclusive
+	 * @param maxY
+	 *            the upper limit on y to check, exclusive
+	 * @return true if this Coord is within the limits of the given parameters
+	 */
+	public boolean isWithinRectangle(int minX, int minY, int maxX, int maxY) {
+		return x >= minX && y >= minY && x < maxX && y < maxY;
+	}
+
+	public int getX() {
+		return x;
+	}
+
+	public Coord setX(int x) {
+		return get(x, y);
+	}
+
+	public int getY() {
+		return y;
+	}
+
+	public Coord setY(int y) {
+		return get(x, y);
+	}
+
+	@Override
+	public String toString() {
+		return "(" + x + "," + y + ")";
+	}
+
+	@Override
+	public int hashCode() {
+		int hash = 7;
+		hash = 113 * hash + x;
+		hash = 113 * hash + y;
+		return hash;
+	}
+
+	/**
+	 * Something like hashCode(), but reversible with {@code Coord.decode()}. Works
+	 * for Coords between roughly -256 and 32000 in each of x and y, but will
+	 * probably only decode to pooled Coords if x and y are both between -3 and 255
+	 * (inclusive for both).
+	 * 
+	 * @return an int as a unique code for this Coord
+	 */
+	public int encode() {
+		return ((x + 256) << 16) ^ (y + 256);
+	}
+
+	/**
+	 * An alternative to getting a Coord with Coord.get() only to encode() it as the
+	 * next step. This doesn't create a Coord in the middle step. Can be decoded
+	 * with Coord.decode() to get the (x,y) Coord.
+	 * 
+	 * @param x
+	 *            the x position to encode
+	 * @param y
+	 *            the y position to encode
+	 * @return the coded int that a Coord at (x,y) would produce with encode()
+	 */
+	public static int pureEncode(int x, int y) {
+		return ((x + 256) << 16) ^ (y + 256);
+	}
+
+	/**
+	 * This can take an int produced by {@code someCoord.encode()} and get the
+	 * original Coord back out of it. It works for all pooled Coords where the pool
+	 * hasn't been expanded past about 32,000 in either dimension. It even works for
+	 * Coords with negative x or y as well, if they are no lower than -256 in either
+	 * dimension. This will almost certainly fail (producing a gibberish Coord that
+	 * probably won't be pooled) on hashes produced by any other class, including
+	 * subclasses of Coord.
+	 * 
+	 * @param code
+	 *            an encoded int from a Coord, but not a subclass of Coord
+	 * @return the Coord that gave hash as its hashCode()
+	 */
+	public static Coord decode(int code) {
+		return get((code >>> 16) - 256, (code & 0xFFFF) - 256);
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (o instanceof Coord) {
+			Coord other = (Coord) o;
+			return x == other.x && y == other.y;
+		} else {
+			return false;
+		}
+	}
+
+	private static Coord[][] POOL = new Coord[259][259];
+	static {
+		int width = POOL.length, height = POOL[0].length;
+		for (int i = 0; i < width; i++) {
+			for (int j = 0; j < height; j++) {
+				POOL[i][j] = new Coord(i - 3, j - 3);
+			}
+		}
+	}
+
+	/**
+	 * Gets the width of the pool used as a cache for Coords, not including negative
+	 * Coords. Unless expandPool() has been called, this should be 256. Useful for
+	 * finding the upper (exclusive) bound for x values that can be used efficiently
+	 * in Coords. Requesting a Coord with a x greater than or equal to this value
+	 * will result in a new Coord being allocated and not cached, which may cause
+	 * problems with code that expects the normal reference equality of Coords to be
+	 * upheld and in extreme cases may require more time garbage collecting than is
+	 * normally necessary.
+	 * 
+	 * @return the width of the Coord cache, disregarding negative Coords
+	 */
+	public static int getCacheWidth() {
+		return POOL.length - 3;
+	}
+
+	/**
+	 * Gets the height of the pool used as a cache for Coords, not including
+	 * negative Coords. Unless expandPool() has been called, this should be 256.
+	 * Useful for finding the upper (exclusive) bound for y values that can be used
+	 * efficiently in Coords. Requesting a Coord with a y greater than or equal to
+	 * this value will result in a new Coord being allocated and not cached, which
+	 * may cause problems with code that expects the normal reference equality of
+	 * Coords to be upheld and in extreme cases may require more time garbage
+	 * collecting than is normally necessary.
+	 * 
+	 * @return the height of the Coord cache, disregarding negative Coords
+	 */
+	public static int getCacheHeight() {
+		return POOL[0].length - 3;
+	}
+
+	/**
+	 * Enlarges the pool of cached Coords to the given width and height, and doesn't
+	 * change a dimension if it would be reduced in size. Cached Coord values will
+	 * be reused by Coord.get instead of re-allocated each time. The default pool
+	 * allows Coords with x and y each between -3 and 255, inclusive, to be cached,
+	 * and is considered to have width and height of 256 to begin with. Giving a
+	 * width greater than 256 will allow Coords with x greater than 255 to be
+	 * cached; likewise for height. If width or height is smaller than the current
+	 * cache width or height, that dimension will not change, but the other still
+	 * may if it is valid. You cannot shrink the pool size.
+	 * 
+	 * @param width
+	 *            the new width for the pool of cached Coords; will be ignored if
+	 *            smaller than the current width
+	 * @param height
+	 *            the new height for the pool of cached Coords; will be ignored if
+	 *            smaller than the current height
+	 */
+	public static void expandPoolTo(int width, int height) {
+		expandPool(Math.max(0, width + 3 - POOL.length), Math.max(0, height + 3 - POOL[0].length));
+	}
+
+	/**
+	 * Enlarges the pool of cached Coords by the given amount of expansion for x and
+	 * y. Cached Coord values will be reused by Coord.get instead of re-allocated
+	 * each time. The default pool allows Coords with x and y each between -3 and
+	 * 255, inclusive, to be cached, and this can increase the size in the positive
+	 * direction. If either xIncrease or yIncrease is negative, this method returns
+	 * immediately and does nothing else; the same is true of both arguments are
+	 * zero. You cannot shrink the pool size.
+	 * 
+	 * @param xIncrease
+	 *            the amount to increase cache's width by
+	 * @param yIncrease
+	 *            the amount to increase cache's height by
+	 */
+	public static void expandPool(int xIncrease, int yIncrease) {
+		if (xIncrease < 0 || yIncrease < 0 || (xIncrease | yIncrease) == 0)
+			return;
+		int width = POOL.length, height = POOL[0].length;
+		Coord[][] POOL2 = new Coord[width + xIncrease][height + yIncrease];
+		for (int i = 0; i < width; i++) {
+			POOL2[i] = new Coord[height + yIncrease];
+			System.arraycopy(POOL[i], 0, POOL2[i], 0, height);
+			for (int j = 0; j < height + yIncrease; j++) {
+				if (POOL2[i][j] == null)
+					POOL2[i][j] = new Coord(i - 3, j - 3);
+			}
+		}
+		for (int i = width; i < width + xIncrease; i++) {
+			POOL2[i] = new Coord[height + yIncrease];
+			for (int j = 0; j < height + yIncrease; j++) {
+				POOL2[i][j] = new Coord(i - 3, j - 3);
+			}
+		}
+		POOL = POOL2;
+	}
 }

+ 0 - 16
squidlib/src/main/java/squidpony/squidgrid/gui/gdx/Filter.java

@@ -1,16 +0,0 @@
-package squidpony.squidgrid.gui.gdx;
-
-import com.badlogic.gdx.graphics.Color;
-
-import squidpony.IFilter;
-
-/**
- * An abstract class that handles changes between a given color component and an actual one, and may carry state as a
- * float array.
- * Created by Tommy Ettinger on 10/31/2015.
- */
-public abstract class Filter<T extends Color> implements IFilter<T> {
-
-    public float[] state;
-
-}

+ 11 - 12
squidlib/src/main/java/squidpony/squidgrid/gui/gdx/GrayscaleFilter.java

@@ -5,18 +5,17 @@ import com.badlogic.gdx.graphics.Color;
 import squidpony.IFilter;
 
 /**
- * A Filter that converts all colors passed to it to grayscale, like a black and white film.
+ * A Filter that converts all colors passed to it to grayscale, like a black and
+ * white film.
  */
-public class GrayscaleFilter implements IFilter<Color>
-{
-    public GrayscaleFilter()
-    {
-    	/* Nothing to do */
-    }
+public class GrayscaleFilter implements IFilter<Color> {
+	public GrayscaleFilter() {
+		/* Nothing to do */
+	}
 
-    @Override
-    public Color alter(float r, float g, float b, float a) {
-        float v = (r + g + b) / 3f;
-        return new Color(v, v, v, a);
-    }
+	@Override
+	public Color alter(float r, float g, float b, float a) {
+		float v = (r + g + b) / 3f;
+		return new Color(v, v, v, a);
+	}
 }

+ 1 - 1
squidlib/src/main/java/squidpony/squidgrid/gui/gdx/SquidColorCenter.java

@@ -12,7 +12,7 @@ import squidpony.squidmath.StatefulRNG;
 /**
  * A concrete implementation of {@link IColorCenter} for libgdx's
  * {@link com.badlogic.gdx.graphics.Color}. Supports filtering any colors that
- * this creates using a {@link Filter}, such as one from {@link Filters}.
+ * this creates using a {@code Filter}, such as one from {@link Filters}.
  *
  * @author smelC
  * @author Tommy Ettinger

+ 10 - 66
squidlib/src/main/java/squidpony/squidgrid/gui/gdx/SquidPanel.java

@@ -37,7 +37,6 @@ public class SquidPanel extends Group implements ISquidPanel<Color> {
 	public float DEFAULT_ANIMATION_DURATION = 0.12F;
 	protected int animationCount = 0;
 	protected Color defaultForeground = Color.WHITE;
-	protected IColorCenter<Color> scc;
 	protected final int cellWidth, cellHeight;
 	protected int gridWidth, gridHeight, gridOffsetX = 0, gridOffsetY = 0;
 	protected final String[][] contents;
@@ -108,7 +107,7 @@ public class SquidPanel extends Group implements ISquidPanel<Color> {
 	 *            the factory to use for cell rendering
 	 */
 	public SquidPanel(int gridWidth, int gridHeight, TextCellFactory factory) {
-		this(gridWidth, gridHeight, factory, DefaultResources.getSCC());
+		this(gridWidth, gridHeight, factory, 0f, 0f);
 	}
 
 	/**
@@ -130,37 +129,9 @@ public class SquidPanel extends Group implements ISquidPanel<Color> {
 	 *            The color center to use. Can be {@code null}, but then must be set
 	 *            later on with {@link #setColorCenter(IColorCenter)}.
 	 */
-	public SquidPanel(int gridWidth, int gridHeight, TextCellFactory factory, IColorCenter<Color> center) {
-		this(gridWidth, gridHeight, factory, center, 0f, 0f);
-	}
-
-	/**
-	 * Builds a panel with the given grid size and all other parameters determined
-	 * by the factory. Even if sprite images are being used, a TextCellFactory is
-	 * still needed to perform sizing and other utility functions.
-	 *
-	 * If the TextCellFactory has not yet been initialized, then it will be sized at
-	 * 12x12 px per cell. If it is null then a default one will be created and
-	 * initialized.
-	 *
-	 * @param gridWidth
-	 *            the number of cells horizontally
-	 * @param gridHeight
-	 *            the number of cells vertically
-	 * @param factory
-	 *            the factory to use for cell rendering
-	 * @param center
-	 *            The color center to use. Can be {@code null}, but then must be set
-	 *            later on with {@link #setColorCenter(IColorCenter)}.
-	 */
-	public SquidPanel(int gridWidth, int gridHeight, TextCellFactory factory, IColorCenter<Color> center, float xOffset,
-			float yOffset) {
+	public SquidPanel(int gridWidth, int gridHeight, TextCellFactory factory, float xOffset, float yOffset) {
 		this.gridWidth = gridWidth;
 		this.gridHeight = gridHeight;
-		if (center == null)
-			scc = DefaultResources.getSCC();
-		else
-			scc = center;
 
 		if (factory == null) {
 			textFactory = new TextCellFactory();
@@ -176,7 +147,7 @@ public class SquidPanel extends Group implements ISquidPanel<Color> {
 		contents = new String[gridWidth][gridHeight];
 		colors = new Color[gridWidth][gridHeight];
 		for (int i = 0; i < gridWidth; i++) {
-			Arrays.fill(colors[i], scc.filter(Color.CLEAR));
+			Arrays.fill(colors[i], Color.CLEAR);
 		}
 
 		int w = gridWidth * cellWidth;
@@ -295,7 +266,7 @@ public class SquidPanel extends Group implements ISquidPanel<Color> {
 		for (IColoredString.Bucket<? extends Color> fragment : cs) {
 			final String s = fragment.getText();
 			final Color color = fragment.getColor();
-			put(x, yOffset, s, color == null ? getDefaultForegroundColor() : scc.filter(color));
+			put(x, yOffset, s, color == null ? getDefaultForegroundColor() : color);
 			x += s.length();
 		}
 	}
@@ -429,7 +400,7 @@ public class SquidPanel extends Group implements ISquidPanel<Color> {
 			return;// skip if out of bounds
 		}
 		contents[x][y] = String.valueOf(c);
-		colors[x][y] = scc.filter(color);
+		colors[x][y] = color; // scc.filter(color);
 	}
 
 	@Override
@@ -484,7 +455,7 @@ public class SquidPanel extends Group implements ISquidPanel<Color> {
 		int inc = onlyRenderEven ? 2 : 1;
 		for (int x = gridOffsetX; x < gridWidth; x += inc) {
 			for (int y = gridOffsetY; y < gridHeight; y += inc) {
-				tmp = scc.filter(colors[x][y]);
+				tmp = colors[x][y];
 				textFactory.draw(batch, contents[x][y], tmp, xOffset + /*- getX() + 1f * */ x * cellWidth,
 						yOffset + /*- getY() + 1f * */ (gridHeight - y) * cellHeight + 1f);
 			}
@@ -558,7 +529,7 @@ public class SquidPanel extends Group implements ISquidPanel<Color> {
 		if (name == null || name.isEmpty())
 			return null;
 		else {
-			final Actor a = textFactory.makeActor(name, scc.filter(color));
+			final Actor a = textFactory.makeActor(name, color);
 			a.setName(name);
 			a.setPosition(adjustX(x, doubleWidth) - getX() * 2, adjustY(y) - getY() * 2);
 			addActor(a);
@@ -983,7 +954,7 @@ public class SquidPanel extends Group implements ISquidPanel<Color> {
 		duration = clampDuration(duration);
 		ae.animating = true;
 		animationCount++;
-		Color ac = scc.filter(a.getColor());
+		Color ac = a.getColor();
 		a.addAction(Actions.sequence(Actions.color(color, duration * 0.3f), Actions.color(ac, duration * 0.7f),
 				Actions.delay(duration, Actions.run(new Runnable() {
 					@Override
@@ -1043,7 +1014,7 @@ public class SquidPanel extends Group implements ISquidPanel<Color> {
 		duration = clampDuration(duration);
 		animationCount++;
 
-		Color ac = scc.filter(a.getColor());
+		Color ac = a.getColor();
 
 		final int nbActions = 3 + (0 < delay ? 1 : 0) + (postRunnable == null ? 0 : 1);
 		final Action[] sequence = new Action[nbActions];
@@ -1105,7 +1076,7 @@ public class SquidPanel extends Group implements ISquidPanel<Color> {
 			return;
 		duration = clampDuration(duration);
 		animationCount++;
-		final Color c = scc.filter(color);
+		final Color c = color;
 		a.addAction(Actions.sequence(Actions.color(c, duration), Actions.run(new Runnable() {
 			@Override
 			public void run() {
@@ -1136,33 +1107,6 @@ public class SquidPanel extends Group implements ISquidPanel<Color> {
 		return this;
 	}
 
-	/**
-	 * @return The current color center. Never {@code null}.
-	 */
-	public IColorCenter<Color> getColorCenter() {
-		return scc;
-	}
-
-	/**
-	 * Use this method if you use your own {@link IColorCenter} and want this panel
-	 * not to allocate its own colors (or fill {@link DefaultResources#getSCC()} but
-	 * instead to the provided center.
-	 * 
-	 * @param scc
-	 *            The color center to use. Should not be {@code null}.
-	 * @return {@code this}
-	 * @throws NullPointerException
-	 *             If {@code scc} is {@code null}.
-	 */
-	@Override
-	public SquidPanel setColorCenter(IColorCenter<Color> scc) {
-		if (scc == null)
-			/* Better fail now than later */
-			throw new NullPointerException("The color center should not be null in " + getClass().getSimpleName());
-		this.scc = scc;
-		return this;
-	}
-
 	public String getAt(int x, int y) {
 		if (contents[x][y] == null)
 			return "";

+ 7 - 9
squidlib/src/main/java/squidpony/squidgrid/gui/gdx/SquidPanelBuilder.java

@@ -44,16 +44,16 @@ public abstract class SquidPanelBuilder extends IPanelBuilder.Skeleton {
 	 * @param largestFont
 	 *            The largest font size available.
 	 * @param fontOffset
-	 *            This offset is added to the cell size when computing the font
-	 *            size for a given cell size.
+	 *            This offset is added to the cell size when computing the font size
+	 *            for a given cell size.
 	 * @param icc
 	 *            The color center to give to
-	 *            {@link SquidPanel#setColorCenter(IColorCenter)}, or
-	 *            {@code null} not to call this method.
+	 *            {@link SquidPanel#setColorCenter(IColorCenter)}, or {@code null}
+	 *            not to call this method.
 	 * @param assetManager
 	 */
-	public SquidPanelBuilder(int smallestFont, int largestFont, int fontOffset,
-			/* @Nullable */IColorCenter<Color> icc, /* @Nullable */ AssetManager assetManager) {
+	public SquidPanelBuilder(int smallestFont, int largestFont, int fontOffset, /* @Nullable */IColorCenter<Color> icc,
+			/* @Nullable */ AssetManager assetManager) {
 		this.icc = icc;
 		this.assetManager = assetManager;
 
@@ -78,7 +78,7 @@ public abstract class SquidPanelBuilder extends IPanelBuilder.Skeleton {
 
 	@Override
 	public SquidPanel buildByCells(int hCells, int vCells, int cellWidth, int cellHeight,
-			/*@Nullable*/ TextCellFactory tcf_) {
+			/* @Nullable */ TextCellFactory tcf_) {
 		final TextCellFactory tcf;
 		final boolean freshTCF;
 		if (tcf_ != null && tcf_.width() == cellWidth && tcf_.height() == cellHeight) {
@@ -105,8 +105,6 @@ public abstract class SquidPanelBuilder extends IPanelBuilder.Skeleton {
 				tcf.width(cellWidth).height(cellHeight);
 			}
 			final SquidPanel result = new SquidPanel(hCells, vCells, tcf);
-			if (icc != null)
-				result.setColorCenter(icc);
 			if (defaultForegroundColor != null)
 				result.setDefaultForeground(defaultForegroundColor);
 			return result;