View Full Version : Problema algoritmo per combinazioni poker
grollagrolla123
07-05-2009, 12:25
Ciao a tutti.
Probabilmente sarà un problema non difficile da risolvere ma mi sta mettendo in crisi e mi sta bloccando il progetto in C.
Dopo aver servito le 5 carte al giocatore ,le quali ognuna è una struttura con i campi valore e seme di tipo puntatore a array di caratteri,non riesco a trovare le varie combinazioni del gioco del poker. Avevo pensato ad una funzione che prende un array di Carte e due indici che scorrono l'array e trovano le occorrenze. Dopo aver risolto il problema che il confronto tra le carte non doveva avvenire nel caso i due indici fossero uguali, mi sono bloccato sul fatto che vengono controllate più volte le carte con le combinazioni.
l'array a[1 2 5 10 2]
conterà che 2 c'è 2 volte invece di una sola
mentre a[1 2 4 2 2]
conterà che il 2 c'è 6 volte!
avevo pensato di mettere su un array di interi la posizione delle carte già contate, ma si complica l'algoritmo con cicli annidati ripetutamente.
vi ringrazio per la risposta in anticipo.
Ciao a tutti.
Probabilmente sarà un problema non difficile da risolvere ma mi sta mettendo in crisi e mi sta bloccando il progetto in C.
Dopo aver servito le 5 carte al giocatore ,le quali ognuna è una struttura con i campi valore e seme di tipo puntatore a array di caratteri,non riesco a trovare le varie combinazioni del gioco del poker. Avevo pensato ad una funzione che prende un array di Carte e due indici che scorrono l'array e trovano le occorrenze. Dopo aver risolto il problema che il confronto tra le carte non doveva avvenire nel caso i due indici fossero uguali, mi sono bloccato sul fatto che vengono controllate più volte le carte con le combinazioni.
l'array a[1 2 5 10 2]
conterà che 2 c'è 2 volte invece di una sola
mentre a[1 2 4 2 2]
conterà che il 2 c'è 6 volte!
avevo pensato di mettere su un array di interi la posizione delle carte già contate, ma si complica l'algoritmo con cicli annidati ripetutamente.
vi ringrazio per la risposta in anticipo.
Io non passerei dal constrollo delle combinazioni ma
Prednerei l'array delle carte e lo ordinerei secondo il valore
Passeri questo nuovo array ai filtri.
1. C'e' almeno una coppia?
2. C'e' almeno una doppia coppia?
3. C'e' almeno un tris?
4. C'e' almeno una scala?
5. C'e' almeno un full? (Ovvero c'e' almeno un tris e almeno una doppia coppia?)
6. C'e' almeno un colore?
Etc.
Partendo dal presupposto che l'array e' ordinato, tali risposte sono abbastanza semplici.
grollagrolla123
07-05-2009, 13:40
Giusta deduzione
L'unica cosa che il valore delle carte non è intero ma bensì è di tipo stringa.
struct carta{
char* seme;
char* valore;
};
Ordinarli per valore è molto più complesso trattandosi di carattari.
Anche aggiungendo un campo intero alla struttura si pottrebbe ordinarli per valore, ma non sono sicuro che sia la strada più giusta.
Giusta deduzione
L'unica cosa che il valore delle carte non è intero ma bensì è di tipo stringa.
struct carta{
char* seme;
char* valore;
};
Ordinarli per valore è molto più complesso trattandosi di carattari.
Anche aggiungendo un campo intero alla struttura si pottrebbe ordinarli per valore, ma non sono sicuro che sia la strada più giusta.
Ma puoi anche ordinarli per stringa, la complessita' delle funzioni di cui sopra non dovrebbe cambiare piu' di tanto.
Oppure puoi ordinarli per una funzione custom, che appunto convertira' il valore in intero e assegnera' 11,12,13,14 per fante, donna, re e asso, da usarsi solo per l'ordinamento e subito dimenticato dopo.
Aggiungere il valore alla struttura confermo che non e' cosa buona, meglio avere una funzione con qualche switch-case.
Al limite puoi tenerti una lookup di conversione da valore-->Numero. Una hashtable sarebbe meglio, anche se so gia' che in C e' un 3/4 di suicidio.
grollagrolla123
08-05-2009, 15:57
Grazie del suggerimento è stato molto utile.La funzione custom l'ho così implementata.
void custom (Card* w_mano){
char * astring[15]={"zero","uno","due","tre","quattro","cinque","sei","sette","otto","nove","dieci","jack","regina","re","asso"};
int a[15]={0};
int i=0;
int j=0;
int c=0;
printf("funzione custom\n");
for(;i<5;i++) for(j=0;j<=15;j++) if(w_mano[i].valore==astring[j]) a[j]+=1;
for(j=2;j<15;j++)printf("%s==%d\n",astring[j],a[j]);
printf("\n");
for(j=2;j<15;j++){
switch(a[j]){
case 2: printf("coppia di %s\n\n",astring[j]);c+=2;break;
case 3: printf("tris di %s\n\n",astring[j]);c+=3;break;
case 4: printf("poker di %s\n\n",astring[j]);break;
}
}
if(c==4)printf("doppia coppia\n");
if(c==5)printf("full\n");
}
Grazie del suggerimento è stato molto utile.La funzione custom l'ho così implementata.
void custom (Card* w_mano){
char * astring[15]={"zero","uno","due","tre","quattro","cinque","sei","sette","otto","nove","dieci","jack","regina","re","asso"};
int a[15]={0};
int i=0;
int j=0;
int c=0;
printf("funzione custom\n");
for(;i<5;i++) for(j=0;j<=15;j++) if(w_mano[i].valore==astring[j]) a[j]+=1;
for(j=2;j<15;j++)printf("%s==%d\n",astring[j],a[j]);
printf("\n");
for(j=2;j<15;j++){
switch(a[j]){
case 2: printf("coppia di %s\n\n",astring[j]);c+=2;break;
case 3: printf("tris di %s\n\n",astring[j]);c+=3;break;
case 4: printf("poker di %s\n\n",astring[j]);break;
}
}
if(c==4)printf("doppia coppia\n");
if(c==5)printf("full\n");
}
Ma in C per comparare stringhe non occorre usare strcmp (o simili)?
grollagrolla123
08-05-2009, 16:07
strcmp serve a confrontare la lunghezza della stringa con un'altra,restituisce un intero positivo se la prima è più lunga,zero se sono lunghe uguali e negativo se è più lunga la seconda
BrutPitt
08-05-2009, 16:34
Guarda che ha ragione gugoXX.
E' corretto cio' che hai detto tu, ma riguarda SOLO il valore di ritorno... strcmp compara, carattere per carattere le stringhe e restuituisce 0 in caso di ugiaglianza (e ovviamente lunghezza)... etc.
Con l'operatore "==" su i char *, controlli se sono uguali gli "indirizzi" in cui le stringhe sono allocate.
Se vuoi usare l'operatore "==" devi usare la classe string della STL.
grollagrolla123
08-05-2009, 17:02
come è possibile che a me ora funziona perfettamente??
if(w_mano[i].valore==astring[j]) a[j]+=1;
se fosse come dici tu gli elementi dell'array int a[] non verrebero mai incrementati perchè gl'indirizzi di memoria dove è allocato l'array di strutture non concide con l'array di puntatori a carattere char* astring[].
poi il compilatore sentenzia...
BrutPitt
08-05-2009, 17:14
Sicuro?
Prova ad azzerare correttamente gli elementi di a[]
Con una dichiarazione del tipo:
int a[15]={0};
Azzeri solo a[0]... e gli altri elemti hanno valori aleatori... insomma cio' che capita :)
Se vuoi azzerare TUTTI gli elementi di a[]... devi usare una dichiarazione del tipo:
int a[15]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
... o un ciclo di for
grollagrolla123
08-05-2009, 17:32
senti vedi Deitel & Deitel capitolo 6.
se uno inizializza un vettore con {0} assegnerà 0 al primo elemento ma in fase di compilazione AUTOMATICAMENTE assegnerà 0 a ogni elemento non inizializato
BrutPitt
08-05-2009, 17:44
opppsss... su questo hai ragione... e' vero... basta anche solo l'inizializzazione di un SOLO elemento... :)
Pensavo fosse una feature del C++, ma e' vero anche per il C.
In ogni caso... gia' che ci sei controlla anche strcmp.
||ElChE||88
08-05-2009, 17:45
if(w_mano[i].valore==astring[j]) a[j]+=1;
se fosse come dici tu gli elementi dell'array int a[] non verrebero mai incrementati perchè gl'indirizzi di memoria dove è allocato l'array di strutture non concide con l'array di puntatori a carattere char* astring[].
Probabilmente e' il compilatore che ottimizza salvando due stringhe uguali nella stessa posizione (tanto sono costanti).
E' comunque sbagliato usarlo in questo modo.
grollagrolla123
08-05-2009, 18:03
assolutamente no.
w_mano[2].valore="due";
astring[2]="due";
printf("w_mano[2].valore==%p astring[2]==%p\n",&w_mano[2].valore,&astring[2]);
l'indirizzo è assolutamente diverso.
uso dev-c++ 4.9.9.2
||ElChE||88
08-05-2009, 18:05
#include <stdlib.h>
int main()
{
int i;
char *string = malloc(5 * sizeof(char));
char *string2 = malloc(5 * sizeof(char));
for (i = 0; i < 4; ++i)
{
string[i] = 'a';
string2[i] = 'a';
}
string[4] = '\0', string2[4] = '\0';
printf("%d\n", string == string2);
free(string), free(string2);
return 0;
}
Output: 0
Ah, e strcmp ritorna 0 (significa che il contenuto delle stringhe è uguale).
L'operatore == controlla soltanto l'indirizzo. Fine.
grollagrolla123
08-05-2009, 18:27
char* string="prova";
char* string2="prova";
printf("%d\n", string == string2); output 0
if(string==string2) printf("fa l' IF\n"); output fa l' IF
controlla pure te.
spiegami perchè con l' IF funziona e con la printf() no
||ElChE||88
08-05-2009, 18:31
controlla pure te.
spiegami perchè con l' IF funziona e con la printf() no
Controllato. L'output è 1 (stesso indirizzo).
Edit: ah, comunque è impossibile che la stessa comparazione ritorni risultati diversi.
grollagrolla123
08-05-2009, 18:51
int main(){
char* s1="stringa1";
char* s2="srrddddinga1";
printf("%d\n",*s1==*s2);
printf("*********\n %d\n %p %p\n",s1==s2,&s1,&s2);
system("pause");
}
guarda l'output.
||ElChE||88
08-05-2009, 19:02
int main(){
char* s1="stringa1";
char* s2="srrddddinga1";
printf("%d\n",*s1==*s2);
printf("*********\n %d\n %p %p\n",s1==s2,&s1,&s2);
system("pause");
}
guarda l'output.
1 (compari il primo carattere della prima stringa con il primo carattere della seconda stringa)
0 (compari gli indirizzi)
Che cosa c'è di strano?
grollagrolla123
08-05-2009, 19:11
1 (compari il primo carattere della prima stringa con il primo carattere della seconda stringa)
0 (compari gli indirizzi)
Che cosa c'è di strano?
char s1[]="stringa1";
char s2[]="stringa1";
printf("%d\n",s1==s2);
l'output sarà 0
mentre con
char *s1="stringa1";
char *s2="stringa1";
printf("%d\n",s1==s2);
l'output sarà 1
non capisco perchè
Semplicemente perché il compilatore ottimizza e crea un solo constant literal "stringa1". Quindi nel secondo caso l'indirizzo puntato è lo stesso.
grollagrolla123
08-05-2009, 19:28
ci voleva chuck schuldiner per farmi capire :D
grazie ora è più chiaro.
Di niente ;)
ci voleva chuck schuldiner per farmi capire :D
:ave:
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.