Scrivere una briscola in C++

di il
33 risposte

Scrivere una briscola in C++

Salve a tutti, sono nuovo del forum. Sono uno studente universitario e seguo un corso di programmazione in c++, per l'esame devo sviluppare un gioco di carte, nel mio caso la briscola. Vorrei chiedervi qualche consiglio su come svilupparlo. Fino ad ora sono riuscito a creare un programma che generi le carte, le mescoli e le distribuisca ma non riesco a dare un criterio di vincita, a sommare i punti e a ridistribuire le carte ad ogni mano.

Allego parte del codice che ritengo possa essere corretta:

#include<iostream>
#include<windows.h> 						//Contiene alcune utili librerie
#include<cstdlib>							//Contiene il prototipo della funzione srand
#include<cmath>
#include<ctime>								//Contiene il prototipo della funzione time
#include<iomanip>							//Contiene il prototipo della funzione setw

using namespace std;

struct carte {									//Definisce la struttura delle carte
	int valore;
	int punti;
	char seme;
} briscola;

carte mazzo [40];						//Il mazzo è composto da 40 carte
carte terra [2];						//Sul 'tavolo' sono presenti 2 carte
carte manoPC [3];						//Il computer ha 3 carte in 'mano'
carte manoGiocatore [3];				//Il giocatore  ha 3 carte in 'mano'
carte presaPC [40];						//Numero massimo di carte del PC
carte presaG [40]; 			  			//Numero massimo di carte del giocatore

int puntiPc;						    //Punti di partenza del PC
int puntiGiocatore;						//Punti di partenza del giocatore
bool mazzierePc;						//Il computer è il mazziere
bool primoGiocatore;					//Serve a stabilire il turno del giocatore umano
bool primaUmano;
bool prendeGiocatore;
bool prendePc;
int x = 6;


void carteMazzo () {																	//Rappresenta le carte del mazzo
	
	/* Il mazzo è un array di 40 elementi. Esso viene diviso in gruppi di 10
	calcolando il resto della divisione per 10. Si aggiunge 1 al risultato perchè
	l'array comprende 40 valori da 0 a 39.  Il valore risultante corrisponde al VALORE.
	Il seme della carta viene definito usando l'intervallo di valori 0-9 per denari,
	10-19 per bastoni 20-29 per coppe e 30-39 per spade.*/
			
	for (int i=0; i<40; i++){
		mazzo[i].valore = i%10+1;					
	int seme = i/10 + 1;								
	switch (seme) {
		case 0 : mazzo[i].seme = 'D'	;			//Denari
				break;
		case 1 : mazzo[i].seme = 'B';				//Bastoni
				break;
		case 2 : mazzo[i].seme = 'C';				//Coppe
				break;
		case 3 : mazzo[i].seme = 'S';				//Spade
				break;
	}
	}
}

void mescolaMazzo() {															//Mescola il mazzo di carte
	
	/* Questa funzione ha restituire un vettore che rappresenta un mazzo di carte mescolato. 
   La corrispondenza che associa ciascun numero intero tra 0 e 39 a ogni singola carta del mazzo 
   e' descritta nella funzione 'carteMazzo*/
   
  	int i, j;
    srand( time(0) ); 										 //Randomizziamo i numeri

  	for(i=0; i<40; i++) {
  	mazzo[i];	}											//generiamo un mazzo ordinato come appena tolto dalla scatola
  	
	for(i=0; i<40; i++){
    j = rand()%40 + 1 ;										//generiamo un numero casuale di partenza
    
    carte seme = mazzo[i];									// Scambiamo la i-esima carta con la j-esima
    mazzo[i] = mazzo[j];
    mazzo[j] = seme;
  }

}

void mostraBriscola () {														//Mostra la briscola 
	briscola.valore = mazzo[39].valore;											//Seleziona la carta in cima al mazzo
	briscola.seme = mazzo[39].seme;
	cout<<endl<<"La briscola e' : "<<briscola.valore<<" di "<<briscola.seme<<endl;
}

int punteggio (	){																//Stabilisce il punteggio associato ad ogni carta
	carteMazzo();
																
 	int p;
 	int valore;
 	for (int i=0; i<40; i++){
 	valore = mazzo[i].valore;
 	  
	 switch (valore){
	 	case 1 : mazzo[i].punti = 11;
	 		break;
	 	case 2 : mazzo[i].punti = 0;
	 		break;
	 	case 3 : mazzo[i].punti = 10;
	 		break;
	 	case 10 : mazzo[i].punti = 4;
	 		break;
	 	case 9 : mazzo[i].punti = 3;
	 		break;
	 	case 8 : mazzo[i].punti=2;
	 		break;
	 	case 7 : mazzo[i].punti = 0;
	 		break;
	 	case 6 : mazzo[i].punti = 0;
	 		break;
	 	case 5 : mazzo[i].punti = 0;
	 		break;
	 	case 4 : mazzo[i].punti = 0;
	 		break;
	 	default : mazzo[i].punti = 0;
	 }
 	}
 return(p) ;

 }

bool inizioPartita () {																//Seleziona chi inizia il gioco

	bool primoGiocatore;
	srand(time(NULL));																//Randomizzazione numeri casuali
	primoGiocatore = rand()%2;	
	
	cout<<endl<<endl<<primoGiocatore<<endl<<endl;													//Genera arbitrariamente 0 o 1
	
	if (primoGiocatore == true)														//Se esce 1 inizia l'umano
		cout<<"Inizia la partita l'umano'\n";
	else 
		cout<<"Inizia la partita il calcolatore\n";										//Se esce 0 inizia il calcolatore

return primoGiocatore;

}
void distribuireCarte() {         				 								// Funzione per dare le carte ai giocatori

    if (mazzierePc) {
        for (int i=0; i<3; i++){           										//utilizzo del for per variare in numero di carte preso nella prima mano.
        manoGiocatore[i] = mazzo[i*2];   										// caso in cui le carte vengono date prima all'utente e poi all'avversario.
        manoPC[i] = mazzo[i*2+1];
        } 
    }
		else {
        for (int i=0; i<3; i++)
        {   manoGiocatore[i] = mazzo[i*2+1]; 									// caso in cui le carte vengono date prima all'avversario e poi all'utente.
            manoPC[i] = mazzo[i*2];
      }
  }

}

