PROBLEMA 27:            Poker American
    DEADLINE:               Luni, 8 august
    DOMENIU:                Din nou, euristica
    PUNCTAJ:                100 dexteri
    
    Cu promisiunea ca voi incerca sa nu trimit si la urmatoarea problema tot
    una cu euristici, iata despre ce este vorba in jocul de poker american. Se
    iau 24 de carti de joc dintr-un pachet, si anume 9, 10, J, Q, K, A. Acestea
    se amesteca bine-bine si, rand pe rand, se intorc pe fata. Apoi cartile se
    asaza pe masa in patru coloane a cate cinci carti in asa fel incat la orice
    moment de timp diferenta intre cea mai lunga si cea mai scurta coloana sa
    fie cel mult 1. Subliniem doua aspecte:
    
    1) 4x5=20, deci patru din cele douazeci si patru de carti vor ramane
    nefolosite.
    2) O carte o data intoarsa pe fata trebuie asezata pe masa in una din cele
    patru coloane INAINTE de a intoarce urmatoarea carte.
    
    Iata un exemplu privind ordinea in care ar putea fi asezate pe masa cele
    douazeci de carti:
    
      3  1  2  4
      7  6  8  5
      9 10 11 12
     16 13 15 14
     18 19 17 20
    
    Pentru ca totul sa fie clar, remarcam ca dupa ce asezam cartile cu numarul
    de ordine 4k+1, 4k+2 si 4k+3, cartea cu numarul 4k+4 va fi asezata fortat
    in coloana care a ramas mai scurta (k=0,1,2,3,4).
    
    Care este scopul acestui joc? Dupa asezarea celor 20 de carti, pentru
    fiecare din cele patru coloane se acorda intre 0 si 8 puncte, astfel:
    
    - 8 puncte pentru QUINTA REGALA, adica una din combinatiile 9-10-J-Q-K sau
      10-J-Q-K-A, toate de aceeasi culoare. Cartile nu trebuie neaparat sa fie
      in ordine. De exemplu combinatia Q-K-J-A-10, toate de trefla, este o
      quinta regala.
    - 7 puncte pentru CULOARE, adica orice cinci carti de aceeasi culoare, in
      orice ordine (cu conditia sa nu se incadreze in categoria quinta
      regala, desigur). Exemplu: 9-A-10-K-Q, toate de pica.
    - 6 puncte pentru CAREU, adica patru carti egale ca valoare si a cincea
      diferita, de exemplu patru dame si-un valet.
    - 5 puncte pentru FULL, adica trei carti de un fel si o pereche de alt fel,
      de exemplu trei dame si doi valeti.
    - 4 puncte pentru quinta, adica o permutare a multimii 9-10-J-Q-K sau
      10-J-Q-K-A, dar bineinteles nu o quinta regala.
    - 3 puncte pentru TREI BUCATI, adica trei carti egale si doua diferite de
      acestea si diferite intre ele, de exemplu trei nouari, un as si un popa.
    - 2 puncte pentru DOUA PERECHI, de exemplu pentru doi valeti, doua dame si
      un decar.
    - 1 punct pentru O PERECHE, de exemplu doi nouari, un as, un popa si o
      dama.
    - 0 puncte (chiar greu de obtinut!) pentru nimic din cele de sus, de
      exemplu pentru A-K-Q-J de pica si 9 de cupa.
    
    Totalul punctelor este deci intre 0 si 32.
    Notand cu T trefla, cu C cupa, cu P pica si cu R rombul, iata cum s-ar
    puncta jocul:
    
     JT 10C  9C  QP    Doua perechi + Full + O pereche + Trei Bucati ==>
     9P 10R  AP  QR    2 + 5 + 1 + 3 = 11 puncte
     KT 10T  KP  KR
     KC  AT  9T  QC
     JR  AR  JC  9R
    
    Pentru a vi se furniza cartile din pachet "una cate una", fara a le putea
    urmari pe celelalte :), veti folosi modulul POKER.TPU, respectiv POKER.H.
    Veti include acest modul in sursa voastra cu o linie:
    
    Pascal:         uses Poker;
    C:              #include "poker.h"
    
    Acesta va furnizeaza functiile:
    
    Pascal:         procedure p_startgame;
    C:              void p_startgame(void)
    
    Initializeaza jocul. Se apeleaza o singura data, inaintea oricarei alte
    functii din modul.
    
    Pascal:         procedure p_look(var value, color:integer);
    C:              void p_look(int *value, int *color)
    
    "Se uita" la urmatoarea carte din pachet, intorcand in variabilele value si
    color valoarea si culoarea cartii. value poate fi 1, 2, 3, 4, 5 sau 6. 1
    simbolizeaza un nouar, 2 un decar, 3 un valet, 4 o dama, 5 un popa, iar 6
    un as. color poate fi 1, 2, 3 sau 4. 1 este pica, 2 este cupa, 3 este
    rombul, iar 4 este trefla.
    
    Pascal:         procedure p_place(column:integer);
    C:              void p_place(int column)
    
    Plaseaza cartea la care v-ati uitat pe coloana pe care doriti (column are o
    valoare intre 1 si 4). In clipa in care apelati p_place() pentru a 20-a
    oara, programul vostru va fi automat oprit, iar un evaluator va afla
    scorul.
    
    MODUL DE FOLOSIRE al acestor functii trebuie sa fie cam asa:
    
    Pascal:         uses Poker;
                    ...
                    begin
                      p_startgame;
                      for i:=1 to 20 do
                        begin
                          p_look(v, c);
                          t:=f(v,c);        { t este bine calculat }
                          p_place(t);
                        end;
                    end.
    
    C:              #include "poker.h"
                    ...
                    void main(void)
                    { p_startgame();
                      for (i=1; i<=20; i++)
                        { p_look(&v, &c);
                          t=f(v,c);         // t este bine calculat
                          p_place(t);
                        }
                    }
    
    Observatii:
    1. Cartile vor fi date chiar la intamplare, nu vor fi asezate de un nene
    rauvoitor. Bineinteles, testele vor fi aceleasi pentru toti.
    2. Un test este picat si cotat cu 0 puncte daca:
       - Nu apeleaza la timp p_startgame(), sau o apeleaza de doua ori.
       - Nu respecta succesiunea de apeluri p_startgame() - p_look() -
         p_place() - p_look() - p_place() - p_look() - p_place() ...
       - Plaseaza prea multe carti pe aceeasi coloana, creand o diferenta mai
         mare de 1 intre cea mai lunga si cea mai scurta coloana, de exemplu:
         p_place(1) - p_place(2) - p_place(3) - p_place(1) (iar coloana 4
         ramane goala)
    3. Modificarea DFCC-ului se va face astfel: se vor insuma punctajele
    obtinute pentru cele 10 teste. Cel mai mare punctaj va obtine echivalentul
    a 10 teste trecute in problemele obisnuite (deci castigul maxim la DFCC).
    Restul punctajelor vor fi scalate si rotunjite la cel mai apropiat intreg.
    De exemplu, daca totalul maximul obtinut a fost de 180 de puncte, atunci cu
    120 de puncte ati obtine 6.666 teste din 10, care se vor rotunji la 7. Cu
    60 puncte ati obtine 3.333 teste din 10, care se vor rotunji la 3.
    
    TIMP DE EXECUTIE: 5 secunde/joc. Un apel al functiei p_startgame(), plus 20
    de apeluri p_look() plus douazeci de apeluri p_place() dureaza maxim 0.1
    secunde.
    
    Mult succes, si scuze pentru enuntul cam lung. Sper sa va puneti mintea in
    numar mai mare cu problema asta.