示例#1
0
 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;
   }
 }
示例#2
0
  /**
   * 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;
  }