Esercizio 11
Scrivi un programma che analizzi una mano di poker (5 carte) e ne valuti il risultato.
Il programma deve leggere e classificare una mano di
poker.
Ogni carta della mano deve avere sia un seme (cuori, quadri, fiori o picche)
che un valore (due, tre, quattro, cinque, sei, sette, otto, nove, dieci,
fante, regina, re o asso).
Non ammettiamo l'uso del jolly.
Il programma leggerà una mano composta da cinque carte e la classificherà
in una delle seguenti categorie ( elencate in ordine dalla migliore alla
peggiore):
9 - Scala reale (K Q J 10 e asso dello stesso
seme)
8 - Scala a colore (sia scala che colore)
7 - Poker (quattro carte dello stesso valore)
6 - Full (un tris e una coppia)
5 - Colore (cinque carte dello stesso colore)
4 - Scala (cinque carte di valore consecutivo)
3 - Tris ( tre carte dello stesso valore)
2 - Doppia coppia (due coppie)
1 - Coppia (due carte dello sesso valore)
0 - Carta alta (qualsiasi altra combinazione)
Se una mano rientra in una o più categorie,il programma dovrà scegliere
la migliore. Useremo le seguenti abbreviazioni per semplificare l'input
per indicare il valore e i semi ( le lettere potranno essere maiuscole o
minuscole):
Valori : 1 2 3 4 5 6 7 8 9 0 j q k
semi : c q p f
Useremo, dunque, il numero 1 per indicare l'asso.
Useremo il numero 0 per indicare il 10.
Nel caso l'utente dovesse immettere una carta non valida o se cercasse di
immettere due volte la medesima carta, il programma deve generare un messaggio
di errore, ignorare la carta immessa e richiederne un'altra.
Una esecuzione del programma si presenterà in questo modo:
carta:kq
carta:jq
carta:1p
carta:3f
carta:4c
13 1
11 1
1 2
3 3
4 0
RISULTATO:cartaAlta
Il programma è costituito dal main() che legge una mano di cinque carte,
e da un paio di metodi statici che analizzano la mano e restituiscono al
main() un valore numerico (max) indicatore del risultato ottenuto.
Nel main() è presente un vettore di strighe R[ ]:
"Colore","Full","Poker","ScalaColore","ScalaReale"};
la stampa di R[max] ci permette di individuare il miglior risultato ottenuto.
Ogni metodo restituisce un valore intero che stabilisce se il risultato
è stato ottenuto o meno.
Ad es. se si verificasse un poker il metodo full() restituisce:7 (altrimenti
restituisce 0) in tal caso se la variabile del main() max è impostata ad
un valore minore, essa viene reimpostata a 7. La stampa:
System.out.println( "RISULTATO :"+R[max]);
restituisce l'output:
RISULTATO:Poker
se la variabile max è invece impostata ad un valore maggiore (di 7) essa
non subisce variazioni, perchè vuol dire che è stata già rilevata la presenza
di una scala a colore o di una scala reale che sono più importanti del poker.
Queste discriminazioni vengono eseguite a livello del codice:
if(full(M)>max)max=full(M);
System.out.println("RISULTATO:"+R[max]);
E' dunque evidente come il programma principale faccia
uso di 2 metodi in totale per classificare il gruppo di carte:
scalacolore(M)
full(M)
Bisogna specificare che il metodo scalacolore(M)
identifica la presenza di una scala, di un colore, di una scala a colore
o di una scala reale.
Il metodo full(M) identifica
l'eventuale presenza di una coppia, di una doppia coppia, di un tris, di
un full e di un poker.
Oltre a questi metodi, ne è presente uno ulteriore chiamato valida()
che si preoccupa di verificare se la combinazione dei caratteri immessi
per definire una carta è valida o meno.
La struttura di dati principale è la matrice di interi M[row][col]
dove :
final static int row=5;
final static int col=2;
sono due costanti che definiscono le righe [5] e le colonne
[2] della matrice.
Ogni riga della matrice costituisce una carta (ci sono 5 righe, ognuna per
le 5 carte).
La prima colonna della matrice identifica il valore della carta. La seconda
colonna, identifica il seme. All'interno del metodo valida() avviene la
decodifica dei valori alfanumerici inseriti da tastiera in valori numerici
secondo lo schema:
int T[]={0, 0};
switch(ch1){
case '0': T[0]=10;break;
case '1': T[0]=1;break;
case '2': T[0]=2;break;
case '3': T[0]=3;break;
case '4': T[0]=4;break;
case '5': T[0]=5;break;
case '6': T[0]=6;break;
case '7': T[0]=7;break;
case '8': T[0]=8;break;
case '9': T[0]=9;break;
case 'j': T[0]=11;break;
case 'q': T[0]=12;break;
case 'k': T[0]=13;break;
default:System.out.println("carta non valida");
}//end switch
switch(ch2){
case 'c': T[1]=0;break;
case 'q': T[1]=1;break;
case 'p': T[1]=2;break;
case 'f': T[1]=3;break;
default:System.out.println("carta non valida");
}//end switch
return T; }//fine valida
Come si nota il metodo restituisce un vettore T[ ] di due posti dove in T[0] viene inserito il codice identificativo della carta e in T[1] quello identificativo del seme.
Nel metodo full(M)
si nota la presenza di una seconda matrice (ausiliaria) A[5][2] che
ha il compito di memorizzare i valori e le corrispondenti frequenze,
ordinati in modo decrescente in modo da facilitare l'individuazione
delle varie combinazioni full, poker etc..
Il programma completo è dunque il seguente:
import java.io.*;
class pokerdef{
final static int row=5;
final static int col=2;
public static void main (String args []) throws IOException{
BufferedReader h= new BufferedReader(new InputStreamReader(System.in));
String s;
char ch1,ch2;
int T[]={0, 0},seme,valore;
int M[][]=new int[row][col];
String R[]={"cartaAlta","Coppia","DoppiaCoppia","Tris",
"Scala","Colore","Full","Poker","ScalaColore","ScalaReale"};
int i=0,j=0,max=0;
do{
do{
System.out.print(" carta:");
s=h.readLine();
if(s.length()>1){
ch1=s.charAt(0);
ch2=s.charAt(1);
T=valida(ch1,ch2);
valore=T[0];
seme=T[1];
}//fine if
}while(s.length()>2 || s.length()==0);
M[i][0]=T[0];
M[i][1]=T[1];
if(i>0)//controllo doppioni
for(int k=0;k < i;k++)
if(M[k][0]==M[i][0] &&
M[k][1]==M[i][1]){
i--;
System.out.println("non
valida");
}//fine controllo doppioni
i++;
}while(i < row);
if(scalacolore(M)>max)max=scalacolore(M);
if(full(M)>max)max=full(M);
System.out.println("RISULTATO:"+R[max]);
}//fine main
static int [] valida(char ch1,char ch2){
int T[]={0, 0};
switch(ch1){
case '0': T[0]=10;break;
case '1': T[0]=1;break;
case '2': T[0]=2;break;
case '3': T[0]=3;break;
case '4': T[0]=4;break;
case '5': T[0]=5;break;
case '6': T[0]=6;break;
case '7': T[0]=7;break;
case '8': T[0]=8;break;
case '9': T[0]=9;break;
case 'j': T[0]=11;break;
case 'q': T[0]=12;break;
case 'k': T[0]=13;break;
default:System.out.println("carta non valida");
}//end switch
switch(ch2){
case 'c': T[1]=0;break;
case 'q': T[1]=1;break;
case 'p': T[1]=2;break;
case 'f': T[1]=3;break;
default:System.out.println("carta non valida");
}//end switch
return T;
}//fine valida
//______________________________________________scalacolore
static int scalacolore(int M[][]){
int i,j,x,k,sc=0;
boolean stair=true;
boolean color=false;
boolean scalacolore=false;
boolean scalareale=true;
//stampa matrice M
for(i=0;i < row;i++){//qui stampo la matrice M
for(j=0;j < col;j++)System.out.print(M[i][j]+"
");
System.out.println();
}//fine for i
System.out.println("------------");
//colore
if((M[0][1]>=2 && M[1][1]>=2 && M[2][1]>=2 && M[3][1]>=2 && M[4][1]>=2)
||
(M[0][1]<2 && M[1][1]<2 && M[2][1]<2 && M[3][1]<2
&& M[4][1]<2))color=true;
else color=false;
for(i=0;i < row-1;i++) //ordinamento per
valore della matrice M
for(j=i+1;j < row;j++)
if(M[j][0]>M[i][0]){
x=M[j][0];k=M[j][1];
M[j][0]=M[i][0];
M[j][1]=M[i][1];
M[i][0]=x;M[i][1]=k;
}//fine ordinamento
//verifico la scala
for(i=0;i < row-1;i++)
if((M[i][0]-M[i+1][0])!=1)stair=false;
//scala a colore
if(stair==true && color==true)scalacolore=true;
//fine scalareale
if(M[0][0]==13 && M[1][0]==12 && M[2][0]==11 && M[3][0]==10 && M[1][0]==12)
scalareale=true;
else scalareale=false;
if(stair==true)sc=4;//ho fatto scala
if(color==true)sc=5;//ho fatto colore
if(scalacolore==true)sc=8;//ho fatto scala
a colore
if(scalareale==true)sc=9; return sc; //scala
reale
}//fine scalacolore
//________________________________________________________full
static int full(int M[][]){
int A[][] = new int[row][col];//matrice
delle frequenze
int i,j,x=1,k;
boolean presente;
for(i=0;i < row-1;i++){
for(j=i+1;j < row;j++)
if(M[j][0]==M[i][0])x++; presente=false;
for(k=0;k < row;k++) if(A[k][0]==M[i][0])presente=true;
if(presente==false){
A[i][0]=M[i][0];
A[i][1]=x;} x=1;
}//fine for i
//ordinamento della matrice A
for(i=0;i < row-1;i++) for(j=i+1;j < row;j++)
if(A[j][1]>A[i][1]){
x=A[j][0];
k=A[j][1];
A[j][0]=A[i][0];
A[j][1]=A[i][1];
A[i][0]=x;A[i][1]=k;
}//fine ordinamento
if(A[0][1]==4)return 7;//poker
else if(A[0][1]==3 && A[1][1]==2)return 6;//full
else if(A[0][1]>=3 && A[1][1] < 2)return 3;//tris
else if(A[0][1]==2 && A[1][1]==2)return 2;//doppia
coppia
else if(A[0][1]==2 && A[1][1] <=1)return 1;//coppia
else return 0;//carta alta
}//fine full
}// fine classe
}// fine classe