1+
2+ #include "./methods.h"
3+
4+ #include <limits.h>
5+ #include <stdio.h>
6+
7+ #include "../patterns/main.h"
8+ #include "./macros.h"
9+ #include "./structs.h"
10+
11+ int countAliveNeighbors (TGame * pGame , int cellRow , int cellCol , int radius ) {
12+ int i ;
13+ int j ;
14+
15+ int startRow = cellRow - radius ;
16+ int startCol = cellCol - radius ;
17+
18+ int endRow = cellRow + radius + 1 ;
19+ int endCol = cellCol + radius + 1 ;
20+
21+ int aliveNeighbors = 0 ;
22+
23+ for (i = startRow ; i < endRow ; i ++ ) {
24+ if (i > pGame -> rows - 1 ) break ;
25+ if (i < 0 ) continue ;
26+
27+ for (j = startCol ; j < endCol ; j ++ ) {
28+ if (j > pGame -> cols - 1 ) break ;
29+ if (j < 0 ) continue ;
30+
31+ if (i == cellRow && j == cellCol ) continue ;
32+
33+ if (pGame -> dashboard [i ][j ] == ALIVE_CELL || pGame -> dashboard [i ][j ] == DEAD_CELL_NG )
34+ aliveNeighbors ++ ;
35+ }
36+ }
37+
38+ return aliveNeighbors ;
39+ }
40+
41+ void drawPattern (TGame * pGame , char * pattern ) {
42+ TPattern SPattern ;
43+
44+ char arr [PATTERN_ROWS ][PATTERN_COLS ];
45+
46+ SPattern .arr = arr ;
47+
48+ fillDashboard (pGame , DEAD_CELL );
49+
50+ if (strcmpi (pattern , "glider" ) == 0 ) {
51+ newGliderPattern (& SPattern );
52+ pGame -> cellsAlive = 5 ;
53+ } else if (strcmpi (pattern , "glider cannon" ) == 0 ) {
54+ newGliderCannonPattern (& SPattern );
55+ pGame -> cellsAlive = 36 ;
56+ } else if (strcmpi (pattern , "press" ) == 0 ) {
57+ newPressPattern (& SPattern );
58+ pGame -> cellsAlive = 48 ;
59+ } else if (strcmpi (pattern , "toad" ) == 0 ) {
60+ newToadPattern (& SPattern );
61+ pGame -> cellsAlive = 6 ;
62+ } else {
63+ return ;
64+ }
65+
66+ pGame -> cellsDead = (pGame -> cols * pGame -> rows ) - pGame -> cellsAlive ;
67+ pGame -> generation = 0 ;
68+
69+ drawPatternInDashboard (pGame , & SPattern );
70+ }
71+
72+ void drawPatternInDashboard (TGame * pGame , TPattern * pPattern ) {
73+ int i ;
74+ int j ;
75+
76+ int pI = 0 ;
77+ int pJ = 0 ;
78+
79+ int startRow = pGame -> center [0 ] - pPattern -> center [0 ];
80+ int startCol = pGame -> center [1 ] - pPattern -> center [1 ];
81+
82+ for (i = startRow ; pI < pPattern -> rows ; i ++ ) {
83+ if (i < 0 ) continue ;
84+ if (i > pGame -> rows - 1 ) break ;
85+
86+ for (j = startCol ; pJ < pPattern -> cols ; j ++ ) {
87+ if (j < 0 ) continue ;
88+ if (j > pGame -> cols - 1 ) break ;
89+
90+ pGame -> dashboard [i ][j ] = pPattern -> arr [pI ][pJ ];
91+ pJ ++ ;
92+ };
93+
94+ pJ = 0 ;
95+ pI ++ ;
96+ }
97+ }
98+
99+ void fillDashboard (TGame * pGame , char with ) {
100+ int i ;
101+ int j ;
102+
103+ for (i = 0 ; i < pGame -> rows ; i ++ ) {
104+ for (j = 0 ; j < pGame -> cols ; j ++ ) {
105+ pGame -> dashboard [i ][j ] = with ;
106+ }
107+ }
108+ }
109+
110+ void generateNextGeneration (TGame * pGame ) {
111+ int i ;
112+ int j ;
113+
114+ int aliveNeighbors ;
115+
116+ for (i = 0 ; i < pGame -> rows ; i ++ ) {
117+ for (j = 0 ; j < pGame -> cols ; j ++ ) {
118+ aliveNeighbors = countAliveNeighbors (pGame , i , j , NEIGHBORHOOD_RADIUS );
119+
120+ if (pGame -> dashboard [i ][j ] == DEAD_CELL ) {
121+ if (aliveNeighbors == 3 ) {
122+ pGame -> cellsDead -- ;
123+ pGame -> cellsAlive ++ ;
124+ pGame -> dashboard [i ][j ] = ALIVE_CELL_NG ;
125+ };
126+
127+ continue ;
128+ }
129+
130+ if (aliveNeighbors < 2 || aliveNeighbors > 3 ) {
131+ pGame -> cellsAlive -- ;
132+ pGame -> cellsDead ++ ;
133+ pGame -> dashboard [i ][j ] = DEAD_CELL_NG ;
134+ };
135+ }
136+ }
137+
138+ for (i = 0 ; i < pGame -> rows ; i ++ ) {
139+ for (j = 0 ; j < pGame -> cols ; j ++ ) {
140+ if (pGame -> dashboard [i ][j ] == DEAD_CELL_NG ) {
141+ pGame -> dashboard [i ][j ] = DEAD_CELL ;
142+ continue ;
143+ }
144+
145+ if (pGame -> dashboard [i ][j ] == ALIVE_CELL_NG ) pGame -> dashboard [i ][j ] = ALIVE_CELL ;
146+ }
147+ }
148+ }
149+
150+ void printDashboardByConsole (TGame * pGame ) {
151+ int i ;
152+ int j ;
153+
154+ for (i = 0 ; i < pGame -> rows ; i ++ ) {
155+ printf ("\n" );
156+
157+ for (j = 0 ; j < pGame -> cols ; j ++ ) {
158+ printf ("%c" , pGame -> dashboard [i ][j ]);
159+ }
160+ }
161+ }
162+
163+ void printGameByConsole (TGame * pGame ) {
164+ int i ;
165+ int j ;
166+
167+ // Print header
168+ for (i = 0 ; i < pGame -> cols + 2 ; i ++ ) printf ("-" );
169+
170+ printf ("\n| Cells alive: %*d |" , pGame -> cols - 17 + 2 , pGame -> cellsAlive );
171+ printf ("\n| Cells dead: %*d |" , pGame -> cols - 16 + 2 , pGame -> cellsDead );
172+ printf ("\n| Generation: %*d |" , pGame -> cols - 16 + 2 , pGame -> generation );
173+
174+ if (pGame -> maximumGeneration == INT_MAX ) {
175+ printf ("\n| Maximum generation: %*s |" , pGame -> cols - 25 + 3 , "infinity" );
176+ } else {
177+ printf ("\n| Maximum generation: %*d |" , pGame -> cols - 25 + 3 , pGame -> maximumGeneration );
178+ }
179+
180+ printf ("\n| Delay between generations: %*d ms |\n" , pGame -> cols - 35 + 3 ,
181+ pGame -> delayBetweenGenerations );
182+
183+ // Print dashboard
184+ for (i = 0 ; i < pGame -> cols + 2 ; i ++ ) printf ("-" );
185+
186+ for (i = 0 ; i < pGame -> rows ; i ++ ) {
187+ printf ("\n|" );
188+
189+ for (j = 0 ; j < pGame -> cols ; j ++ ) {
190+ printf ("%c" , pGame -> dashboard [i ][j ]);
191+ }
192+
193+ printf ("|" );
194+ }
195+
196+ printf ("\n" );
197+ for (i = 0 ; i < pGame -> cols + 2 ; i ++ ) printf ("-" );
198+ }
199+
200+ void setDashboardCenter (TGame * pGame ) {
201+ int row = pGame -> rows / 2 ;
202+ int col = pGame -> cols / 2 ;
203+
204+ pGame -> center [0 ] = row ;
205+ pGame -> center [1 ] = col ;
206+ }
207+
208+ void startGameByConsole (TGame * pGame , int maxGeneration , int delayBetweenGenerations ) {
209+ int generation = 0 ;
210+ int isToInfinity = maxGeneration == INT_MAX ;
211+
212+ pGame -> generation = 0 ;
213+ pGame -> maximumGeneration = maxGeneration ;
214+ pGame -> delayBetweenGenerations = delayBetweenGenerations ;
215+
216+ system ("cls" );
217+ printGameByConsole (pGame );
218+ if (generation == maxGeneration ) return ;
219+ sleep (delayBetweenGenerations );
220+
221+ while (isToInfinity || generation < maxGeneration ) {
222+ generateNextGeneration (pGame );
223+
224+ if (generation != INT_MAX ) {
225+ generation ++ ;
226+ pGame -> generation = generation ;
227+ };
228+
229+ system ("cls" );
230+ printGameByConsole (pGame );
231+ if (generation != maxGeneration ) sleep (delayBetweenGenerations );
232+ }
233+ }
0 commit comments