package game.entries.ghosts; import game.core.Game; import java.awt.Point; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; /** * Grid class with utilities for path-finding and sorting cells. * @author toriscope * */ public class GD { final private Map<Point, Integer> map; private Game game; public final static int CELL_PIXEL_SEPERATION = 4; public static final Direction[] CARDINAL = new Direction[]{Direction.DOWN, Direction.UP, Direction.LEFT, Direction.RIGHT}; public GD() { map = new HashMap<Point, Integer>(); game = null; } /** * Call this each step. * @param game */ public void rebuildMap(final Game game) { map.clear(); this.game = game; for (int i = 0; i < 1291; i++) { Point p = new Point(game.getX(i), game.getY(i)); map.put(p, i); } } public boolean isValid(final Point p) { return map.containsKey(p); } public int getIndex(final Point p) { if (isValid(p)) { return map.get(p); } else { return -1; } } public List<Direction> getAllowedCellsSurrounding(final Point origin) { final List<Direction> newDirs = new LinkedList<Direction>(); for (Direction d : CARDINAL) { if (isValid(add(origin, d.offset))) { newDirs.add(d); } } Collections.shuffle(newDirs); // Shuffle to ensure random tie-breaking return newDirs; } public static Comparator<Direction> buildTargetComparator( final Point origin, final Point target) { return new Comparator<Direction>() { public int compare(Direction o1, Direction o2) { Float a = distance(add(origin, o1.offset), target); Float b = distance(add(origin, o2.offset), target); return a.compareTo(b); } }; } public static enum Direction { NONE(-1, new Point(0, 0)), UP(Game.UP, new Point(0, -CELL_PIXEL_SEPERATION)), RIGHT(Game.RIGHT, new Point(CELL_PIXEL_SEPERATION, 0)), DOWN(Game.DOWN, new Point(0,CELL_PIXEL_SEPERATION)), LEFT(Game.LEFT, new Point(-CELL_PIXEL_SEPERATION, 0)); final public int num; final public Point offset; private Direction(final int num, final Point p) { this.num = num; this.offset = p; } public static Direction getDIR(final int d) { for (Direction s : Direction.values()) { if (d == s.num) return s; } return Direction.NONE; } public static Direction getOpDIR(int dir) { switch(Direction.getDIR(dir)) { case UP: return DOWN; case DOWN: return UP; case LEFT: return RIGHT; case RIGHT: return LEFT; default: break; } return null; } } public static float distance(final Point a, final Point b) { return (float) Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2)); } public static Point add(final Point a, final Point b) { return new Point(a.x + b.x, a.y + b.y); } public static Point sub(final Point a, final Point b) { return add(a, scale(b, -1)); } public static Point scale(final Point a, final int scalar) { return new Point(a.x * scalar, a.y * scalar); } public Point toPoint(int loc) { return new Point(game.getX(loc), game.getY(loc)); } }