Пример #1
1
  /**
   * Changes the positions of the worm as a result of a jump from the current position.
   *
   * @post If the worm jumped out of the map it will have been removed.
   *     |this.getWorld().getWorms().contains(this) == false
   * @post The worm jumped to the correct position | while (world.isPassable(tempXpos, tempYpos,
   *     this.getRadius())) | tempXpos = this.jumpStep(t)[0] | tempYpos = this.jumpStep(t)[1] | t +=
   *     timeStep | if ((world.isAdjacent(tempXpos, tempYpos, this.getRadius())) && |
   *     (Math.sqrt(Math.pow((origXpos-tempXpos), 2)+Math.pow((origYpos-tempYpos),
   *     2))>=this.getRadius() )) | new.getXpos() == tempXpos | new.getYpos() == tempYpos
   * @post The worm's actionpoints are reduced to zero. |new.getActionPoints() == 0;
   * @throws IllegalStateException When the worm has no action point left to jump the exception is
   *     thrown. |! canJump()
   */
  @Raw
  public void jump(Double timeStep) throws IllegalStateException {
    if (this.canJump()) {
      World world = this.getWorld();
      double origXpos = this.getXpos();
      double origYpos = this.getYpos();
      double tempXpos = this.getXpos();
      double tempYpos = this.getYpos();
      double t = 0;
      while (world.isPassable(tempXpos, tempYpos, this.getRadius())) {
        tempXpos = this.jumpStep(t)[0];
        tempYpos = this.jumpStep(t)[1];
        t += timeStep;

        if (isOutOfTheMap(tempXpos, tempYpos)) {
          this.killWorm();
          break;
        }
        if ((world.isAdjacent(tempXpos, tempYpos, this.getRadius()))
            && (Math.sqrt(Math.pow((origXpos - tempXpos), 2) + Math.pow((origYpos - tempYpos), 2))
                >= this.getRadius())) {
          this.setXpos(tempXpos);
          this.setYpos(tempYpos);
          this.consumeFood();
          this.setActionPoints(0);
          break;
        }
      }
    } else throw new IllegalStateException();
  }
Пример #2
0
  /**
   * Returns the time it would take for a potential jump from the current position in the direction
   * this Worm is facing.
   *
   * @effect
   * @return returns the time needed for a moving object to make a jump | - New method:
   *     positionAtTime(T) = new Position(getX() + calculateVelocity() * cos(getDirection)*T, getY()
   *     + calculateVelocity()*sin(getDirection())*T -g/2*T²) | if for each T in [0,time-stepSize]:
   *     | (getWorld().isPassableForCircle(getRadius(),getRadius(), positionAtTime(T)) == true | &&
   *     getWorld().isPassableForCircle(getRadius(),getRadius(), positionAtTime(time)) == false) |
   *     && | if for one t in [0,time-stepSize]: | (this.getOverlappingWorm() != null) | then result
   *     == t
   * @return returns the time needed for a moving object to make a jump | - New method:
   *     positionAtTime(T) = new Position(getX() + calculateVelocity() * cos(getDirection)*T, getY()
   *     + calculateVelocity()*sin(getDirection())*T -g/2*T²) | if for each T in [0,time-stepSize]:
   *     | (getWorld().isPassableForCircle(getRadius(),getRadius(), positionAtTime(T)) == true | &&
   *     getWorld().isPassableForCircle(getRadius(),getRadius(), positionAtTime(time)) == false) |
   *     && | if for each t in [0,time-stepSize]: | (this.getOverlappingWorm() == null) | then
   *     result == time |
   * @effect if this projectile overlaps with a worm then the worm is set as overlappingworm |
   *     this.setOverlapsWorm(newPosition)
   */
  @Override
  public double jumpTime(double stepSize)
      throws IllegalJumpTimeException, IllegalArgumentException {
    double t = 0;
    boolean found = false;
    while (!found) {
      double alpha = getDirection();
      double v0 = calculateVelocity();
      double v0x = v0 * Math.cos(alpha);
      double v0y = v0 * Math.sin(alpha);
      double x = getX() + v0x * t;
      double y = getY() + v0y * t - g / 2 * t * t;

      Position newPosition = new Position(x, y);
      t = t + stepSize;
      if (!this.getWorld().isPassableForCircle(this.getRadius(), this.getRadius(), newPosition))
        found = true;

      this.setOverlapsWorm(newPosition);

      if (this.getOverlappingWorm() != null) found = true;
      t = t + stepSize;
    }
    return (t - stepSize);
  }
