edutecnica

Esercizio 5        

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[ ]:

String R[]={"cartaAlta","Coppia","DoppiaCoppia","Tris","Scala",
       "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(scalacolore(M)>max)max=scalacolore(M);
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:
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

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

.