Package org.nlogo.prim.etc

Source Code of org.nlogo.prim.etc._atpoints

// (C) Uri Wilensky. https://github.com/NetLogo/NetLogo

package org.nlogo.prim.etc;

import org.nlogo.agent.Agent;
import org.nlogo.agent.AgentSet;
import org.nlogo.agent.ArrayAgentSet;
import org.nlogo.agent.Patch;
import org.nlogo.agent.Turtle;
import org.nlogo.api.AgentException;
import org.nlogo.api.Dump;
import org.nlogo.api.I18N;
import org.nlogo.api.LogoException;
import org.nlogo.api.LogoList;
import org.nlogo.api.Syntax;
import org.nlogo.nvm.Context;
import org.nlogo.nvm.EngineException;
import org.nlogo.nvm.Reporter;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

public final strictfp class _atpoints
    extends Reporter {
  @Override
  public Object report(final Context context) throws LogoException {
    // part 1: get arguments, context.checked validity
    AgentSet sourceSet = argEvalAgentSet(context, 0);
    List<Agent> result = new ArrayList<Agent>();
    LogoList points = argEvalList(context, 1);
    for (Iterator<Object> it = points.iterator(); it.hasNext();) {
      if (!validateListEntry(it.next())) {
        throw new EngineException(context, this, I18N.errorsJ().getN(
            "org.nlogo.prim.etc._atpoints.invalidListOfPoints", Dump.logoObject(points)));
      }
    }

    // part 2: figure out which patches are at the given points
    Set<Patch> patches =
        getPatchesAtPoints(context, context.agent, points);

    // part 3: construct a new agentset and return it
    if (sourceSet.type() == Patch.class) {
      if (sourceSet != world.patches()) {   //sourceSet is not the entire set of patches
        for (Iterator<Patch> iter = patches.iterator(); iter.hasNext();) {
          Patch patch = iter.next();
          if (sourceSet.contains(patch)) {
            result.add(patch);
          }
        }
      } else //sourceSet is the entire set of patches
        result.addAll(patches);
      }
    } else if (sourceSet.type() == Turtle.class) {
      if (sourceSet != world.turtles()) {  //sourceSet is not the entire set of turtles
        if (world.isBreed(sourceSet)) {  //source set is a breed
          for (Iterator<Patch> iter = patches.iterator(); iter.hasNext();) {
            Patch otherPatch = iter.next();
            for (Turtle tempTurtle : otherPatch.turtlesHere()) {
              if (sourceSet == tempTurtle.getBreed()) {
                result.add(tempTurtle);
              }
            }
          }
        } else //sourceSet not the entire set of turtles and is not a breed
          for (Iterator<Patch> iter = patches.iterator(); iter.hasNext();) {
            Patch otherPatch = iter.next();
            for (Turtle tempTurtle : otherPatch.turtlesHere()) {
              if (sourceSet.contains(tempTurtle)) {
                result.add(tempTurtle);
              }
            }
          }
        }
      } else {   //sourceSet is the entire set of turtles
        for (Patch p : patches) {
          for (Turtle t : p.turtlesHere()) {
            result.add(t);
          }
        }
      }

    }
    return new ArrayAgentSet
        (sourceSet.type(), result.toArray(new Agent[result.size()]),
            world);
  }

  private boolean validateListEntry(Object entry) {
    if (entry instanceof LogoList) {
      LogoList entryList = (LogoList) entry;
      if (entryList.size() == 2 ||
          ((world.program().is3D())
              && (entryList.size() == 3))) {
        for (Iterator<Object> iter = entryList.iterator(); iter.hasNext();) {
          if (!(iter.next() instanceof Double)) {
            return false;
          }
        }
        return true;
      }
    }
    return false;
  }

  private Set<Patch> getPatchesAtPoints(Context context, Agent agent, LogoList points)
      throws LogoException {
    // use LinkedHashSet here because we want fast lookup, but we also need
    // predictable ordering so runs are reproducible - ST 8/13/03
    LinkedHashSet<Patch> result =
        new LinkedHashSet<Patch>();
    boolean is3D = world.program().is3D();
    for (Iterator<Object> it = points.iterator(); it.hasNext();) {
      LogoList entry = (LogoList) it.next();
      Double x = null;
      Double y = null;
      Double z = org.nlogo.agent.World.ZERO;
      int j = 0;
      for (Iterator<Object> it2 = entry.iterator(); it2.hasNext();) {
        switch (j) {
          case 0:
            x = (Double) it2.next();
            break;
          case 1:
            y = (Double) it2.next();
            break;
          case 2:
            if (!is3D) {
              throw new EngineException(context, this,
                  I18N.errorsJ().getN("org.nlogo.prim.etc._atpoints.invalidListOfPoints", Dump.logoObject(points)));

            }
            z = (Double) it2.next();
            break;
          default:
            throw new EngineException(context, this,
                I18N.errorsJ().getN("org.nlogo.prim.etc._atpoints.invalidListOfPoints", Dump.logoObject(points)));
        }
        j++;
      }
      if (x == null || y == null) {
        throw new EngineException(context, this,
            I18N.errorsJ().getN("org.nlogo.prim.etc._atpoints.invalidListOfPoints", Dump.logoObject(points)));
      }
      try {
        Patch patch = null;
        if (!is3D) {
          patch = agent.getPatchAtOffsets(x.doubleValue(), y.doubleValue());
        } else {
          patch =
              ((org.nlogo.agent.Agent3D) agent).getPatchAtOffsets(x.doubleValue(),
                  y.doubleValue(),
                  z.doubleValue());

        }
        if (patch != null) {
          result.add(patch);
        }
      } catch (AgentException e) { } // NOPMD
    }
    return result;
  }

  @Override
  public Syntax syntax() {
    int left = Syntax.TurtlesetType() | Syntax.PatchsetType();
    int[] right = {Syntax.ListType()};
    int ret = Syntax.AgentsetType();
    return Syntax.reporterSyntax(left, right, ret, org.nlogo.api.Syntax.NormalPrecedence() + 2);
  }
}
TOP

Related Classes of org.nlogo.prim.etc._atpoints

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.