001: #include<stdio.h>
002: #include<stdlib.h>
003: #include<ctype.h>
004: #include<string.h>
005:
006:
007: /* INSERITE/MODIFICATE QUI I PROTOTIPI DELLE VOSTRE FUNZIONI */
008: void salva(char **, int);
009: void stampa(char **, int);
010: void step(char **, int);
011: int vicinato(char **, int, int, int);
012:
013: /* FUNZIONI GIA' DEFINITE, NON MODIFICARE */
014: char menu(void);
015:
016: int main(int argc, char **argv){
017:
018: /* DEFINIRE QUI OPPORTUNA STRUTTURA DATI */
019: char **grid = NULL;
020: int grid_size = 0;
021:
022: int iter;
023: char scelta;
024: while(1)
025: {
026: scelta = menu();
027: switch (scelta)
028: {
029: case 'Q':
030: printf("Bye\n");
031: exit(EXIT_SUCCESS);
032: case 'L':
033: {
034: char filename[1000];
035: printf("Nome del file da aprire: ");
036: scanf(" %s", filename);
037: FILE *fp=fopen(filename, "r");
038: if(!fp)
039: {
040: perror("APERTURA FILE FALLITA");
041: break;
042: }
043: fscanf(fp, "%d", &grid_size); // leggo dimensione griglia
044:
045: // la alloco
046: if(grid){ // se avevo gia' letto altri file, disalloco precedenti griglie
047: // prima disalloco righe
048: for(int r = 0; r < grid_size; ++r)
049: free(grid[r]);
050: // e poi array dei puntatori alle righe
051: free(grid);
052: }
053: grid = malloc(grid_size * sizeof(char *));
054: for(int r = 0; r < grid_size; ++r)
055: grid[r] = malloc(grid_size * sizeof(char));
056:
057: // la inizializzo come vuota (ovvero tutti '.')
058: for(int r = 0; r < grid_size; ++r)
059: for(int c = 0; c < grid_size; ++c)
060: grid[r][c] = '.';
061:
062: // leggo gli altri parametri e modifico griglia
063: int r, c;
064: while(fscanf(fp, "%d%d", &r, &c) == 2)
065: grid[r][c] = '*';
066: fclose(fp);
067: }
068: break;
069: case 'P':
070: stampa(grid, grid_size);
071: break;
072: case 'R':
073: printf("Quante iterazioni? ");
074: scanf("%d", &iter);
075: for(int i=0; i<iter; ++i)
076: {
077: step(grid, grid_size);
078: stampa(grid, grid_size);
079: printf("-----------------------------------\n");
080: }
081: break;
082: case 'S':
083: salva(grid, grid_size);
084: break;
085:
086: }
087: }
088:
089:
090: return 0;
091: }
092:
093: int vicinato(char **g, int n, int r, int c)
094: {
095: // quante cellule ho negli 8 vicini?
096: int cellule_vicine = 0;
097: // guardo gli 8 vicini, in pratica mi devo spostare di +/-1 rispetto le coordinate della cella
098: for(int offset_r = -1; offset_r <= 1; ++offset_r)
099: for(int offset_c = -1; offset_c <= 1; ++offset_c)
100: {
101: // escludo la cella stessa
102: if(!offset_r && !offset_c)
103: continue;
104: // calcolo coordinate vicino in esame
105: int c_vicino = c + offset_c;
106: int r_vicino = r + offset_r;
107:
108: // se fuori dai bordi aggiusto
109: if(c_vicino < 0)
110: c_vicino = n - 1;
111: if(r_vicino < 0)
112: r_vicino = n - 1;
113: if(c_vicino == n)
114: c_vicino = 0;
115: if(r_vicino == n)
116: r_vicino = 0;
117:
118: //dopo eventuali correzioni posso usarle
119: if(g[r_vicino][c_vicino] == '*')
120: cellule_vicine++;
121: }
122: return cellule_vicine;
123: }
124:
125: void step(char **g, int n)
126: {
127: // devo allocare griglia temporanea su cui scrivero' il risultato dell'evoluzione
128: // qui posso usare VLA
129: char tmp[n][n];
130:
131: // cella per cella calcolo il nuovo valore
132: for(int r = 0; r < n; ++r)
133: for(int c = 0; c < n; ++c)
134: {
135: int cellule_vicine = vicinato(g, n, r, c);
136:
137: // applico regole testo
138: if(g[r][c] == '*')
139: {
140: if(cellule_vicine < 2)
141: tmp[r][c] ='.';
142: else if(cellule_vicine == 2 || cellule_vicine == 3)
143: tmp[r][c] ='*';
144: else if(cellule_vicine > 3)
145: tmp[r][c] ='.';
146: }
147: else
148: {
149: if(cellule_vicine == 3)
150: tmp[r][c] ='*';
151: else
152: tmp[r][c] ='.';
153: }
154: }
155: // aggiorno griglia copiandovi la temporanea
156: for(int r = 0; r < n; ++r)
157: for(int c = 0; c < n; ++c)
158: g[r][c] = tmp[r][c];
159:
160: }
161:
162: void stampa(char **g, int n)
163: {
164: for(int r = 0; r < n; ++r)
165: {
166: for(int c = 0; c < n; ++c)
167: printf("%c", g[r][c]);
168: printf("\n");
169: }
170:
171: }
172:
173: void salva(char **g, int n)
174: {
175: char filename[1000];
176: printf("Nome del file in cui salvare: ");
177: scanf(" %s", filename);
178: FILE *fp=fopen(filename, "w");
179: if(!fp)
180: {
181: perror("APERTURA FILE PER SALVARE FALLITA");
182: return;
183: }
184: // scrive nel file la dimensione
185: fprintf(fp, "%d\n", n);
186:
187: // e le coordinate di tutte le cellule vive
188: for(int r = 0; r < n; ++r)
189: for(int c = 0; c < n; ++c)
190: if(g[r][c] == '*')
191: fprintf(fp, "%d %d\n", r, c);
192:
193: fclose(fp);
194: }
195:
196: /***************************************************
197: LE SEGUENTI FUNZIONI NON VANNO MODIFICATE
198: ***************************************************/
199:
200: // stampa menu' e chiede scelta a utente
201: char menu(void)
202: {
203: char c;
204:
205: printf("MENU': L - load, S - save, R - evolve, P - print, Q - exit: ");
206: scanf(" %c", &c);
207: while(getchar() != '\n'); // clean input buffer
208:
209: c = toupper(c);
210: return c;
211: }
212:
213:
214: