Tor vergata cpp project relation

From campisano.org
Jump to navigation Jump to search

Consegna progetto per esame fondamenti di informatica 1					(validità 2002/2003)


Il compito assegnato prevede lo svolgimento di un progetto da scegliersi tramite un piccolo programma iniziale.
Questo programma deve convertire i caratteri del proprio nome e cognome in codice ascii, sommare questi caratteri e restituire il modulo 9 di questa somma: il risultato ottenuto corrisponde al numero del progetto (da 0 a 8) che il candidato deve svolgere.
In particolare, le cifre del nome e cognome devono essere date al programma con iniziali maiuscole, ed è calcolato nella somma il carattere di spaziatura (equivalente a 32 nella codifica ascii).

Questo compito preliminare non specificava con quante chiamate di input bisognasse acquisire il nome e cognome dall'utente, dunque per mio gusto personale ho preferito usare 2 chiamate cin (una per il nome e l'altra per il cognome) piuttosto che una cin.getline.
Come è èvidente, il carattere di spaziatura (che nell'esempio si trova nell'input dell'utente tra nome e cognome) è stato ugualmente considerato, aggiungendo 32 alla somma dei caratteri codificati.

Riporto di seguito la mia soluzione:



//	file ascii.c

     1	#include <iostream>

     2	
     3	using std::cout;
     4	using std::cin;
     5	
     6	int main ()
     7	{
     8		
     9		//	inizializzo gli array	
    10		char cin_frst [32]={0};
    11		char cin_scnd [32]={0};
    12		int word_len = sizeof(cin_frst);
    13	
    14	
    15		
    16		//	input
    17		cout << "\nInserisci nome:\n";
    18		cin >> cin_frst;
    19		cout << "\nInserisci cognome:\n";
    20		cin >> cin_scnd;
    21	
    22	
    23		
    24		//	output
    25		cout << "\nHai inserito ";
    26	
    27		int frst_len=0;
    28		while (cin_frst[frst_len]){
    29			cout << cin_frst[frst_len];
    30			frst_len++;	//	lunghezza di cin_frst
    31		}
    32		cout << " ";
    33	
    34		int scnd_len=0;
    35		while (cin_scnd[scnd_len]){
    36			cout << cin_scnd[scnd_len];
    37			scnd_len++;	//	lunghezza di cin_frst
    38		}
    39		
    40		int len = frst_len+scnd_len;
    41	
    42		
    43		
    44		cout << " (" << len << " caratteri)\n";
    45	
    46		//	converto in ascii
    47		cout << "\nCodifica Ascii\n";
    48		cout << "n°\tascii\tchar\n";
    49		int ascii[len];
    50	//
    51		int j=0;
    52		while (cin_frst[j]){
    53			ascii[j] = (int)cin_frst[j];
    54			cout << j+1 << "\t" << ascii[j] << "\t(" << cin_frst[j] << ")\n";
    55			j++;
    56		}
    57		
    58		cout << "\n";
    59		
    60		int k=0;
    61		while (cin_scnd[k]){
    62			ascii[j+k] = (int)cin_scnd[k];
    63			cout << j+k+1 << "\t" << ascii[j+k] << "\t(" << cin_scnd[k] << ")\n";
    64			k++;
    65		}
    66		
    67		
    68	
    69		//	calcolo modulo
    70		int mod = 32;/*	questo perchè va sommato il carattere spazio (32),
    71				come da esempio	*/
    72		
    73		for (int i=0; i<len; i++)
    74			mod += ascii[i];
    75			
    76		mod = mod % 9;
    77	
    78		
    79		cout << "\a\n\tTi tocca il progetto " << mod << "\n\n";
    80	}
    81	

Il programma è molto semplice:

dopo aver incluso la libreria per l'I/O iostream
dichiaro due array di 32 caratteri (inizializzati a 0) dove inserisco l'input dall'utente.

Successivamente stampo a schermo i caratteri inseriti dall'utente, usando lo stesso ciclo anche per calcolare la lunghezza degli array nome e cognome.

Con gli altri due cicli while codifico in ascii gli array (inserendo il risultato in un unico array di interi ascii[]) e stampo a schermo il risultato.

Con l'ultimo ciclo for, sommo gli elementi dell'array ascii,
dunque ne calcolo il modulo e stampo a schermo il numero equivalente al progetto che l'utente deve svolgere.

Seguendo l'output del programma, ho svolto il progetto n° 7.



Il progetto n° 7 consiste nel simulare il gioco di carte ``Go Fish!''.
Lo scopo del gioco è descritto come segue:



<<
	PROGETTO 7

Progettare e codificare delle classi C++ per simulare il gioco di carte ``Go fish!''. Le mosse del giocatore utente sono inserite da tastiera ogni volta, mentre le mosse del giocatore computer vengono decise indipendentemente, in modo casuale oppure secondo una determinata strategia.

Particolare credito verrà data a chi realizzerà strategie di gioco intelligenti e/o curerà l'interfaccia grafica.

Le regole del gioco sono le seguenti. Si gioca con un mazzo da 52 carte (A, 2-10, J, Q, K), e l'obiettivo è collezionare ``libri''. Un libro è costituito da quattro carte con lo stesso valore (ad esempio, quattro assi).

A ciascun giocatore vengono date sette carte, le restanti vengono lasciate in un mazzo coperto sul tavolo. In ciascun turno di gioco un giocatore chiede una carta di un certo valore all'avversario (``Dammi un sette!''), purché egli abbia già in mano una carta con lo stesso valore. Se l'avversario possiede tale carta la passa al giocatore, ed il giocatore, avendo indovinato, ha diritto a fare una nuova richiesta. Se invece l'avversario non possiede la carta richiesta risponde con ``Go fish!'', e il giocatore pesca una carta dal mazzo in mezzo al tavolo. Se la carta pescata ha lo stesso valore di quella richiesta, il giocatore ha diritto a fare un'altra richiesta all'avversario. Se invece la carta pescata ha un valore differente, tocca all'avversario fare richieste al giocatore, seguendo lo stesso schema.

Non appena un giocatore ottiene quattro carte con lo stesso valore, le cala sul tavolo. Il gioco termina quando un giocatore resta senza carte in mano, e vince colui che ha collezionato il maggior numero di ``libri'' (gruppi di quattro carte dello stesso valore). 


>>

Nel testo non è stata considerata l'ipotesi di una partita che finisce con i giocatori che hanno lo stesso numero di libri,
e ho dato per scontato che in quel caso sia 'patta'.



Anche se penso che la programmazione strutturata sia più efficiente, l'esercizio va svolto usando codice orientato a oggetti.
Questo è di concezione più semplice e facile da modificare, ma ho notato una duplicazione del tempo di compilazione (almeno in ambiente Linux), dovuta probabilmente al linking dei vari oggetti.
Usando Linux non saprei davvero come scegliere una libreria grafica adatta anche su altri ambienti, le Allegro e le SDL usano male le interfacce a finestre (bottoni, font, campi di testo, menu) mentre le GTK non sono compatibili con Windows, e non sapendo che sistema operativo verrà usato per visionare il lavoro ho puntato sulla portabilità e ho usato output semplice a caratteri.



Nel forum (o discussion room, come si preferisce) è stato indicato di trascrivere in questo documento la descrizione top-down usata per scrivere questo codice.
Io ho letto quanto il libro di testo (e il materiale informatico) dice sulla logica top-down, sullo pseudocodice e sui diagrammi, ma non sono riuscito a concludere un gran che usando quei metodi: non riesco mai ad arrivare ad un raffinamento tale che mi permetta di scrivere codice C++, e mi ritrovo davanti all'editor di testo pensando cosa mi serva per ottenere un determinato risultato.
Visto che riesco ad ottenere qualcosa di buono anche facendomi qualche schizzo a matita e buttando giù man mano le idee, rinuncio allo pseudocodice; una descrizione simile dello sviluppo del progetto si trova di seguito, quando viene descritta l'implementazione della classe Partita. Per avere maggiori dettagli basta consultare le spiegazioni sulle implementazioni delle varie classi, che seguono il codice delle classi.



Per il mio progetto ho utilizzato 5 classi: la classe carta, la classe mazzo che non è altro che un array di oggetti carta, la classe giocatore e la classe avversario contenenti oltre l'array delle proprie carte e i metodi per gestirle, e la classe partita, nella quale si svolgono tutte le azioni; nella funzione main() c'è soltanto la dichiarazione di un oggetto partita.

Descrivo ora in dettaglio le mie soluzioni spiegando i ragionamenti che hanno portato a determinate scelte, includendo per ogni classe, nell'ordine, il codice dei file header, il significato delle proprietà (ovvero i dati membro, quasi tutti private), l'implementazione delle funzioni della classe, e le operazioni che questi metodi eseguono.



//	file carta.h

     1	#ifndef CARTA_H
     2	#define CARTA_H
     3	
     4	#include <iostream>

     5	using std::cout;
     6	using std::cin;
     7	
     8	class Carta {
     9		public:
    10			Carta();
    11	
    12			int	getVal();
    13			char*	getSeed();
    14			
    15			void	setVal(int);
    16			void	setSeed(int);
    17	
    18			void	azzera();
    19	
    20		private:
    21			int	val;
    22			int	seed;
    23	
    24			static char* cu;
    25			static char* qu;
    26			static char* fi;
    27			static char* pi;
    28	
    29	};
    30	
    31	#endif
    
La classe carta ha ovviamente due dati, il valore ed il seme (esempio asso di cuori),
e dei metodi necessari a visualizzare le sue proprietà e alla loro corretta manipolazione.
Sia il valore che il seme sono due interi, mentre i successivi puntatori sono static perchè sono in comune a tutti gli oggetti di questa classe. 

//	file carta.c

     1	#include "carta.h"
     2	
     3	char*	Carta::cu = "cuori";
     4	char*	Carta::qu = "quadri";
     5	char*	Carta::fi = "fiori";
     6	char*	Carta::pi = "picche";
     7	
     8	
     9	Carta::Carta(){
    10	
    11		val=0;
    12		seed=0;
    13	}
    14	
    15	int	Carta::getVal(){
    16		return val;
    17	}
    18	
    19	char*	Carta::getSeed(){
    20		
    21		switch (seed){
    22			case 1:
    23				return cu;
    24			case 2:
    25				return qu;
    26			case 3:
    27				return fi;
    28			case 4:
    29				return pi;
    30			default:
    31				return "0";
    32		}
    33	}
    34	
    35	void	Carta::setVal(int _val){
    36		if (_val<14 && _val>0)
    37			val=_val;
    38		else
    39			cout << "\nvalore sbagliato per carta\n";
    40	}
    41	
    42	void	Carta::setSeed(int _seed){
    43		if (_seed<5 && _seed>0)
    44			seed=_seed;
    45		else
    46			cout << "\nseme sbagliato per carta\n";
    47	}
    48	
    49	void	Carta::azzera(){
    50		val=0;
    51		seed=0;
    52	}
    53

Per prima cosa vengono inizializzati i puntatori static della classe carta, che servono a visualizzare il seme di ogni carta.
Questa scelta è stata fatta per non dover mettere in ogni oggetto carta un array di char per descriverne il tipo di seme, perchè sarebbe stato uno spreco di risorse. Utilizzare una funzione esterna friend della classe che restituisse il seme leggendo array di caratteri, dichiarati come globali o nella funzione main, sarebbe stato possibile, ma si sarebbe resa la classe Carta dipendente da dati esterni, ed è poco logico se si vuole utilizzare la programmazione orientata agli oggetti.

Il costruttore inizializza il valore e il seme della carta a 0, valore che permette ai gestori di capire che questa carta è 'nulla'.
Mi spiego meglio con un esempio: quando inizializzo l'array di carte del giocatore, tutte le carte sono 'nulle', difatti prima che si distribuiscano le carte i giocatori non hanno carte in mano. Per sapere se in una posizione dell'array c'è una carta, controllo che il suo valore sia diverso da 0.

I metodi getVal(), getSeed(), setVal() e setSeed() restituiscono e impostano il valore ed il seme della carta: il principio è del minimo privilegio? bene, in questo modo, rendendo le proprietà della classe private, controllo che i dati da inserire abbiano un significato secondo il tipo di dato.

Il metodo azzera() è soltanto una scorciatoia: settare quei valori alla carta è una cosa frequente, e non è necessario in questo modo controllare il valore da impostare visto che è definito qui; in teoria è per efficienza, in pratica il programma è talmente leggero che si potrebbe considerare eccessiva questa implementazione, ma è anche più veloce per il programmatore settare come 'nulla' una carta in questo modo.





//	file mazzo.h

     1	#ifndef MAZZO_H
     2	#define MAZZO_H
     3	#include <cstdlib>

     4	#include <iostream>
     5	using std::cout;
     6	using std::cin;
     7	#include "carta.h"
     8	
     9	class Mazzo {
    10		public:
    11			Mazzo();
    12			
    13			void	init();
    14			void	mischia();
    15			void	show();
    16			Carta	popCarta();
    17			int	getPnt();
    18			
    19		private:
    20			Carta	carte[52];
    21			int	pnt;
    22	};
    23	
    24	#endif

La classe Mazzo è composta da un array di oggetti Carta e da un intero che funge da puntatore per la posizione della prossima carta da pescare. Il nome dell'array carte[] è esso stesso un puntatore al primo elemento dell'array, e avrei potuto usare quello facendolo puntare all'elemento successivo, ma a parte la pericolosità nel giocare con i puntatori in questo modo, altre chiamate a quell'array, come quella per il debug che visualizza il contenuto dell'intero mazzo, non sarebbero state possibili non potendo controllare la posizione del puntatore rispetto al primo elemento dell'array (perchè complicarsi la vita per non usare un int di 4 bytes?).

//	file mazzo.c

     1	#include "mazzo.h"

     2	
     3	Mazzo::Mazzo(){
     4	
     5	//	inizializzo
     6		init();
     7	
     8	//	show();		//?	debug
     9	
    10	//	e mischio
    11		mischia();
    12	
    13	//	show();		//?	debug
    14	}
    15	
    16	//	inizializzo il mazzo:
    17	//	carte in ordine da 1 a 13
    18	//	e da cuori a picche
    19	void	Mazzo::init(){
    20	
    21		Carta tempC;
    22		for (int j=0; j<52; j++){
    23			int k = j/13;
    24			tempC.setVal(1+(j%13));
    25			tempC.setSeed(1+(k%4));
    26			
    27			carte[j]=tempC;
    28		}
    29		pnt=51;
    30	}
    31	
    32	//	mischio il mazzo
    33	void	Mazzo::mischia(){
    34	
    35		
    36		for (int i=0; i<52; i++){
    37		
    38		//	posizione a caso
    39			int r = rand()%52;
    40	
    41		//	memorizza della carta alla posizione 'i'
    42			Carta x = carte[i];
    43	
    44		//	metti nella posizione 'i' quella carta
    45			carte[i]=carte[r];
    46	
    47		//	metti la carta che stava nella posizione 'i'
    48		//	nella posizione casuale 'r'

    49			carte[r]=x;
    50		}
    51	}
    52	
    53	//	cede una carta
    54	Carta	Mazzo::popCarta(){
    55		
    56		Carta tempCarta=carte[pnt];
    57		carte[pnt].azzera();
    58		
    59		//	punta la carta precedente,
    60		//	ma ritorna quella che era l'attuale
    61		//	se l'incremento lo metto dopo return, lo salta.
    62		pnt--;
    63		return tempCarta;
    64	}
    65	
    66	//	restituisce la posizione del puntatore
    67	int	Mazzo::getPnt(){
    68		return pnt;
    69	}
    70	
    71	//	visualizza il mazzo per il debug
    72	void	Mazzo::show(){
    73	
    74		cout << "\n";
    75		for (int j=0; j<52; j++){
    76			cout << j << "\t" << carte[j].getVal();
    77			cout << "\t" << carte[j].getSeed() << "\n";
    78		}
    79		cout << "\n";
    80	}
    81	

La classe Mazzo include le prime operazioni significative del programma.
Alla dichiarazione, il costruttore inizializza e mischia le carte.

Il metodo init() inizializza le carte in ordine, dall'asso di cuori al re di picche, come fosse un mazzo nuovo, da notare che il puntatore pnt è inizializzato a 51, ovvero alla fine dell'array e infatti verrà decrementato (è un caso, si sarebbe potuto fare benissimo il contrario, modificando di poco le implementazioni).

Il metodo() mischia scorre una sola volta l'array carte[], e ogni carta (dalla prima all'ultima) viene scambiata con una in una posizione casuale: questo sistema è semplice ed efficiente.

Il metodo popCarta() è suggerito dal funzionamento dello stack in assembly: restituisce la carta e decrementa il puntatore.
In realtà prima salva la carta da restituire togliendola dal mazzo, poi decrementa il puntatore e solo dopo restituisce la carta salvata; questo perchè decrementare il puntatore dopo l'istruzione return sarebbe inutile, in quanto la funzione terminerebbe all'istruzione return e il decremento del puntatore non verrebbe effettuato.

Infine il metodo show() visualizza l'intero array di carte, in ordine, e serve solo per il debug.





//	file giocatore.h

     1	#ifndef GIOCATORE_H
     2	#define GIOCATORE_H
     3	
     4	#include <iostream>

     5	#include <cstdlib>
     6	using std::cout;
     7	using std::cin;
     8	#include "carta.h"
     9	
    10	class Giocatore {
    11		public:
    12			Giocatore();
    13	
    14			int	ask();
    15	
    16			void	show();
    17			int	findVal(int);
    18			
    19			void	pushCarta(Carta);
    20			Carta	popNcarta(int);
    21	
    22			void	scarta();
    23			int	checkEnd();	
    24			char*	getName();
    25			int	getLibri();
    26	
    27		private:
    28			Carta	carte[40];
    29			int	nCarte;
    30			char	name[32];
    31			int	pnt;
    32			int	libri;
    33	};
    34	
    35	#endif


