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.