I am making a simulation with MASON. I have a SparseGrid2D object which I populated as follows in my main simulation class:
protonLayer = new SparseGrid2D(HEIGHT, WIDTH);
MersenneTwisterFast g = new MersenneTwisterFast();
for(int i = 0; i < NUM_PROTONS; i++) {
// Creating the proton
Proton p = new Proton(new Int2D(g.nextInt(WIDTH), g.nextInt(HEIGHT)), this);
// Adding it to schedule
schedule.scheduleRepeating(p);
}
And in my steppable class I then call:
Bag neigh = s.protonLayer.getMooreNeighbors(location.getX(), location.getY(), 1, 1, new Bag(), new IntBag(), new IntBag());
However, for some reason neight.size() keeps returning one instead of returning all neighboring cells. I thought that getMooreNeighbors excluded empty neighboring cells, so I added:
// Moore locations doesn't return empty grids .-.
for(int i = 0; i < WIDTH; i++) {
for(int j = 0; j < HEIGHT; j++) {
protonLayer.setObjectLocation(new String("a"), i, j);
}
}
To my main class to try and get around this, but it hasn't worked even though every cell is now populated by at least one object!
Any thoughts?
Full version of code:
ProtonTest.java
package protontest;
import ec.util.MersenneTwisterFast;
import sim.engine.SimState;
import sim.field.grid.SparseGrid2D;
import sim.util.Int2D;
public class ProtonTest extends SimState{
public SparseGrid2D protonLayer;
public final int HEIGHT = 100;
public final int WIDTH = 100;
public final int NUM_PROTONS = 1;
public ProtonTest(long seed) {
super(seed);
}
public void start() {
protonLayer = new SparseGrid2D(HEIGHT, WIDTH);
MersenneTwisterFast g = new MersenneTwisterFast();
for(int i = 0; i < NUM_PROTONS; i++) {
// Creating the proton
Proton p = new Proton(new Int2D(g.nextInt(WIDTH), g.nextInt(HEIGHT)), this);
// Adding it to schedule
schedule.scheduleRepeating(p);
}
// Moore locations doesn't return empty grids .-.
for(int i = 0; i < WIDTH; i++) {
for(int j = 0; j < HEIGHT; j++) {
protonLayer.setObjectLocation(new String("a"), i, j);
}
}
}
public static void main(String[] args) {
doLoop(ProtonTest.class, args);
System.exit(0);
}
}
Proton.java
package protontest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import com.lowagie.text.pdf.hyphenation.TernaryTree.Iterator;
import ec.util.MersenneTwisterFast;
import sim.engine.SimState;
import sim.engine.Steppable;
import sim.util.Bag;
import sim.util.Int2D;
import sim.util.IntBag;
public class Proton implements Steppable {
public Int2D location;
// Building the proton and adding it to a random location
public Proton(SimState state) {
ProtonTest s = (ProtonTest) state;
MersenneTwisterFast g = new MersenneTwisterFast();
// Random location
int xloc = g.nextInt(s.WIDTH);
int yloc = g.nextInt(s.HEIGHT);
location = new Int2D(xloc, yloc);
// Add object
s.protonLayer.setObjectLocation(this, location);
}
// Building the proton and setting it at a given location
public Proton(Int2D location, SimState state) {
this.location = location;
ProtonTest s = (ProtonTest) state;
s.protonLayer.setObjectLocation(this, location);
}
// Same as constructor above, but takes two ints instead of an Int2D object
public Proton(int xloc, int yloc, SimState state) {
this(new Int2D(xloc, yloc), state);
}
// Stepping about
public void step(SimState state) {
ProtonTest s = (ProtonTest) state;
MersenneTwisterFast g = new MersenneTwisterFast();
// First thing first, does the proton stabilize independently?
int p = 100; // Proton will stabilize (hence be removed from the simulation) with probability of 1/p
int rand = g.nextInt(p);
// If rand = 0 then it met the 1/p probability fo being removed.
if(rand == 0) {
s.protonLayer.remove(this);
return;
}
// Get moore neighbors
Bag neigh = s.protonLayer.getMooreNeighbors(location.getX(), location.getY(), 1, 1, new Bag(), new IntBag(), new IntBag());
// Now we make a map that maps a location to an int. The int will be increased for every proton found at such location in the neighborhood.
Map<Int2D, Integer> m = new HashMap<Int2D, Integer>();
ArrayList<Int2D> a = new ArrayList<Int2D>();
// Looping through neighbors
for(Object o : neigh) {
// The "Proton Neighbor"
Proton pN = (Proton) o;
// Location of current element
Int2D thisLocation = pN.location;
if(!m.containsKey(location)) {
m.put(location, 1);
// There probably is a better way of iterating through maps
a.add(location);
} else {
// Everybody loves casting
int newCounter = ((int) m.get(location)) + 1;
m.put(location, (Integer) newCounter);
}
}
// Wait, we also want to know how many protons in the current cell
int pAtLocation = s.protonLayer.numObjectsAtLocationOfObject(this);
// Get minimum value from map (ie location where there are fewer protons in neighborhood)
int currentMin = pAtLocation;
Int2D location = this.location;
// For each neighbor
for(Int2D loc : a) {
// Get number of protons
int currentM = (int) m.get(loc);
// If there are fewer then the proton will migrate there, unless a better locationis found
if(currentM <= currentMin) {
currentMin = currentM;
location = loc;
}
}
// Move the proton to the new location aaaaaand done
s.protonLayer.setObjectLocation(this, location);
System.out.println(neigh.size());
}
}