int scegliCarta () {															//Permette all'utente di scegliere la carta da giocare
	/*La scelta della carta avviene tramite un costrutto if..else che permette
	di stabilire la posizione della carta sul tavolo (primo o secondo turno).
	Dopo che si sceglie la carta da giocare viene prelevata la carta corrispondente
	nell'array manoGiocatore. */
	
	int scelta;
	for (int j=0; j<3; j++){
		cout<<j+1<<setw(5)<<manoGiocatore[j].valore<<" di "<<manoGiocatore[j].seme<<endl;
	}
	cout<<"Quale carta desideri giocare? \n";
	cin>>scelta;
	
	if (primoGiocatore) {
		terra[0].valore = manoGiocatore[scelta-1].valore;
		terra[0].seme=manoGiocatore[scelta-1].seme; 
		terra[0].punti=manoGiocatore[scelta-1].punti;
	} else {
		terra[1].valore=manoGiocatore[scelta-1].valore;
		terra[1].seme=manoGiocatore[scelta-1].seme;
		terra[1].punti=manoGiocatore[scelta-1].punti;
	}
	
	cout<<"Hai tirato"<<manoGiocatore[scelta-1].valore<<manoGiocatore[scelta-1].seme;
	return (scelta-1);
}

Questo è il mio punto di partenza. Se qualcuno ha suggerimenti sia su come sviluppare sia su come poter continuare questo progetto mi sarebbe di grande aiuto. Ringrazio anticipatamente tutti.

