var MAXM, MAXN: integer;
choose_Rect : array[1..MAXPATM,1..MAXPATN] of rect;
Filled_Choice : array[1..MAXPATM,1..MAXPATN] of boolean;
Rules : array[1..4,0..8] of rect;
goRect, OKRect:rect;
Rules_Choice : array[1..4,0..8] of boolean;
mouseLoc: Point; {so we can use mouse & cursor positions to control}
type field = array [1..MAXMi,1..MAXMi] of integer;
var old_value, new_value: field; {more memory allocation stuff}
var choice:array [0..8] of char;
var p, m, n, i, j, count, sum_neighbors, sum_far_neighbors:integer;
var xd, yd, side:integer;
var ch: char; {you have to name all the variables you will ever use}
procedure draw_Init_Pattern; {beginning of first procedure}
begin
for m:=1 to MAXPATM do {sets left to right squares}
begin
for n:=1 to MAXPATN do {sets top to bottom squares}
begin
setrect(choose_Rect[m,n],150+m*Sq_Width,n*Sq_Width,150+m*Sq_Width+Sq_Width,n*Sq_Width+Sq_Width);
framerect(choose_Rect[m,n]);
end;
end;
setrect(OKRect,230,220,280,250);framerect(OKRect);
moveto(240, 240);drawstring(' OK ?');
end; {and this is the end of that first procedure}
procedure random_pattern; {another procedure, never actually used!!}
begin; {actually, maybe it is sometimes used}
for m:= 2 to MAXM-1 do
begin
for n:= 2 to MAXN-1 do
begin
old_value[m,n]:=0;
if random mod 10>5 then
old_value[m,n]:=1;
end;
end;
end; {The boundary of the end of that last procedure}
procedure draw_Rules_Pattern; {another procedure, that DOES get used}
begin
begin
for m:=1 to 4 do
begin
for n:=1 to 9 do
begin
setrect(Rules[m,n], m*Sq_Width,n*Sq_Width, m*Sq_Width+Sq_Width,n*Sq_Width+Sq_Width);
framerect(Rules[m,n]);
end;
end; {notice the somewhat different ways that the word "end" gets used}
end;
setrect(goRect,30,220,80,250);framerect(goRect);
moveto(40, 240);drawstring(' GO');
end; {this is the end of the "draw_Rules_Pattern" procedure}
procedure Label_Rule_Chooser; {start of yet another procedure}
if choice[0]='f' then begin choice[0]:='s';fillrect (Rules[2,1],black); fillrect (Rules[1,1],white);fillrect (Rules[3,1],white);
procedure initial_pattern; var mm,nn: integer;
eraserect(OKRect);
procedure Pen_draw_dots;
begin {main program} {AT LONG LAST!! THE ACTUAL PROGRAM!}
writeln('How big a field do you want? Type a number from 10 to 87.');
InitGraf(@thePort);OpenPort(@MyPort); {never mind about this stuff here}
textfont(monaco); textsize(9); textface([]);
side:=350 div MAXM;
draw_Init_Pattern; {the names of procedures that you defined above}
count:= 0; clearscreen;xd:=120; yd:=110;
end. {this means the end of the whole program}
begin
moveto(10,12); drawstring('Empt ');
moveto(40,12); drawstring('Same');
moveto(70,12); drawstring('Fill');
moveto(100,12); drawstring('Reverse');
moveto(10,30); drawstring('0');
moveto(10,50); drawstring('1');
moveto(10,70); drawstring('2');
moveto(10,90); drawstring('3');
moveto(10,110); drawstring('4');
moveto(10,130); drawstring('5');
moveto(10,150); drawstring('6');
moveto(10,170); drawstring('7');
moveto(10,190); drawstring('8');
end; {the end of a procedure that definitely DOES get used}
procedure Fill_Current_Rules; {yet another procedure}
begin {can you figure out what this one does?}
for i:=0 to 8 do
begin
if choice[i]='e' then
begin
fillrect(rules[1,i+1],black);
fillrect(rules[2,i+1],white);
fillrect(rules[3,i+1],white);
fillrect(rules[4,i+1],white);
end;
if choice[i]='s' then
begin
fillrect(rules[1,i+1],white);
fillrect(rules[2,i+1],black);
fillrect(rules[3,i+1],white);
fillrect(rules[4,i+1],white);
end;
if choice[i]='f' then
begin
fillrect(rules[1,i+1],white);
fillrect(rules[2,i+1],white);
fillrect(rules[3,i+1],black);
fillrect(rules[4,i+1],white);
end;
if choice[i]='r' then
begin
fillrect(rules[1,i+1],white);
fillrect(rules[2,i+1],white);
fillrect(rules[3,i+1],white);
fillrect(rules[4,i+1],black);
end;
end;
end; {The last of this procedure, that I want you to try and recognize}
procedure choose_rules;
begin
repeat
getmouse(mouseLoc);{asks the computer where the cursor currently is}
if button then {and if the mouse button is pushed, does the following}
begin {note how "begin" and "end" are like parentheses in multiplying}
getmouse(mouseLoc);
if (abs(mouseLoc.h-50)<50) and (abs(mouseloc.v-110)<90) then
begin
i:= 1+ (mouseloc.v-20) div 20;
if abs(mouseloc.h-30)<10 then begin
choice[i-1]:='e';fillrect (Rules[1,i],black);
fillrect (Rules[2,i],white);fillrect (Rules[3,i],white);
draw_Rules_Pattern;
end;
if abs(mouseloc.h-50)<10 then begin
choice[i-1]:='s';fillrect (Rules[2,i],black);
fillrect (Rules[1,i],white);fillrect (Rules[3,i],white);fillrect (Rules[4,i],white);
draw_Rules_Pattern;
end;
if abs(mouseloc.h-70)<10 then begin
choice[i-1]:='f';fillrect (Rules[3,i], black);
fillrect (Rules[1,i],white);fillrect (Rules[2,i],white);fillrect (Rules[4,i],white);
draw_Rules_Pattern;
end;
if abs(mouseloc.h-90)<10 then begin
choice[i-1]:='r';fillrect (Rules[4,i], black);
fillrect (Rules[1,i],white);fillrect (Rules[2,i],white);fillrect (Rules[3,i],white);
draw_Rules_Pattern;
end;
draw_Rules_Pattern;end;
end;
end;
if mouseloc.h>300 then random_pattern;
{maybe we use that procedure after all!!}
until ((abs(mouseloc.v-235))<15) and ((abs(mouseloc.h-55))<25) and button ;
end;
begin {resets all values to zero=empty every time we start over}
for m:= 1 to MAXM do
begin
for n:= 1 to MAXN do
begin
new_value[m,n]:= 0;
old_value[m,n]:= 0;
end;
end;
repeat
getmouse(mouseLoc);
if button then
begin
getmouse(mouseLoc);
if (abs(mouseLoc.h-150-MAXPATM*Sq_Width/2)
m:=(mouseloc.h-170) div 20 +1 + round(MAXM/2) ;
n:=(mouseloc.v-20 ) div 20 +1 + round(MAXN/2) ; {writeln('m = ',m,'n = ',n);}
{this previous comment was left over from debugging, when I first wrote it}
old_value[m,n]:=(old_value[m,n]+ 1) mod 2;
if old_value[m,n]=1 then fillrect(choose_Rect[m-round(MAXM/2),n-round(MAXN/2)],black);
if old_value[m,n]=0 then fillrect(choose_Rect[m-round(MAXM/2),n-round(MAXN/2)],white);
draw_Init_Pattern;
end; end;
until ((abs(mouseloc.v-235))<15) and ((abs(mouseloc.h-255))<25) and button;
setrect(OKRect,230,220,280,250);framerect(OKRect);
moveto(240, 240);drawstring(' DONE');
moveto(75,270);drawstring('Now choose your rules on the grid at the left');
end; {That procedure sure was long and confusing, wasn't it?}
begin
{side := 200 div MAXM;}
PenSize(SIDE-1,SIDE);
moveto(round(xd+SIDE*m), yd+SIDE*n-130);
Line(1,0);
end;
procedure sum_neighbor_values; {Figure out why I wrote it this way!}
begin; {I mean part just after "sum_neighbors"}
for m:= 2 to MAXM-1 do
begin
for n:= 2 to MAXN-1 do
begin
sum_neighbors:=old_value[m-1,n-1] + old_value[m,n-1] + old_value[m+1,n-1]+
old_value[m-1,n ] + old_value[m+1,n ]+
old_value[m-1,n+1] + old_value[m,n+1] + old_value[m+1,n+1] ;
for j:= 0 to 8 do
begin
if sum_neighbors= j then
begin
if Choice[j]= 'e' then new_value[m,n]:=0;
if Choice[j]= 'f' then new_value[m,n]:=1;
if Choice[j]= 's' then new_value[m,n]:= old_value[m,n];
if Choice[j]= 'r' then
begin
if old_value[m,n]=0 then new_value[m,n]:=1;
if old_value[m,n]=1 then new_value[m,n]:=0;
end;
end;
end;
end;
end;
end;
procedure sum_farther_neighbors; {we don't use this}
begin; {but can you figure it out?}
for m:= 3 to MAXM-2 do
begin
for n:= 3 to MAXN-2 do
begin
sum_far_neighbors:= old_value[m-1,n-2] + old_value[m,n-2] + old_value[m+1,n-2]+
old_value[m-2,n-1 ] + old_value[m+2,n-1 ]+
old_value[m-2,n ] + old_value[m+2,n ]+
old_value[m-2,n+1 ] + old_value[m+2,n+1 ]+
old_value[m-1,n+2] + old_value[m,n+2] + old_value[m+1,n+2] ;
for j:= 0 to 8 do
begin
if sum_neighbors= j then
begin
if Choice[j]= 'e' then new_value[m,n]:=0;
if Choice[j]= 'f' then new_value[m,n]:=1;
if Choice[j]= 's' then new_value[m,n]:= old_value[m,n];
if Choice[j]= 'r' then
begin
if old_value[m,n]=0 then new_value[m,n]:=1;
if old_value[m,n]=1 then new_value[m,n]:=0;
end;
end;
end;
end;
end;
end;
procedure old_new; {we have to do this each cycle, can you see why?}
begin;
for m:= 2 to MAXM-1 do
begin
for n:= 2 to MAXN-1 do
begin
old_value[m,n]:=new_value[m,n]
end;
end;
end; {The end of a rather short procedure, isn't it?}
procedure plot_pattern; {This makes the pattern appear on the screen!}
begin;
for m:= 2 to MAXM-1 do
begin
for n:= 2 to MAXN-1 do
begin
if old_value[m,n]= 0 then PenPat(white);
if old_value[m,n]= 1 then PenPat(black);
Pen_draw_dots {NEW_draw_dots} {draw_dots};
end;
end;
end;
procedure summarize_rules;
begin;
Writeln(' '); Writeln(' ');
for j:=0 to 8 do
begin
writeln (' ',j,' ',Choice[j]);
end;
end;
readln(MAXM); MAXN:=MAXM;
writeln('MAXN= ',MAXN);
FillRect(myport.portbits.Bounds,white);initCursor;
draw_Rules_Pattern; {become like magic incantations! In the program itself}
{you just say the name, and the computer does whatever you told it to}
Label_Rule_Chooser; initial_pattern; choose_rules;
summarize_rules; plot_pattern;
while not keypressed do
begin;
{writeln('Just about to sum neighbors');} {left over from debugging}
sum_neighbor_values;
old_new;
{writeln('Just about to plot patterns'); } {left over from debugging}
plot_pattern;
if button {and (mouseloc.h<10)} then
{if (mouseloc.h>350) then
random_pattern;} {take off the brackets & you can use this}
begin
InitGraf(@thePort);OpenPort(@MyPort);
FillRect(myport.portbits.Bounds,white);initCursor;
textfont(monaco);textsize(9);textface([]);
Label_Rule_Chooser; Fill_Current_Rules;
choose_rules;
end;
end;
readln; {gives you a last look at the pattern, if you want to copy it}
{It causes the last pattern to stay on the screen until you type "return"}
{please notice what happens when "end" has a period after it,
instead of a semicolon!} {a BIG difference}