ack/lang/m2/test/Thalmann/LifeGame.mod
1988-04-20 10:43:48 +00:00

152 lines
2.9 KiB
Modula-2

MODULE LifeGame;
(* From: MODULA-2, An Introduction, by Daniel Thalmann, Springer-Verlag,
New York, 1985
Figure 10.18
*)
(* John Horton Conway's game "life" *)
FROM InOut IMPORT Write, WriteString, WriteLn, WriteCard,
ReadCard, Done;
CONST
MaxInd = 20;
MaxInd1 = MaxInd+1;
TYPE
IndRange = [1..MaxInd];
IndRange1 = [0..MaxInd1];
State = [0..1];
Cells = ARRAY IndRange1, IndRange1 OF State;
IndStat = [0..17];
VAR
Generation, NbOfGen: CARDINAL;
PreviousNext: BOOLEAN;
CellsState: ARRAY BOOLEAN OF Cells;
Status: ARRAY IndStat OF State;
PROCEDURE InitGame;
PROCEDURE InitAndReadPos;
VAR
Line, Column: CARDINAL;
BEGIN
FOR Line := 0 TO MaxInd1 DO
FOR Column := 0 TO MaxInd1 DO
CellsState[FALSE][Line, Column] := 0;
END;
END;
CellsState[TRUE] := CellsState[FALSE];
(* Read positions *)
ReadCard(Line);
WHILE Done DO
ReadCard(Column);
CellsState[FALSE][Line, Column] := 1;
ReadCard(Line);
END;
PreviousNext := FALSE;
Generation := 0;
END InitAndReadPos;
PROCEDURE InitStatus;
(* Ezra Gottheil method *)
VAR
Ind: IndStat;
BEGIN
FOR Ind := 0 TO 17 DO
Status[Ind] := 0;
END;
Status[3] := 1;
Status[11] := 1;
Status[12] := 1;
END InitStatus;
BEGIN (* InitGame *)
WriteString("Please, enter the number of generations: ");
ReadCard(NbOfGen);
WriteLn;
WriteString(" line and column positions: ");
InitAndReadPos;
InitStatus;
END InitGame;
PROCEDURE NextGeneration;
VAR
Line, Column: IndRange;
nbN: CARDINAL;
PROCEDURE Neighbourhood(L, C: IndRange1; VAR nbn: CARDINAL);
VAR
Line1, Column1: IndRange1;
BEGIN
nbn := 0;
FOR Line1 := L - 1 TO L + 1 DO
FOR Column1 := C - 1 TO C + 1 DO
INC(nbn, CellsState[PreviousNext][Line1, Column1]);
END;
END;
DEC(nbn, CellsState[PreviousNext][L, C]);
END Neighbourhood;
BEGIN (* NextGeneration *)
FOR Line := 1 TO MaxInd DO
FOR Column := 1 TO MaxInd DO
Neighbourhood(Line, Column, nbN);
CellsState[NOT PreviousNext][Line, Column] :=
Status[CellsState[PreviousNext][Line, Column]*9 + nbN];
END;
END;
PreviousNext := NOT PreviousNext;
END NextGeneration;
PROCEDURE Impression;
VAR
N: CARDINAL;
Line, Column: IndRange;
BEGIN
WriteLn ;
WriteString(" GENERATION : ");
WriteCard(Generation, 3);
WriteLn;
WriteLn;
WriteString(" ");
FOR N := 1 TO 2 * MaxInd + 3 DO
Write("-");
END;
WriteLn;
FOR Line := 1 TO MaxInd DO
WriteString(" |");
FOR Column := 1 TO MaxInd DO
IF CellsState[PreviousNext][Line, Column] = 1 THEN
WriteString(" @");
ELSE
WriteString(" .");
END;
END;
WriteString(" |");
WriteLn;
END;
WriteString(" ");
FOR N := 1 TO 2*MaxInd + 3 DO
Write("-");
END;
WriteLn;
WriteLn;
END Impression;
BEGIN
InitGame;
Impression;
LOOP
INC(Generation);
NextGeneration;
Impression;
IF Generation = NbOfGen THEN EXIT; END;
END;
END LifeGame.