Пример #1
0
  /**
   * The method makes the worm move to a next position that is adjacent to impassable terrain
   * following the slope of that terrain in the direction. The worm shall aim to maximize the
   * distance while minimizing the divergence. If no such location exists because all locations in
   * the direction +- 0,7875 are impassable the worm shall remain at its current position. If
   * locations in the direction are passable but not adjacent the worm shall move there and then
   * drop passively.
   *
   * @post If the worm can maximize the distance while minimizing the divergence, the worm has moved
   *     to the optimal location. |for (double a = 0.1;a<=this.getRadius();a=a+(0.01*a)) { | x2 =
   *     x+Math.cos(direction)*a; | y2 = y+Math.sin(direction)*a; | if (world.isAdjacent(x2, y2,
   *     this.getRadius()) && | world.isPassable(x2, y2, this.getRadius())) { | double d =
   *     Math.sqrt(Math.pow((x-x2),2)+Math.pow((y-y2),2)); | double s = Math.atan((x-x2)/(y-y2)); |
   *     if ((d>=maxD) && (s<minS)) { | minS=s; | maxD=d; | x2Max = x2; | y2Max= y2; | direction =
   *     direction +0.0175; |new.getXpos()==x2Max |new.getYpos() == y2Max
   * @post If the worm can't maximize the distance while minimizing the divergence and there is only
   *     impassable terrain in the checked directions, the worm will not have moved. |new.getXpos()
   *     == old.getXpos() |new.getYpos() == old.getYpos()
   * @post If the worm can't maximize the distance while minimizing the divergence and there is only
   *     passable terrain in the checked directions that is not adjacent, the worm will move there.
   *     |new.getXpos() == old.getXpos() + cos(direction)*radius |new.getYpos() == old.getYpos() +
   *     sin(direction)*radius
   * @post The worms actionpoints are correctly reduced. |new.getActionPoints ==
   *     old.getActionPoints() - old.computeCost2(old.getXpos(),old.getYpos())
   * @throws IllegalArgumentException If the worm can't move because he has insufficient
   *     actionpoints the exception is thrown. | ! isValidStep()
   * @throws IllegalStateException If the worm can't move because the worm isn't positioned in
   *     passable terrain and adjacent to impassable terrain the exception is thrown. | ! canMove()
   */
  @Raw
  public void move() throws IllegalArgumentException, IllegalStateException {
    if (!isValidStep()) throw new IllegalArgumentException();
    if (canMove()) {
      World world = this.getWorld();
      double x = this.getXpos();
      double y = this.getYpos();
      double prevx = x;
      double prevy = y;
      double x2 = x;
      double y2 = y;
      double x2Max = x2;
      double y2Max = y2;
      double c = -0.7875;
      double direction = this.getDirection() + c;

      double maxD = 0;
      double minS = this.getDirection();

      // geval 1: na gaan of in direction+-45° er een gischike volgende positie is
      //			en zo ja, ernaar verplaatsen.
      for (double a = 0.1; a <= this.getRadius(); a = a + (0.01 * a)) {
        x2 = x + Math.cos(direction) * a;
        y2 = y + Math.sin(direction) * a;
        if (world.isAdjacent(x2, y2, this.getRadius())
            && world.isPassable(x2, y2, this.getRadius())) {
          double d = Math.sqrt(Math.pow((x - x2), 2) + Math.pow((y - y2), 2));
          double s = Math.atan((x - x2) / (y - y2));
          if ((d >= maxD) && (s < minS)) {
            minS = s;
            maxD = d;
            x2Max = x2;
            y2Max = y2;
          }
        }
        direction = direction + 0.0175;
      }
      if (this.isOutOfTheMap(x2Max, y2Max)) {
        this.killWorm();
      } else {
        this.setXpos(x2Max);
        this.setYpos(y2Max);
        this.setActionPoints(this.getActionPoints() - this.computeCost2(prevx, prevy));
      }

      // geval2: Er werd in direction+-45° geen geschikte plaats gevonden
      //			nagaan of er in direction naar een passable locatie kan verplaatst worden,
      //			daarnaar verplaatsen en dan vallen (fall).
      if ((x2Max == x) && (y2Max == y)) {
        double pasXpos = x;
        double pasYpos = y;

        pasXpos = (x + (Math.cos(this.getDirection()) * this.getRadius()));
        pasYpos = (y + (Math.sin(this.getDirection()) * this.getRadius()));
        if (!world.isAdjacent(pasXpos, pasYpos, this.getRadius())
            && world.isPassable(pasXpos, pasYpos, this.getRadius())) {
          if (this.isOutOfTheMap(pasXpos, pasYpos)) {
            this.killWorm();
          } else {
            this.setXpos(pasXpos);
            this.setYpos(pasYpos);
            this.setActionPoints(this.getActionPoints() - this.computeCost2(prevx, prevy));
          }
        }
      }
      this.consumeFood();
    } else throw new IllegalStateException();
  }