33 Risposte

  • Re: Scrivere una briscola in C++

    Non c'è nulla di C++ in quel programma, è essenzialmente C "schietto".

    A parte questo, cosa ti turba particolarmente?
  • Re: Scrivere una briscola in C++

    Grazie per la risposta, la cosa che maggiormente mi turba è proprio il non riuscire ad andare avanti col progetto.
    Non so come stabilire chi vince la mano e assegnare i punti al giocatore vincitore della mano.. ho provato a stabilire un criterio per stabilire se a prendere è il primo giocatore, ma non funziona.. allego il codice:
    
    bool primaMaggiore () {
    
    	char seme1, seme2, br;												//Variabili seme 
    	br = briscola.seme;	
    	int punti1, punti2, valore1, valore2 ;										//Punti prima e seconda carta
    	bool semeUguale, briscolaSeme1, briscolaSeme2;
    	bool carta1Maggiore, carta2Maggiore;
    	
    	valore1 = terra[0].valore; 													//Valore prima carta sul tavolo
    	valore2 = terra[1].valore;													//Valore seconda carta sul tavoo
    	seme1 = terra[0].seme;														//Seme pima carta sul tavolo
    	seme2 = terra[1].seme;														//Seme seconda carta sul tavolo
    	punti1 = terra[0].punti; 													//Punti prima carta
    	punti2 = terra[1].punti;        											//Punti seconda carta
    	
    	
    	semeUguale = (seme1 == seme2);
    	carta1Maggiore = ((punti1 > punti2) || (punti1==punti2 && valore1 > valore2));
    	carta2Maggiore = ((punti1 < punti2) || (punti1==punti2 && valore1 < valore2));
    	briscolaSeme1 = (seme1 == br);
    	briscolaSeme2 = (seme2 == br);
    	
    	if ((semeUguale && carta1Maggiore) || (!semeUguale && !briscolaSeme2))
    			return (carta1Maggiore);
    }
    
    presa(int U, int C){
    	
    	bool carta1Maggiore;
    	
    if (primoGiocatore == true) { 													//True = Umano
    		
    		if (primaMaggiore){          //carta1maggiore
    			puntiGiocatore = puntiGiocatore + (terra[0].punti) + (terra[1].punti);
    			
    			manoGiocatore[U].seme = mazzo[x].seme;
    			manoGiocatore[U].punti = mazzo[x].punti;
    			manoGiocatore[U].valore = mazzo[x].valore;
    			x++;
    			cout<<endl<<"Prende l'umano. "<<"I suoi punti sono: "<<puntiGiocatore<<endl;
    						cout<<"-------------------------------------------"<<endl;	
    			} 
    		else {
    			puntiPc = puntiPc + terra[0].punti + terra[1].punti;
    			
    			manoPC[C].seme = mazzo[x].seme;
    			manoPC[C].punti = mazzo[x].punti;
    			manoPC[C].valore = mazzo[x].valore;
    			x++;
    			
    			cout<<endl<<"Prende il calcolatore "<<"I suoi punti sono: "<<puntiPc<<endl;
    						cout<<"-------------------------------------------"<<endl;	
    			} 
    }
    if(primoGiocatore == false) {													//False = Calcolatore
    	
    		if (primaMaggiore){
    			puntiPc = puntiPc + terra[0].punti + terra[1].punti;
    			
    			manoPC [C].seme = mazzo[x].seme;
    			manoPC [C].punti = mazzo[x].punti;
    			manoPC [C].valore = mazzo[x].valore;
    			x++;
    			
    			cout<<endl<<"Prende il calcolatore "<<"I suoi punti sono: "<<puntiPc<<endl;
    						cout<<"-------------------------------------------"<<endl;		
    			}
    		else{
    			puntiGiocatore = puntiGiocatore + terra[0].punti + terra[1].punti;
    			
    			manoGiocatore[U].seme = mazzo[x].seme;
    			manoGiocatore[U].punti = mazzo[x].punti;
    			manoGiocatore[U].valore = mazzo[x].valore;
    			x++;
    			
    			cout<<endl<<"Prende l'umano. "<<"I suoi punti sono: "<<puntiGiocatore<<endl;
    						cout<<"-------------------------------------------"<<endl;	
    			}
    }
    } //fine funzione presa
    
  • Re: Scrivere una briscola in C++

    Non conosco la briscola, sapresti generalizzare le fasi di gioco e dire su quali di esse trovi difficoltà?

    Ho notato che il codice risulta un po' ridondante a causa del fatto che consideri separatamente i casi in cui il giocatore di turno sia l'utente o il PC. La soluzione potrebbe essere quella di prevedere una struct "giocatore" ed utilizzare un puntatore a "giocatore".

    Nella funzione carteMazzo() credo ci sia qualcosa che non va nell'inizializzazione della variabile seme.
  • Re: Scrivere una briscola in C++

    Grazie per la risposta, allora:
    Non conosco la briscola, sapresti generalizzare le fasi di gioco e dire su quali di esse trovi difficoltà?
    1 - Si mescola il mazzo e si distribuiscono 3 carte a giocatore
    2 - Si prende l'ultima carta dal mazzo e la si considera come briscola
    3 - Il primo giocatore gioca una carta arbitraria (solitamente evitando la briscola per conservarla)
    4 - L'altro giocatore gioca una carta in base al criterio di presa (Punti maggiori, valore della carta ed eventuale briscola)
    5 - Dopo che uno dei due giocatori vince la mano si prende un'altra carta a testa dal mazzo e si ripete il gioco fino ad esaurimento delle carte.
    6 - Vince chi alla fine ha il numero maggiore di punti
    Ho notato che il codice risulta un po' ridondante a causa del fatto che consideri separatamente i casi in cui il giocatore di turno sia l'utente o il PC. La soluzione potrebbe essere quella di prevedere una struct "giocatore" ed utilizzare un puntatore a "giocatore".
    I puntatori non sono nel programma del corso e non posso usarli..
  • Re: Scrivere una briscola in C++

    Più o meno ho capito come si articola il gioco.

    - innanzitutto ti consiglio di scrivere il codice in modo più ordinato, in questo modo risulterà anche per me più facile da leggere. Intendo qualcosa del genere:
    #include<iostream>
    #include<windows.h>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<iomanip>
    
    using namespace std;
    
    struct carte
    {
       int valore;
       int punti;
       char seme;
    };
    
    carte briscola;
    carte mazzo[40];
    carte terra[2];
    carte manoPC[3];
    carte manoGiocatore[3];
    carte presaPC[40];
    carte presaG[40];
    
    int puntiPc;
    int puntiGiocatore;
    bool mazzierePc;
    bool primoGiocatore;
    bool primaUmano;
    bool prendeGiocatore;
    bool prendePc;
    int x = 6;
    
    void carteMazzo()
    {
        for(int i = 0; i < 40; i++)
        {
            mazzo[i].valore = i % 10 + 1;
            int seme = i / 10 + 1;
            switch(seme)
            {
                case 0: mazzo[i].seme = 'D';
                break;
                case 1: mazzo[i].seme = 'B';
                break;
                case 2: mazzo[i].seme = 'C';
                break;
                case 3: mazzo[i].seme = 'S';
                break;
            }
        }
    }
    
    void mescolaMazzo()
    {
        int i, j;
        srand(time(0));
        for(i = 0; i < 40; i++)
        {
            mazzo[i];
        }
        for(i = 0; i < 40; i++)
        {
            j = rand() % 40 + 1;
            carte seme = mazzo[i];
            mazzo[i] = mazzo[j];
            mazzo[j] = seme;
        }
    }
    
    void mostraBriscola()
    {
        briscola.valore = mazzo[39].valore;
        briscola.seme = mazzo[39].seme;
        cout << endl << "La briscola e' : " << briscola.valore << " di " << briscola.seme << endl;
    }
    
    int punteggio()
    {
        carteMazzo();
        int p;
        int valore;
        for(int i = 0; i < 40; i++)
        {
            valore = mazzo[i].valore;
            switch(valore)
            {
                case 1 : mazzo[i].punti = 11;
                break;
                case 2 : mazzo[i].punti = 0;
                break;
                case 3 : mazzo[i].punti = 10;
                break;
                case 10 : mazzo[i].punti = 4;
                break;
                case 9 : mazzo[i].punti = 3;
                break;
                case 8 : mazzo[i].punti = 2;
                break;
                case 7 : mazzo[i].punti = 0;
                break;
                case 6 : mazzo[i].punti = 0;
                break;
                case 5 : mazzo[i].punti = 0;
                break;
                case 4 : mazzo[i].punti = 0;
                break;
                default : mazzo[i].punti = 0;
            }
        }
        return(p);
    }
    
    bool inizioPartita()
    {
        bool primoGiocatore;
        srand(time(NULL));
        primoGiocatore = rand() % 2;
        cout << endl << endl << primoGiocatore << endl << endl;
        if(primoGiocatore == true)
        {
            cout << "Inizia la partita l'umano'\n";
        }
        else
        {
            cout << "Inizia la partita il calcolatore\n";
        }
        return primoGiocatore;
    }
    
    void distribuireCarte()
    {
        if(mazzierePc)
        {
            for(int i = 0; i < 3; i++)
            {
                manoGiocatore[i] = mazzo[i * 2];
                manoPC[i] = mazzo[i * 2 + 1];
            }
        }
        else
        {
            for(int i = 0; i < 3; i++)
            {
                manoGiocatore[i] = mazzo[i * 2 + 1];
                manoPC[i] = mazzo[i * 2];
            }
        }
    }
    
    int scegliCarta()
    {
        int scelta;
        for(int j = 0; j < 3; j++)
        {
            cout << j + 1 << setw(5) << manoGiocatore[j].valore << " di " << manoGiocatore[j].seme << endl;
        }
        cout << "Quale carta desideri giocare? \n";
        cin >> scelta;
        if(primoGiocatore)
        {
            terra[0].valore = manoGiocatore[scelta - 1].valore;
            terra[0].seme = manoGiocatore[scelta - 1].seme;
            terra[0].punti = manoGiocatore[scelta - 1].punti;
        }
        else
        {
            terra[1].valore = manoGiocatore[scelta - 1].valore;
            terra[1].seme = manoGiocatore[scelta - 1].seme;
            terra[1].punti = manoGiocatore[scelta - 1].punti;
        }
        cout << "Hai tirato" << manoGiocatore[scelta - 1].valore << manoGiocatore[scelta - 1].seme;
        return(scelta - 1);
    }
    
    bool primaMaggiore()
    {
        char seme1, seme2, br;
        br = briscola.seme;
        int punti1, punti2, valore1, valore2 ;
        bool semeUguale, briscolaSeme1, briscolaSeme2;
        bool carta1Maggiore, carta2Maggiore;
        valore1 = terra[0].valore;
        valore2 = terra[1].valore;
        seme1 = terra[0].seme;
        seme2 = terra[1].seme;
        punti1 = terra[0].punti;
        punti2 = terra[1].punti;
        semeUguale = (seme1 == seme2);
        carta1Maggiore = ((punti1 > punti2) || (punti1==punti2 && valore1 > valore2));
        carta2Maggiore = ((punti1 < punti2) || (punti1==punti2 && valore1 < valore2));
        briscolaSeme1 = (seme1 == br);
        briscolaSeme2 = (seme2 == br);
        if((semeUguale && carta1Maggiore) || (!semeUguale && !briscolaSeme2))
        {
            return(carta1Maggiore);
        }
    }
    
    void presa(int U, int C)
    {
        bool carta1Maggiore;
        if(primoGiocatore == true)
        {
            if(primaMaggiore)
            {
                puntiGiocatore = puntiGiocatore + (terra[0].punti) + (terra[1].punti);
                manoGiocatore[U].seme = mazzo[x].seme;
                manoGiocatore[U].punti = mazzo[x].punti;
                manoGiocatore[U].valore = mazzo[x].valore;
                x++;
                cout << endl << "Prende l'umano. " << "I suoi punti sono: " << puntiGiocatore << endl;
                cout << "-------------------------------------------" << endl;
            }
            else
            {
                puntiPc = puntiPc + terra[0].punti + terra[1].punti;
                manoPC[C].seme = mazzo[x].seme;
                manoPC[C].punti = mazzo[x].punti;
                manoPC[C].valore = mazzo[x].valore;
                x++;
                cout << endl << "Prende il calcolatore " << "I suoi punti sono: " << puntiPc << endl;
                cout << "-------------------------------------------" << endl;
            }
        }
        if(primoGiocatore == false)
        {
            if(primaMaggiore)
            {
                puntiPc = puntiPc + terra[0].punti + terra[1].punti;
                manoPC [C].seme = mazzo[x].seme;
                manoPC [C].punti = mazzo[x].punti;
                manoPC [C].valore = mazzo[x].valore;
                x++;
                cout << endl << "Prende il calcolatore " << "I suoi punti sono: " << puntiPc << endl;
                cout << "-------------------------------------------" << endl;
            }
            else
            {
                puntiGiocatore = puntiGiocatore + terra[0].punti + terra[1].punti;
                manoGiocatore[U].seme = mazzo[x].seme;
                manoGiocatore[U].punti = mazzo[x].punti;
                manoGiocatore[U].valore = mazzo[x].valore;
                x++;
                cout << endl << "Prende l'umano. " << "I suoi punti sono: " << puntiGiocatore << endl;
                cout << "-------------------------------------------" << endl;
            }
        }
    }
    
    int main()
    {
    
    }
    - le librerie cmath, windows.h e cstdlib non servono;
    - analizziamo una funzione alla volta. Partiamo da carteMazzo() (a cui darei un nome più significativo, tipo prepara_mazzo()). Se poni seme=i/10+1, poichè i varia tra 0 e 39, la variabile seme varierà tra 1 e 4, mentre i casi dello switch comprendono 0, 1, 2 e 3;
    - nello switch presente nella funzione punteggio() non sfrutti bene il caso default. Se ci ragioni ti renderai conto che escluso il default bastano solo 5 casi;
    - perchè creare una funzione punteggio() se non la usi? Perchè tale funzione dovrebbe ritornare un intero, se si limita a riempire il campo valore? Inoltre il valore di ritorno assume un valore pseudocasuale dal momento che alla variabile p non viene assegnato nessun valore. In ogni caso il mio consiglio è quello di accorpare la funzione punteggio() nella funzione carteMazzo();
    - la funzione srand() va chiamata una sola volta, quindi fallo all'inizio del main;
    - veniamo alla funzione mescolaMazzo()... a cosa serve il seguente frammento di codice?
    for(i = 0; i < 40; i++)
        {
            mazzo[i];
        }
    j assumerà valori che vanno da 1 a 40, ma gli indici delle carte nel mazzo vanno da 0 a 39.
    *** L'algoritmo da te utilizzato per mescolare il mazzo non è il massimo dal punto di vista probabilistico, in quanto non tutte le possibili configurazioni del mazzo avranno la stessa probabilità di realizzarsi. Un modo per ottenere una configurazione del mazzo davvero casuale potrebbe essere il seguente:
    - selezioniamo una carta a caso dal mazzo di 40 carte (che chiameremo mazzo_1) e la mettiamo da parte come per formare un nuovo mazzo (che chiameremo mazzo_2);
    - selezioniamo una carta a caso tra le 39 carte restanti nel mazzo_1 e la mettiamo in cima al mazzo_2;
    - selezioniamo una carta a caso tra le 38 carte restanti nel mazzo_1 e la mettiamo in cima al mazzo_2;
    - proseguiremo in questo modo finché nel mazzo_1 resterà una sola carta.
    Prova ad implementare un algoritmo che segua il suddetto esempio "pratico".

    Inizia ad apportare i suddetti aggiustamenti, poi ci dedicheremo alle altre funzioni e al modo in cui strutturare la partita.

    EDIT:
    ***
  • Re: Scrivere una briscola in C++

    Grazie mille per l'accurata risposta, ho provato ad apportare le correzioni suggerite, spero di averlo fatto al meglio. Allego il codice completo (nel frattempo ho cercato di aggiungere altro)
    #include<iostream>
    #include<windows.h> 						//Contiene alcune utili librerie
    #include<cstdlib>							//Contiene il prototipo della funzione srand
    #include<ctime>								//Contiene il prototipo della funzione time
    #include<iomanip>							//Contiene il prototipo della funzione setw
    
    using namespace std;
    
    
    struct carte {									//Definisce la struttura delle carte
    	int valore;
    	int punti;
    	char seme;
    };
    
    carte briscola;
    carte mazzo [40];						//Il mazzo è composto da 40 carte
    carte terra [2];						//Sul 'tavolo' sono presenti 2 carte
    carte manoPC [3];						//Il computer ha 3 carte in 'mano'
    carte manoGiocatore [3];				//Il giocatore  ha 3 carte in 'mano'
    carte presaPC [40];						//Numero massimo di carte del PC
    carte presaG [40]; 			  			//Numero massimo di carte del giocatore
    
    int puntiPc;						    //Punti di partenza del PC
    int puntiGiocatore;						//Punti di partenza del giocatore
    bool mazzierePc;						//Il computer è il mazziere
    bool primoGiocatore;					//Serve a stabilire il turno del giocatore umano
    bool primaUmano;
    bool prendeGiocatore;
    bool prendePc;
    int x = 6;
    
    
    void titolo (){                                 //Contiene il titolo del gioco
    	cout<<endl;
    	cout<<"_______________________________________________________________________________        \n"
    	      "                                                                                       \n"
    	      "   ######     ######    #   #####   #######   ########    #           ####             \n"
    	      "   #     #    #     #   #  #        #         #      #    #          #    #            \n"
    		  "   #    #     #     #   #  #        #         #      #    #         #      #           \n"
    		  "   # # #      # # #     #  ####     #         #      #    #        ##########          \n"
    		  "   #    #     # #       #       #   #         #      #    #        #        #          \n"
    		  "   #     #    #   #     #       #   #         #      #    #        #        #          \n"
    		  "   #####      #    #    #  ######   #######   ########    #######  #        #          \n"
    		  "_______________________________________________________________________________        \n";	  
    	cout<<endl;
    }
    
    void regole (){   								//Contiene le regole del gioco
    
    int continuare;
    
    	    cout<<endl<<"Si gioca con un mazzo di 40 carte diviso in 4 semi di 10 carte ciascuno.\n" 
    		"I punti in totale sono 120 e vince chi ne realizza almeno 61. Se i punti sono 60 il gioco e' pari.\n"
    		"Sono date 3 carte per giocatore, la prima del mazzo viene posta scoperta sul tavolo e rappresenta la briscola.\n"
    		"Partendo dal giocatore a destra del mazziere a seguire, ogni giocatore giocherà la carta \nche riterrà più opportuna per aggiudicarsi la mano\n"
    		"Per aggiudicarsi la mano :\n"
    		"- il primo giocatore di mano determina il seme di mano o dominante\n"
    		"- la mano viene aggiudicata dal giocatore che posa una carta del seme di mano, ma con valore di presa maggiore, \n"  
    		"  oppure giocando una qualsiasi carta del seme di briscola, anche con valore di presa inferiore.\n"
    		<<endl<< 																	//serve per andare e capo o lasciare uno spazio vuoto.
    		"---------- PUNTI ----------\n"
    		"Asso    = 11\nTre     = 10\nRe       = 4\nCavallo  = 3\nDonna    = 2\n2,4,5,6,7 valgolo 0 punti\n"
    		"---------------------------\n";
    		
    		cout<<endl;
    		cout<<"Premere 1 per continuare il gioco..";
    		cin>>continuare;
    		if (continuare == 1) {
    			system ("CLS"); 															//Pulisce lo schermo 
    		}
    }
    
    void intestazione () {							//Intestazione del gioco 
    
    	system("color 2F");														//Cambia il colore di sfondo da nero a verde. 
    	SetConsoleTitleA("-------- Briscola --------");							//Cambia titolo alla console. 	
    	int scelta;
    	
        titolo();
    	
    	cout<<"\nPremere 1 per leggere le regole del gioco o 2 per giocare: ";
    	cin>>scelta;
    	if (scelta == 1){
    			regole();
    	}
    	
    }
    
    void preparaMazzo () {																	//Rappresenta le carte del mazzo
    	
    	/* Il mazzo è un array di 40 elementi. Esso viene diviso in gruppi di 10
    	calcolando il resto della divisione per 10. Si aggiunge 1 al risultato perchè
    	l'array comprende 40 valori da 0 a 39.  Il valore risultante corrisponde al VALORE.
    	Il seme della carta viene definito usando l'intervallo di valori 0-9 per denari,
    	10-19 per bastoni 20-29 per coppe e 30-39 per spade.*/
    			
    	for (int i=0; i<40; i++){
    		mazzo[i].valore = i%10+1;	
    						
    	int seme = i/10;	
    								
    		switch (seme) 
    	{
    		case 0 : mazzo[i].seme = 'D';				//Denari
    				break;
    		case 1 : mazzo[i].seme = 'B';				//Bastoni
    				break;
    		case 2 : mazzo[i].seme = 'C';				//Coppe
    				break;
    		case 3 : mazzo[i].seme = 'S';				//Spade
    				break;
    	}
    	
    	int valore = mazzo[i].valore; 					//Stabilisce il punteggio associato ad ogni carta
     	  
    		switch (valore)
    	 {
    	 	case 1 : mazzo[i].punti = 11;
    	 		break;
    	 	case 3 : mazzo[i].punti = 10;
    	 		break;
    	 	case 10 : mazzo[i].punti = 4;
    	 		break;
    	 	case 9 : mazzo[i].punti = 3;
    	 		break;
    	 	case 8 : mazzo[i].punti=2;
    	 		break;
    	 	default : mazzo[i].punti = 0;
    	 }
    	
    	}
    }
    
    void mescolaMazzo() {															//Mescola il mazzo di carte
    	
    	/* Questa funzione ha restituire un vettore che rappresenta un mazzo di carte mescolato. 
       La corrispondenza che associa ciascun numero intero tra 0 e 39 a ogni singola carta del mazzo 
       e' descritta nella funzione 'carteMazzo*/
       
      	int i, j;
        srand( time(0) ); 										 //Randomizziamo i numeri
    
      	for(i=0; i<40; i++)
    	{
      		mazzo[i];											//generiamo un mazzo ordinato come appena tolto dalla scatola
    	}											
      	
    	for(i=0; i<40; i++){
        j = rand()%40 + 1 ;										//generiamo un numero casuale di partenza
        
        carte seme = mazzo[i];									// Scambiamo la i-esima carta con la j-esima
        mazzo[i] = mazzo[j];
        mazzo[j] = seme;
      }
    
    }
    
    void mostraBriscola () {														//Mostra la briscola 
    	briscola.valore = mazzo[39].valore;											//Seleziona la carta in cima al mazzo
    	briscola.seme = mazzo[39].seme;
    	cout<<endl<<"La briscola e' : "<<briscola.valore<<" di "<<briscola.seme<<endl;
    }
    
    
    bool inizioPartita () {																//Seleziona chi inizia il gioco
    
    	bool primoGiocatore;
    	srand(time(NULL));																//Randomizzazione numeri casuali
    	primoGiocatore = rand()%2;	
    	
    	if (primoGiocatore == true)														     //Se esce 1 inizia l'umano
    		cout<<"Inizia la partita l'umano'\n";
    	else 
    		cout<<"Inizia la partita il calcolatore\n";										//Se esce 0 inizia il calcolatore
    
    return primoGiocatore;
    
    }
    
    void distribuireCarte() {         				 								// Funzione per dare le carte ai giocatori
    
        if (mazzierePc) {
            for (int i=0; i<3; i++){           										//utilizzo del for per variare in numero di carte preso nella prima mano.
            manoGiocatore[i] = mazzo[i*2];   										// caso in cui le carte vengono date prima all'utente e poi all'avversario.
            manoPC[i] = mazzo[i*2+1];
            } 
        }
    		else {
            for (int i=0; i<3; i++)
            {   manoGiocatore[i] = mazzo[i*2+1]; 									// caso in cui le carte vengono date prima all'avversario e poi all'utente.
                manoPC[i] = mazzo[i*2];
          }
      }
    
    }
    
    int scegliCarta () {															//Permette all'utente di scegliere la carta da giocare
    	/*La scelta della carta avviene tramite un costrutto if..else che permette
    	di stabilire la posizione della carta sul tavolo (primo o secondo turno).
    	Dopo che si sceglie la carta da giocare viene prelevata la carta corrispondente
    	nell'array manoGiocatore. */
    	
    	int scelta;
    	for (int j=0; j<3; j++){
    		cout<<j+1<<setw(5)<<manoGiocatore[j].valore<<" di "<<manoGiocatore[j].seme<<endl;
    	}
    	cout<<"Quale carta desideri giocare? \n";
    	cin>>scelta;
    	
    	if (primoGiocatore == true) 
    	{
    		terra[0].valore = manoGiocatore[scelta-1].valore;
    		terra[0].seme=manoGiocatore[scelta-1].seme; 
    		terra[0].punti=manoGiocatore[scelta-1].punti;
    	} 
    	else 
    	{
    		terra[1].valore=manoGiocatore[scelta-1].valore;
    		terra[1].seme=manoGiocatore[scelta-1].seme;
    		terra[1].punti=manoGiocatore[scelta-1].punti;
    	}
    	
    	cout<<"Hai tirato"<<manoGiocatore[scelta-1].valore<<manoGiocatore[scelta-1].seme;
    	return (scelta-1);
    }
    
    int PcGiocaPrimo (){															//Caso in cui il calcolatore lanci per primo
    	
    	for (int i=0; i<3; i++)
    	{
    		if ((manoPC[i].seme != briscola.seme ))
    		{
    			terra[0].seme = manoPC[i].seme;
    			terra[0].valore = i;
    				
    		}
    	}
    	
    	int m;
    	srand(time(NULL));
    	m = rand()%3;
    	
    	cout<<"L'avversario ha lanciato la carta "<<manoPC[m].valore<<manoPC[m].seme<<endl;;
    	return m;  
    }
    
    int PcGiocaSecondo (){													     	//Il calcolatore decide la carta da giocare se è il secondo a tirare
    	
    	if (terra[0].seme != briscola.seme){ 												//Seme briscola diverso dal seme a terra
    		for (int i=0; i<3; i++)
    		{
    			if ((terra[0].seme == manoPC[i].seme) && (manoPC[i].punti >= 2) && (manoPC[0].punti > terra[0].punti))
    			terra[1].seme = manoPC[i].seme;
    			terra[1].valore=i;
    		}
    	}
    	if ((terra[0].punti == 10) || (terra[0].punti == 11))								//A terra asso o 3
    	    {
    		for (int i=0; i<3; i++){
    			if ((terra[0].seme == manoPC[i].seme) && (manoPC[i].punti > terra[0].punti)){
    			terra[1].punti = manoPC[i].punti;
    			terra[1].valore = i; 
    			} //fine if
    			
    		} 
    	}
    				
    	for (int i=0; i<3; i++)														//Punteggio in mano minore di quello a terra
    		{
    		if (manoPC[i].punti < terra[0].punti);
    		terra[1].punti = manoPC[i].punti;
            terra[1].valore = i;	
    		}
    	
    	{ for (int i=0;i<3;i++)
          { 
    	  if (manoPC[i].valore < terra[0].valore)  											//Valore carte in mano più basso di quello a terra
            {  terra[1].valore= manoPC[i].valore;
               terra[1].valore=i;
            }
          }                                     
        }       
    	
    	int m;
    	srand(time(NULL));
    	m = rand()%3;
    	
    	cout<<"L'avversario ha lanciato la carta "<<manoPC[m].valore<<manoPC[m].seme<<endl;
    	return m;   
    }
    
    bool primaMaggiore () {
    
    	char seme1, seme2, br;												//Variabili seme 
    	br = briscola.seme;	
    	int punti1, punti2, valore1, valore2 ;										//Punti prima e seconda carta
    	bool semeUguale, briscolaSeme1, briscolaSeme2;
    	bool carta1Maggiore, carta2Maggiore;
    	
    	valore1 = terra[0].valore; 													//Valore prima carta sul tavolo
    	valore2 = terra[1].valore;													//Valore seconda carta sul tavoo
    	seme1 = terra[0].seme;														//Seme pima carta sul tavolo
    	seme2 = terra[1].seme;														//Seme seconda carta sul tavolo
    	punti1 = terra[0].punti; 													//Punti prima carta
    	punti2 = terra[1].punti;        											//Punti seconda carta
    	
    	
    	semeUguale = (seme1 == seme2);
    	carta1Maggiore = ((punti1 > punti2) || (punti1==punti2 && valore1 > valore2));
    	carta2Maggiore = ((punti1 < punti2) || (punti1==punti2 && valore1 < valore2));
    	briscolaSeme1 = (seme1 == br);
    	briscolaSeme2 = (seme2 == br);
    	
    	if ((semeUguale && carta1Maggiore) || (!semeUguale && !briscolaSeme2))
    			return (carta1Maggiore);
    }
    
    presa(int U, int C){
    	
    	bool carta1Maggiore;
    	
    if (primoGiocatore == true) { 													//True = Umano
    		
    		if (primaMaggiore){          //carta1maggiore
    			puntiGiocatore = puntiGiocatore + (terra[0].punti) + (terra[1].punti);
    			
    			manoGiocatore[U].seme = mazzo[x].seme;
    			manoGiocatore[U].punti = mazzo[x].punti;
    			manoGiocatore[U].valore = mazzo[x].valore;
    			x++;
    			cout<<endl<<"Prende l'umano. "<<"I suoi punti sono: "<<puntiGiocatore<<endl;
    						cout<<"-------------------------------------------"<<endl;	
    			} 
    		else {
    			puntiPc = puntiPc + terra[0].punti + terra[1].punti;
    			
    			manoPC[C].seme = mazzo[x].seme;
    			manoPC[C].punti = mazzo[x].punti;
    			manoPC[C].valore = mazzo[x].valore;
    			x++;
    			
    			cout<<endl<<"Prende il calcolatore "<<"I suoi punti sono: "<<puntiPc<<endl;
    						cout<<"-------------------------------------------"<<endl;	
    			} 
    }
    if(primoGiocatore == false) {													//False = Calcolatore
    	
    		if (primaMaggiore){
    			puntiPc = puntiPc + terra[0].punti + terra[1].punti;
    			
    			manoPC [C].seme = mazzo[x].seme;
    			manoPC [C].punti = mazzo[x].punti;
    			manoPC [C].valore = mazzo[x].valore;
    			x++;
    			
    			cout<<endl<<"Prende il calcolatore "<<"I suoi punti sono: "<<puntiPc<<endl;
    						cout<<"-------------------------------------------"<<endl;		
    			}
    		else{
    			puntiGiocatore = puntiGiocatore + terra[0].punti + terra[1].punti;
    			
    			manoGiocatore[U].seme = mazzo[x].seme;
    			manoGiocatore[U].punti = mazzo[x].punti;
    			manoGiocatore[U].valore = mazzo[x].valore;
    			x++;
    			
    			cout<<endl<<"Prende l'umano. "<<"I suoi punti sono: "<<puntiGiocatore<<endl;
    						cout<<"-------------------------------------------"<<endl;	
    			}
    }
    } //fine funzione presa
    
    mano () { 																			//DA RIVEDERE 
       	int Um; //umano
    	int pC; //calcolatore
        if (primoGiocatore == true) {
            Um = scegliCarta();
            pC = PcGiocaSecondo();
        }
         if (primoGiocatore == false) {
            pC = PcGiocaPrimo();
            Um = scegliCarta();
        }
             presa(Um,pC);
    }
    
    void partita(){
    	
    		distribuireCarte();
     	 for (int i=0; i<20; i++){
     	 	mano();
     	  }
    }
    
    int main () {
    	
    	intestazione();
    	
    	inizioPartita();
    	
    	preparaMazzo();
    	
    	mescolaMazzo();
    
    	mostraBriscola();
    	
    	
    	
    	partita();
    	    
    	
    
    	return 0; //denota una corretta terminazione del programma
    }
    - veniamo alla funzione mescolaMazzo()... a cosa serve il seguente frammento di codice?
    for(i = 0; i < 40; i++)
        {
            mazzo[i];
        }
    Questo frammento di codice dovrebbe rappresentare un mazzo ordinato, l'ho inserito come punto di partenza per mescolare le carte.

    Ho provato ad implementare l'algoritmo suggerito, ma non sono riuscito ad affrontare il problema.
  • Re: Scrivere una briscola in C++

    Grazie mille per l'accurata risposta, ho provato ad apportare le correzioni suggerite, spero di averlo fatto al meglio.
    La funzione preparaMazzo() adesso va bene (le variabili seme e valore possono essere evitate).
    Questo frammento di codice dovrebbe rappresentare un mazzo ordinato, l'ho inserito come punto di partenza per mescolare le carte.
    In realtà quella parte di codice non fa niente... è come scrivere
    int a = 2;
    for(unsigned int i = 0; i < 10; ++i)
    {
        a;
    }
    Inoltre se richiami la funzione mescolaMazzo() dopo preparaMazzo(), l'array mazzo sarà già costituito da "un mazzo ordinato come appena tolto dalla scatola".
    Ho provato ad implementare l'algoritmo suggerito, ma non sono riuscito ad affrontare il problema.
    Il metodo che ho descritto nel post precedente può essere applicato nel seguente modo:
    - scambiare l'elemento di indice 0 con quello di indice casuale compreso tra 0 e 39;
    - scambiare l'elemento di indice 1 con quello di indice casuale compreso tra 1 e 39;
    - scambiare l'elemento di indice 2 con quello di indice casuale compreso tra 2 e 39;
    ...
    - scambiare l'elemento di indice 37 con quello di indice casuale compreso tra 37 e 39;
    - scambiare l'elemento di indice 38 con quello di indice casuale compreso tra 38 e 39.
    Allego il codice completo (nel frattempo ho cercato di aggiungere altro)
    Se domani ho tempo mi leggo il codice con calma e ti faccio sapere.
    In ogni caso hai provato il programma? Funziona tutto o c'è qualcosa che non va?
  • Re: Scrivere una briscola in C++

    Se domani ho tempo mi leggo il codice con calma e ti faccio sapere.
    Grazie!

    Oggi provo nuovamente a fare l'algoritmo per mescolare le carte.

    Si, ho provato il programma ma non funziona, viene eseguito senza errori ma :

    - Dopo aver selezionato chi inizia, anche se il promo giocatore è l'umano tira per primo il computer
    - La funzione di presa non funziona, anche se lancio una carta maggiore prende sempre il computer
    - Ad ogni mano non vengono mai aggiornate le mie carte e risultano sempre le stesse
    - Non mantiene il conteggio dei punti

    questi sono i problemi principali che sto avendo eseguendo il gioco.
  • Re: Scrivere una briscola in C++

    Ho provato a rifare l'algoritmo di mescolamento ma non sono riuscito a farlo funzionare, allego il codice:
    #include <iostream>
    #include <ctime>
    #include <cstdlib>
    using namespace std;
    
    int main () {
    	
    	unsigned srand(time(0));
    	
    	int mazzo [39];
    	int j;
    	int box;
    	
    	
    	for (int i=0; i<40; i++)
    	{
    		j = i + rand()%(40 - i);  
    					
    		box = mazzo[i];
    		mazzo[i] = mazzo[j];
    		mazzo [j] = box;
    	}
    //visualizzare il mazzo mescolato per verificare il mescolamento	
    	for (int i=0; i<40; i++) 
    	{
    		
    		cout << mazzo[i]<<endl;
    		
    	}
    	return 0;
    }
  • Re: Scrivere una briscola in C++

    Il mazzo è di 40 carte, non 39
    int mazzo [39]; è errata
    prova con int mazzo [40];
  • Re: Scrivere una briscola in C++

    Grazie per la risposta, egualmente non funziona.. quando vado a visualizzare il nuovo mazzo ottengo numeri che non rientrano nell'intervallo richiesto:

    Posto ciò che ottengo:

    0
    0
    1381184
    0
    0
    1
    143
    268501009
    -2129550298
    0
    0
    1380952
    0
    0
    0
    0
    0
    4254497
    0
    0
    -1844354035
    -1
    1
    0
    32763
    -1
    8
    0
    1
    0
    0
    0
    0
    40
    4253488
    4253589
    0
    4254521
    0
    4253488
  • Re: Scrivere una briscola in C++

    Non capisco la logica di j = i + rand()%(40 - i);
    Fare semplicemente j = rand()%40+1? Così ottieni sicuramente un numero da 1 a 40
  • Re: Scrivere una briscola in C++

    Sto cercando di applicare l'algoritmo suggerito da Nippolo, per questo motivo ho cercato di fare in quel modo..
  • Re: Scrivere una briscola in C++

    typedef ha scritto:


    Ho provato a rifare l'algoritmo di mescolamento ma non sono riuscito a farlo funzionare, allego il codice: ...
    - perché metti "unsigned" davanti alla chiamata della funzione srand()?
    - come detto da jfet il mazzo ha 40 carte;
    - nel primo for deve essere i<39, infatti per i=39 j può assumere il solo valore 39.
    Grazie per la risposta, egualmente non funziona.. quando vado a visualizzare il nuovo mazzo ottengo numeri che non rientrano nell'intervallo richiesto: ...
    Che valori assumono gli elementi dell'array mazzo prima del mescolamento?
    Non capisco la logica di j = i + rand()%(40 - i);
    Nei miei precedenti post è spiegato il perché.
Devi accedere o registrarti per scrivere nel forum
33 risposte