Exemplo n.º 1
0
  protected PointOfInterest standingOrder(Point2D whereIAm) {
    Point2D target =
        new Point2D.Double(
            whereIAm.getX() + (spiralHeading.getDx() * MOVEMENT_LENGTH),
            whereIAm.getY() + (spiralHeading.getDy() * MOVEMENT_LENGTH));

    while (!StaticDiver.pointIsOnBoard(target.getX(), target.getY(), boardRadius)) {
      switch (spiralHeading) {
        case N:
          spiralHeading = Direction.W;
          break;
        case E:
          spiralHeading = Direction.N;
          break;
        case S:
          spiralHeading = Direction.E;
          break;
        case W:
          spiralHeading = Direction.S;
          break;
      }

      target =
          new Point2D.Double(
              whereIAm.getX() + (spiralHeading.getDx() * MOVEMENT_LENGTH),
              whereIAm.getY() + (spiralHeading.getDy() * MOVEMENT_LENGTH));
    }

    return new PointOfInterest(target);
  }
Exemplo n.º 2
0
  /*Should only be called once*/
  private void findDanger() {

    for (Observation o : whatYouSee) {
      //			logger.trace("What I see: " + o.getName() + "\t\tIs it dangerous? " + o.isDangerous());
      if (!o.isDangerous()) continue;

      Point2D predictedLocation;

      int speed = 0;
      int happy = 0; // can't use o.happiness() because that is 0 when you are on boat!
      for (SeaLifePrototype life : seaLifePossibilities) {
        if (life.getName().equals(o.getName())) {
          speed = life.getSpeed();
          happy = life.getHappiness();
          break;
        }
      }

      // Get the location and distance based on predicted location
      // (taking into account whether creature is stationary or moving).
      if (speed == 0 || o.getDirection() == null) {
        predictedLocation = o.getLocation();
      } else {
        // predict where it will be
        Point2D loc =
            new Point2D.Double(
                //						o.getLocation().getX() + (o.getDirection().getDx() *
                // (o.getDirection().isDiag() ? 3 : 2)),
                //						o.getLocation().getY() + (o.getDirection().getDy() *
                // (o.getDirection().isDiag() ? 3 : 2))
                o.getLocation().getX() + (o.getDirection().getDx()),
                o.getLocation().getY() + (o.getDirection().getDy()));
        if (ourBoard.inBounds((int) loc.getX(), (int) loc.getY())) {
          predictedLocation = loc;
        } else {
          predictedLocation = o.getLocation();
        }
      }

      // For each Direction that diver can move, calculate the sum of danger from all creatures
      // affecting it.
      // The danger is scaled based on distance (decreases by a factor of radius).
      for (Direction d : Direction.values()) {

        Point2D nextPosition =
            new Point2D.Double(myPosition.getX() + d.getDx(), myPosition.getY() + d.getDy());

        if (!ourBoard.inBounds((int) nextPosition.getX(), (int) nextPosition.getY())) continue;

        double distanceToCreature = Math.max(1.0, nextPosition.distance(predictedLocation));

        //				logger.debug("Direction:"+d+" distanceToCreature = " + distanceToCreature);

        // Only consider dangerous creatures if:
        // 1. They are stationary and affect cells next to the candidate cell, OR
        // 2. They are moving and affect cells within DANGER_MAX_DISTANCE of the candidate cell.
        if (o.isDangerous()
            && ((speed == 0 && distanceToCreature <= STATIONARY_DANGER_DISTANCE)
                || (speed > 0 && distanceToCreature <= DANGER_MAX_DISTANCE))) {

          double formerDirectionDanger = 0;

          if (directionDanger.containsKey(d)) {
            formerDirectionDanger = directionDanger.get(d);
            // logger.debug("formerDirectionDanger = " + formerDirectionDanger);
          }

          directionDanger.put(
              d,
              new Double(
                  formerDirectionDanger
                      + (Math.abs(happy * DANGER_MULTIPLIER) / Math.pow(distanceToCreature, 2))));
        }
      }
    }
  }
