package dev.llan.model.board; import java.util.ArrayList; import java.util.List; import java.util.Objects; public class Point implements Cloneable { private static final int[][] neighborTranslations = { {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1} }; private static final double ROOT2 = 1.42; public static double getDistance(Point a, Point b) { double squaredSum = Math.pow((a.col - b.col), 2) + Math.pow((a.row - b.row), 2); return Math.sqrt(squaredSum); } public static double getManhattanDistance(Point a, Point b) { return Math.abs(a.col - b.col) + Math.abs(a.row - b.row); } private final int row; private final int col; public Point(int row, int col) { this.row = row; this.col = col; } public int getRow() { return row; } public int getCol() { return col; } public List findImmediateNeighbors(Grid grid) { List neighbors = new ArrayList<>(); for (int[] translation : neighborTranslations) { Point neighbor = new Point(this.row + translation[0], this.col + translation[1]); if (grid.validPosition(neighbor)) { neighbors.add(neighbor); } } return neighbors; } public List findWithin(Grid grid, double radius, boolean includeEntities) { List nearby = new ArrayList<>(); int maxDistance = (int) Math.ceil(radius); for(int row = -maxDistance; row <= maxDistance; row++) { for(int col = -maxDistance; col <= maxDistance; col++) { if(row == 0 && col == 0) { continue; } Point neighbor = new Point(this.row + row, this.col + col); addIfNearbyPoint(grid, nearby, neighbor, radius, includeEntities); } } return nearby; } private void addIfNearbyPoint(Grid grid, List nearby, Point neighbor, double radius, boolean includeEntities) { boolean shouldAdd; if(includeEntities) { shouldAdd = grid.attackablePosition(neighbor); } else { shouldAdd = grid.validPosition(neighbor); } if(shouldAdd) { double distance = Point.getDistance(this, neighbor); if(distance <= radius) { nearby.add(neighbor); } } } public List findClosestVacant(Grid grid) { double radius = ROOT2; List withinRadius = this.findWithin(grid, radius, false); while (withinRadius.isEmpty()) { radius += ROOT2; withinRadius = this.findWithin(grid, radius, false); } return withinRadius; } public Point translate(int dRow, int dCol) { return new Point(this.row + dRow, this.col + dCol); } @Override public String toString() { return "(" + row + "," + col + ")"; } @Override public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; Point point = (Point) o; return row == point.row && col == point.col; } @Override public int hashCode() { return Objects.hash(row, col); } @Override public Point clone() { Point clone = new Point(this.row, this.col); return clone; } }