예제 #1
0
파일: Player.java 프로젝트: avc2120/wtr
  private Point teleport(Point location, double offset, Map<Integer, Point> id_lut) {
    Point self = id_lut.get(self_id);
    double x = Math.max(Math.min(location.x, 20), 0);
    double y = Math.max(Math.min(location.y, 20), 0);
    double dx = x - self.x;
    double dy = y - self.y;
    double r = Math.hypot(dx, dy) - offset;
    if (Math.abs(r) > 6) {
      r = Math.signum(r) * 6;
    }
    double th = Math.atan2(dy, dx);

    return new Point(r * Math.cos(th), r * Math.sin(th), self_id);
  }
예제 #2
0
 public static double heuristicCostEstimate(Cell start, Cell goal) {
   return Math.hypot(start.x - goal.x, start.y - goal.y);
   //        return Math.abs(goal.x - start.x) + Math.abs(goal.y - start.y);
 }
예제 #3
0
  // try to push asteroid
  public void play(Asteroid[] asteroids, double[] energy, double[] direction) {
    time++;

    if (time > 0.9 * time_limit) {
      finish_flag = true;
    }

    int n = asteroids.length;

    /* fix orbits of troublemaker asteroids that intially shared the same orbit with nucleus */
    if (!troublemakers.isEmpty()) {
      ArrayList<Long> temp = new ArrayList<Long>();
      for (long id : troublemakers) {
        int t = Utils.findAsteroidIndexById(asteroids, id);
        Point p1 = asteroids[t].orbit.positionAt(time);
        Point p2 = asteroids[t].orbit.positionAt(time + 1);
        if (Math.hypot(p1.x, p1.y) > Math.hypot(p2.x, p2.y)) {
          Push push = Hohmann.generateCorrection(asteroids[t], t, time);
          energy[t] = push.energy;
          direction[t] = push.direction;
        } else {
          temp.add(id);
        }
      }
      troublemakers = temp;
    }

    if (asteroids.length < number_of_asteroids) {
      System.out.println("A collision just occurred at time " + time);
      // Check for non-circular orbit
      int new_asteroid_idx = 0;
      for (int i = 0; i < asteroids.length; i++) {
        if (!seenId.contains(asteroids[i].id)) {
          new_asteroid_idx = i;
          seenId.add(asteroids[i].id);

          if (Math.abs(asteroids[i].orbit.a - asteroids[i].orbit.b) > EPSILON) {
            // Correct for non-circular orbit
            System.out.println("CORRECTION");
            Push push = Hohmann.generateCorrection(asteroids[i], i, time);
            energy[i] = push.energy;
            direction[i] = push.direction;

            asteroids[i] = Asteroid.push(asteroids[i], time, energy[i], direction[i]);

            // Redo the queue

            Queue<Push> new_queue = new PriorityQueue<>(new Push.TimeComparator());
            for (Push p : push_queue) {
              Asteroid a = p.asteroid;
              long time_to_push = Hohmann.timeToPush(time, a, asteroids[i]);
              if (time_to_push != -1) {
                Push np = Hohmann.generatePush(a, -1, asteroids[i], time_to_push);
                if (time_to_push + np.expected_collision_time <= time_limit) {
                  new_queue.add(np);
                } else {
                  usedId.remove(a.id);
                }
              } else {
                System.out.println("WTF");
                usedId.remove(a.id);
              }
            }
            push_queue = new_queue;
          }
        }
      }

      if (Utils.findAsteroidById(asteroids, nucleus_id) == null) {
        nucleus_id = asteroids[new_asteroid_idx].id;
        System.out.println("NUCLEUS ID CHANGED");
        usedId.add(nucleus_id);
      }
      number_of_asteroids = asteroids.length;

      unlock_time = -1;

      no_progress = false;
    }

    nucleus = Utils.findAsteroidById(asteroids, nucleus_id);

    /* push out asteroids that share the same orbit with nucleus */
    for (int i = 0; i < asteroids.length; i++) {
      Asteroid ast = asteroids[i];
      if (nucleus == ast) {
        continue;
      }
      if (Math.abs(ast.orbit.a - nucleus.orbit.a) <= EPSILON
          && Math.abs(ast.orbit.b - nucleus.orbit.b) <= EPSILON) {
        troublemakers.add(ast.id);
        Push push = Hohmann.generatePushToRadius(ast, i, ast.orbit.a * orbit_multiplier, time);
        energy[i] = push.energy;
        direction[i] = push.direction;
      }
    }

    if (finish_flag) {
      finishGame(asteroids, nucleus, energy, direction);
      return;
    }

    if (time < unlock_time) return;

    while (!push_queue.isEmpty() && time == push_queue.peek().time) {
      Push push_info = push_queue.remove();

      int index;
      for (index = 0; index < asteroids.length; index++) {
        if (asteroids[index].id == push_info.asteroid.id) {
          break;
        }
      }
      if (index != asteroids.length) {
        Asteroid a = Asteroid.push(asteroids[index], time, push_info.energy, push_info.direction);
        long collision_time =
            CollisionChecker.checkCollision(
                a, nucleus, push_info.expected_collision_time, time, time_limit);
        if (collision_time != -1) {
          energy[index] = push_info.energy;
          direction[index] = push_info.direction;
          asteroids[index] =
              Asteroid.push(asteroids[index], time, push_info.energy, push_info.direction);
          System.out.println(
              "This is "
                  + time
                  + ". Collision will happen at "
                  + time
                  + push_info.expected_collision_time);

          unlock_time = time + push_info.expected_collision_time;
          while (!push_queue.isEmpty()
              && push_queue.peek().time < time + push_info.expected_collision_time) {
            usedId.remove(push_queue.remove().asteroid.id);
          }
        } else {
          System.out.println("Didn't happen");
          usedId.remove(push_info.asteroid.id);
        }
      }
    }

    if (time < unlock_time) return;

    double used_mass = 0;
    for (Asteroid a : asteroids) {
      if (usedId.contains(a.id)) {
        used_mass += a.mass;
      }
    }

    if (used_mass < target_mass) {
      // Of all remaining asteroids, find the one with lowest energy push
      System.out.println("There are " + n + " asteroids to be considered.");
      ArrayList<Push> pushes = new ArrayList<>();
      for (int i = 0; i < n; i++) {
        if (asteroids[i].id == nucleus_id) {
          continue;
        }
        int curr_asteroid_index = i;
        Asteroid curr_asteroid = asteroids[curr_asteroid_index];
        // Ignore asteroids with elliptical orbits
        if (usedId.contains(curr_asteroid.id)) {
          continue;
        }
        long time_to_push = Hohmann.timeToPush(time, curr_asteroid, nucleus);
        if (time_to_push != -1) {
          Push push =
              Hohmann.generatePush(curr_asteroid, curr_asteroid_index, nucleus, time_to_push);
          if (time_to_push + push.expected_collision_time <= time_limit) {
            pushes.add(push);
          }
        }
      }

      Collections.sort(pushes, new Push.EnergyComparator());

      double mass_considered = 0;
      ArrayList<Push> valid_pushes = new ArrayList<>();
      for (Push p : pushes) {
        if (mass_considered < target_mass - used_mass) {
          mass_considered += p.asteroid.mass;
          valid_pushes.add(p);
          System.out.println(
              "Time: " + p.time / 365.0 + " Energy: " + p.energy + " Mass: " + target_mass);
          push_queue.add(p);
          usedId.add(p.asteroid.id);
        }
      }
    }
  }
예제 #4
0
파일: Player.java 프로젝트: avc2120/wtr
 private double dist(Point a, Point b) {
   return Math.hypot(a.x - b.x, a.y - b.y);
 }
예제 #5
0
 /** Return distance between this location and another */
 public double distanceTo(Location other) {
   return Math.hypot(this.x - other.x, this.y - other.y);
 }