package net.curtlewis.maze.grid; import java.util.Map; import net.curtlewis.maze.distance.Distances; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class Cell { private int row; private int col; private Map<Cell, Boolean> links; private Cell north; private Cell south; private Cell east; private Cell west; private Distances distances; public Cell(int row, int col) { this.row = row; this.col = col; this.links = new HashMap<Cell, Boolean>(); } public int getRow() { return row; } public int getCol() { return col; } public Cell getNorth() { return north; } public void setNorth(Cell cell) { north = cell; } public Cell getSouth() { return south; } public void setSouth(Cell cell) { south = cell; } public Cell getEast() { return east; } public void setEast(Cell cell) { east = cell; } public Cell getWest() { return west; } public void setWest(Cell cell) { west = cell; } /** * Link a this cell with its neighbor `cell`. If `bidi` is true * set `cell` link back to this cell. * @param cell Neighboring cell of this cell * @param bidi bidirectional linking boolean */ public void link(Cell cell, boolean bidi) { links.put(cell, true); if (bidi) { cell.link(this, false); } } public void link(Cell cell) { link(cell, true); } /** * Unlink this cell from its neighbor `cell`. If `bidi` is true * unlink `cell` from this cell. * @param cell * @param bidi */ public void unlink(Cell cell, boolean bidi) { if (links.containsKey(cell)) { links.remove(cell); } if (bidi) { cell.unlink(this, false); } } public void unlink(Cell cell) { unlink(cell, true); } public List<Cell> getLinks() { return new ArrayList<>(links.keySet()); } public boolean hasLink(Cell cell) { return links.containsKey(cell); } public List<Cell> neighbors() { ArrayList<Cell> list = new ArrayList<>(); if (north != null) { list.add(north); } if (south != null) { list.add(south); } if (east != null) { list.add(east); } if (west != null) { list.add(west); } return list; } public String toString() { return "Cell[row: " + row + " col: " + col + "]"; } public Distances getDistances() { return distances; } public Distances calculateDistances() { distances = new Distances(this); List<Cell> frontier = new ArrayList<>(); frontier.add(this); while(frontier.size() > 0) { List<Cell> newFrontier = new ArrayList<>(); frontier.forEach(cell -> { cell.getLinks().forEach(linked -> { if (!distances.getCells().contains(linked)) { distances.setDistanceTo(linked, distances.getDistance(cell) + 1); newFrontier.add(linked); } }); }); frontier = newFrontier; } return distances; } }