La classe Giocatore è composta dal solito array di carte, stavolta composto solamente da 40 elementi, perchè si possono avere solo 3 carte per ogni valore (perchè 4 carte dello stesso valore saranno scartate), 13 sono i tipi di valore dunque 13*3=39.
Ho scelto di avere un array di 40 elementi perchè in un solo caso uno dei due giocatori può arrivare ad avere in mano 40 carte:
nel caso poco probabile (quasi assurdo) che il giocatore abbia 3 valori per ogni tipo di carta, ovvero 39 carte, questi non può scartare, dunque alla richiesta del giocatore di una altra carta all'avversario (che comporterà solo successivamente lo scarto delle 4 carte dello stesso tipo), per un solo istante il giocatore avrà 40 carte, e se l'array fosse di sole 39 carte la 40 andrà persa e il giocatore non potrà scartare le altre 3 carte dello stesso valore della carta persa.

Ovviamente il giocatore avrà un nome, e 31 caratteri (l'ultimo è riservato per il char '\0') sono più che sufficienti.

Il puntatore pnt segue la stessa logica di quella del puntatore del mazzo.

La variabile intera libri è usata per calcolare il punteggio finale, ovvero viene incrementata ogni volta che il giocatore scarta una serie di 4 carte dello stesso valore, un 'libro' appunto.


//	file giocatore.h 

     1	#include "giocatore.h"

     2	
     3	Giocatore::Giocatore() {
     4		
     5		nCarte=sizeof(carte)/sizeof(Carta);
     6	
     7		pnt=-1;	//	il fatto è che push ficca una carta a partire da 
     8			//	dopo il puntatore, dunque la prima la ficca a zero
     9			//	e non c'è pericolo se le carte vengono
    10			//	messe solo con push...
    11		libri=0;
    12	
    13		cout << "\nInserisci il tuo nome (max 30 char): ";
    14		cin.getline(name, 32);
    15	}
    16	
    17	char*	Giocatore::getName(){
    18		return name;
    19		}
    20	
    21	int	Giocatore::getLibri(){
    22		return libri;
    23	}
    24	
    25	int	Giocatore::ask(){
    26	
    27		int par;
    28		int find;
    29	
    30	//	chiede una carta al giocatore finché questi non ne sceglie una fra quelle che ha
    31		do {
    32		//	chiede una carta al giocatore finché questi non ne sceglie una fra 1 e 13
    33			do {
    34				char arrChar[3]={'\n'};
    35		
    36				cout << "\nInserisci un valore fra 1 e 13\n";
    37					cin.clear();
    38					cin.sync();
    39	
    40					if (arrChar[0]!='\n' && arrChar[1]!='\n' && arrChar[2]!='\n'){
    41						while(cin.get()!='\n');
    42						
    43					}
    44					cin.getline(arrChar, 3);
    45					par=atoi(arrChar);
    46	
    47				while (!par){
    48					cout << "\aChe hai scritto?!?\n";
    49	
    50					cin.clear();
    51					cin.sync();
    52	
    53					if (arrChar[0]!='\n' && arrChar[1]!='\n' && arrChar[2]!='\n'){
    54						while(cin.get()!='\n');
    55						
    56					}
    57					cin.getline(arrChar, 3);
    58					par=atoi(arrChar);
    59				};
    60	
    61			}while (par<1 || par>13);
    62	
    63			find = findVal((char)par);
    64	
    65			if (find<0)
    66				cout << "\nNon hai una carta di quel valore,\nscegli un'altra carta\n";
    67			
    68		}while (find<0);
    69	
    70		return par;	//	se tutto è corretto ritorna il valore inserito dall'utente
    71	}
    72	
    73	//	ritorna la posizione del primo valore trovato
    74	int	Giocatore::findVal(int _val){
    75	
    76		for (int j=0; j<nCarte; j++){
    77		
    78			if (_val == carte[j].getVal())
    79				return j;
    80		}
    81	//	se non la trova
    82		return -1;
    83	}
    84	
    85	//	restituisce la carta alla posizione specificata
    86	Carta	Giocatore::popNcarta(int _pnt){
    87		
    88		Carta tempCarta=carte[_pnt];
    89		carte[_pnt].azzera();
    90		
    91		return tempCarta;
    92	}
    93	
    94	//	aggiunge una carta
    95	void	Giocatore::pushCarta(Carta _card){
    96		pnt++;
    97		carte[pnt] = _card;
    98	}
    99	
   100	void	Giocatore::show(){
   101	
   102		cout << "\n";
   103		int w=0;
   104		for (int j=0; j<nCarte; j++){
   105	
   106			//	fa vedere solo le carte che ha
   107			int k = carte[j].getVal();
   108			if (k!=0){
   109				if (w%3==0)
   110					cout << "\n\t";
   111				
   112				cout << k << "   " << carte[j].getSeed() << "\t";
   113				w++;
   114			}
   115		}
   116		cout << "\n";
   117	}
   118	
   119	void	Giocatore::scarta(){
   120	
   121	//	per ogni tipo di valore
   122		for (int j=1; j<=13; j++){
   123	
   124			int tmp = 0;
   125			
   126		//	controlla quante carte di quel tipo ha
   127			for (int k=0; k<nCarte; k++)
   128				if (carte[k].getVal()==j)
   129					tmp++;
   130	
   131		//	se ha tutte le carte di questo valore, scartale
   132			if (tmp==4) {
   133				for (int w=0; w<nCarte; w++)
   134					if (carte[w].getVal()==j)
   135						carte[w].azzera();
   136	
   137				cout << "\tScarto i " << j << "\n";
   138				libri++;
   139			}
   140		}
   141	}
   142	
   143	int	Giocatore::checkEnd(){
   144	//	se ha finito le carte la partita è finita
   145		int ended=1;
   146		for (int w=0; w<nCarte; w++)
   147			if (carte[w].getVal()!=0){
   148				ended=0;
   149				break;
   150			}
   151		return ended;
   152	}
   153	 


Per prima cosa il costruttore della classe inizializza il puntatore a -1.
Sembra strano, ma ciò è in funzione della logica del metodo pushCarta.

Poi il punteggio del giocatore, ovvero la variabile libri, viene inizializzata a 0.

Il metodo getNome() restituisce un puntatore all'array nome[]. Restituire un puntatore ad un dato di un oggetto, forse, non è troppo coerente con la programmazione orientata agli oggetti, ma ricopiare l'intera stringa è troppo dispendioso, in termini di memoria ma anche di lavoro per il programmatore.

Il metodo getLibri() serve per visualizzare il punteggio attuale, ed è usato alla fine del gioco.

Il metodo ask() è usato per chiedere all'utente quale carta vuole chiedere, e controllare che rispetti le regole del gioco.
Ci sono due cicli: come è commentato sul codice, il più esterno controlla che l'utente scelga una carta fra quelle che ha,
mentre il più interno controlla che l'input sia un valore compreso tra 1 e 13 inclusi, e ambedue ripetono la richiesta di input se l'utente non rispetta tali regole. Da notare che, per come è scritto il codice, viene eseguito prima il secondo ciclo (il più interno), e poi il primo (il più esterno).

Il metodo findVal() cerca una carta di un tipo di valore specificato, e restituisce la posizione della prima carta di quel valore che trova, mentre se non ne trova restituisce -1. So bene che in un ciclo o in una istruzione if il valore 0 è considerato falso e ogni valore positivo o negativo (quindi anche -1) è considerato vero, ma non potevo usare 0 come valore di ritorno nel caso che il metodo non trovi la carta specificata, perchè l'array nel quale cerca inizia da 0 e quindi la carta specificata si potrebbe trovare anche nella posizione 0 dell'array.

Il metodo popNcarta() restituisce la carta alla posizione specificata e la toglie dall'array del giocatore. Di solito il parametro passato a questo metodo è restituito dalla funzione findVal.

Il metodo pushCarta() incrementa il puntatore di 1 e aggiunge alla nuova posizione (ovvero quella dove punta il puntatore dopo l'incremento) l'oggetto Carta che il metodo ha ricevuto come argomento.

Il metodo show(), è ovvio, visualizza le carte in possesso del giocatore.

Il metodo scarta() controlla quante carte per ogni tipo di valore possiede il giocatore;
se sono 4, le toglie dall'array delle carte del giocatore e incrementa il valore di libri, che ricordo serve a tenere il conto dei punti fatti dal giocatore.

Infine il metodo checkEnd() controlla che il giocatore abbia ancora qualche carta in mano.
Se il giocatore non ha più carte in mano, la partita è finita e lo comunica restituendo 1.





//	file avversario.h

     1	#ifndef AVVERSARIO_H
     2	#define AVVERSARIO_H
     3	
     4	#include <iostream>

     5	using std::cout;
     6	using std::cin;
     7	#include "carta.h"
     8	
     9	class Avversario {
    10		public:
    11			Avversario();
    12	
    13			void	show();
    14			int	findVal(int);
    15	
    16			void	pushCarta(Carta);
    17			Carta	popNcarta(int);
    18	
    19			int	findTrace(int);
    20			void	pushTrace(int);
    21			int	popNtrace(int);
    22	
    23			void	scarta();
    24			int	checkEnd();		
    25			int	ask();
    26			char*	getName();
    27			int	getLibri();
    28	
    29		private:
    30			Carta	carte[40];
    31			int	nCarte;
    32			char	name[5];
    33			int	pnt;
    34	
    35			//	tengo traccia delle carte che il giocatore chiede all'avversario,
    36			int	trace[30];	//lo limito a 30, e faccio tornare il puntatore a 0
    37			int	lenTrace;
    38			int	pntTrace;
    39			int	libri;
    40	};
    41	
42 #endif 

La classe Avversario è molto simile alla classe Giocatore.
Di nuovo ci sono i dati che vengono utilizzati per quella che azzardo a definire IA del giocatore, grazie ai quali cerco di stabilire una strategia di gioco.

Questi dati sono l'array di interi trace[], dove memorizzo le richieste di carte che l'utente fa al computer,
il puntatore pntTrace utilizzato per accedere agli elementi di trace[],
e lenTrace, ovvero l'intero che indica il numero di elementi di trace[], che la convenzione ISO mi impedisce di settare a 30 o ad un valore dinamico come sizeof(trace)/sizeof(int), e che quindi inizializzo nel costruttore della classe.
    
//	file avversario.c

     1	#include "avversario.h"
     2	
     3	Avversario::Avversario() {
     4	
     5		nCarte=sizeof(carte)/sizeof(Carta);
     6	
     7		lenTrace=sizeof(trace)/sizeof(int);
     8		for (int j=0; j<lenTrace; j++)
     9			trace[j]=0;	//inizializzo trace a 0
    10	
    11		pnt=-1;	//	il fatto è che push inserisce una carta a partire da 
    12		//	dopo il puntatore, dunque la prima la ficca a zero
    13		//	e non c'è pericolo se le carte vengono
    14		//	messe solo con push...
    15		libri=0;
    16	
    17		pntTrace=-1;
    18	
    19		name[0]='T';
    20		name[1]='1';
    21		name[2]='t';
    22		name[3]='0';
    23		name[4]='\0';
    24	}
    25	
    26	char*	Avversario::getName(){
    27	
    28		return name;
    29	}
    30	
    31	int	Avversario::getLibri(){
    32		
    33		return libri;
    34	}
    35	
    36	
    37	//	ritorna la posizione del primo valore trovato
    38	int	Avversario::findVal(int _val){
    39	
    40		for (int j=0; j<nCarte; j++){
    41		
    42			if (_val == carte[j].getVal())
    43				return j;
    44		}
    45	//	se non la trova
    46		return -1;
    47	}
    48	
    49	//	restituisce la carta alla posizione specificata
    50	Carta	Avversario::popNcarta(int _pnt){
    51		
    52		Carta tempCarta=carte[_pnt];
    53		carte[_pnt].azzera();
    54		
    55		return tempCarta;
    56	}
    57	
    58	//	aggiunge una carta
    59	void	Avversario::pushCarta(Carta _card){
    60		pnt++;
    61		carte[pnt] = _card;
    62	}
    63	
    64	void	Avversario::show(){
    65	
    66		cout << "\n";
    67		int w=0;
    68		for (int j=0; j<nCarte; j++){
    69	
    70			//	fa vedere solo le carte che ha
    71			int k = carte[j].getVal();
    72			if (k!=0){
    73				if (w%3==0)
    74					cout << "\n\t\t\t\t\t";
    75	
    76				cout << k << "   " << carte[j].getSeed() << "\t";
    77				w++;
    78			}
    79		}
    80		cout << "\n";
    81	}
    82	
    83	void	Avversario::scarta(){
    84	
    85	//	per ogni tipo di valore
    86		for (int j=1; j<=13; j++){
    87	
    88			int tmp = 0;
    89			
    90		//	controlla quante carte di quel tipo ha
    91			for (int k=0; k<nCarte; k++)
    92				if (carte[k].getVal()==j)
    93					tmp++;
    94	
    95		//	se ha tutte le carte di questo valore, scartale
    96			if (tmp==4) {
    97				for (int w=0; w<nCarte; w++)
    98					if (carte[w].getVal()==j)
    99						carte[w].azzera();
   100	
   101				cout << "\tScarto i " << j << "\n";
   102				libri++;
   103			}
   104		}
   105	}
   106	
   107	int	Avversario::checkEnd(){
   108	//	se ha finito le carte la partita è finita
   109		int ended=1;
   110		for (int w=0; w<nCarte; w++)
   111			if (carte[w].getVal()!=0){
   112				ended=0;
   113				break;
   114			}
   115		return ended;
   116	}
   117	
   118	////////////////////////////
   119	//		I.A.
   120	
   121	
   122	//	ritorna la posizione del primo valore trovato fra le carte richieste da Player a Computer
   123	int	Avversario::findTrace(int _val){
   124	
   125		for (int j=0; j<lenTrace; j++){
   126		
   127			if (_val == trace[j])
   128				return j;
   129		}
   130	//	se non la trova
   131		return -1;
   132	}
   133	
   134	//	memorizza l'ultima carta richiesta da Player a Computer
   135	void	Avversario::pushTrace(int _val){
   136	
   137		if (pntTrace<(lenTrace-1))
   138			pntTrace++;	//scrivo sulla prossima posizione
   139		else
   140			pntTrace=0;	//me se l'array è finito ricomincio da 0
   141	
   142		trace[pntTrace] = _val;
   143	}
   144	
   145	//	restituisce la carta alla posizione specificata fra quelle
   146	//	richieste da Player a Computer
   147	int	Avversario::popNtrace(int _pnt){
   148		
   149		int temp=trace[_pnt];
   150		trace[_pnt]=0;
   151		
   152		return temp;
   153	}
   154	
   155	//	restituisce la carta da chiedere a Player
   156		int	Avversario::ask(){
   157	
   158		int count[14]={0};  //count[0] resta inutilizzato
   159		int best=0;
   160		int max=0;
   161	//	per ogni tipo di valore
   162		for (int tipo=1; tipo<=13; tipo++){
   163	
   164			int tmp=0;
   165		//	controlla quante carte di quel tipo ha
   166			for (int k=0; k<nCarte; k++){
   167				if (carte[k].getVal()==tipo)
   168					tmp++;
   169			}
   170			count[tipo]=tmp;	//memorizza i valori
   171	
   172		//	se questa carta che ho me l'ha chiesta anche il giocatore
   173		//	e ce ne ho in maggior numero della best precedente
   174			if(findTrace(tipo)!=-1 && count[best]<tmp){
   175				best=tipo;
   176			}
   177			
   178		//	se count[0] era utilizzato questa istruzione dava problemi, perchè max all'inizio è =0
   179			if (count[max]<tmp)
   180				max=tipo;	//memorizza la carta che ho in maggior numero
   181	
   182	
   183		//	cout << tipo << ")\tmax: " << max << "\tbest: " << best << "";
   184		//	cout << "\tfind:  " << findTrace(tipo) << "\tcount[tipo]: " << count[tipo] << "\tcount[best]: " << count[best] << "\n";
   185	
   186	
   187		}
   188		//for (int z=0; z<lenTrace; z++)
   189		//	cout << trace[z] << "\n";
   190	
   191		//	se con quel sistema non si è potuto scegliere una carta,
   192		//	chiede quella che ha in maggior numero
   193		if (best==0)
   194			best=max;
   195	
   196		return best;
   197	}
   198	////////////////////////////
   199	 


Anche l'implementazione dei metodi della classe Avversario è simile a quella della classe Giocatore.
Nel costruttore le uniche differenze con Giocatore è nell'inizializzazione dell'array nome[] e delle proprietà usate per l'IA,
ovvero lenTrace che viene inizializzato dinamicamente a seconda del numero degli elementi dell'array trace[], e gli elementi dell'array trace[] che vengono inizializzati tutti a 0.

Un altro metodo non presente nella classe Giocatore è findTrace(), ma come è intuibile funziona come findVal(), e cioè restituisce il primo valore che trova nell'array trace[].

Il metodo pushTrace() funziona simile a pushCarta(): se il puntatore corrente è minore di (lenTrace-1) incrementa il puntatore, altrimenti vuol dire che è finito lo spazio disponibile in trace[] e quindi impostando il puntatore a 0 ricomincia a scrivere dal primo elemento dell'array.
Diversamente dall'array delle carte, l'array trace[] memorizza le richieste che il giocatore fa all'avversario (poi vedremo per quale scopo); questo significa che se il giocatore è sfortunato e non indovina mai le carte che ha l'avversario, la partita può dilungarsi e le richieste del giocatore possono superare la grandezza dell'array trace. Viene controllato che il puntatore sia minore di lenTrace-1, invece di lenTrace, perchè il puntatore passa dai valori 0 fino a lenTrace-1; esempio: lenTrace è uguale a 5, il puntatore è uguale a 4; if(pntTrace<lenTrace) restituirebbe vero, dunque il puntatore sarebbe incrementato a 5 ed il valore verrebbe scritto su trace[5], mentre l'indice di un array di 5 elementi varia da 0 a 4.

Il metodo popNtrace() è praticamente uguale a popNcarta(), solo che estrae un valore in una determinata posizione dall'array trace[] invece dell'array carte[].

Il metodo ask() è quello che, in modo più o meno logico, permette all'avversario di scegliere una determinata carta da chiedere al giocatore.
Questo metodo prende in considerazione due array: l'array delle carte possedute dal computer (carte[]) e l'array di carte richieste dal giocatore (trace[]);
viene eseguito un loop: per ogni tipo di carta controlla quante carte di quel tipo si possiedono e memorizza i risultati nell'array count[14].
Il primo elemento di questo array è vuoto, mentre per ogni elemento successivo (dopo il ciclo precedente che confronta i due array) questo array contiene il numero delle carte di quel valore in possesso (ad esempio se si hanno 3 assi e 1 due il risultato è count[0]=0 count[1]=3 e count[2]=1).
Dopodichè il metodo controlla se quel tipo di valore è fra quelli richiesti dal giocatore (cioè li cerca nell'array trace[]).

Il risultato è che se vengono trovate una o più carte fra quelle dentro l'array trace[] che si trovano anche fra le carte del computer, il metodo restituisce il tipo di valore fra queste carte che si hanno in maggior numero, altrimenti restituisce semplicemente il valore di carta che il computer ha in numero maggiore.
E' complicato, lo so (l'ho scritto io!)...
un paio di esempi sono d'obbligo:
	caso 1)
fra le carte del computer ci sono 3 assi e 1 due, oltre ad altre carte che non ci interessano;
fra le carte chieste dall'utente al computer ci sono asso e due, oltre ad altre;
in questo caso il metodo restituisce uno,
ovvero una carta che l'utente ha (altrimenti perchè l'ha chiesta al giocatore?), che allo stesso tempo ha anche il computer (e dunque secondo le regole la può chiedere), e fra le carte che rispettano quest'ultima condizione, l'asso è quella che computer ha in maggior numero
(nell'esempio di prima anche il due era una carta sicura da chiedere, ma è meglio chiedere l'asso perchè se ne hanno già tre!)
	caso 2)
