Newer
Older
maze / src / main / net / curtlewis / maze / grid / Cell.java
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;
    }
}