Pristine Ack-5.5
[Ack-5.5.git] / lang / m2 / test / Thalmann / LifeGame.mod
1 MODULE LifeGame;
2
3 (* From: MODULA-2, An Introduction, by Daniel Thalmann, Springer-Verlag,
4          New York, 1985
5    Figure 10.18
6 *)
7
8 (* John Horton Conway's game "life" *)
9
10   FROM InOut IMPORT     Write, WriteString, WriteLn, WriteCard,
11                         ReadCard, Done;
12
13   CONST
14         MaxInd = 20;
15         MaxInd1 = MaxInd+1;
16
17   TYPE
18         IndRange = [1..MaxInd];
19         IndRange1 = [0..MaxInd1];
20         State = [0..1];
21         Cells = ARRAY IndRange1, IndRange1 OF State;
22         IndStat = [0..17];
23
24   VAR
25         Generation, NbOfGen: CARDINAL;
26         PreviousNext: BOOLEAN;
27         CellsState: ARRAY BOOLEAN OF Cells;
28         Status: ARRAY IndStat OF State;
29
30   PROCEDURE InitGame;
31
32     PROCEDURE InitAndReadPos;
33       VAR
34         Line, Column: CARDINAL;
35
36     BEGIN
37         FOR Line := 0 TO MaxInd1 DO
38           FOR Column := 0 TO MaxInd1 DO
39                 CellsState[FALSE][Line, Column] := 0;
40           END;
41         END;
42         CellsState[TRUE] := CellsState[FALSE];
43
44         (* Read positions *)
45         ReadCard(Line);
46         WHILE Done DO
47                 ReadCard(Column);
48                 CellsState[FALSE][Line, Column] := 1;
49                 ReadCard(Line);
50         END;
51
52         PreviousNext := FALSE;
53         Generation := 0;
54     END InitAndReadPos;
55
56     PROCEDURE InitStatus;
57     (* Ezra Gottheil method *)
58       VAR
59         Ind: IndStat;
60     BEGIN
61         FOR Ind := 0 TO 17 DO
62                 Status[Ind] := 0;
63         END;
64         Status[3] := 1;
65         Status[11] := 1;
66         Status[12] := 1;
67     END InitStatus;
68
69   BEGIN (* InitGame *)
70         WriteString("Please, enter the number of generations: ");
71         ReadCard(NbOfGen);
72         WriteLn;
73         WriteString("              line and column positions: ");
74         InitAndReadPos;
75         InitStatus;
76   END InitGame;
77
78   PROCEDURE NextGeneration;
79     VAR
80         Line, Column: IndRange;
81         nbN: CARDINAL;
82
83     PROCEDURE Neighbourhood(L, C: IndRange1; VAR nbn: CARDINAL);
84       VAR
85         Line1, Column1: IndRange1;
86     BEGIN
87         nbn := 0;
88         FOR Line1 := L - 1 TO L + 1 DO
89           FOR Column1 := C - 1 TO C + 1 DO
90                 INC(nbn, CellsState[PreviousNext][Line1, Column1]);
91           END;
92         END;
93         DEC(nbn, CellsState[PreviousNext][L, C]);
94     END Neighbourhood;
95
96   BEGIN (* NextGeneration *)
97         FOR Line := 1 TO MaxInd DO
98           FOR Column := 1 TO MaxInd DO
99                 Neighbourhood(Line, Column, nbN);
100                 CellsState[NOT PreviousNext][Line, Column] := 
101                   Status[CellsState[PreviousNext][Line, Column]*9 + nbN];
102           END;
103         END;
104         PreviousNext := NOT PreviousNext;
105   END NextGeneration;
106
107   PROCEDURE Impression;
108   VAR
109         N: CARDINAL;
110         Line, Column: IndRange;
111   BEGIN
112         WriteLn ;
113         WriteString("           GENERATION : ");
114         WriteCard(Generation, 3);
115         WriteLn;
116         WriteLn;
117         WriteString("          ");
118         FOR N := 1 TO 2 * MaxInd + 3 DO
119                 Write("-");
120         END;
121         WriteLn;
122         FOR Line := 1 TO MaxInd DO
123                 WriteString("          |");
124                 FOR Column := 1 TO MaxInd DO
125                   IF CellsState[PreviousNext][Line, Column] = 1 THEN
126                         WriteString(" @");
127                   ELSE
128                         WriteString(" .");
129                   END;
130                 END;
131                 WriteString(" |");
132                 WriteLn;
133         END;
134         WriteString("          ");
135         FOR N := 1 TO 2*MaxInd + 3 DO
136                 Write("-");
137         END;
138         WriteLn;
139         WriteLn;
140   END Impression;
141
142 BEGIN
143         InitGame;
144         Impression;
145         LOOP
146                 INC(Generation);
147                 NextGeneration;
148                 Impression;
149                 IF Generation = NbOfGen THEN EXIT; END;
150         END;
151 END LifeGame.