package dev.llan.model.board; import dev.llan.model.board.Tile.TileType; import java.util.ArrayList; import java.util.List; public class Grid implements Cloneable { private Tile[][] map; private int rowSize; private int colSize; public Grid(int size) { this(size, size, true); } public Grid(int rowSize, int colSize, boolean init) { this.rowSize = rowSize; this.colSize = colSize; this.map = new Tile[rowSize][colSize]; if (init) { for (int row = 0; row < rowSize; row++) { initRow(row); } } } public void setGrid(Tile[][] newMap) { this.map = newMap; } private void initRow(int row) { for (int col = 0; col < colSize; col++) { map[row][col] = new Tile(new Point(row, col), Tile.TileType.VACANT); } } public int getRowSize() { return rowSize; } public int getColSize() { return colSize; } public boolean validPosition(Point position) { int row = position.getRow(); int col = position.getCol(); if (withinIndices(row, rowSize) && withinIndices(col, colSize)) { return tileAt(position).getType() == TileType.VACANT; } return false; } public boolean attackablePosition(Point position) { int row = position.getRow(); int col = position.getCol(); if (withinIndices(row, rowSize) && withinIndices(col, colSize)) { return tileAt(position).getType() != TileType.UNMOVABLE; } return false; } public double getMovementCost(Point neighbor, Point parent) { Tile neighborTile = tileAt(neighbor); double baseCost = neighborTile.getTerrainCost(); int dRow = Math.abs(neighbor.getRow() - parent.getRow()); int dCol = Math.abs(neighbor.getCol() - parent.getCol()); return baseCost * Math.sqrt(dRow * dRow + dCol * dCol); } private boolean withinIndices(int index, int maxIndex) { return 0 <= index && index < maxIndex; } public Tile tileAt(Point position) { return map[position.getRow()][position.getCol()]; } public void updateVisibilities(Point center, double radius) { this.tileAt(center).setVisible(true); List potentialPoints = withinSquare(center, radius); for (Point point : potentialPoints) { if (Point.getDistance(center, point) <= radius) { this.tileAt(point).setVisible(true); } } } private List withinSquare(Point center, double radius) { List points = new ArrayList<>(); int maxRadius = (int) Math.ceil(radius); int row = center.getRow(); int col = center.getCol(); for (int dRow = -maxRadius; dRow <= maxRadius; dRow++) { for (int dCol = -maxRadius; dCol <= maxRadius; dCol++) { if (dRow == 0 && dCol == 0) continue; int newRow = row + dRow; int newCol = col + dCol; if (withinIndices(newRow, rowSize) && withinIndices(newCol, colSize)) { Point point = new Point(newRow, newCol); points.add(point); } } } return points; } @Override protected Grid clone() { Grid clone = new Grid(this.rowSize, this.colSize, false); for (int row = 0; row < this.rowSize; row++) { for (int col = 0; col < this.colSize; col++) { clone.map[row][col] = this.map[row][col].clone(); } } return clone; } }