package com.kartoflane.ftl.floorgen; import java.awt.Point; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; /** * A simple undirected point graph to hold the shape of the room layout in a more usable fashion. * * The graph is symmetric, irreflexive and not transitive. */ class Graph implements Iterable<Point> { private Map<Point, List<Point>> adjMap; public Graph() { adjMap = new HashMap<Point, List<Point>>(); } /** * Creates a shallow copy of the specified graph. */ public Graph(Graph graph) { this(); adjMap.putAll(graph.adjMap); } public Iterator<Point> iterator() { return adjMap.keySet().iterator(); } public void addEdge(Point v1, Point v2) { newEdge(v1, v2); newEdge(v2, v1); } public void removeEdge(Point v1, Point v2) { delEdge(v1, v2); delEdge(v2, v1); } public boolean hasEdge(Point v1, Point v2) { List<Point> list = adjMap.get(v1); if (list == null) return false; return list.contains(v2); } public boolean hasEdge(Point v1, int v2x, int v2y) { return hasEdge(v1, new Point(v2x, v2y)); } public boolean hasEdge(int v1x, int v1y, int v2x, int v2y) { return hasEdge(new Point(v1x, v1y), new Point(v2x, v2y)); } public List<Point> listNeighbours(Point v) { if (adjMap.get(v) == null) return new ArrayList<Point>(); else return new ArrayList<Point>(adjMap.get(v)); } public int countEdges(Point v) { if (adjMap.get(v) == null) return 0; else return adjMap.get(v).size(); } /** * Prints the graph in the form of a table. Each row represents a point in the graph, * and numbers listed in that row indicate points that row is connected to. */ public String toString() { int f = 1, s = adjMap.keySet().size(); while (s > 0) { s /= 10; f += 1; } StringBuilder buf = new StringBuilder(); int i = 1; for (Point v : adjMap.keySet()) { buf.append(String.format("%-" + f + "s", i)); buf.append(String.format("%11s", toString(v))); buf.append(": "); List<Point> l = adjMap.get(v); int j = 1; for (Point w : adjMap.keySet()) { if (l.contains(w)) { buf.append(String.format("%" + f + "s", j)); } j++; } buf.append("\n"); i++; } return buf.toString(); } private String toString(Point v) { return "{ " + v.x + ", " + v.y + " }"; } /* * Private methods */ private void delEdge(Point v1, Point v2) { List<Point> list = adjMap.get(v1); if (list == null) return; list.remove(v2); if (list.isEmpty()) adjMap.remove(v1); } private void newEdge(Point v1, Point v2) { List<Point> list = adjMap.get(v1); if (list == null) { list = new LinkedList<Point>(); adjMap.put(v1, list); } if (!list.contains(v2) && !v1.equals(v2)) list.add(v2); } }