package games.strategy.engine.data; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import games.strategy.util.Match; // TODO this class doesn't take movementcost into account... typically the shortest route is the fastest route, but not // always... public class RouteFinder { private final GameMap m_map; private final Match<Territory> m_condition; private final Map<Territory, Territory> m_previous; public RouteFinder(final GameMap map, final Match<Territory> condition) { m_map = map; m_condition = condition; m_previous = new HashMap<>(); } public Route findRoute(final Territory start, final Territory end) { final Set<Territory> startSet = m_map.getNeighbors(start, m_condition); for (final Territory t : startSet) { m_previous.put(t, start); } if (calculate(startSet, end)) { return getRoute(start, end); } return null; } private boolean calculate(final Set<Territory> startSet, final Territory end) { final Set<Territory> nextSet = new HashSet<>(); for (final Territory t : startSet) { final Set<Territory> neighbors = m_map.getNeighbors(t, m_condition); for (final Territory neighbor : neighbors) { if (!m_previous.containsKey(neighbor)) { m_previous.put(neighbor, t); if (neighbor.equals(end)) { return true; } nextSet.add(neighbor); } } } if (nextSet.isEmpty()) { return false; } return calculate(nextSet, end); } private Route getRoute(final Territory start, final Territory destination) { final List<Territory> route = new ArrayList<>(); Territory current = destination; while (current != start) { if (current == null) { return null; } route.add(current); current = m_previous.get(current); } route.add(start); Collections.reverse(route); return new Route(route); } }