public Dijkstra(MapLocation... sources) { this.sources = new LocSet(sources); for (MapLocation source : sources) { queue.insert(0, source); distance[source.x][source.y] = 0; // parent[source.x][source.y] = source; // leave as null to cause exceptions if we accidentally try to use it // from[source.x][source.y] = Direction.NONE; } }
/** * Compute until either bytecodes have run out or we find a destination. * * @param end Hash-map of destination. * @param bytecodes The bytecode limit. * @param broadcast Whether to broadcast the results (used by the HQ). * @return Whether we found a destination. */ public boolean compute(boolean[][] end, int bytecodes, boolean broadcast) { // cache variables int min, w, x, y; int[] weight; MapLocation next, nbr, prev, p; Direction dir; final BucketQueue<MapLocation> queue = this.queue; final int[][] distance = this.distance; final Direction[][] from = this.from; // final MapLocation[][] parent = this.parent; final boolean[][] unsafe = getUnsafe(); // int iters = 0; // int bc = Clock.getBytecodeNum(); while (queue.size > 0) { // iters++; if (Clock.getBytecodeNum() >= bytecodes - 500) { break; } // RC.setIndicatorString(0, Integer.toString(min)); // ALERT: queue.min is valid only after a call to deleteMin()! next = queue.deleteMin(); min = queue.min; x = next.x; y = next.y; // check if we have already visited this node if (min == distance[x][y]) { if (unsafe[x][y]) min += 100; dir = from[x][y]; /* * if (dir != null) { * prev = next.subtract(dir); * p = parent[prev.x][prev.y]; * if (min <= distance[p.x][p.y] + PARENT_DIST) { * parent[x][y] = p; * } else { * parent[x][y] = prev; * } * } */ if (broadcast) { try { messagingSystem.writePathingInfo(next, dir, min, null /* parent[x][y] */); } catch (GameActionException e) { // e.printStackTrace(); } } // if (end[x][y]) { // reached = next; // break; // } weight = WEIGHT[RC.senseTerrainTile(next).ordinal()]; int i; if (dir == null) { dir = Direction.NORTH; i = 8; } else if (dir.isDiagonal()) { dir = dir.rotateLeft().rotateLeft(); i = 5; } else { dir = dir.rotateLeft(); i = 3; } for (; --i >= 0; dir = dir.rotateRight()) { nbr = next.add(dir); if (RC.senseTerrainTile(nbr).isTraversableAtHeight(RobotLevel.ON_GROUND)) { w = min + weight[dir.ordinal()]; x = nbr.x; y = nbr.y; if (from[x][y] == null) { queue.insert_fast(w, nbr); // System.out.println("inserted " + nbr + " with distance " + w + " from " + dir); distance[x][y] = w; from[x][y] = dir; } else { if (w < distance[x][y]) { queue.insert_fast(w, nbr); distance[x][y] = w; from[x][y] = dir; } } } } } } // bc = Clock.getBytecodeNum() - bc; // RC.setIndicatorString(2, "average Dijkstra bytecodes: " + bc / iters); return reached != null; }