/**
   * Removes an {@code Actor} from the {@code World}. The {@code Actor} must be both bound to this
   * {@code World} and not held by another {@code Actor}. However, if the {@code Actor} is expired,
   * it may always be removed.
   *
   * @param actor the {@code Actor} to be removed
   */
  public void removeActor(Actor actor) {
    Guard.argumentIsNotNull(actor);
    Guard.verifyState(actor.bound(this));
    Guard.verifyState(!actor.held() || actor.expired());

    unregisterActor(actor);
    removeFromGrid(actor);
    actor.setWorld(null);
  }
  /**
   * Adds an {@code Actor} to the {@code World} at the specified location.
   *
   * @param actor the {@code World} being added
   * @param x the x location of the {@code Actor}
   * @param y the y location of the {@code Actor}
   */
  public void addActor(Actor actor, int x, int y) {
    Guard.argumentIsNotNull(actor);
    Guard.argumentsInsideBounds(x, y, width, height);
    Guard.verifyState(!actor.bound());
    Guard.verifyState(!actor.held());

    actor.setWorld(this);
    actor.setXY(x, y);
    addToGrid(actor);
    registerActor(actor);
  }
  /**
   * Returns the probability of the specified value given a particular {@code Categorical}.
   *
   * @param key the key of the {@code Categorical} being queried
   * @param value the value being queried
   * @return the probability of value given the key
   */
  public double probabilityGiven(K key, V value) {
    Guard.verifyState(totals.sumCounts() > 0);

    return sumCountGiven(key) > 0 ? getCategorical(key).probability(value) : 0;
  }