/* Still Life generator copyright 1996-97 by Paul Callahan (23-Jan-97 revision)*/ import java.util.*; import java.net.*; import java.awt.*; import java.applet.*; class CellBoard { int scale; int xorig, yorig; int cellrad; int ncolumns, nrows; int cells[][]; int neighbors[][]; boolean mark[][]; boolean fixed[][]; int i_fix[]; int j_fix[]; int fix_ind[][]; int nfix; int nviolations; int ncells; int randmove; int randset; int couldToggle; Color meshcolor=Color.blue; Color fixedcolor=Color.cyan; Color bg=Color.white; Color fg=Color.black; Color border=Color.red.darker(); Color inconsistent=Color.red; static int rules[][]={ {0,0,0,1,0,0,0,0,0}, {0,0,1,1,0,0,0,0,0} }; Color advicecol[]; CellBoard(int nrows0, int ncolumns0, int scale0) { ncolumns=ncolumns0; nrows=nrows0; scale=scale0; cells=new int[nrows][ncolumns]; neighbors=new int[nrows][ncolumns]; mark=new boolean[nrows][ncolumns]; fixed=new boolean[nrows][ncolumns]; fix_ind=new int[nrows][ncolumns]; i_fix=new int[(nrows-2)*(ncolumns-2)]; j_fix=new int[(nrows-2)*(ncolumns-2)]; nfix=0; nviolations=0; ncells=0; randmove=3; randset=10; for (int i=0; imaximprove) { maximprove=adv; choose_i=i; choose_j=j; count=1; } else if (adv==maximprove) { count++; if (rng.nextInt()%count==0) { choose_i=i; choose_j=j; } } } } if (choose_i== -1) { return false; } if (rng.nextInt()%randmove==0) displayToggle(rand_i, rand_j, g); else displayToggle(choose_i, choose_j, g); return true; } int violation(int i, int j) { i=i%nrows; if (i<0) i+=nrows; j=j%ncolumns; if (j<0) j+=ncolumns; return rules[cells[i][j]][neighbors[i][j]]^cells[i][j]; } boolean couldHelp(int i, int j) { return violation(i-1,j-1) + violation(i-1,j ) + violation(i-1,j+1) + violation(i ,j-1) + violation(i ,j ) + violation(i ,j+1) + violation(i+1,j-1) + violation(i+1,j ) + violation(i+1,j+1) > 0; } int dviolation(int i, int j, int dneighbor) { int val=cells[i][j]; int ncount=neighbors[i][j]; int retval=0; if (rules[val][ncount]==val) { if (rules[val][ncount+dneighbor]!=val) retval= 1; } else { if (rules[val][ncount+dneighbor]==val) retval= -1; } return retval; } int getAdvice(int i, int j) { int val=cells[i][j]; int ncount=neighbors[i][j]; int dcell=1-2*val; int dviol= dviolation(i-1,j-1,dcell)+ dviolation(i-1,j ,dcell)+ dviolation(i-1,j+1,dcell)+ dviolation(i ,j-1,dcell)+ dviolation(i ,j+1,dcell)+ dviolation(i+1,j-1,dcell)+ dviolation(i+1,j ,dcell)+ dviolation(i+1,j+1,dcell); if (rules[val][ncount]==val) { if (rules[val+dcell][ncount]!=val+dcell) dviol++; } else { if (rules[val+dcell][ncount]==val+dcell) dviol--; } return -dviol; } void paintViolations(Graphics g) { g.clipRect(xorig-scale,yorig-scale,ncolumns*scale+1,nrows*scale+1); for (int i=0; i=yorig && x>=xorig && i>0 && i0 && j=yorig && x>=xorig && i>0 && i0 && j=0 && i+di<=nrows-1 && j+dj>=0 && j+dj<=ncolumns-1) { drawCell(i+di,j+dj,g); drawViolation(i+di,j+dj,g); if (i+di>0 && i+di0 && j+dj=0) { i_fix[ind]=i_fix[--nfix]; j_fix[ind]=j_fix[nfix]; fix_ind[i_fix[ind]][j_fix[ind]]=ind; if (!fixed[i][j]) couldToggle--; fix_ind[i][j]= -1; } } else { if (ind== -1) { fix_ind[i][j]=nfix; i_fix[nfix]=i; j_fix[nfix++]=j; if (!fixed[i][j]) couldToggle++; } int dviolations=getAdvice(i,j); int advicerad=cellrad-10+Math.abs(dviolations); if (dviolations< -4) dviolations= -4; else if (dviolations >4) dviolations=4; g.setColor(advicecol[dviolations+4]); g.fillRect(xorig+j*scale-scale/2-advicerad, yorig+i*scale-scale/2-advicerad, 2*advicerad+1, 2*advicerad+1); } } void drawCell(int i, int j, Graphics g) { if (!fixed[i][j]) g.setColor(bg); else g.setColor(fixedcolor); g.fillRect(xorig+(j-1)*scale+1, yorig+(i-1)*scale+1, scale-1, scale-1); g.setColor(meshcolor); if (i>1 && i0 && j1 && j0 && i