Exemplo n.º 3
0
  public Direction findSafestDirection(
      Point2D myPosition,
      Point2D myPreviousPosition,
      Set<Observation> whatYouSee,
      Direction preferredDirection,
      boolean shouldReturnToBoat) {
    updateCoordinates(myPosition, myPreviousPosition, whatYouSee);
    findDanger();

    // if we are at boat, reset the tracked helper state
    if (myPosition.equals(new Point2D.Double(0, 0))) {
      backtrackLocations.clear();
    }

    // logger.debug("in find safest direction");
    double minDanger = Integer.MAX_VALUE;

    ArrayList<DirectionAndDanger> directionsSafeToDangerous = new ArrayList<DirectionAndDanger>();
    ArrayList<Direction> safestDirections = new ArrayList<Direction>();

    // First, find the minimum danger. Create an equivalence class of directions sharing this value.
    for (Direction d : Direction.values()) {
      double curDanger;
      if (directionDanger.containsKey(d)) {
        curDanger = Math.abs(directionDanger.get(d));
        // logger.trace("directionDanger.get("+d+") = "+curDanger);
      } else {
        curDanger = 0;
      }

      Point2D nextPosition =
          new Point2D.Double(myPosition.getX() + d.getDx(), myPosition.getY() + d.getDy());
      // Do not consider directions that take us too close to the walls
      if (ourBoard.isNearBoundary(
          nextPosition, Math.max(WALL_MAX_DISTANCE, (double) r / Math.sqrt(2.0) - 1.0))) {
        continue;
      }

      // Do not consider directions that put us in backtracked locations
      // i.e. we are trying to go around danger, so don't go backwards
      if (backtrackLocations.contains(nextPosition)) {
        continue;
      }

      //			logger.debug("current danger in direction " + d + ":" + curDanger);

      if (curDanger < minDanger) {
        safestDirections.clear();
        safestDirections.add(d);
        // logger.debug("Min Danger so far in Direction: " + d);

        minDanger = curDanger;
      } else if (curDanger == minDanger) {
        safestDirections.add(d);
      }

      directionsSafeToDangerous.add(new DirectionAndDanger(d, curDanger));
    }

    // Sort from least dangerous to most dangerous
    Collections.sort(directionsSafeToDangerous);

    mySafestDirection = null;
    if (shouldReturnToBoat) {
      // If returning to boat, always head in preferredDirection if it is among the safest
      if (preferredDirection == null) {
        mySafestDirection = null;
      } else if (safestDirections.contains(preferredDirection)) {
        mySafestDirection = preferredDirection;
      } else {
        // Prioritize the directions closer to the safest
        // And de-prioritize the previous location
        Direction previousDirection = OurBoard.getDirectionTowards(myPosition, myPreviousPosition);
        for (Direction d : DirectionUtil.getClosestDirections(preferredDirection)) {
          if (safestDirections.contains(d) && !d.equals(previousDirection)) {
            mySafestDirection = d;
            break;
          }
        }
        // We excluded previous direction in above loop.
        // If mySafestDirection == null, that means safest is previous direction.
        if (mySafestDirection == null) {
          if (!directionsSafeToDangerous.isEmpty()) {
            mySafestDirection = directionsSafeToDangerous.get(0).getDirection();
          } else {
            // just go back towards boat...
            mySafestDirection = OurBoard.getDirectionTowards(myPosition, new Point2D.Double(0, 0));
          }
        }

        // we did not pick preferredDirection, so next time make sure we don't come back
        backtrackLocations.add(myPreviousPosition);
      }
    } else {
      // 80% of the time, continue in preferredDirection if it is among the safest

      if (preferredDirection != null
          && safestDirections.contains(preferredDirection)
          && random.nextDouble() <= 0.80) {

        mySafestDirection = preferredDirection;
      } else {
        List<Direction> closestDirections = DirectionUtil.getClosestDirections(preferredDirection);
        // Try to pick the safest direction out of [forward-left, forward-right, left, right]
        List<Direction> firstTwo = closestDirections.subList(0, 2);
        List<Direction> nextTwo = closestDirections.subList(2, 4);
        // Look at the top 3 safest directions
        if (directionsSafeToDangerous.size() >= 3) {
          for (DirectionAndDanger dad : directionsSafeToDangerous.subList(0, 3)) {
            // skip the one going backwards
            if (dad.equals(OurBoard.getDirectionTowards(myPosition, myPreviousPosition))) {
              continue;
            }
            if (firstTwo.contains(dad.getDirection())) {
              mySafestDirection = dad.getDirection();
              break;
            } else if (nextTwo.contains(dad.getDirection())) {
              mySafestDirection = dad.getDirection();
              break;
            }
          }
        }
        if (mySafestDirection == null) {
          if (!safestDirections.isEmpty()) {
            Collections.shuffle(safestDirections);
            mySafestDirection = safestDirections.get(0);
          } else {
            // no safe directions?? return to boat then...
            mySafestDirection = OurBoard.getDirectionTowards(myPosition, new Point2D.Double(0, 0));
          }
        }

        // we did not pick preferredDirection, so next time make sure we don't come back
        backtrackLocations.add(myPreviousPosition);
      }
    }

    // if we end up going in preferredDirection, no need to avoid backtrack areas anymore
    backtrackLocations.clear();

    // logger.debug("Safest direction: " + mySafestDirection + " (from among " +
    // safestDirections.toString() + ")");
    return mySafestDirection;
  }