Пример #3
0
  /**
   * Returns the time it takes to worm to jump (to his new position).
   *
   * @throws IllegalStateException If the worm can't jump the exception is thrown. | ! canJump()
   */
  @Raw
  public double jumpTime(double timeStep) throws IllegalStateException {
    World world = this.getWorld();
    double origXpos = this.getXpos();
    double origYpos = this.getYpos();
    double tempXpos = this.getXpos();
    double tempYpos = this.getYpos();
    double t = 0;
    if (this.canJump()) {
      while (world.isPassable(tempXpos, tempYpos, this.getRadius())) {
        tempXpos = this.jumpStep(t)[0];
        tempYpos = this.jumpStep(t)[1];
        t += timeStep;

        if ((world.isAdjacent(tempXpos, tempYpos, this.getRadius()))
            && (Math.sqrt(Math.pow((origXpos - tempXpos), 2) + Math.pow((origYpos - tempYpos), 2))
                >= this.getRadius())) {
          return t;
        }
        if (isOutOfTheMap(tempXpos, tempYpos)) {
          return t;
        }
      }
      return t;
    } else throw new IllegalStateException();
  }
Пример #4
0
  /**
   * Calculates and returns the position of a jumping projectile at the given time.
   *
   * @param t The time at which we want to know the location of this projectile during the jump.
   * @param direction the direction in which the projectile is launched
   * @pre the direction given must be valid |isValidDirection(direction)
   * @return The position where this projectile lands after a potential jump. This projectile is not
   *     facing down | if ( ! isFacingDown()) | result == this.jumpStep(this.jumpTime())
   *     <p>This projectile is facing down, so this projectile doesn't jump | if (
   *     isFacingDown(direction)) | result == this.jumpStep(0)
   * @effect if the projectile overlaps with a worm the worm will be set as the overlappingWorm |
   *     this.setOverlapsWorm(newPosition);
   * @throws IllegalArgumentException the given value for t is not in the interval [0, jumpTime()].
   *     | ! isValidJumpTime(t)
   * @throws IllegalJumpTimeExcecption if for the given t the position is no longer passable for the
   *     movingObject | -New variable: newPosition = new Position(getX() +
   *     calculateVelocity()*cos(alpha)*t, getY() + calculateVelocity*sin(alpha)*t); | !
   *     this.getWorld().isPassableForCircle_BruteForce(this.getRadius(), newPosition)
   * @throws IllegalJumptTimeException if the projectile overlaps with a worm for the given t | -New
   *     variable: newPosition = new Position(getX() + calculateVelocity()*cos(alpha)*t, getY() +
   *     calculateVelocity*sin(alpha)*t); | overlapsWorm(newPosition);
   */
  @Override
  public Position jumpStep(double t, double direction)
      throws IllegalJumpTimeException, IllegalArgumentException {
    assert isValidDirection(direction);
    if (!isValidJumpTime(t)) {
      throw new IllegalArgumentException("negative time");
    }

    if (t == 0) return this.getPosition();
    else {

      if (isFacingDown(direction)) {
        return this.getPosition();
      }
      double alpha = getDirection();
      double v0 = calculateVelocity();
      double v0x = v0 * Math.cos(alpha);
      double v0y = v0 * Math.sin(alpha);
      double x = getX() + v0x * t;
      double y = getY() + v0y * t - g / 2 * t * t;
      Position newPosition = new Position(x, y);

      this.setOverlapsWorm(newPosition);

      return newPosition;
    }
  }
