Print

Print


Dear Mike,

> I am confused how the following code from Tutorial3 accomplishes the
> task of
> instantiating an assortment of particle agents:
>
> public void start()
>         {
>         super.start();
>         trails = new DoubleGrid2D(gridWidth, gridHeight);
>         particles = new SparseGrid2D(gridWidth, gridHeight);
>
>         Particle p;
>
>         for(int i=0 ; i<numParticles ; i++)
>             {
>             p = new Particle(random.nextInt(3) - 1, random.nextInt(3)
> - 1);
> schedule.scheduleRepeating(p);
>             particles.setObjectLocation(p,
>                                         new
> Int2D(random.nextInt(gridWidth),random.nextInt(gridHeight)));
>
>             }
>
> It would appear that we want to a create a collection of particles,
> but in
> fact we keep creating a single instance of the particle class (or at
> least
> multiple objects with the same reference "p." If we wanted to have the
> particles interact with each other (bounce off of each other), how
> could we
> differentiate between the particle objects, since they all have the
> same
> reference?

We do indeed want to create a collection of particles, and we do
accomplish that with the code in Tutorial3.  Here's how it is working:

The declaration

>             p = new Particle(random.nextInt(3) - 1, random.nextInt(3)
> - 1);

creates a new object of type particle.  p could be seen simply as a
C-style pointer to the newly created object (if you are more familiar
to programming in C).  The next line of code,

> schedule.scheduleRepeating(p);

adds the particle to the scheduler.  At this point in time, the
scheduler maintains another pointer to the specific object, such as to
pulse the particle at each time step.  The last line,

>             particles.setObjectLocation(p,
>                                         new
> Int2D(random.nextInt(gridWidth),random.nextInt(gridHeight)));

simply adds the particle to the SparseGrid2D field, which maintains
also a list of pointers to all the objects that reside in this field
(plus their location in the field).

At the next iteration, the value of p changes (as you point out): a new
object/particle is created, and p points to it.  This new particle is
added to the scheduler and to the field as before.  However, the
scheduler also maintains the pointer to the previously created
particle(s), and so does the field.

In order to differentiate among the particles, you you have multiple
approaches.  For example, the scheduler calls the step method of each
particle at each time step - at that point, you can differentiate
between the particle that has been called, and the other particles that
reside on the SparseField2D.  Also, you may ask the SparseField2D to
give you lists of the objects that reside there (via the methods
getObjectsAtLocation and getAllObjects for example) - in that case, you
could distinguish among the particles based on their indexes,
locations, or simply if they point to different objects in memory.

Also, your statement "how could we differentiate between the particle
objects, since they all have the same reference" is a bit incorrect, in
the sense that the same reference (p) that you mention is destroyed
immediately after the start method ends.  The start method is used to
simply create the objects, schedule them, and insert them in the field,
and it is the job of the scheduler to call them later on.  That code is
transparent to you as a programmer, what you need to pay attention to
is Particle's step method, which is where you will have to define the
behavior of your particle at each time step.

I hope this answers your question.

Regards,

Liviu.