protected Graph<Cell, CellsLink> getDirectedGraph(Mine mine) { Graph<Cell, CellsLink> graph = new DirectedSparseGraph<Cell, CellsLink>(); for (CellsLink link : getCellLinks(mine)) { graph.addEdge(link, link.getSource(), link.getTarget()); } return graph; }
@Override public void solve() { while (true) { Mine mine = null; mine = initialMine.clone(); Game game = new Game(mine); while (game.getState() == GameState.Game) { Cell robotCell = mine.getRobotCell(); String map = mine.toText(); String mapWithoutRobot = mine.toTextWithoutRobot(); if (!loseMovs.containsKey(map)) { loseMovs.put(map, new HashSet<Movement>()); } if (!loseLinks.containsKey(map)) { loseLinks.put(map, new HashSet<CellsLink>()); } if (!noWay.containsKey(map)) { noWay.put(map, new HashSet<Coordinate>()); } if (!attendedWalkingAroundCoordinates.containsKey(mapWithoutRobot)) { attendedWalkingAroundCoordinates.put(mapWithoutRobot, new HashSet<Coordinate>()); } attendedWalkingAroundCoordinates.get(mapWithoutRobot).add(robotCell.getCoordinate()); Set<Cell> targets = new HashSet<Cell>(); boolean isFreeWay = false; for (Cell cell : mine.getAdjacentCells(robotCell)) { Movement mov = robotCell.getCoordinate().getNecessaryMovement(cell.getCoordinate()); isFreeWay |= !attendedWalkingAroundCoordinates.get(mapWithoutRobot).contains(cell.getCoordinate()) && !loseMovs.get(map).contains(mov); } if (isFreeWay) { targets.addAll(mine.findCells(CellContent.Lambda)); targets.addAll(mine.findCells(CellContent.HighOrderRock)); if (targets.size() == 0) targets.addAll(mine.findCells(CellContent.OpenLambdaLift)); targets.removeAll(mine.getCells(noWay.get(map))); } else { targets.addAll(mine.findCells(CellContent.Empty)); targets.addAll(mine.findCells(CellContent.Earth)); targets.addAll(mine.findCells(CellContent.HuttonsRazor)); for (CellContent content : CellContent.getTrampolines()) { targets.addAll(mine.findCells(content)); } targets.removeAll(mine.getCells(attendedWalkingAroundCoordinates.get(mapWithoutRobot))); targets.removeAll(mine.getCells(noWay.get(map))); if (targets.size() == 0) { game.move(Movement.ABORT); continue; } } Graph<Cell, CellsLink> graph = getDirectedGraph(mine); DijkstraShortestPath<Cell, CellsLink> alg = new DijkstraShortestPath<Cell, CellsLink>( graph, new CellsLinkTransformer<CellsLink, Double>()); Cell nextTarget = null; List<CellsLink> routeToNextTarget = null; double shortestDist = Double.MAX_VALUE; for (Cell target : targets) { List<CellsLink> route = null; Number dist = null; try { route = alg.getPath(mine.getRobotCell(), target); dist = alg.getDistance(mine.getRobotCell(), target); } catch (IllegalArgumentException e) { noWay.get(map).add(target.getCoordinate()); continue; } if (dist != null && route != null && route.size() > 0 && dist.doubleValue() < shortestDist) { CellsLink firstLink = route.get(0); Movement mov = firstLink .getSource() .getCoordinate() .getNecessaryMovement(firstLink.getTarget().getCoordinate()); if (!loseMovs.get(map).contains(mov) && !attendedWalkingAroundCoordinates .get(mapWithoutRobot) .contains(target.getCoordinate())) { shortestDist = dist.doubleValue(); nextTarget = target; routeToNextTarget = route; } } } if (nextTarget != null) { for (CellsLink link : routeToNextTarget) { Cell source = link.getSource(); Cell target = link.getTarget(); if (isSafeMovement(mine, source, target)) { Movement mov = source.getCoordinate().getNecessaryMovement(target.getCoordinate()); GameState state = game.move(mov); if (state == GameState.Lose || state == GameState.Abort) { loseMovs.get(map).add(mov); loseLinks.get(map).add(link); } } break; } } else { // Walking around for (Movement mov : Movement.values()) { if (!loseMovs.get(map).contains(mov)) { if (mov == Movement.RAZOR && mine.getRazorsCount() > 0) { boolean isRazorApplied = false; for (Cell cell : mine.getNeighboringCells(robotCell)) { isRazorApplied |= cell.getContent() == CellContent.WadlersBeard; } if (!isRazorApplied) continue; } Cell movCell = null; for (Cell cell : mine.getAdjacentCells(robotCell)) { if (robotCell.getCoordinate().getNecessaryMovement(cell.getCoordinate()) == mov) { if (!attendedWalkingAroundCoordinates .get(mapWithoutRobot) .contains(cell.getCoordinate())) { movCell = cell; break; } } } if (mov == Movement.WAIT || mov == Movement.RAZOR || movCell != null && !attendedWalkingAroundCoordinates .get(mapWithoutRobot) .contains(movCell.getCoordinate())) { GameState state = game.move(mov); if (movCell != null && mapWithoutRobot.equals(mine.toTextWithoutRobot())) attendedWalkingAroundCoordinates .get(mapWithoutRobot) .add(movCell.getCoordinate()); if (state == GameState.Game && map.equals(mine.toText())) { loseMovs.get(map).add(mov); } break; } } } } } addNewRoute(game); attemptsCount++; } }