> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.DVYCi5-l3pe/rev.235
 * 
 * authors: 
 *   
 *   
 *   Derek Wood
 *   Don Blair
 *   

 * license (unless otherwise specified): 
 *   creative commons attribution-share alike 3.0 license.
 *   https://creativecommons.org/licenses/by-sa/3.0/ 
 */ 



// This sketch builds on a prior work, "ising", created by Don Blair
// http://studio.sketchpad.cc/sp/pad/view/ro.9h-i6y8lg2U-K/rev.4

int L=50;
int N=L*L;
int[] s = new int[N];
int Q=2;
int spacing=5;
int dotsize=5;
float Beta=1/2.6;

int gap=100;
int sweeps=0;
int freeze=-1;


void setup() {
  
  size(500,500);
 // frameRate(10);
  
  // initial setup
  
  for (int i=0;i<L;i++) {
    
    for (int j=0;j<L;j++) {
      int n=i+j*L;
    
      int r=(int) random(0,Q);
      s[n]=r;
      
    }
  }
  
  display();
}

void sweep2(int neighborRange) {
  
  int k;
  int i;
  int newSpin;
  int delta;
  int x, y;
  
  for (k=0;k<N;k++) {
    
    //i=(int) random(0,N);
    x=(int) random(0,L);
    y=(int) random(0,L);
    
    i=x+y*L;
    newSpin= (int) random(0,Q);
    //newSpin=random(0,1);
    //newSpin=(int)Math.floor(newSpin+0.5);
    
    delta = getDelta(x, y, newSpin, neighborRange);
    
    if (delta<=0) {
     s[i]=newSpin; 
    }
    else {
     float ra=random(0,1);
     float ex=exp(-2*Beta*delta);
     if (ra<ex) {
      s[i]=newSpin;
     
     } 
    }
  }
  sweeps++;
  }

int getDelta(int x, int y, int newSpin, int neighborRange) {
  
  int nnx,nny,neighborSpin;
  int dx,dy;
  
  int oldSpin=s[x+y*L];
  
  int oldsum=0;
  int newsum=0;
  int delta;
  
  for (dx=-neighborRange;dx<=neighborRange;dx++) {
    
    for (dy=-neighborRange;dy<=neighborRange;dy++) {
      
      nnx=mod(x+dx,L);
      nny=mod(y+dy,L);
      //nnx = x+dx;
      //nny = y+dy;
      
      if ((nnx!=x) || (nny!=y)) {
        
        neighborSpin=s[nnx+L*nny];
        
        if (oldSpin==neighborSpin) {
          oldsum++;
        }
        
        if (newSpin==neighborSpin) {
          newsum++;
        }
      
      }
      
    }
    
  }
  
  delta=-(newsum-oldsum);
  
  return delta;
  
}

void display() {

  background(0);
  //println("----------------------------");
  for (int j=0;j<L;j++) {
    
    for (int i=0;i<L;i++) {
      int n=i+j*L;
      int v=s[n];
      //if (j==0) println(v);
      //float fillval=(float) v / (float) Q * 255;
      int fillval=0;
      if (v==0) fillval=0;
      if (v==1) fillval=255;
      int x=i*dotsize+gap;
      int y=j*dotsize+gap;
      fill(fillval);
      //println(fillval);
      noStroke();
      rect(x,y,dotsize,dotsize);
      //ellipse(x+dotsize/2,y+dotsize/2,dotsize*1.1,dotsize*1.1);
        
    }
  }
  
  fill(255);
  text("sweeps="+sweeps,gap,gap/2);
  //text(normmag,gap/2,gap/2+20);
  
  
}
void draw() {
  
  //display
  //background(0);
  display();
  if (freeze==-1) {
  sweep2(1);
  }
 
  
  
}

void mousePressed() {
  freeze*=-1;
  
}

// return k mod m
public static int mod(int k, int m) {
 k = k % m;
 if(k < 0) k+=m;
 return(k);
}//mod()