001: #include<stdio.h>
002: #include<stdlib.h>
003: #include<ctype.h>
004: #include<string.h>
005:
006:
007: /* INSERITE QUI LA DEFINIZIONE DELLE EVENTUALI struct NECESSARIE */
008:
009: struct turtle
010: {
011: int riga, colonna;
012: int direzione;
013: int penna;
014: };
015:
016:
017: /* INSERITE/MODIFICATE QUI I PROTOTIPI DELLE VOSTRE FUNZIONI */
018: void avanza(struct turtle *, char **, int, int);
019: void stampa(struct turtle *, char **, int, int);
020: void stampa_tartaruga(const struct turtle *);
021: void ruota(struct turtle *);
022: void toggle(struct turtle *, char **, int, int);
023: char comando(FILE *);
024:
025: /* FUNZIONI GIA' DEFINITE, NON MODIFICARE */
026: char menu(void);
027:
028: int main(int argc, char **argv){
029:
030: /* DEFINIRE QUI OPPORTUNA STRUTTURA DATI */
031:
032: /* griglia ovvero array bidimensionale di char e relative dimensioni */
033: char **griglia = NULL;
034: int righe = 0, colonne = 0;
035:
036: /* tartaruga */
037: struct turtle tartaruga;
038:
039: FILE *fp=NULL;
040: int iter;
041: char scelta;
042: while(1)
043: {
044: scelta = menu();
045: switch (scelta)
046: {
047: case 'Q':
048: if(fp) fclose(fp);
049: printf("Bye\n");
050: exit(EXIT_SUCCESS);
051: case 'L':
052: {
053: char filename[1000];
054: printf("Nome del file da aprire: ");
055: scanf(" %s", filename);
056: if(fp) // se avevo gia' letto altri file devo chiudere...
057: fclose(fp);
058: fp=fopen(filename, "r");
059: if(!fp)
060: {
061: perror("APERTURA FILE FALLITA");
062: break;
063: }
064:
065: // la alloco
066: if(griglia) // se avevo gia' letto altri file, disalloco precedenti griglie
067: {
068: // disalloco righe
069: for(int r = 0; r < righe; ++r)
070: free(griglia[r]);
071:
072: // disalloco puntatori righe
073: free(griglia);
074: }
075:
076:
077: // ok, posso iniziare a leggere i dati
078: fscanf(fp, "%d %d", &righe, &colonne); // leggo dimensioni griglia
079:
080: // alloco puntatori righe
081: griglia = malloc(righe * sizeof(char *));
082: // alloco righe
083: for(int r = 0; r < righe; ++r)
084: griglia[r] = malloc(colonne * sizeof(char));
085:
086: // la inizializzo come vuota (ovvero tutti '.')
087: for(int r = 0; r < righe; ++r)
088: for(int c = 0; c < colonne; ++c)
089: griglia[r][c] = '.';
090:
091: // leggo parametri tartaruga
092: fscanf(fp, "%d %d %d %d", &tartaruga.riga, &tartaruga.colonna, &tartaruga.direzione, &tartaruga.penna);
093: // nel caso penna giu' inizio a segnare
094: if(tartaruga.penna)
095: griglia[tartaruga.riga][tartaruga.colonna] = 'X';
096:
097: // elimino "a capo" dopo parametri tartaruga
098: getc(fp);
099:
100: }
101: break;
102: case 'R':
103: int iter;
104: printf("Quante iterazioni? ");
105: scanf("%d", &iter);
106: for(int i=0; i<iter; ++i)
107: {
108: char command = comando(fp);
109: if(command == '\0')
110: {
111: printf("Non ci sono piu' comandi\n");
112: break;
113: }
114: printf("Ho letto %c\n", command);
115: if(command == 'A')
116: avanza(&tartaruga, griglia, righe, colonne);
117: else if(command == 'D')
118: ruota(&tartaruga);
119: else if(command == 'T')
120: toggle(&tartaruga, griglia, righe, colonne);
121: stampa(&tartaruga, griglia, righe, colonne);
122: }
123: break;
124: case 'T':
125: stampa_tartaruga(&tartaruga);
126: break;
127: case 'P':
128: stampa(&tartaruga, griglia, righe, colonne);
129: break;
130:
131: }
132: }
133:
134:
135: return 0;
136: }
137:
138: char comando(FILE *fp)
139: {
140: if(!fp) return '\0'; // va controllato anche se il file fosse stato precedentemente aperto
141: int c = fgetc(fp);
142: if(c != EOF && (c == 'T' || c == 'D' || c == 'A')) return c; // restituisco valore se e solo se non sono arrivato a fine file e comando letto e' uno di quelli previsti
143: else return '\0';
144: }
145:
146: void stampa_tartaruga(const struct turtle *t)
147: {
148: printf("La tartaruga si trova nella posizione (%d,%d), orientata di %d gradi e la penna e' %s\n",
149: t->riga, t->colonna, t->direzione, (t->penna?"giu'":"su"));
150: }
151:
152: void toggle(struct turtle *t, char **g, int righe, int colonne)
153: {
154: t->penna = (t->penna?0:1);
155: if(t->penna)
156: g[t->riga][t->colonna] = 'X';
157: }
158:
159: void ruota(struct turtle *t)
160: {
161: t->direzione = (t->direzione + 270)%360;
162: }
163:
164: void avanza(struct turtle *t, char **g, int righe, int colonne)
165: {
166: // variabili temporanee per calcolo nuova posizione
167: int riga_tartaruga = t->riga;
168: int colonna_tartaruga = t->colonna;
169:
170: switch(t->direzione) // la scelta di memorizzare l'angolo e' apparentemente la piu' semplice ma non si presta benissimo in fase di utilizzo, sarebbe stato piu' pratico memorizzare il vettore direzione
171: {
172: case 0:
173: ++colonna_tartaruga;
174: break;
175: case 90:
176: --riga_tartaruga;
177: break;
178: case 180:
179: --colonna_tartaruga;
180: break;
181: case 270:
182: ++riga_tartaruga;
183: break;
184: default:
185: printf("Errore in avanza(): direzione %d non prevista\n", t->direzione);
186: exit(EXIT_FAILURE);
187: }
188:
189: // controllo se sono rimasto entro la griglia
190: if(colonna_tartaruga < 0 || colonna_tartaruga >= colonne || riga_tartaruga < 0 || riga_tartaruga >= righe)
191: return; // se sono al di fuori dei confini della griglia esco senza aggiornare niente
192:
193: // aggiorno posizione tartaruga e, nel caso, scrivo sulla griglia
194: t->riga = riga_tartaruga;
195: t->colonna = colonna_tartaruga;
196: if(t->penna)
197: g[t->riga][t->colonna] = 'X';
198: }
199:
200: void stampa(struct turtle *t, char **g, int righe, int colonne)
201: {
202: for(int r = 0; r < righe; ++r)
203: {
204: for(int c = 0; c < colonne; ++c)
205: if(c != t->colonna || r != t->riga)
206: printf("%c", g[r][c]);
207: else
208: printf(t->penna?"o":"O");
209: printf("\n");
210: }
211: }
212:
213: /***************************************************
214: LE SEGUENTI FUNZIONI NON VANNO MODIFICATE
215: ***************************************************/
216:
217: // stampa menu' e chiede scelta a utente
218: char menu(void)
219: {
220: char c;
221:
222: printf("MENU': L - load, R - run, P - print grid, T - print turtle status, Q - exit: ");
223: scanf(" %c", &c);
224: while(getchar() != '\n'); // clean input buffer
225:
226: c = toupper(c);
227: return c;
228: }
229:
230:
231: