Classe Ambiente
Classe Ambiente
|
protected:
map<string,luogo*> luoghi;
luogo* utente;
luogo* fine;
static oggcont zaino;
string titolo;
string finegioco;
list<string> dati;
public:
ambiente(luogo& ll);
~ambiente();
bool carica();
void setutente(luogo* & l);
string prntitolo();
ambiente& operator+=(luogo& l);
void analizza(string s);
void start();
void end();
int salva();
|
La struttura dati della classe ambiente incentrata su una mappa di
oggetti Luogo.
Oltre alla mappa di luoghi, nella parte protetta di questa classe
allocato un puntatore a luogo (luogo* utente) che punta in ogni
fase del gioco al luogo in cui si trova il giocatore.
Il puntatore a luogo fine (luogo* fine) memorizza lindirizzo
del luogo in cui si concluder lavventura.
Un altro componente del campo protetto una stringa (string titolo)
che serve per poter personalizzare il titolo dellavventura.
La stringa finegioco (string finegioco),invece, inizializza il
messaggio che verr stampato quando lobiettivo del gioco sar
raggiunto, quindi alla conclusione del gioco.
Infine viene allocata una lista di stringhe (list<string> dati)
da inizializzare con i nomi degli oggetti da recuperare per raggiungere
lobiettivo.
E presente anche un oggetto di tipo contenitore (Oggcont, vedi
la classe oggetto), dichiarato static, che abbiamo utilizzato per
rappresentare lo zaino. Lo zaino un oggetto che non inserito in
alcun luogo e al quale lutente pu accedere attraverso le funzioni
lascia e prendi. E un oggetto di default infatti sar sempre
presente in qualsiasi storia creata con il nostro Gota.
METODI
Nel campo pubblico, oltre al costruttore che assegna
lindirizzo del luogo passato come argomento al puntatore utente e al
distruttore che cancella dalla mappa i luoghi puntati, abbiamo inserito
due semplici funzioni: void prntitolo () e void setutente
(luogo*& l).
La prima ritorna la stringa titolo del campo protetto; la seconda
assegna al puntatore utente il puntatore parametro formale e
individua cos la posizione del giocatore nella mappa dei luoghi.
La ridefinizione delloperatore += (ambiente& operator
+=(luogo& l))permette di inserire un luogo nella mappa della
classe ambiente attraverso operazioni del tipo ambiente+=luogo.
La funzione void start() stampa la descrizione di un luogo quando
vi si effettua il primo accesso attraverso una chiamata alla funzione
guarda del Luogo. In seguito la funzione cambiastato() definita
nella classe Luogo setta a true il booleano stato nella parte protetta
della classe Luogo e impedisce successive stampe della descrizione lunga
in caso di futuro accesso al luogo.
La funzione che gestisce la fine del gioco invece void end(),
che scorre la lista dati presente nel campo protetto e per ogni stringa
della lista, richiamando la funzione ricerca sui luoghi, controlla se
nel luogo presente il nome delloggetto chiave. Se nel luogo
sono presenti tutti gli oggetti della lista dati, allora viene stampato
il messaggio di fine gioco.
ANALIZZATORE SINTATTICO
Lanalizzatore sintattico il tramite tra i
comandi inseriti da tastiera dallutente e il funzionamento del gioco.
La funzione che svolge il lavoro di analizzatore sintattico void
analizza(string s), che da una stringa passata come argomento (il
comando inserito dallutente) riesce a risalire alle opportune
funzioni che consentono di giocare lavventura.
Il principio di funzionamento dellanalizzatore sintattico quello
di separare le singole parole che costituiscono la stringa immessa
dallutente e di sistemarle allinterno di un array statico di
stringhe. Attraverso il primo ciclo for, allinterno del quale un
iteratore scorre le lettere della stringa, viene ricavata la dimensione
dellarray da allocare sfruttando gli spazi presenti tra una parola e
laltra evitando opportunamente di conteggiare gli spazi ripetuti. In
un secondo ciclo for, invece, viene fatta scorrere nuovamente la stringa
e le singole parole, memorizzate carattere per carattere in una stringa
temporanea, vengono inserite nelle posizioni dellarray.
In questo modo, facendo dei controlli sulle stringhe presenti in ogni
posizione dellarray , possibile gestire le corrette combinazioni
verbo-oggetto, richiamare le opportune funzioni sulle classi Luogo e
Oggetto e segnalare opportunamente eventuali comandi mancanti o errori.
I comandi gestiti dallanalizzatore sono:
prendi oggetto;
usa oggetto con oggetto;
lascia oggetto;
vai direzione;
apri oggetto;
apri oggetto con oggetto;
oggetto;
accendi oggetto;
accendi oggetto con oggetto;
guarda oggetto, luogo;
esci;
salva;
aiuto.
SALVA
Il metodo salva presente nella classe ambiente di
fondamentale importanza per il corretto funzionamento del gioco, in
quanto attraverso questa funzione possibile interrompere una partita
in un punto qualsiasi e riprenderla in seguito caricando la versione
precedentemente salvata.
Il funzionamento del metodo salva si basa sulla scrittura dei dati su
file.
Attraverso lutilizzo della classe fstream presente nellomonima
libreria, in un file prescelto (world.ini) vengono scritte tutte quelle
informazioni inerenti lavventura necessarie per ricostruire la stessa
al momento del caricamento. Per far s che ci avvenga correttamente
la funzione salva della classe ambiente effettua delle chiamate ad
alcune funzioni (come la salva) presenti nelle altre classi (Luogo,
Oggetto, etc). Importante nella scrittura del file world.ini lutilizzo
di separatori di inizio e di fine che permettono una corretta lettura da
parte della carica.
CARICA
Il metodo carica funziona in simbiosi con il metodo
salva, in quanto la lettura, oltre che da un file di default (mondo.ini),
pu essere effettuata dal file generato dalla salva (world.ini).
Limplementazione di questa funzione prevede, dopo la scelta del file
da caricare e la gestione di eventuali errori, la lettura del file
avviene per singole righe mediante la funzione getline e, cosa molto
importante, avviene limitatamente ad ogni intervallo individuato dai
separatori di inizio e di fine. La prima stringa ad essere inizializzata
quella del titolo. In questo caso la getline legge tra i separatori
[Titolo] e [EndTitolo] e inizializza la stringa titolo nel campo
protetto di Ambiente con il contenuto di tutte le righe comprese
(considerando anche i ritorni a capo).
Dopo il titolo, vengono caricati gli oggetti contenuti nello zaino; con
un meccanismo identico al caricamento del titolo e a quello di tutti gli
altri elementi, la getline scorre e legge tutte le righe comprese tra
i separatori.
La lettura si arresta appena viene trovato il separatore di inizio di un
oggetto o di un oggetto-derivato; quando questo avviene, utilizzando loperatore
>> ridefinito nella classe Oggetto, si costruisce loggetto in
funzione di fstream (vedi operatore >>), se ne assegna lindirizzo
a un puntatore e tramite loperatore += ridefinito si inserisce loggetto
nello zaino.
Per la costruzione dei luoghi, come per la costruzione degli oggetti
abbiamo appositamente ridefinito loperatore >> (fstream&
operator >>) in modo da ottimizzare al meglio il codice. Una
volta ottenuto il puntatore al luogo costruito, viene inizializzata la
stringa di descrizione e attraverso la funzione insert (insert una
funzione della STD per le mappe), viene inserito il luogo nellambiente.
Caricati i luoghi, bisogna caricare gli oggetti in esso contenuti
Ovviamente con un primo ciclo while si scorre la mappa dei luoghi
affinch in ogni luogo siano inseriti i relativi oggetti. Per ogni
luogo, attraverso un secondo ciclo while si scorrono tutte le
linee tramite la solita getline e su ogni singola linea viene chiamata
la funzione research (vedi research). Questa ritorna true o false se
riuscita o meno a dividere la linea di ingresso. In caso affermativo si
assegna alla stringa temporanea nomeluogo la stringa right restituita
dalla research. A questo punto, dopo aver controllato che il luogo
esiste nellAmbiente, si costruiscono, come per lo zaino, gli oggetti
con tutte le loro propriet (attraverso loperatore >>) e si
inseriscono nel luogo (operatore +=).
Il caricamento dei puntatori a luogo necessario per collegare in
maniera corretta i luoghi appena creati. Questa volta se il risultato
della funzione research true e se il luogo esiste, vengono fatti una
serie di controlli sulla stringa left restituita. Se left NOMELUOGO,
la stringa nomeluogo viene inizializzata con il valore right; se left
una direzione (NORD, SUD, EST, OVEST, ALTO, BASSO), tramite le funzioni
pdirezione (pnord, psud, pest, povest, palto, pbasso)per ogni luogo
vengono inizializzati i puntatori in base alla stringa right; se left
unostruzione (OStrUZIONENORD, OStrUZIONESUD, OStrUZIONEEST,
OStrUZIONEOVEST, OStrUZIONEALTO, OStrUZIONEBASSO) tramite le funzioni
Odirezione (Onord, Osud, Oest, Oovest, Oalto, Obasso) per ogni luogo si
inizializzano i puntatori delle ostruzioni con il campo right della
research.
Quando si arriva al separatore di inizio [FineGioco] comincia linserimento
degli oggetti chiave nella lista dati di Ambiente. Sempre grazie
al lavoro della research, infatti, viene fatto un controllo sulla
stringa left; se si tratta di OBJ viene fatto linserimento mentre se
si tratta di FINELUOGO si inizializza il puntatore fine dellAmbiente
con lindirizzo del luogo in cui si conclude avventura.
La linea successiva che viene esaminata [MsgFineGioco], attraverso
cui viene inizializzata la stringa finegioco di Ambiente con un
messaggio che indichi la conclusione dellavventura.
Lultima linea letta dalla carica [Utente]; se la research torna
come stringa left INIZIO, allora il puntatore utente di Ambiente viene
inizializzato con lindirizzo del luogo corrispondente alla stringa
right. Se il luogo viene trovato il caricamento finito e si pu
iniziare a giocare altrimenti il programma visualizza un messaggio di
errore.
|