home *** CD-ROM | disk | FTP | other *** search
- {PROGRAM AUTHOR: Mark Aldon Weiss PROGRAM DONATED TO PUBLIC DOMAIN}
-
- CONST
-
- MaxNumRows = 105; MaxNumCols = 92; MaxLengthRowString = 125;
-
- { MaxLengthRowString is greater than MaxNumCols to allow for spillover on }
- { input so that user may use repeat key to, say, type alot of noncreatures }
- { without worrying about typing exactly enough to fill the row. }
-
-
-
- TYPE
-
- Colony = Array[1..MaxNumRows,1..MaxNumCols] of Char;
-
-
-
- VAR
-
- again: Boolean;
-
- GenCount,NumOcc1st,CreatureCount,HowManyMore,i: Integer;
-
- creature,noncreature,how1st,HowRand,option,ch : Char;
-
- NumRows: 0..MaxNumRows; NumCols: 0..MaxNumCols; SpaceRequired: Integer;
-
- frac1st: Real; field: 1..2; GRID: Colony; PrintFormat: 1..3;
-
- RowString: String[MaxLengthRowString];
-
-
-
- PROCEDURE HELP;
-
- Begin {HELP}
- Writeln;
- Writeln(' N#--type an N and then any positive integer; the next');
- Writeln(' # generations are computed and displayed.');
- Writeln(' S#--type an S and then any positive integer; the next');
- Writeln(' # generations are computed and the last displayed.');
- Writeln(' Q#--type a Q and any integer in order to QUIT the current');
- Writeln(' grid. You will then be able to start a new one.')
- End; {HELP}
-
-
-
- PROCEDURE GetOptions;
-
- Begin {GetOptions}
- Writeln;
- Writeln(' You may have a maximum of ',MaxNumRows,' rows in your grid.');
- Writeln(' How many rows do you want for your grid (remember,');
- Write(' no creatures are allowed in the first or last row)? ');
- Readln(NumRows); Writeln;
- Writeln(' You may have a maximum of ',MaxNumCols,' columns in your grid.');
- Writeln(' How many columns do you want for your grid (remember,');
- Write(' no creatures are allowed in the first or last column)? ');
- Readln(NumCols);
- Writeln;
- Write(' Type the character you want to represent a creature -------> ');
- Readln(creature);
- Write(' Type the character you want to represent a NONcreature ----> ');
- Readln(noncreature);
- Writeln;
- Writeln(' While the terminal display will have no spaces between the grid');
- Writeln(' characters, you may have a blank space between the grid characters');
- Write(' on the printout. Do you want a blank separating characters? ');
- Readln(ch); Writeln;
- IF ch IN ['y','Y'] THEN Field := 2 ELSE Field := 1;
- SpaceRequired := NumCols * Field + 25;
- IF SpaceRequired <= 66 THEN PrintFormat := 1;
- IF (SpaceRequired > 66) AND (SpaceRequired <= 80) THEN PrintFormat := 2;
- IF (SpaceRequired > 80) AND (SpaceRequired <= 132) THEN PrintFormat := 3;
- IF SpaceRequired > 132 THEN
- Begin
- Field := 1;
- PrintFormat := 3;
- SpaceRequired := NumCols + 25;
- If SpaceRequired > 132 Then
- Begin
- Writeln(#7,' WARNING: Your grid will have too many columns to fit on');
- Writeln(' one line of the printout. You will therefore get');
- Writeln(' wrap-arounds, but your grid will still print.');
- Writeln
- End
- End;
- REPEAT
- Writeln(' Do you want a random first generation (type r) or do you want to');
- Write(' make your own first generation (type s)? ');
- Readln(how1st)
- UNTIL how1st IN ['r','R','s','S'];
- IF how1st IN ['r','R'] THEN
- Begin
- REPEAT
- Writeln(' Do you want BOTH the number and the placement of creatures to');
- Writeln(' be random (type b) or only the placement of creatures to be');
- Write(' random (type p)? '); Readln(HowRand)
- UNTIL HowRand IN ['b','B','p','P'];
- If HowRand In ['p','P'] Then
- Begin
- Writeln(' What fraction (between 0 & 1) of your first generation grid');
- Write(' do you want to be occupied (i.e., have creatures)? ');
- Readln(frac1st);
- NumOcc1st := ROUND( frac1st * (NumRows-2) * (NumCols-2) )
- End
- End
- End; {GetOptions}
-
-
-
- PROCEDURE PrintGrid;
-
- Var r,c,midpt: Integer;
-
- Begin {PrintGrid}
- IF GenCount = 1 THEN CreatureCount := NumOcc1st;
- midpt := NumRows DIV 2;
- FOR r := 1 to (midpt-1) DO
- Begin
- Write(lst,' '); For c := 1 to NumCols Do Write(lst,GRID[r,c]:Field);
- Writeln(lst)
- End;
- Write(lst,' '); For c := 1 to NumCols Do Write(lst,GRID[midpt,c]:Field);
- Writeln(lst,' GENERATION ',GenCount);
- Write(lst,' '); For c := 1 to NumCols Do Write(lst,GRID[midpt+1,c]:Field);
- Writeln(lst,' Frac. Occ. = ',CreatureCount/( (NumRows-2)*(NumCols-2) ):8:6);
- FOR r := (midpt+2) to NumRows DO
- Begin
- Write(lst,' '); For c := 1 to NumCols Do Write(lst,GRID[r,c]:Field);
- Writeln(lst)
- End
- End; {PrintGrid}
-
-
-
- PROCEDURE WriteGridToTerminal;
-
- Var r,c,midpt: Integer;
-
- Begin {WriteGridToTerminal}
- IF GenCount = 1 THEN CreatureCount := NumOcc1st;
- midpt := NumRows DIV 2;
- FOR r := 1 to (midpt-1) DO
- Begin
- Write(' '); For c := 1 to NumCols Do Write(GRID[r,c]);
- Writeln
- End;
- Write(' '); For c := 1 to NumCols Do Write(GRID[midpt,c]);
- Writeln(' GENERATION ',GenCount);
- Write(' '); For c := 1 to NumCols Do Write(GRID[midpt+1,c]);
- Writeln(' Frac. Occ. = ',CreatureCount/( (NumRows-2)*(NumCols-2) ):8:6);
- FOR r := (midpt+2) to NumRows DO
- Begin
- Write(' '); For c := 1 to NumCols Do Write(GRID[r,c]);
- Writeln
- End
- End; {WriteGridToTerminal}
-
-
-
- PROCEDURE FirstGen;
-
- Var c,r,midpt: Integer; ch,correction: char;
-
- Begin {FirstGen}
- FOR r := 1 to NumRows DO FOR c := 1 to NumCols DO GRID[r,c] := noncreature;
- IF how1st IN ['s','S'] THEN
- Begin
- NumOcc1st := 0;
- Writeln(' ':10,'C O L U M N');
- Write(' ':10);
- FOR c := 2 to (NumCols-1) DO Write( (10+c) MOD 10 );
- Writeln;
- FOR r := 2 to (NumRows-1) DO
- Begin
- Write(' row',r:3,': ');
- Readln(RowString);
- For c := 2 to (NumCols-1) Do
- Begin
- GRID[r,c] := RowString[c-1];
- IF GRID[r,c] = creature THEN NumOcc1st := NumOcc1st + 1
- End
- End;
- midpt := NumRows DIV 2;
- Writeln; Writeln;
- Writeln(' This is your first generation grid as it now stands:');
- Writeln;
- Writeln(' ':10,'C O L U M N');
- Write(' ':10);
- FOR c := 2 to (NumCols-1) DO Write( (10+c) MOD 10 );
- Writeln;
- FOR r := 2 to (midpt-1) DO
- Begin
- Writeln;
- Write(' row',r:3,': ');
- For c := 2 to (NumCols-1) Do Write(GRID[r,c])
- End;
- Writeln;
- Write(' row',midpt:3,': ');
- FOR c := 2 to (NumCols-1) Do Write(GRID[midpt,c]);
- Writeln(' GENERATION 1');
- Write(' row',(midpt+1):3,': ');
- FOR c := 2 to (NumCols-1) Do Write(GRID[midpt+1,c]);
- Write(' Fraction Nonborder Occupied = ');
- Write(NumOcc1st/( (NumRows-2)*(NumCols-2) ):8:6);
- FOR r := (midpt+2) to (NumRows-1) DO
- Begin
- Writeln;
- Write(' row',r:3,': ');
- For c := 2 to (NumCols-1) Do Write(GRID[r,c])
- End;
- Writeln; Writeln;
- Write(' Do you want to make any corrections? ');
- Readln(correction);
- IF correction IN ['y','Y'] THEN WHILE correction IN ['y','Y'] DO
- Begin
- Write(' Row of mistake -----> '); Readln(r);
- Write(' Column of mistake --> '); Readln(c);
- Write(' Desired creature or non-creature character');
- Write(' for this location ----> '); Readln(ch);
- GRID[r,c] := ch;
- Write(' Any more corrections? ');
- Readln(correction)
- End
- End;
- IF how1st IN ['r','R'] THEN
- Begin
- IF HowRand IN ['b','B'] THEN
- NumOcc1st := ROUND( RANDOM*(NumRows-2)*(NumCols-2) );
- CreatureCount := 0;
- WHILE CreatureCount < NumOcc1st DO {Place a creature randomly}
- Begin
- CreatureCount := CreatureCount + 1;
- REPEAT
- r := ROUND( ((NumRows-1)-2) * RANDOM + 2);
- c := ROUND( ((NumCols-1)-2) * RANDOM + 2)
- UNTIL GRID[r,c] <> creature;
- GRID[r,c] := creature;
- { The REPEAT loop is so that you don't put a creature where there }
- { already was one since this would not increase the number of ran- }
- { domly placed creatures. Once a random grid postion is found that }
- { is not already occupied, a creature is placed in that position. }
- { The assignments to r and c in the REPEAT loop may be confusing. }
- { Just keep in mind that for, say, an 11-row grid you want a random }
- { number from 2 to 10. The assignment accomplishes this. }
- End;
- WriteGridToTerminal
- End;
- PrintGrid
- End; {FirstGen}
-
-
-
- PROCEDURE NextGen;
-
- Var r,c,NumNeighbors,occupations: Integer; TempMat: Colony;
-
- MatNeighbors: Array[1..MaxNumRows,1..MaxNumCols] of Integer;
-
- Begin {NextGen}
- FOR r := 1 to NumRows DO FOR c := 1 to NumCols DO TempMat[r,c] := noncreature;
- FOR r := 2 to (NumRows-1) DO FOR c := 2 to (NumCols-1) DO
- Begin
- NumNeighbors := 0;
- IF GRID[r+1,c+1] = creature THEN NumNeighbors := NumNeighbors + 1;
- IF GRID[r+1,c ] = creature THEN NumNeighbors := NumNeighbors + 1;
- IF GRID[r+1,c-1] = creature THEN NumNeighbors := NumNeighbors + 1;
- IF GRID[r ,c+1] = creature THEN NumNeighbors := NumNeighbors + 1;
- IF GRID[r ,c-1] = creature THEN NumNeighbors := NumNeighbors + 1;
- IF GRID[r-1,c+1] = creature THEN NumNeighbors := NumNeighbors + 1;
- IF GRID[r-1,c ] = creature THEN NumNeighbors := NumNeighbors + 1;
- IF GRID[r-1,c-1] = creature THEN NumNeighbors := NumNeighbors + 1;
- MatNeighbors[r,c] := NumNeighbors
- End;
- FOR r := 2 to (NumRows-1) DO FOR c := 2 to (NumCols-1) DO
- IF (MatNeighbors[r,c]<>2) AND (MatNeighbors[r,c]<>3) THEN
- TempMat[r,c] := noncreature ELSE TempMat[r,c] := GRID[r,c];
- FOR r := 2 to (NumRows-1) DO FOR c := 2 to (NumCols-1) DO
- IF GRID[r,c] = noncreature THEN
- Begin
- occupations := 0;
- IF GRID[r+1,c+1] = creature THEN occupations := occupations + 1;
- IF GRID[r+1,c ] = creature THEN occupations := occupations + 1;
- IF GRID[r+1,c-1] = creature THEN occupations := occupations + 1;
- IF GRID[r ,c+1] = creature THEN occupations := occupations + 1;
- IF GRID[r ,c-1] = creature THEN occupations := occupations + 1;
- IF GRID[r-1,c+1] = creature THEN occupations := occupations + 1;
- IF GRID[r-1,c ] = creature THEN occupations := occupations + 1;
- IF GRID[r-1,c-1] = creature THEN occupations := occupations + 1;
- IF occupations = 3 THEN TempMat[r,c] := creature
- End;
- CreatureCount := 0;
- FOR r := 1 to NumRows DO FOR c := 1 to NumCols DO
- Begin
- GRID[r,c] := TempMat[r,c];
- IF GRID[r,c] = creature THEN CreatureCount := CreatureCount + 1
- End
- End; {NextGen}
-
-
-
- BEGIN { M A I N P R O G R A M }
- Writeln;
- Writeln;
- Writeln(' This program is the game of life. It has a great many extra ');
- Writeln(' features that will become apparent as the program is executed.');
- Writeln(' The rules of life are that a creature will survive in the next');
- Writeln(' generation only if there are exactly 2 or 3 neighboring creatures.');
- Writeln(' A creature is born in the next generation if there are exactly 3');
- Writeln(' creatures surrounding the non-creature grid space. NO CREATURES');
- Writeln(' ARE PERMITTED IN THE BORDER OF THE GRID.');
- Writeln;
- Writeln(' Turn the printer off. Turn the knob on the printer to set a page');
- Writeln(' so it''s at the top of a sheet. Turn the printer ON.');
- Writeln;
- REPEAT
- Write(#7,' Did you follow the instructions? '); Readln(ch)
- UNTIL ch IN ['y','Y'];
- Writeln(lst,#27'C'#0#11#27'N'#3);
- { codes to Epson printer for length of page = 11 in., skip over perf. 3 lines }
- again := TRUE;
- WHILE again DO
- Begin
- GenCount := 1;
- GetOptions;
- CASE PrintFormat OF
- 1: Writeln(lst,#27'W'#1#15#27'2'#27'U'#0);
- 2: Writeln(lst,#27'W'#0#18#27'U'#0#27'2');
- 3: IF Field = 1 THEN Writeln(lst,#15#27'U'#1#27'0'#27'W'#0)
- ELSE Writeln(lst,#15#27'U'#0#27'2'#27'W'#0)
- End; {of CASE}
- {These are various codes to the printer to turn on/off double width}
- {or compressed print or unidirectional printing or 8 lines per inch, etc.}
- Writeln;
- FirstGen;
- Writeln;
- REPEAT
- Writeln;
- Write(' Type N# S# Q# or H4(for help) ----> ');
- Readln(option,HowManyMore);
- IF option IN ['n','N'] THEN FOR i := 1 to HowManyMore DO
- Begin
- Writeln; Writeln(lst);
- GenCount := GenCount + 1;
- NextGen;
- WriteGridToTerminal; PrintGrid
- End;
- IF option IN ['s','S'] THEN
- Begin
- FOR i := 1 to HowManyMore DO
- Begin
- GenCount := GenCount + 1;
- NextGen
- End;
- Writeln;
- Writeln(lst);
- WriteGridToTerminal; PrintGrid
- End;
- IF option IN ['q','Q'] THEN
- Begin
- Writeln; Writeln
- End;
- IF option IN ['h','H'] THEN HELP
- UNTIL option IN ['q','Q'];
- Writeln;
- Write(' Do you want to start over with a new first generation? ');
- Readln(ch);
- IF ch IN ['y','Y'] THEN again := TRUE ELSE again := FAlSE
- End
- END. { M A I N P R O G R A M }
-
-