Mescolare e distribuire le carte

di il
2 risposte

Mescolare e distribuire le carte

Salve a tutti,
mi sono imbattuto in un esercizio sui puntatori che mi sta procurando non pochi problemi. L'esercizio in questione è preso dal libro "Il linguaggio C" di Deitel, alla fine del capitolo 7, numero 7.12.
La traccia dell'esercizio chiede di modificare un programma già sviluppato dal libro come dimostrazione, che per l'appunto mescola e distribuisce le carte, e fare in modo che distribuisca solo 5 carte e determino se tra quelle cinque vi sia una coppia, una doppia coppia, un tris, un poker, un colore o una scala (non vedo perchè il full sia stato escluso e pertanto io ho voluto comunque inserirlo)
Buona parte del codice che sto per inserire è copiata riga per riga dal libro. Le uniche modifiche che ho apportato si trovano nella funzione "deal" e l'aggiunta della funzione "couple".
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define SUITS 4					//il numero di semi
#define FACES 13				//il numero di facce
#define CARDS 5 				// il numero di carte che voglio che distribuisca


/* run this program using the console pauser or add your own getch, system("pause") or input loop */

void shuffle(int wDeck[][FACES]);							// prototipo per mescolare le carte
void deal(int wDeck[][FACES], const char *wFace[], const char *wSuits[]);		// prototipo per distribuire le carte (5 in questo caso)
void couple(const char *wFace[]);												// prototipo per valutare la mano

int main(int argc, char *argv[]) {

	int deck[SUITS][FACES] = {0};							// inizializzo il vettore bidimensionale di 52 elementi a 0, ogni elemento verrà poi modificato in shuffle per definire in che ordine vadano distribuite
	
	srand(time(NULL));										// seme casuale
	shuffle(deck);											// passo il mazzo inizializzato a 0 alla funzione shuffle
	
	const char *suit[SUITS] = {"Cuori", "Quadri", "Fiori", "Picche"};						//dichiaro e inizializzo i vettori dei semi e delle facce				
	const char *face[FACES] = {"Asso", "Due", "Tre", "Quattro", "Cinque", "Sei",			//vettori di puntatori rispettivamente di 5 e 13 elementi
							   "Sette", "Otto", "Nove", "Dieci", "Jack", "Regina", "Re"};
	
	deal(deck, face, suit);									//passo il mazzo mescolato e i due vettori appena inizializzati alla funzione che distribuisce le carte
	
	return 0;
}


void shuffle(int wDeck[][FACES]){
	
	int card;						// questo contatore serve a definire l'ordinamento delle carte
	
	for(card=1; card<=CARDS; card++){	
		int row;						//inizializzo le righe 
		int column;						//inizializzo le colonne
		
		do{
			row = rand()%SUITS;					//assegno un valore casuale alle righe
			column = rand()%FACES;				//assegno un valore casuale alle colonne
		} while(wDeck[row][column] != 0);		//mi assicuro che quel particolare elemento del mazzo non sia già stato modificato 
		
		wDeck[row][column] = card;				//associo a quell'elemento il numero di carta che determina quando dovrà essere pescato
	}	
}


void deal(int wDeck[][FACES], const char *wFace[], const char *wSuit[]){
	
	int card;								//contatore per trovare la prima, la seconda, la terza carta e così via
	const char *handSuit[CARDS]={0};		//questi due vettori vorrei che mi servissero a "salvare" il valore del seme e
	const char *handFace[CARDS]={0};		//della faccia della carta pescata in modo tale che io possa valutarle anche uscito dal ciclo for
	int i=0;								//contatore per salvare il seme e la faccia della carta nel corretto elemento dei due vettori appena inizializzati
	
	for(card=1; card<=CARDS; card++){		//il ciclo for comincia a cercare la carta numero 1
		int row, column;					//contatori delle righe e delle colonne per scandire il vettore bidimensionale deck
		
		for(row=0; row<SUITS; row++){										//ciclo per spostarmi sulle 4 righe
			for(column=0; column<FACES; column++){							//ciclo per spostarmi sulle 13 colonne
				if(wDeck[row][column] == card){								//verifico che l'elemento [row][column] corrisponda al numero di carta cercato
					printf("%5s di %-8s%c\n", wFace[column], wSuit[row]);	//stampo la carta (es. Asso di Cuori)
					handSuit[i]=wSuit[row];									//salvo il seme della carta appena trovata nel vettore handSuit
					handFace[i]=wFace[column];								//salvo la faccia della carta appena trovata nel vettore handFace
					i++;					//incremento il contatore i in modo tale che quando verrà trovata la prossima carta i due vettori hand si trovino sull'elemento 1
				}							
			}								//io penso che ci sia un errore in questo punto dovuto ai due vettori e al contatore. Dopo averli inseriri infatti accanto alla carta
		}									// appena stampata appaiono dei simboli come la chiocciola o la cediglia (una c con una specie di coda sotto)
	}
	
	couple(handFace);
}

											//La seguente funzione dovrebbe almeno in parte valutare la mano trovando coppie, doppie coppie, tris, poker e full