fra le carte del computer non c'è neanche una carta fra quelle che l'utente ha chiesto;
in questo caso qualsiasi carta va bene, e il metodo restituisce il valore più frequente fra le sue carte
(se ha 2 quattro, 3 cinque e 1 sette il metodo restituisce cinque)





//	file partita.h

     1	#ifndef PARTITA_H
     2	#define PARTITA_H
     3	
     4	#include <iostream>

     5	using std::cout;
     6	using std::cin;
     7	#include "mazzo.h"
     8	#include "giocatore.h"
     9	#include "avversario.h"
    10	
    11	class Partita {
    12		public:
    13			Partita();
    14	
    15			void	Distr();
    16			void	Start();
    17			void	End();
    18	
    19		private:
    20			Giocatore	Player;
    21			Avversario	Computer;
    22			Mazzo		Pack;
    23	};
    24	
25 #endif 

La classe partita è semplice, contiene come dati membro il mazzo e i due giocatori necessari per fare una partita a carte.

//	file partita.c

     1	#include "partita.h"

     2	
     3	Partita::Partita() {
     4	
     5	//	stampa messaggio di benvenuto...
     6		cout << "\033[H\033[J\n\n\n\t\t\tGoFish!\n";
     7	
     8	//	distribuisci carte
     9		Distr();
    10	
    11	//	inizia il gioco
    12		Start();
    13	}
    14	
    15	//	distribuisci carte
    16	void Partita::Distr(){
    17	
    18		
    19	//	per 14 carte del mazzo (7 per ciascuno)
    20	//	a partire dalla Pack.pnt
    21		int pnt = Pack.getPnt();
    22	
    23		for (int j=pnt; j>pnt-14; j--){
    24		
    25		//	se è pari
    26			if (j%2==0){
    27				
    28			//	dai la carta al player
    29			//	e levala dal mazzo
    30				Player.pushCarta (Pack.popCarta());
    31				
    32							
    33		//	altrimenti
    34			}else{
    35				
    36			//	dai la carta al player
    37			//	e levala dal mazzo
    38				Computer.pushCarta (Pack.popCarta());
    39			}
    40		}
    41	}
    42	
    43	//	inizio la partita...
    44	void Partita::Start(){	
    45	
    46			//	questa parte si potrebbe implementare in un metodo
    47			//	specifico (= probab. non riutilizzabile)
    48			//	di nome gofish, tanto per levarlo da qui...
    49	
    50	//	il loop continua finché la partita non è finita
    51	//	il controllo viene effettuato durante il gioco,
    52	//	ogni volta che uno dei giocatori scarta...
    53		while (true){
    54	
    55			cout << "\n";
    56			//cout << "\033[H\033[J";
    57	
    58			//////////////////////////////////
    59			//				//
    60			//	tocca a Player		//
    61			//				//
    62			//////////////////////////////////
    63	
    64			cout << "\n\n\n------------------------------" << Player.getName() << "-------------------------Libri: " << Player.getLibri() << "\n";
    65			
    66			int find;	//	mi serve anche dopo il prossimo blocco
    67			//	Player chiede un'altra carta se indovina la prossima carta del mazzo
    68			do {
    69				
    70				cout << "\n\tChiedi una carta all'avversario:\n";
    71				//Pack.show();		//	?debug
    72				//Computer.show();	//	?debug
    73				Player.show();
    74				
    75				int val = Player.ask();
    76				find = Computer.findVal(val);
    77			//	comunico all'IA di Computer
    78			//	quale carta Player gli abbia chiesto
    79				Computer.pushTrace(val);
    80	
    81			//	Player chiede un'altra carta se ne ha chiesta una che Computer ha
    82				while(find!=-1){
    83	
    84				//	Computer passa a Player la carta
    85					Player.pushCarta(Computer.popNcarta(find));
    86				//	scarta se possibile
    87					Player.scarta();
    88	
    89				//	se un dei due è rimasto senza carte, la partita è finita
    90					if (Player.checkEnd() || Computer.checkEnd())
    91						End();
    92			
    93					cout << "\a\n\t\t\t\t\tCe l'ho!\n";
    94					cout << "Chiedi un'altra carta\n";
    95					//Pack.show();		//	?debug
    96					//Computer.show();	//	?debug
    97					Player.show();
    98	
    99					val = Player.ask();
   100					find = Computer.findVal(val);
   101	
   102				//	comunico all'IA di Computer
   103				//	quale carta Player gli abbia chiesto
   104					Computer.pushTrace(val);
   105				}
   106	
   107				cout << "\n\t\t\t\t\tGoFish!\n";
   108	
   109			//	prendi una carta dal mazzo
   110				Carta dalMazzo = Pack.popCarta();
   111				Player.pushCarta(dalMazzo);
   112				
   113			//	scarta se possibile
   114				Player.scarta();
   115				
   116			//	se Player è rimasto senza carte, la partita è finita
   117				if (Player.checkEnd())
   118					End();
   119		
   120			//	se ha il valore di quella chiesta a Computer
   121				if (dalMazzo.getVal()==val) {
   122					
   123					//Pack.show();		//	?debug
   124	
   125					cout << "\a\nHai pescato la carta che hai chiesto!\n";
   126	
   127				//	chiedi di nuovo una carta a Computer
   128					find=0;
   129				
   130					//Computer.show();		//	?debug
   131					//Player.show();		//	?debug
   132					cout << "\n";
   133				}
   134	
   135			}while (find>=0);
   136	
   137	
   138			//////////////////////////////////
   139			//				//
   140			//	tocca a Computer	//
   141			//				//
   142			//////////////////////////////////
   143	
   144			cout << "\n\n\n------------------------------" << Computer.getName() << "-----------------------Libri: " << Computer.getLibri() << "\n";
   145			
   146			int findComp;	//	mi serve anche dopo il prossimo blocco
   147		//	Computer chiede un'altra carta se indovina la prossima carta del mazzo
   148			do {
   149				
   150				//Pack.show();			//	?debug
   151				//Computer.show();		//	?debug
   152				Player.show();
   153				int asked=Computer.ask();
   154	
   155				cout << "\n\t\t\t\t\tTi chiedo un " << asked << "\nPremi [invio] per continuare...\n";
   156				char null[10];		//	pausa
   157				cin.getline(null,10);	//	pausa
   158		
   159				findComp = Player.findVal(asked);
   160	
   161			//	Computer chiede un'altra carta se ne ha chesta una che Player ha
   162				while(findComp!=-1){
   163	
   164				//	Player passa a Computer la carta
   165					Computer.pushCarta(Player.popNcarta(findComp));
   166					
   167				//	scarta se possibile
   168					Computer.scarta();
   169				
   170				//	se un dei due è rimasto senza carte, la partita è finita
   171					if (Computer.checkEnd() || Player.checkEnd())
   172						End();
   173	
   174					//Pack.show();		//	?debug
   175					//Computer.show();	//	?debug
   176					cout << "\a\n\t\t\t\t\tC'e l'hai!\n";
   177					Player.show();
   178					cout << "\n";
   179	
   180	
   181					asked=Computer.ask();
   182	
   183					cout << "\n\t\t\t\t\tTi chiedo un " << asked << "\nPremi [invio] per continuare...\n";
   184					char null[10];		//	pausa
   185					cin.getline(null,10);	//	pausa
   186	
   187					findComp = Player.findVal(asked);
   188				}
   189	
   190			//	se computer non ha indovinato una carta di Player,
   191			//	è possibile che Player abbia avuto e poi finito le carte di quel tipo
   192			//	dunque per l'IA di Computer è meglio togliere queste carte dalla lista
   193			//	delle carte che Computer pensa siano in possesso di Player
   194			
   195				int posT = Computer.findTrace(asked);		//cerca la carta richiesta dal computer sulla sua lista
   196	
   197				while (posT!=-1){				//finché ne trova una
   198					Computer.popNtrace(posT);		//la leva dalla lista
   199					posT = Computer.findTrace(asked);	//cerca la prossima carta dello stesso tipo
   200				}
   201				cout << "\nNiente.\t\t\t\tPesco dal mazzo\n";
   202				
   203			//	prendi una carta dal mazzo
   204				Carta dalMazzoC = Pack.popCarta();
   205				Computer.pushCarta(dalMazzoC);
   206	
   207			//	scarta se possibile
   208				Computer.scarta();
   209				
   210			//	se Computer è rimasto senza carte, la partita è finita
   211				if (Computer.checkEnd())
   212					End();
   213	
   214			//	se ha il valore di quella chiesta a Player
   215				if (dalMazzoC.getVal()==asked) {
   216					//Pack.show();		//	?debug
   217	
   218					cout << "\a\n\t\t\t\t\tHo pescato la carta che ho chiesto!\n";
   219	
   220				//	chiedi di nuovo una carta a Player
   221					findComp=0;
   222				
   223					//Computer.show();		//	?debug
   224					//Player.show();		//	?debug
   225				}
   226	
   227			}while(findComp>=0);
   228		}
   229	}
   230	
   231	
   232	
   233	void	Partita::End(){
   234	
   235		int p=Player.getLibri();
   236		int c=Computer.getLibri();
   237	
   238		if (p>c){
   239			cout << "\a\n\n\n";
   240			cout << Player.getName();
   241			cout << ", hai vinto!\n";
   242			cout << "hai collezionato " << p << " libri contro " << c << " di ";
   243			cout << Computer.getName();
   244			cout << "\n";
   245		}else if (p<c){
   246			cout << "\a\n\n\n\t\t\t\t\t" << "Hai perso!\n";
   247			cout << Computer.getName();
   248			cout << " ha collezionato " << c << " libri contro i tuoi " << p << "\n";
   249		}else{
   250			cout << "\a\n\n\n" << "E' patta:\n";
   251			cout << " avete collezionato " << p << " libri ciascuno.\n";
   252		}
   253	
   254		exit (0);
   255	}
   256	 