Пример #5
0
  /**
   * Returns the worms position during a jump on a given time (after the jump started).
   *
   * @param timeAfterLaunch The time after the jump started
   * @throws IllegalStateException If the worm can't jump the exception is thrown. | ! canJump()
   */
  @Basic
  @Raw
  public double[] jumpStep(double timeAfterLaunch) throws IllegalStateException {
    double[] step;
    step = new double[2];
    if (!this.canJump()) throw new IllegalStateException();

    step[0] =
        ((this.jumpVelocity() * Math.cos(this.getDirection()) * timeAfterLaunch) + this.getXpos());
    step[1] =
        (this.jumpVelocity() * Math.sin(this.getDirection()) * timeAfterLaunch
                - 0.5 * G * Math.pow(timeAfterLaunch, 2))
            + this.getYpos();
    return step;
  }
Пример #6
0
  /**
   * Changes the positions of the projectile as a result of a jump from the current position.
   *
   * @post If the projectile hits a worm this worm loses some hit points and the projectile is
   *     removed from the world and set non active. | if ((Math.sqrt(Math.pow(w.getXpos()-tempXpos,
   *     2)+Math.pow(w.getYpos()-tempYpos, 2))< maxDistance)) | while (this.getActive == true) |
   *     then (new.setHitPoints(worm.getHitPoints-this.getDamage()) | then (world.getProjectile() ==
   *     null) | then (new.getActive == false))
   * @post If the projectile doesn't hit a worm, the projectile will be deleted when it leaves the
   *     map or when it hits impassable terrain. | if !((Math.sqrt(Math.pow(w.getXpos()-tempXpos,
   *     2)+Math.pow(w.getYpos()-tempYpos, 2))< maxDistance)) | then ( if
   *     ((isOutOfTheMap(tempXpos,tempYpos))) | then ((world.getProjectile() == null) | then
   *     (new.getActive == false)) | (else if (world.isImpassable(tempXpos, tempYpos,
   *     this.getRadius()))) | then ((world.getProjectile() == null) | then (new.getActive ==
   *     false)))
   * @throws IllegalStateException If the projectile can't jump the exception is thrown. |!
   *     canJump()
   */
  @Raw
  public void jump(Double timeStep) throws IllegalStateException {
    if (this.canJump()) {
      World world = this.getWorld();
      double tempXpos = this.getXpos();
      double tempYpos = this.getYpos();
      double t = 0;
      while ((world.isPassable(tempXpos, tempYpos, this.getRadius()))) {

        tempXpos = this.jumpStep(t)[0];
        tempYpos = this.jumpStep(t)[1];

        Collection<Worm> collection = (world.getWorms());

        for (Worm w : collection) {
          Worm overlappingWorm = null;
          double maxDistance = this.getRadius() + w.getRadius();

          if (!(w == world.getCurrentWorm())
              && (Math.sqrt(
                      Math.pow(w.getXpos() - tempXpos, 2) + Math.pow(w.getYpos() - tempYpos, 2))
                  < maxDistance)) {

            overlappingWorm = w;
            while ((this.getActive() == true)) {
              overlappingWorm.setHitPoints(overlappingWorm.getHitPoints() - this.getDamage());
              this.deleteProjectile(world);
              this.setActive(false);
            }

          } else {
            overlappingWorm = null;
            if ((isOutOfTheMap(tempXpos, tempYpos))) {
              this.deleteProjectile(world);
              this.setActive(false);
            } else if (((world.isImpassable(tempXpos, tempYpos, this.getRadius())))
                && (this.getActive() == true)) {
              this.deleteProjectile(world);
              this.setActive(false);
            }
          }
        }
        t += timeStep;
      }
    } else {
      throw new IllegalStateException();
    }
  }
