case 0: //time tunnel

              {

              s=(int)buf[C]%2+(int)buf[N]%2+(int)buf[S]%2+(int)buf[E]%2+(int)buf[W]%2;

              if ((s>0)&&(s<5))

                   c=(((int)buf[C]/2)%2)^1;

              else

                   c=(((int)buf[C]/2)%2)^0;

              c=c+2*((int)buf[C]%2);

              break;

              }

              case 1: //BBC2

              {

              s=((int)buf[C]!=0)+((int)buf[N]!=0)+((int)buf[S]!=0)+((int)buf[E]!=0)+((int)buf[W]!=0);

              c=0;

              if ((int)buf[C]!=0) c=(int)buf[C]-1; else if (s&1) c=top-1;

              break;

              }

              case 2: //infect

              {

              if(rl<13) {gg=7; k1=2; k2=3;} else {gg=10*rar[3]+rar[4]; k1=rar[6]+0.1*rar[8]; k2=rar[10]+0.1*rar[12]; }

              s=(int)buf[C]+(int)buf[N]+(int)buf[S]+(int)buf[E]+(int)buf[W]+(int)buf[NE]+(int)buf[NW]+(int)buf[SE]+(int)buf[SW];

              A=((int)buf[N]>0)+((int)buf[S]>0)+((int)buf[E]>0)+((int)buf[W]>0)+((int)buf[NE]>0)+((int)buf[NW]>0)+((int)buf[SE]>0)+((int)buf[SW]>0);

              B=((int)buf[N]==top)+((int)buf[S]==top)+((int)buf[E]==top)+((int)buf[W]==top)+((int)buf[NE]==top)+((int)buf[NW]==top)+((int)buf[SE]==top)+((int)buf[SW]==top);

              if ((int)buf[C]==0) c=floor(A/k1)+floor(B/k2); else c=floor(s/A)+gg;

              if ((int)buf[C]==top) c=0;

              if ((c>top)||(c<0)) c=top;

              break;

              }

              case 3: //demons

                   if(rl==0)

                       {            

                   //   printf("%d %d  ",rl,top);

                       nn=(int)buf[N]; ss=(int)buf[S]; ee=(int)buf[E]; ww=(int)buf[W];

                       if (nn==0) nn=top; if (ee==0) ee=top; if (ww==0) ww=top; if (ss==0) ss=top;

                       if ((nn==(int)buf[C]+1)||(ee==(int)buf[C]+1)||(ss==(int)buf[C]+1)||(ww==(int)buf[C]+1)) c=(int)buf[C]+1; else c=(int)buf[C];

                       if (c>=top) c=0;

                       break;

                       }

                   else if((rar[0]==0)&&(rar[1]==0)) //pattern breeder

                       {

                       nn=(int)buf[N]; ss=(int)buf[S]; ee=(int)buf[E]; ww=(int)buf[W];

                       if(rar[4]!=1)

                            s=(nn>0)+(ee>0)+(ss>0)+(ww>0);

                       else

                            s=(nn)+(ee)+(ss)+(ww);

                       if (rar[3]%2==1)

                       {

                            cc=(int)buf[C];

                            if(rar[4]!=1)

                                 s=s+(cc>0);

                            else

                                 s=s+(cc);

                       }

                       if(rar[3]>=2)

                            {

                            ne=(int)buf[NE]; nw=(int)buf[NW]; se=(int)buf[SE]; sw=(int)buf[SW];

                            if(rar[4]!=1)

                                 s=s+(ne>0)+(se>0)+(sw>0)+(nw>0);

                            else

                                 s=s+(ne)+(se)+(sw)+(nw);

                            }

                       if(rar[3]>=4)

                            {

                            N=(iy-3)*sx+(ix-1); if (iy<=2) N=N+sx*sy;

                            S=(iy+1)*sx+(ix-1); if (iy>=sy-1) S=S-sx*sy;

                            W=(iy-1)*sx+(ix-3); if (ix<=2) W=W+sx;

                            E=(iy-1)*sx+(ix+1); if (ix>=sx-1) E=E-sx;

                            nn=(int)buf[N]; ss=(int)buf[S]; ee=(int)buf[E]; ww=(int)buf[W];

                            if(rar[4]!=1)

                                 s=s+(nn>0)+(ee>0)+(ss>0)+(ww>0);

                            else

                                 s=s+(nn)+(ee)+(ss)+(ww);

                            }

                       c=s%top;

                       break;

                       }

                   else if ((rar[0]==0)&&(rar[1]==1)) //rock-paper-scissors

                       {

                       c=(int)buf[C];

                       nn=(int)(buf[N]-c); nn=rpsfix(nn);

                       ss=(int)(buf[S]-c); ss=rpsfix(ss);

                       ee=(int)(buf[E]-c); ee=rpsfix(ee); 

                       ww=(int)(buf[W]-c); ww=rpsfix(ww);

                       s=sgn(nn)+sgn(ee)+sgn(ss)+sgn(ww);

                       t=dff(nn)+dff(ee)+dff(ss)+dff(ww);

    

                       if(rar[7]==1)

                            {

                            ne=(int)(buf[NE]-c); ne=rpsfix(ne);

                            nw=(int)(buf[NW]-c); nw=rpsfix(nw);

                            se=(int)(buf[SE]-c); se=rpsfix(se);

                            sw=(int)(buf[SW]-c); sw=rpsfix(sw);

                            s=s+sgn(ne)+sgn(se)+sgn(sw)+sgn(nw);

                            t=t+dff(ne)+dff(se)+dff(sw)+dff(nw);

                            }

                       if (rar[2]<2)

                       {

                            if (s>=rar[3]) c=mv(rar[4],c);

                            if ((s>-rar[3])&&(s<rar[3])) c=mv(rar[5],c);

                            if (s<=-rar[3]) c=mv(rar[6],c);

                            if (c==3) c=0; if (c==-1) c=2;

                       }

                       else

                       {

                            if (c<3)

                            {

                                 if (s>=rar[3]) c=mv(rar[4],c);

                                 if ((s>-rar[3])&&(s<rar[3])) c=mv(rar[5],c);

                                 if (s<=-rar[3]) c=mv(rar[6],c);

                                 if (c==3) c=0; if (c==-1) c=2;

                            }

                            else

                            {

                                 if (s>=rar[3]) c=mv(rar[12],c);

                                 if ((s>-rar[3])&&(s<rar[3])) c=mv(rar[13],c);

                                 if (s<=-rar[3]) c=mv(rar[14],c);

                                 if (c==6) c=3; if (c==2) c=5;

                            }

                            if (t>=rar[11]) if (c<3) c=c+3; else c=c-3;

                       }

                       if(rar[8]!=1)

                            {

                            pp=0.1*rar[9]+0.01*rar[10];

                            if (rand()>pp*RAND_MAX) if (rar[2]<2) c=rand()%3; else c=rand()%6;

                            }

                       break;

                       }

                      

                   else

                       {

                       nn=(int)buf[N]; ss=(int)buf[S]; ee=(int)buf[E]; ww=(int)buf[W];

                       if (nn==0) nn=top; if (ee==0) ee=top; if (ww==0) ww=top; if (ss==0) ss=top;

                       s=(nn==(int)buf[C]+1)+(ee==(int)buf[C]+1)+(ss==(int)buf[C]+1)+(ww==(int)buf[C]+1);

                       if(rar[3]>=1)

                            {

                            ne=(int)buf[NE]; nw=(int)buf[NW]; se=(int)buf[SE]; sw=(int)buf[SW];

                            s2=(rar[3]-1)%2+1;

                            if (ne<s2) ne=ne+top; if (nw<s2) nw=nw+top; if (sw<s2) sw=sw+top; if (se<s2) se=se+top;

                            s=s+(ne==(int)buf[C]+s2)+(se==(int)buf[C]+s2)+(sw==(int)buf[C]+s2)+(nw==(int)buf[C]+s2);

                            }

                       if(rar[3]>=3)

                            {

                            N=(iy-3)*sx+(ix-1); if (iy<=2) N=N+sx*sy;

                            S=(iy+1)*sx+(ix-1); if (iy>=sy-1) S=S-sx*sy;

                            W=(iy-1)*sx+(ix-3); if (ix<=2) W=W+sx;

                            E=(iy-1)*sx+(ix+1); if (ix>=sx-1) E=E-sx;

                            nn=(int)buf[N]; ss=(int)buf[S]; ee=(int)buf[E]; ww=(int)buf[W];

                            s2=2*(rar[3]-3)+1;

                            if (nn<s2) nn=nn+top; if (ee<s2) ee=ee+top; if (ww<s2) ww=ww+top; if (ss<s2) ss=ss+top;

                            s=s+(nn==(int)buf[C]+s2)+(ee==(int)buf[C]+s2)+(ss==(int)buf[C]+s2)+(ww==(int)buf[C]+s2);

                            }

                       if(s>=rar[2]) { c=(int)buf[C]+1; if (c>=top) c=0; } else c=(int)buf[C];

                      

                       break;                     

                       }

              case 4: //life games which depend only on the sum of states in a moore neighbourhood

              {

              s=((int)buf[N]!=0)+((int)buf[S]!=0)+((int)buf[E]!=0)+((int)buf[W]!=0)+((int)buf[NE]!=0)+((int)buf[NW]!=0)+((int)buf[SE]!=0)+((int)buf[SW]!=0);

              //s=(int)buf[N]+(int)buf[S]+(int)buf[E]+(int)buf[W]+(int)buf[NE]+(int)buf[NW]+(int)buf[SE]+(int)buf[SW];

                   if (cf==1) s=s+((int)buf[C]!=0);

              if((bl==0)&&(sl==0)) //standard Conway's life

                   if((int)buf[C]==0)

                       if(s==3) c=top-1; else c=0;

                   else

                       if((s==2)||(s==3)) {c=(int)buf[C]-1; if(c<top/7) c=ceil(top/7); } else c=0;                 

                   //if ((s==3)||(((int)buf[C]==1)&&(s==2))) c=1; else c=0;

              else if(ag==0)  //an input rule defined life game

                   if ((int)buf[C]==0)

                       {

                       fl=0;

                       for(i=0;i<bl;i++)

                            if(bar[i]==s) {fl=1; break;}

                       if(fl==1) c=top-1; else c=0;

                       //if(fl==1) c=1; else c=0;

                       }

                   else

                       {

                       fl=0;

                       for(i=0;i<sl;i++)

                            if(sar[i]==s) {fl=1; break;}

                       if(fl==1) {c=(int)buf[C]-1; if(c<top/7) c=ceil(top/7); } else c=0;

                       //if(fl==1) c=1;  else c=0;

                       }

              else

                   {

                   s=((int)buf[N]==top-1)+((int)buf[S]==top-1)+((int)buf[E]==top-1)+((int)buf[W]==top-1)+((int)buf[NE]==top-1)+((int)buf[NW]==top-1)+((int)buf[SE]==top-1)+((int)buf[SW]==top-1);                

                   //if((s<0)||(s>8)) printf("%d ",s);

                   if ((int)buf[C]==0)

                       {

                       fl=0;

                       for(i=0;i<bl;i++)

                            if(bar[i]==s) {fl=1; break;}

                       if(fl==1) c=top-1; else c=0;

                       //if(fl==1) c=1; else c=0;

                       }

                   else if ((int)buf[C]==top-1)

                       {

                       fl=0;

                       for(i=0;i<sl;i++)

                            if(sar[i]==s) {fl=1; break;}

                       if(fl==1) c=top-1;  else c=(int)buf[C]-1;

                       //if(fl==1) c=1;  else c=0;

                       }

                   else

                       c=(int)buf[C]-1;

                   }

              break;

              }

              case 5: //persian

              {

              s=(int)buf[N]%2+(int)buf[E]%2+(int)buf[S]%2+(int)buf[W]%2;

              if ((int)buf[C]%2!=0) c=(s<=2); else c=((s>=1)&&(s<=4));

              c=c+2*((int)buf[C]%2);

              break;

              }

              case 6: //hour glass

              {

              s=2*(2*(2*(2*((int)buf[E]%2) + (int)buf[W]%2) + (int)buf[S]%2) + (int)buf[N]%2) + (int)buf[C]%2;

              if((s>=1)&&(s<=3)) c=1;

              else if ((s==11)||(s==21)||(s==31)) c=1;

              else if ((s>=29)&&(s<=31)) c=1;

              else c=0;

              if ((int)buf[C]%2!=0) c=c+2;

              break;

              }

              case 7: //shrike

              {

              s=(int)buf[N]%2+(int)buf[E]%2+(int)buf[S]%2+(int)buf[W]%2;

              if ((int)buf[C]%2!=0) c=((s>=2)&&(s<=4)); else c=((s==1)||(s==3)||(s==4));

              c=c+2*((int)buf[C]%2);

              break;

              }

              case 8: //moore fractal extended

              {

              s=(int)buf[N]%2+(int)buf[S]%2+(int)buf[E]%2+(int)buf[W]%2+(int)buf[NE]%2+(int)buf[NW]%2+(int)buf[SE]%2+(int)buf[SW]%2;

              if(s==1) c=1; else c=(int)buf[C]%2;

              //added for superimposed effect

              s=((int)buf[N]/2)%2+((int)buf[S]/2)%2+((int)buf[E]/2)%2+((int)buf[W]/2)%2+((int)buf[NE]/2)%2+((int)buf[NW]/2)%2+((int)buf[SE]/2)%2+((int)buf[SW]/2)%2;

              if(s>4) c=c+2; else c=c+2*((int)buf[C]/2)%2;

              c=c+2*((int)buf[C]%2)-2*((int)buf[C]/2)%2;

              if (c==8) c=0;

              break;

              }

              case 9: //fires

              {

              c=0;

              s2=0;

              if ((int)buf[N]==2) s2=s2+1;

              if ((int)buf[S]==2) s2=s2+1;

              if ((int)buf[E]==2) s2=s2+1;

              if ((int)buf[W]==2) s2=s2+1;

              s=0;

              if ((int)buf[N]==1) s=s+1;

              if ((int)buf[S]==1) s=s+1;

              if ((int)buf[E]==1) s=s+1;

              if ((int)buf[W]==1) s=s+1;

              if ((int)buf[C]==3) c=0;

              if ((int)buf[C]==2)

                   if (((int)buf[N]==3)||((int)buf[S]==3)||((int)buf[E]==3)||((int)buf[W]==3)) c=3;

                   else if (s==1) c=1; else c=2;

              if ((int)buf[C]==1) if (s==1) c=1; else c=0;

              if ((int)buf[C]==0) if (s2==0) c=2; else c=0;

              break;

              }

              case 10: //border

              {

              if((((int)buf[C]/2)%2)!=0)

                   {

                   s=(int)buf[C]%2+(int)buf[N]%2+(int)buf[S]%2+(int)buf[E]%2+(int)buf[W]%2+(int)buf[NE]%2+(int)buf[NW]%2+(int)buf[SE]%2+(int)buf[SW]%2;

                   c=(s!=0);

                   }

              else

                   {

                   s=((int)buf[N]%2)*((int)buf[S]%2)*((int)buf[E]%2)*((int)buf[W]%2)*((int)buf[NE]%2)*((int)buf[NW]%2)*((int)buf[SE]%2)*((int)buf[SW]%2);

                   if(s!=0) c=0; else c=(int)buf[C]%2;

                   c=c+2;

                   }

              break;            

              }

              case 11: //diffusion

              {

              s=(int)buf[N]%2+(int)buf[S]%2+(int)buf[E]%2+(int)buf[W]%2+(int)buf[NE]%2+(int)buf[NW]%2+(int)buf[SE]%2+(int)buf[SW]%2;

              if((int)buf[C]%2!=0) c=((s>=2)&&(s<=4)); else c=(s==3);

              c=c+2*((int)buf[C]%2);          

              break;            

              }

              case 12: //brain

              {

              s=(int)buf[N]%2+(int)buf[S]%2+(int)buf[E]%2+(int)buf[W]%2+(int)buf[NE]%2+(int)buf[NW]%2+(int)buf[SE]%2+(int)buf[SW]%2;

              c=(((int)buf[C]==0)&&(s==2))+2*((int)buf[C]%2);

              break;            

              }

              case 13: //Neumann Rule from input

              {

              if(rl!=0)

                   {

                   //

                   //s=top*(top*(top*(top*((int)buf[C]%top)+(int)buf[N]%top)+(int)buf[E]%top)+(int)buf[S]%top)+(int)buf[W]%top;

                   if (rar[0]==1)

                   {

                       if(rar[2]==4)

                            s=top*(top*(top*((int)buf[N])+(int)buf[E])+(int)buf[S])+(int)buf[W];

                       if(rar[2]==5)

                            s=top*(top*(top*(top*((int)buf[C])+(int)buf[N])+(int)buf[E])+(int)buf[S])+(int)buf[W];

                       if(rar[2]==8)

                            s=top*(top*(top*(top*(top*(top*(top*((int)buf[N])+(int)buf[E])+(int)buf[S])+(int)buf[W])+(int)buf[NW])+(int)buf[NE])+(int)buf[SE])+(int)buf[SW];

                       if(rar[2]==9)

                            s=top*(top*(top*(top*(top*(top*(top*(top*((int)buf[C])+(int)buf[N])+(int)buf[E])+(int)buf[S])+(int)buf[W])+(int)buf[NW])+(int)buf[NE])+(int)buf[SE])+(int)buf[SW];

                   }

                   else

                   {

                       s=(int)buf[N]+(int)buf[E]+(int)buf[S]+(int)buf[W];

                       if (rar[2]%4==1)

                            s=s+(int)buf[C];

                       if (rar[2]>=8)        

                            s=s+(int)buf[NW]+(int)buf[NE]+(int)buf[SW]+(int)buf[SE];                   }

                   //if ((ss>rl-1)||(ss<0)) printf("%d %d %d %d %d %d %d\n",ss,top,(int)buf[C],(int)buf[N],(int)buf[E],(int)buf[S],(int)buf[W]);

              //   c=rar[s+1];

                   if ((s>=0)&&(s<rl-1)) c=rar[rl-s-1]; else c=0;

                   }

              else

                   {

                   s=top*(top*(top*(top*((int)buf[C])+(int)buf[N])+(int)buf[E])+(int)buf[S])+(int)buf[W];

                   c=fredkin[s+1];

                   //c=0;

                   }

              break;

              }

              case 14:  //random growth

              {       

              //s=((int)buf[N])+((int)buf[S])+((int)buf[E])+((int)buf[W])+((int)buf[NE])+((int)buf[NW])+((int)buf[SE])+((int)buf[SW]);

              s=((int)buf[N]!=0)+((int)buf[S]!=0)+((int)buf[E]!=0)+((int)buf[W]!=0)+((int)buf[NE]!=0)+((int)buf[NW]!=0)+((int)buf[SE]!=0)+((int)buf[SW]!=0);

              if (((int)buf[C]==0)&&(s<=3)&&(s>0)) c=rand()%(top); else c=(int)buf[C];//if ((int)buf[C]>0) c=(int)buf[C]-rand()%2; else c=0; //rand()%((int)buf[C]+1);

              break;

              }

              // case 15: is actually the default (sum) see below

              case 16:  //1D rule

              {

                   if(iy<sy) c=(int)buf[S];//[C+sx];

              else

                   if(rl==0)

                       {                 

                       s=2*(2*((int)mbuf[NW])+(int)mbuf[N])+(int)mbuf[NE];

                       //s=2*(2*((int)buf[W])+(int)buf[C])+(int)buf[E];

                       c=rule110[s];

                       }

                   else

                   {

                       if(rar[0]==1)

                            {

                            if(rar[2]==3)

                                 s=top*(top*((int)mbuf[NW])+(int)mbuf[N])+(int)mbuf[NE];

                            if(rar[2]==5)

                                 s=top*(top*(top*(top*((int)mbuf[NWW]%top)+(int)mbuf[NW]%top)+(int)mbuf[N]%top)+(int)mbuf[NE]%top)+(int)mbuf[NEE]%top;

                            if(rar[2]==7)

                                 s=top*(top*(top*(top*(top*(top*((int)mbuf[NWWW]%top)+(int)mbuf[NWW]%top)+(int)mbuf[NW]%top)+(int)mbuf[N]%top)+(int)mbuf[NE]%top)+(int)mbuf[NEE]%top)+(int)mbuf[NEEE]%top;

                            c=rar[rl-s-1];

                            }

                       else if(rar[0]==2)

                            {

                            if (rar[2]==3)

                                 s=(int)mbuf[NW]+(int)mbuf[N]+(int)mbuf[NE];

                            if (rar[2]==5)

                                 s=(int)mbuf[NWW]+(int)mbuf[NW]+(int)mbuf[N]+(int)mbuf[NE]+(int)mbuf[NEE];

                            if (rar[2]==7)

                                 s=(int)mbuf[NWWW]+(int)mbuf[NWW]+(int)mbuf[NW]+(int)mbuf[N]+(int)mbuf[NE]+(int)mbuf[NEE]+(int)mbuf[NEEE];

                            if ((s>=0)&&(s<rl-1)) c=rar[rl-s-1]; else c=0;

                            }

                       else

                            {

                            ne=(int)mbuf[NE]; nw=(int)mbuf[NW];

                            if (ne<1) ne=ne+top; if (nw<1) nw=nw+top;

                            s=(ne==(int)mbuf[N]+1)+(nw==(int)mbuf[N]+1);

                            if(rar[2]>=5)

                                 {

                                 ne=(int)mbuf[NEE]; nw=(int)mbuf[NWW];

                                 if (ne<1) ne=ne+top; if (nw<1) nw=nw+top;

                                 s=s+(ne==(int)mbuf[N]+1)+(nw==(int)mbuf[N]+1);

                                 }

                            if(rar[2]>=7)

                                 {

                                 ne=(int)mbuf[NEEE]; nw=(int)mbuf[NWWW];

                                 if (ne<1) ne=ne+top; if (nw<1) nw=nw+top;

                                 s=s+(ne==(int)mbuf[N]+1)+(nw==(int)mbuf[N]+1);

                                 }

                            if(s>=rar[3]) { c=(int)mbuf[N]+1; if (c>=top) c=0; } else c=(int)mbuf[N];

                            }

                       if (rar[0]==4)

                       {

                            {

                                 //nn=(int)buf[N];

                                 nn=(int)mbuf[(iy-3)*sx+(ix-1)];

                                 /*if(((c!=0)&&(nn==0))||((c==0)&&(nn!=0)))

                                     c=1;

                                 else

                                     c=0;*/

                                 c=c-nn;

                                 if (c<0)

                                     c=c+top;

                                 c=c%top;

                                 //c=(c+nn)%top;

                            }

                            //1Dreverse

                       }

                   }                 

              break;

              }

              case 17:  //1D Life/Gen

              {

                   if(iy<sy) c=(int)buf[S];

              else

              {

                   if (ce==3)

                       s=(int)mbuf[NW]+(int)mbuf[NE];

                   if (ce==5)

                       s=(int)mbuf[NWW]+(int)mbuf[NW]+(int)mbuf[NE]+(int)mbuf[NEE];

                   if (ce==7)

                       s=(int)mbuf[NWWW]+(int)mbuf[NWW]+(int)mbuf[NW]+(int)mbuf[NE]+(int)mbuf[NEE]+(int)mbuf[NEEE];

                   if (cf==1) s=s+(int)mbuf[N];

                   if ((int)mbuf[N]==0)

                       {

                       fl=0;

                       for(i=0;i<bl;i++)

                            if(bar[i]==s) {fl=1; break;}

                       if(fl==1) c=top-1; else c=0;

                       //if(fl==1) c=1; else c=0;

                       }

                   else if ((int)mbuf[N]==top-1)

                       {

                       fl=0;

                       for(i=0;i<sl;i++)

                            if(sar[i]==s) {fl=1; break;}

                       if(fl==1) c=top-1;  else c=(int)mbuf[N]-1;

                       //if(fl==1) c=1;  else c=0;

                       }

                   else

                       c=(int)mbuf[N]-1;

              }

              break;

              }

              case 18:  // Shells

              {

              if(iy<sy) c=(int)buf[S];

              else

              {

                       if(rl!=23) {

                            //rr=1; R=2; w1=5; w2=10; m0=0; m1=.3; pp=0.002; d=0; }

                            //rr=2; R=0; w1=6; w2=35; m0=0; m1=0.05; pp=0.002; d=0.1; }//KM fig 11

                            //rr=3; R=0; w1=5; w2=12; m0=0; m1=0.22; pp=0.004; d=0.19; } //KM fig 10

                            //rr=3; R=8; w1=2; w2=11; m0=0; m1=0.3; pp=0.001; d=0; } //KM fig 9

                            //rr=2; R=0; w1=10; w2=48; m0=0; m1=0; pp=0.002; d=0; } //KM fig 4

                            rr=1; R=0; w1=12; w2=48; m0=0; m1=0.0105; pp=0.0033; d=0; } //Lorien1

                            //rr=4; R=9; w1=2; w2=18; m0=0; m1=0.2; pp=0.002; d=0.06; } //KM fig 18iii

                            //rr=4; R=9; w1=5; w2=38; m0=0; m1=0; pp=0.002; d=0.06; }  //Lorien2

                            //rr=2; R=4; w1=8; w2=48; m0=0; m1=0.03; pp=0.002; d=0.055; } //LorienFin

                            //rr=3; R=8; w1=2; w2=11; m0=0; m1=0.3; pp=0.002; d=0.06; } //Christine

                             num=0;

                             for (h=(ix-rr);h<=(ix+rr);h++)    //for all neighbours of the cell

                                 {

                                 hh=h;

                                  if (h<0) hh=h+sx;

                                  if(h>sx-1) hh=h-sx;

                                  if ((int)mbuf[(iy-2)*sx+hh-1]==0)    //adds up how many neighbours are occupied

                                     num=num+1;

                                 }

                             if ((int)mbuf[(iy-2)*sx+ix-1]==0)

                                  num=num-1;

                             if (AA[ix-1]>=1)

                                  if (d==0)

                                     A1[ix-1]=AA[ix-1]-1;

                                  else

                                     A1[ix-1]=round(AA[ix-1]*(1-d));

                             else

                                  A1[ix-1]=0;

                    

                             if ((int)mbuf[(iy-2)*sx+ix-1]==1)

                                 {

                                  x=(double)rand()/2147483647;

                                  if (x<pp)

                                      B1[ix-1]=1;

                                  else

                                      B1[ix-1]=0;

                                 }

                             else

                                  B1[ix-1]=1;

                    

                             if (B1[ix-1]==1)

                                  A2[ix-1]=A1[ix-1]+w1;

                             else

                                  A2[ix-1]=A1[ix-1];

                    

                             if (B1[ix-1]==0)

                                  if (num>round(m0+m1*A2[ix-1]))

                                      B2[ix-1]=1;

                                  else

                                      B2[ix-1]=B1[ix-1];

                             else

                                 B2[ix-1]=B1[ix-1];

                    

                             average=0;

                             dummy=0;

                             for (gi=(ix-R);gi<=(ix+R);gi++)    //for all neighbours of the cell

                                  {

                                  gih=gi;

                                  if (gi<0) gih=gi+sx;

                                  if(gi>sx-1) gih=gi-sx;         

                                  dummy=dummy+A2[gih-1];

                                  }

                             average=(1.0/((2.0*R)+1))*(dummy);

                       //   if((ix==10)) printf("%f %f %d\n",dummy, average,w2);

                             AA[sx+ix-1]=round(average);

                    

                             if (AA[sx+ix-1]>=w2)

                               //  (int)buf[(iy-1)*sx+ix-1]=0;

                               c=0;

                             else

                               //  (int)buf[(iy-1)*sx+ix-1]=B2[ix-1];

                               c=B2[ix-1];

                            c=1-c;

              }

              break;

              }

              case 19: //quantum wave

                   {

                   if((j<stps)||(stps<scarsteps))

                   {

                   if((ph+ix+iy)%2==0)

                       {

                       if(mask[C]!=0)

                            {

                            //if ((fabs(ix-(sx+1)/2)<2)&&((fabs(iy-(sy+1)/2)<2)))

                            //   printf("%d %d %d  ",ix, iy, ph);

                            qu=-2*buf[C];

                            if(mask[N]!=0) qu=qu+buf[N]; else {if(mask[S]!=0) qu=qu+buf[S]; else qu=qu+buf[C]/2;}

                            if(mask[S]!=0) qu=qu+buf[S]; else {if(mask[N]!=0) qu=qu+buf[N]; else qu=qu+buf[C]/2;}

                            if(mask[W]!=0) qu=qu+buf[W]; else {if(mask[E]!=0) qu=qu+buf[E]; else qu=qu+buf[C]/2;}

                            if(mask[E]!=0) qu=qu+buf[E]; else {if(mask[W]!=0) qu=qu+buf[W]; else qu=qu+buf[C]/2;}   

                            qu=qu/2;

                            }

                       else

                            qu=top-1;

                       }

                   else

                       qu=buf[C];

                   if((j>disp3)&&(j%(int)floor((sx-2)*2.0/fac2)==0)&&(mask[C]!=0)) sbuf[C]=sbuf[C]+fabs(qu)/stps*11;

                   }

                   else

                       {

                       qu=sbuf[C];

                       }

                   break;

                   }

              // case 20: is accessed separately as the prisoners' dilemma routine sipd

              case 21: //byl loop

                   {

                   if((buf[C]==0)&&(buf[N]==0)&&(buf[E]==0)&&(buf[S]==0)&&(buf[W]==0))

                            {

                            c=0;

                            break;

                            }

              //   c=buf[C];

                   s2=0;

                   c=buf[C];

                   for(s=0;s<strlen(byl)/6;s++)

                       {

                       if (buf[C]==*(byl+6*s)-48)

                            {

                            nn=*(byl+6*s+1)-48; ee=*(byl+6*s+2)-48;  ss=*(byl+6*s+3)-48; ww=*(byl+6*s+4)-48; cc=*(byl+6*s+5)-48;

                            if((buf[N]==nn)&&(buf[E]==ee)&&(buf[S]==ss)&&(buf[W]==ww)) { c=cc; s2=1; }

                            if((buf[E]==nn)&&(buf[S]==ee)&&(buf[W]==ss)&&(buf[N]==ww)) { c=cc; s2=1; }

                            if((buf[S]==nn)&&(buf[W]==ee)&&(buf[N]==ss)&&(buf[E]==ww)) { c=cc; s2=1; }

                            if((buf[W]==nn)&&(buf[N]==ee)&&(buf[E]==ss)&&(buf[S]==ww)) { c=cc; s2=1; }

                            }

                       if (s2==1) break;

                       //printf("%d %d %d\n",s,c,*(byl+6*s+3)-48);

                       }

                   //c=buf[C];

                  //printf("%d %d %d   \n",s,c,*(byl+6*s+5)-48);

              //   mbuf[C]=c;

                   break;

                   }

              case 22: //diffuse aggregate

                   {

                   if(j==1) c=buf[C];

                   else

                   {

                   if((buf[C]==0)&&(buf[N]==0)&&(buf[E]==0)&&(buf[S]==0)&&(buf[W]==0))

                       {

                       c=0;

                       //printf("%d ",rl);

                       if((rl!=0)&&(rar[0]==114-48))  if (rand()%8000==0) c=(int)(pow(2,rand()%4)); else c=0;

         //c=0;//if (rand()%8000==0) c=(int)(pow(2,rand()%4)); else c=0;

                       }

                   else

                   for(i=0;i<sizeof(rul)/sizeof(int)/6;i++)

                       {

                       c=buf[C];                  

                       if((isin(rul[6*i],buf[C])==1)&&(isin(rul[6*i+1],buf[N])==1)&&(isin(rul[6*i+2],buf[E])==1)&&(isin(rul[6*i+3],buf[S])==1)&&(isin(rul[6*i+4],buf[W])==1))

                            {

                            c=rul[6*i+5];

                            break;

                            }

                       }

                   }

                   break;

                   }

              case 23: //sexy loop

                   {

              //   c=buf[C];

                   if((buf[C]==0)&&(buf[N]==0)&&(buf[E]==0)&&(buf[S]==0)&&(buf[W]==0))

                       {

                       c=0;

                       break;

                       }

              //   if((buf[C]!=8)&&(buf[N]!=8)&&(buf[S]!=8)&&(buf[E]!=8)&&(buf[W]!=8))

                       {

                       s2=0;

                       c=buf[C];

                       for(s=0;s<sizeof(sxrul)/sizeof(int)/6;s++)

                            {

                            if (buf[C]==sxrul[6*s])

                                 {

                                 nn=sxrul[6*s+1]; ee=sxrul[6*s+2];  ss=sxrul[6*s+3]; ww=sxrul[6*s+4]; cc=sxrul[6*s+5];

                                 if((buf[N]==nn)&&(buf[E]==ee)&&(buf[S]==ss)&&(buf[W]==ww)) { c=cc; s2=1; }

                                 if((buf[E]==nn)&&(buf[S]==ee)&&(buf[W]==ss)&&(buf[N]==ww)) { c=cc; s2=1; }

                                 if((buf[S]==nn)&&(buf[W]==ee)&&(buf[N]==ss)&&(buf[E]==ww)) { c=cc; s2=1; }

                                 if((buf[W]==nn)&&(buf[N]==ee)&&(buf[E]==ss)&&(buf[S]==ww)) { c=cc; s2=1; }

                                 }

                            if (s2==1) break;

                            }

                   //   break;

                       }

                   //else

                 if(s2==0)

                                          {

                       for(i=0;i<sizeof(eightrul)/sizeof(int)/6;i++)

                            {

                            //c=buf[C];                     

                            if(sisin(eightrul[6*i],buf[C])==1)

                                 {

                                 if((sisin(eightrul[6*i+1],buf[N])==1)&&(sisin(eightrul[6*i+2],buf[E])==1)&&(sisin(eightrul[6*i+3],buf[S])==1)&&(sisin(eightrul[6*i+4],buf[W])==1)) { c=eightrul[6*i+5]; if(c==6) c=buf[C]; break; }

                                 if((sisin(eightrul[6*i+1],buf[E])==1)&&(sisin(eightrul[6*i+2],buf[S])==1)&&(sisin(eightrul[6*i+3],buf[W])==1)&&(sisin(eightrul[6*i+4],buf[N])==1)) { c=eightrul[6*i+5]; if(c==6) c=buf[C]; break; }

                                 if((sisin(eightrul[6*i+1],buf[S])==1)&&(sisin(eightrul[6*i+2],buf[W])==1)&&(sisin(eightrul[6*i+3],buf[N])==1)&&(sisin(eightrul[6*i+4],buf[E])==1)) { c=eightrul[6*i+5]; if(c==6) c=buf[C]; break; }

                                 if((sisin(eightrul[6*i+1],buf[W])==1)&&(sisin(eightrul[6*i+2],buf[N])==1)&&(sisin(eightrul[6*i+3],buf[E])==1)&&(sisin(eightrul[6*i+4],buf[S])==1)) { c=eightrul[6*i+5]; if(c==6) c=buf[C]; break; }                       

                                 }

                            }                     

                       //break;

                       }

                   break;

                   }

              case 24: //sand pile

                   {

                   s2=top;

                   c=buf[C];

                   if (buf[C]>s2) c=buf[C]-top/2;

                   s=(buf[N]>s2)+(buf[E]>s2)+(buf[S]>s2)+(buf[W]>s2);

                   c=c+s*top/8;

                   break;

                   }

              case 25: //maze solver

                   {

                   for(i=0;i<sizeof(maz)/sizeof(int)/6;i++)

                       {

                       c=buf[C];                  

                       if((misin(maz[6*i],buf[C])==1)&&(misin(maz[6*i+1],buf[N])==1)&&(misin(maz[6*i+2],buf[E])==1)&&(misin(maz[6*i+3],buf[S])==1)&&(misin(maz[6*i+4],buf[W])==1))

                            {

                            c=maz[6*i+5];

                            break;

                            }

                       }

                   break;

                   }

              // case 26: is accessed separately as segregation in Schelling

              default:  //simple summation

              {

              //c=(int)buf[C]%top+(int)buf[N]%top+(int)buf[S]%top+(int)buf[E]%top+(int)buf[W]%top;             

              //c=(int)buf[N]%top+(int)buf[S]%top+(int)buf[E]%top+(int)buf[W]%top;          

              //c=(int)buf[C]+(int)buf[N]+(int)buf[S]+(int)buf[E]+(int)buf[W];

              c=(int)buf[N]+(int)buf[S]+(int)buf[E]+(int)buf[W];

              c=c%top;

              }

 

              }