import java.awt.Dimension; import java.util.ArrayList; public class Map { private final Dimension size; // TODO: is there a particular reason to not use a 2D array? private final Tile grid[]; private ArrayList actors = new ArrayList(); // TODO: rename to selectedActor? private int actorIndex = -1; // TODO: make selectedTile? Tile contains x and y members private int selectedX; private int selectedY; public Map(Dimension size) { this.size = size; // Populate grid with GRASS tiles this.grid = new Tile[this.size.width * this.size.height]; for (int x = 0; x < this.size.width; x++) { for (int y = 0; y < this.size.height; y++) { this.grid[x * this.size.width + y] = new Tile(Tile.Type.GRASS, x, y); } } } // pathfinding algorithm public ArrayList getPath(Actor actor, int x, int y) { ArrayList unsettled = new ArrayList(); ArrayList settled = new ArrayList(); Tile startTile = this.getTile(actor.getX(), actor.getY()); for (Tile i : this.getGrid()) { i.setDistance(10000000); } startTile.setDistance(0); unsettled.add(startTile); settled.add(startTile); boolean stop = false; while (unsettled.size() != 0) { Tile workingTile = unsettled.get(0); unsettled.remove(workingTile); for (Tile i : workingTile.getAdjacent(this)) { if (settled.contains(i)) { continue; } i.setDistance(i.getCost(actor) + workingTile.getDistance()); unsettled.add(i); settled.add(i); } } ArrayList out = new ArrayList(); Tile workingTile = this.getTile(x, y); double bestDistance = 1000000000; Tile bestTile = workingTile; while (true) { for (Tile i : workingTile.getAdjacent(this)) { if (i.getDistance() < bestDistance) { bestDistance = i.getDistance(); bestTile = i; } } out.add(workingTile); if (workingTile.getX() == startTile.getX() && workingTile.getY() == startTile.getY()) { break; } workingTile = bestTile; bestDistance = 1000000000; } return out; } public void update(ArrayList actorsList, Tile[] tileGrid) { // TODO: if this is needed for something, implement copy constructors for Actor and Tile // and delete this code for (Actor actor : actorsList) { Actor newActor = new Actor(actor.getName(), actor.getHP(), actor.isEnemy(), actor.getSkills().agility); newActor.place(actor.getX(), actor.getY()); this.actors.add(newActor); } for (int x = 0; x < this.size.width; x++) { for (int y = 0; y < this.size.height; y++) { Tile.Type oldTileType = tileGrid[x * this.size.width + y].getType(); this.grid[x * this.size.width + y] = new Tile(oldTileType, x, y); } } } // TODO: refractor to resetActorActions(); public void resetActors() { for (Actor actor : this.actors) { if (!actor.isEnemy()) { actor.resetActions(); } } } public Actor getNextActor() { int counter = 0; this.actorIndex++; if (this.actorIndex >= this.actors.size()) { this.actorIndex = 0; } Actor actor = this.actors.get(this.actorIndex); while (actor.isEnemy() || actor.getActionsLeft() <= 0) { this.actorIndex++; if (this.actorIndex >= this.actors.size()) { this.actorIndex = 0; } actor = this.actors.get(this.actorIndex); if (counter > this.actors.size()*2) { return null; } counter++; } return actor; } // TODO: there is the Map cursor and the Mouse cursor, // a solution to the naming shall be found public void setCursor(int x, int y) { this.getTile(this.selectedX, this.selectedY).setCursor(false); if (x == -1 && y == -1) { return; } this.getTile(x, y).setCursor(true); this.selectedX = x; this.selectedY = y; } public Tile[] getGrid() { return this.grid; } public Tile getTile(int x, int y) { return this.grid[x * this.size.width + y]; } public int getSize() { return this.size.width; } public ArrayList getActors() { return this.actors; } public void removeActor(Actor actor) { this.actors.remove(actor); } public void addActor(Actor actor) { this.actors.add(actor); } // TODO: remove by introducing selectedTile member public void clearSelected() { for (Tile tile : this.grid) { tile.setSelected(false); } } }