/* * Copyright (c) 2012. HappyDroids LLC, All rights reserved. */ package com.happydroids.droidtowers.pathfinding; import com.badlogic.gdx.utils.Array; import com.happydroids.droidtowers.TowerConsts; import com.happydroids.droidtowers.entities.Elevator; import com.happydroids.droidtowers.grid.GameGrid; import com.happydroids.droidtowers.grid.GridPosition; import static com.happydroids.droidtowers.types.ProviderType.SERVICE_ELEVATOR; public class TransitPathFinder extends AStar<GridPosition> { protected final GameGrid gameGrid; private final boolean canUseServiceRoutes; private final Array<GridPosition> tmpArray; public TransitPathFinder(GameGrid gameGrid, boolean canUseServiceRoutes) { super(); this.gameGrid = gameGrid; this.canUseServiceRoutes = canUseServiceRoutes; tmpArray = new Array<GridPosition>(4); } @Override protected boolean isGoal(GridPosition gridPosition) { return goal.x == gridPosition.x && goal.y == gridPosition.y; } @Override protected int g(GridPosition from, GridPosition to) { if (from.equals(to)) { return 0; } if (to != null) { if (to.elevator != null && to.elevator.servicesFloor(to.y) && to.elevator.getNumElevatorCars() > 0) { if (canUseServiceRoutes && to.elevator.provides(SERVICE_ELEVATOR)) { return 5; } return 25; } else if (to.stair != null) { return 75; } else if (to.connectedToTransit) { return 100; } } if (to.y == TowerConsts.LOBBY_FLOOR) { // fail safe that an avatar that ran away will come back! return 200; } return Integer.MAX_VALUE; } @Override protected int h(GridPosition from, GridPosition to) { /* Use the Manhattan distance heuristic. */ return Math.abs(goal.x - to.x) + Math.abs(goal.y - to.y); // return Math.pow(goal.x - to.x, 2) + Math.pow(goal.y - to.y, 2); } @Override protected Array<GridPosition> generateSuccessors(GridPosition point) { tmpArray.clear(); Elevator elevator = point.elevator; if (elevator != null && elevator.getNumElevatorCars() > 0) { if ((canUseServiceRoutes && elevator.provides(SERVICE_ELEVATOR) || !canUseServiceRoutes && !elevator.provides(SERVICE_ELEVATOR))) { if (elevator.servicesFloor(point.y + 1)) { checkGridPositionY(tmpArray, point.x, point.y + 1); } if (elevator.servicesFloor(point.y - 1)) { checkGridPositionY(tmpArray, point.x, point.y - 1); } } } else if (point.stair != null) { checkGridPositionY(tmpArray, point.x, point.y + 1); checkGridPositionY(tmpArray, point.x, point.y - 1); } checkGridPositionX(tmpArray, point.x + 1, point.y); checkGridPositionX(tmpArray, point.x - 1, point.y); return tmpArray; } private void checkGridPositionX(Array<GridPosition> successors, int x, int y) { GridPosition position = gameGrid.positionCache().getPosition(x, y); if (position != null && (!position.isEmpty() || y == TowerConsts.LOBBY_FLOOR)) { successors.add(position); } } private void checkGridPositionY(Array<GridPosition> successors, int x, int y) { GridPosition position = gameGrid.positionCache().getPosition(x, y); if (position != null && (position.connectedToTransit || y == TowerConsts.LOBBY_FLOOR)) { if (position.elevator != null && position.elevator.servicesFloor(y)) { successors.add(position); } else if (position.stair != null) { successors.add(position); } } } }