Nel costruttore della classe partita vengono chiamati due metodi di Partita.
Il metodo Distr() distribuisce 14 carte, 7 carte ciascuno alternate.

Nel metodo Start() si svolge l'intera partita, in un ciclo continuo (while(true)) che alterna il gioco dell'utente e del computer.
Nel gioco dell'utente c'è un altro ciclo nel quale, dopo aver stampato a schermo le carte dell'utente, gli viene chiesto di scegliere una carta:
finché questo sceglie una carta che il computer ha, oppure finché la carta scelta viene pescata dal mazzo, il calcolo viene ripetuto e viene chiesto all'utente di scegliere un'altra carta. Da notare che ogni carta che l'utente inserisce viene riferita al computer, che la memorizza nel suo array trace[] che userà per stabilire una strategia di gioco.
Quando l'utente indovina una carta che l'avversario ha, questa carta viene passata dall'avversario all'utente, e viene chiamato il metodo Player.Scarta() che se è il caso penserà a scartare le carte secondo le regole del gioco; quindi viene controllato che i giocatori abbiano ancora carte usando if(Player.checkEnd() || Computer.checkEnd()): se scartando l'utente finisce le carte il metodo Player.checkEnd() restituisce 1, oppure se dando la carta che l'utente ha chiesto il computer rimane senza carte il metodo Computer.checkEnd() restituisce 1; in ambedue i casi viene chiamato il metodo End() che provvederà a contare i punti e a terminare il programma.
Quando l'utente non ha indovinato una delle carte che ha il computer, pesca una carta e viene chiamato nuovamente il metodo Player.Scarta() e ovviamente anche il metodo Player.checkEnd()il quale, nel caso l'utente scartando sia rimasto senza carte, chiama il metodo End() che termina la partita.
Dopodichè, se la carta pescata è uguale a quella richiesta dall'utente, viene ripetuto il ciclo e viene chiesta una nuova carta all'utente, altrimenti il controllo passa al computer.

Lo stesso vale per il computer: gli viene chiesta una carta e finché questa è fra quelle dell'utente, o è dello stesso valore di quella che pesca nel mazzo, chiede altre carte all'utente e scarta, e quando non indovina il controllo passa nuovamente al giocatore.





//	file goFish.c

     1	#include <iostream>

     2	#include <cstdlib>
     3	
     4	#include "carta.h"
     5	#include "mazzo.h"
     6	#include "giocatore.h"
     7	#include "avversario.h"

     8	#include "partita.h"
     9	
    10	
    11	using std::cout;
    12	using std::cin;
    13	
    14	int main(){
    15	
    16		Partita Game;
    17		
    18		return 0;
    19	}
    20	 

Come è evidente, il programma dichiara soltanto un oggetto di tipo Partita e di nome Game,
dunque il controllo passa al costruttore di Game, dove inizierà il gioco.