void couple(const char *hFace[]){			//la funzione credo non venga nemmeno eseguita. 
	
	int i, j;						//i contatori i e j dovrebbero servire a confrontare la prima carta con le altre quattro e così via
	int counter;					//dovrebbe tener conto di quante carte uguali alla i-esima ci sono per determinare che mano si abbia
	int tris, coppia;				//questi due contatori dovrebbero invece permettere di capire se si ha una doppia coppia o un full
	
	counter=0;						//tutti e tre inizializzati a 0
	tris=0;
	coppia=0;
	
	for(i=0; i<CARDS; i++){				//il ciclo for comincia con i = 0 così da partire dalla prima carta della mano
		for(j=i+1; j<CARDS; j++){			//questo parte da j = i+1 perchè se i e j fossero uguali anche i valori della carta lo sarebbero e produrrebbe una coppia che invece non c'è
			if(j<i && hFace[i]==hFace[j]){		//la condizione si accerta che j sia più piccolo di i e che le due carte abbiano lo stesso valore
				counter++;				//in tal caso il contatore del numero di carte uguali viene incrementato
			}
		}
		
		switch (counter){		//lo switch si trova nel primo ciclo for. Serve a determinare coppie, tris e poker poichè considera un solo tipo di carta
			case '1':
				printf("Coppia di %-5s\n", hFace[i]);		//contatore è uguale a 1 significa che ha trovato una carta uguale 
				coppia++;
				break;
				
			case '2':
				printf("Tris di %-5s\n", hFace[i]);		//stesso discorso se trova due carte uguali
				tris++;
				break;
			
			case '3':
				printf("Poker di %-5s\n", hFace[i]);		//oppure tre carte uguali
				break;
			
		}
	}
										//a questo punto potrebbe aver trovato due carte uguali di una faccia e due o tre di un'altra
	if(tris==1 && coppia==1){					//l'istruzione if valuta se si sono verificate insieme una coppia e un tris
		printf("Full!");							//ed eventualmente stampa Full
	}
	if(coppia==2){								//qui invece valuta se il contatore delle coppie è diventato 2
		printf("Doppia coppia!");					//in tal caso stampa doppia coppia
	}
}

Ho cercato di essere il più dettagliato possibile nei commenti in modo tale che risulti evidente quello che stavo cercando di fare.
Come detto io ho cercato di implementare la funzione couple (non è il nome più azzeccato lo so) che ha come argomento un vettore di puntatori (infatti i vettori handSuit e handFace sono stati uguagliati nella funzione deal a wSuit e wFace, anche loro vettori di puntatori).
Il primo problema sorge infatti qui, se handSuit e l'altro vettore li dichiaro const char * va tutto bene e il programma viene eseguito senza errori però a rigor di logica il tentativo di assegnare dei valori diversi ai loro elementi dovrebbe fallire in quanto starei dichiarando un puntatore non costante a dati costanti. Allora ho provato anche a togliere const dalla dichiarazione di quei due vettori ma l'unica differenza è stata la comparsa di due warning proprio in corrispondenza di handSuit=wSuit[row]; e handFace=wFace[column] che riportano il seguente messaggio:

[Warning] assignment discards 'const' qualifier from pointer target type

Per disperazione ho rimesso const nelle dichiarazioni dei due vettori per farlo contento.
Non riesco proprio a capire perchè spuntino quei simboli accanto alle carte (ho pensato a qualche vettore non inizializzato ma gli unici due incriminati sono handSuit e handFace e sono stato attento ad inizializzarli) e perchè il programma termini lì.
Allego un'immagine del programma in esecuzione in modo da dare un'idea.
Questa ovviamente è solo il primo problema di questo esercizio in quanto non saprei come implementare la scala.
Sto usando dev-c++ in quanto durante l'esame sarà installato quello sul computer dell'università.
Se potete darmi dei consigli su come modificare le funzioni "deal" e "couple" da cui sicuramente derivano i miei problemi sarebbe già un ottimo inizio.
Vi ringrazio in anticipo per l'aiuto

Il seguente è il link dello screenshot (fun fact: è una scala ma lui non lo sa )


p.s. Lo stesso esercizio era già stato pubblicato in precedenza da un altro utente (a maggio) ma nessuna delle risposte mi ha aiutato e credo che neanche in quel caso fosse stato risolto.

2 Risposte

  • Re: Mescolare e distribuire le carte

    Per i strani simboli è abbastanza semplice: in deal il printf c'è un %c di troppo.

    In couple nel primo if non capisco a cosa servi la verifica della condizione j<i.
    Inoltre nel secondo for definisci j=i+1 e quindi la condizione precedente è sempre falsa.
  • Re: Mescolare e distribuire le carte

    SuperQWE ha scritto:


    Per i strani simboli è abbastanza semplice: in deal il printf c'è un %c di troppo.

    In couple nel primo if non capisco a cosa servi la verifica della condizione j<i.
    Inoltre nel secondo for definisci j=i+1 e quindi la condizione precedente è sempre falsa.
    Grazie per la risposta e scusami se ti rispondo solo ora, in quei giorni dovendo andare avanti per la preparazione dell'esame quell'esercizio l'ho un po' abbandonato dopo averlo rivisto un po' di volte senza risultati. Grazie lo stesso però, magari gli darò un'altra occhiata facendo attenzione alle cose che mi hai sottolineato in quanto ad oggi neanche io saprei dire perchè ho scritto determinate cose.
Devi accedere o registrarti per scrivere nel forum
2 risposte