Пример #7
0
  /**
   * Makes the worm fall, if it can fall, until the worm falls on an obstacle or falls out of the
   * map.
   *
   * @post The worm has fallen to a new position that is adjacent. The x-position stays the same but
   *     the y-position changes. |this.getWorld().isAdjacent(new.getXpos(),new.getYpos(),
   *     new.getDirecetion) == true |new.getXpos()==old.getXpos() |while
   *     (world.isPassable(this.getXpos(), this.getYpos(), this.getRadius())) | newYpos =
   *     this.getYpos()-this.getRadius() | if (this.getYpos()<0) | then new.getYpos ==
   *     (this.getRadius()*1.1) | break; | else if ((this.getYpos()>=0)){ | while
   *     (!world.isAdjacent(this.getXpos(), this.getYpos(), this.getRadius())) | newYpos =
   *     (this.getYpos()+0.1*this.getRadius()) | new.getYpos() == newYpos
   * @post The worms hitpoints are correctly reduced. |new.getHitPoints() == old.getHitPoints() -
   *     3*distance
   * @post After the fall the worm could be on food this gets checked. | this.consumeFood()
   * @throws IllegalStateException If the worm can't fall because he is on adjacent terrain the
   *     exception is thrown. | ! canFall()
   */
  @Raw
  public void fall() throws IllegalStateException {
    World world = this.getWorld();
    double distance = 0;
    boolean trigger = false;
    if (canFall()) {
      while (world.isPassable(this.getXpos(), this.getYpos(), this.getRadius())) {
        this.setYpos(this.getYpos() - this.getRadius());
        distance += this.getRadius();
        if (this.getYpos() < 0) {
          this.setYpos(0 + this.getRadius() * 1.1);
          trigger = true;
          break;
        }
      }

      if ((this.getYpos() >= 0) && !trigger) {
        while (!world.isAdjacent(this.getXpos(), this.getYpos(), this.getRadius())) {
          this.setYpos(this.getYpos() + 0.1 * this.getRadius());
          distance -= 0.1 * this.getRadius();
        }
      }
      this.setHitPoints(this.getHitPoints() - (3 * (int) Math.floor(distance)));
      this.consumeFood();
    } else {
      throw new IllegalStateException();
    }
  }
Пример #8
0
 /**
  * The method sets the mass of the worm. A worms mass is equal to DENSITY*(4/3)*PI*radius^3, with
  * DENSITY = 1062.
  *
  * @param radius The radius to which the mass must be set accordingly.
  * @post The new mass of the worm is set correctly. |new.getMass() == DENSITY*(4/3)*PI*radius^3
  * @post A new maximum for actionpoints is set. | new.getMaxActionPoints() == new.getMass();
  * @post The number of actionpoints change accordingly. (AP can't be higher than MaxAP) |
  *     new.getMaxActionPoints() >= new.getActionPoints()
  * @throws IllegalArgumentException When the given radius is not a valid radius the exception will
  *     be thrown. | ! isValidRadius(radius))
  */
 @Raw
 private void setMass(double radius) throws IllegalArgumentException {
   if (!isValidRadius(radius)) throw new IllegalArgumentException();
   this.mass = DENSITY * ((4.0 / 3.0) * Math.PI * Math.pow(radius, 3));
   this.setMaxActionPoints();
   this.setMaxHitPoints();
   this.setActionPoints(this.getActionPoints());
 }
Пример #9
0
 /** This method return the food objects that overlap with the worms position. */
 @Raw
 public Food overlappingFood() {
   World world = this.getWorld();
   double maxDistance = this.getRadius() + 0.2;
   Food overlappingFood = null;
   Collection<Food> collection = (world.getFood());
   for (Food f : collection) {
     if (Math.sqrt(
             Math.pow(f.getXpos() - this.getXpos(), 2) + Math.pow(f.getYpos() - this.getYpos(), 2))
         < maxDistance) {
       overlappingFood = f;
       break;
     } else {
       overlappingFood = null;
     }
   }
   return overlappingFood;
 }
Пример #10
0
 /**
  * Sets the team to a random team, if there are teams.
  *
  * @post If there where teams the worm is added to a team. If there where no teams the worm isn't
  *     added to a team. | if ((this.getWorld().getTeams().size()!=0)) { | then this.hasTeam() ==
  *     true;
  */
 @Raw
 public void setTeamRandom() {
   World world = this.getWorld();
   ArrayList<Team> teams = (ArrayList<Team>) world.getTeams();
   if (!(teams.size() == 0)) {
     int i = teams.size();
     int randomIndex = (int) (Math.random() * i);
     this.setTeamTo(teams.get(randomIndex));
   }
 }
