public void step() {
   if (ok) {
     int nx[] = {1, -1, 0, 0};
     int ny[] = {0, 0, 1, -1};
     int x = perimeterListX[numberOfPerimeterSites - 1];
     int y = perimeterListY[numberOfPerimeterSites - 1];
     if (x > Lx - 3) {
       ok = false; // if cluster gets near the end, stop simulation
     }
     numberOfPerimeterSites--;
     site[x][y] -= 1;
     lattice.setValue(x, y, 1);
     for (int i = 0; i < 4; i++) { // finds new perimeter sites
       int perimeterX = x + nx[i];
       int perimeterY = (y + ny[i]) % Ly;
       if (perimeterY == -1) {
         perimeterY = Ly - 1;
       }
       if (site[perimeterX][perimeterY] < 1) { // new perimeter site
         site[perimeterX][perimeterY] += 2;
         numberOfPerimeterSites++;
         insert(perimeterX, perimeterY);
       }
     }
   }
 }
 public void initialize() {
   Lx = 2 * Ly;
   site = new double[Lx][Ly];
   perimeterListX = new int[Lx * Ly];
   perimeterListY = new int[Lx * Ly];
   for (int y = 0; y < Ly; y++) {
     site[0][y] = 1; // occupy first column
     lattice.setValue(0, y, 1);
   }
   for (int y = 0; y < Ly; y++) {
     for (int x = 1; x < Lx; x++) {
       site[x][y] = Math.random();
       lattice.setValue(x, y, 0);
     }
   }
   numberOfPerimeterSites = 0;
   for (int y = 0; y < Ly; y++) { // second column is perimeter sites
     site[1][y] += 2; // perimeter sites have site > 2;
     numberOfPerimeterSites++;
     insert(1, y); // inserts site in perimeter list in order
   }
   ok = true;
 }
 public Invasion(LatticeFrame latticeFrame) {
   lattice = latticeFrame;
   lattice.setIndexedColor(0, Color.blue);
   lattice.setIndexedColor(1, Color.black);
 }