Пример #11
0
 /**
  * Returns the cost in actionpoints for a given number of steps in the current direction.
  *
  * @param steps the number of steps the worm is going to move.
  * @return The cost of steps (integer) in the current direction, rounded up to the next integer.
  *     |(steps*(int) Math.round((Math.abs(Math.cos(this.getDirection()))
  *     |+Math.abs((4*Math.sin(this.getDirection()))))))
  */
 @Basic
 @Raw
 private int computeCostStep(int steps) {
   return Math.abs(
       (int)
           Math.round(
               (steps)
                   * (Math.abs(Math.cos(this.getDirection()))
                       + Math.abs((4.0 * Math.sin(this.getDirection()))))));
 }
Пример #12
0
 /** @return ... | result == Math.sqrt(Math.pow(getXComponent(),2)+Math.pow(getYComponent(),2)) */
 public double getTotalLength() {
   return Math.sqrt(Math.pow(xComp, 2) + Math.pow(yComp, 2));
 }
Пример #13
0
 /**
  * Sets the y-position of the projectile.
  *
  * @param ypos The (new) y-position of the projectile
  * @post the given y-position is the new y-position of the projectile. | new.getYpos() == ypos
  */
 @Raw
 private void setYpos(double ypos) {
   this.ypos =
       ypos + ((this.getRadiusWorm() + this.getRadius()) * 1.1 * Math.sin(this.getDirection()));
   position.setYpos(this.ypos);
 }
Пример #14
0
 /**
  * The method sets the radius of the projectile if it has a valid mass.
  *
  * @post The new radius of the projectile is set. |new.getRadius() ==
  *     Math.pow((3.0/4.0)*(this.getMass()/(density*Math.PI)) ,1.0/3.0)
  * @throws IllegalArgumentException When the mass appropriate to the projectile is not a valid
  *     mass the exception will be thrown. | ! isValidMass(this.getMass()))
  */
 @Raw
 private void setRadius() throws IllegalArgumentException {
   if (!isValidMass(this.getMass())) throw new IllegalArgumentException();
   this.radius = Math.pow((3.0 / 4.0) * (this.getMass() / (density * Math.PI)), 1.0 / 3.0);
 }
Пример #15
0
 /**
  * Returns the cost in actionpoints for a turn of a given angle.
  *
  * @param angle the angle over which the worm would like to turn in radians.
  * @return the cost in actionpoints for a turn of a given angle rounded up to the nearest integer.
  *     |(int) Math.abs(Math.round(((60*angle)/(2*Math.PI))))
  */
 @Basic
 @Raw
 private int computeCostTurn(double angle) {
   return (int) Math.abs(Math.round(((60 * angle) / (2 * Math.PI))));
 }
Пример #16
0
 /**
  * Returns the cost in actionpoints to move in the current direction.
  *
  * @param prevXpos The x-position of the worm before he moved.
  * @param prevYpos The y-position of the worm before he moved.
  */
 @Raw
 private int computeCost2(double prevXpos, double prevYpos) {
   return (int)
       (Math.round(Math.abs(this.getXpos() - prevXpos))
           + Math.round(4 * Math.abs(this.getYpos() - prevYpos)));
 }
Пример #17
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();
  }
Пример #18
0
  /**
   * Set the maximal amount of hit points of this worm.
   *
   * @param mass The hit points change along with the mass.
   * @post The amount of hit points must be equal to the mass of the worm rounded to the nearest
   *     integer. | this.maxHitPoints = (int) Math.round(mass)
   * @post If the mass of a worm changes, the maximal must be adjusted accordingly. | new.getMass()
   *     = mass | this.maxHitPoints == (int) Math.round(new.getMass()) == int Math.round(mass)
   * @effect The maximal amount of hit points has been set.
   */
  @Raw
  private void setMaxHitPoints() {

    if (this.getMass() < Integer.MAX_VALUE) this.maxHitPoints = (int) Math.round(this.getMass());
    else this.maxHitPoints = Integer.MAX_VALUE;
  }
Пример #19
0
 /**
  * Sets the x-position of the projectile.
  *
  * @param xpos The (new) x-position of the projectile
  * @post the given x-position is the new x-position of the projectile. | new.getXpos() == xpos
  */
 @Raw
 private void setXpos(double xpos) {
   this.xpos =
       xpos + ((this.getRadiusWorm() + this.getRadius()) * 1.1 * Math.cos(this.getDirection()));
   position.setXpos(this.xpos);
 }