Pagina 1 din 2

Algoritmi, coduri diverse

Scris: 16 Sep 2013, 01:38
de Manu
Inspirat de Mehran Sahami, lectorul care tine un curs de Java la Stanford University, care vorbea la un moment dat de un algoritm de creare palindromuri fraze, m-am gandit sa caut si eu un fisier text cu toate cuvintele limbii romane pentru a ma juca apoi cu ele.

Stiu ca s-ar fi putut lua din baza de date a Maestro Dex, dar eu ma gandeam sa am o lista cu cuvintele in forma de baza, nominativul singular pentru substantive, nominativul masculin singular pentru adjective, infinitivul scurt pentru verbe etc.

Se pare ca pe site-ul DexOnline.ro exista un fisier numit Scrabble-Loc.txt care contine 72933 cuvinte, acolo fiind si informatii legate de accent si altele.
Am periat fisierul ajungand sa am in cele din urma ceea ce vroiam, doar cuvintele, cate unul pe un rand.

Fisierul TXT poate fi luat de aici, are 732 KB, cel care contine si informatiile suplimentare avea 2,34 MB.
Cuvintele continute sunt scrise cu litere mici si au diacriticele romanei traditionale, ş si ţ cu sedila.

Pe baza acelei liste se pot face tot felul de analize si statistici, lucruri de care eram interesat intr-o vreme, ma refer la statistici in ceea ce priveste vocabularul.

Revenind la palindromuri, am fost curios cate cuvinte de acest fel sunt in limba romana, avand in vedere doar formele de baza ale cuvintelor existente.

Am scris un mic codulet care a detectat 92 palindromuri, luand in calcul si interjectiile "AA", "OOO", "UU", care intr-adevar sunt mai putin relevante.

De aici poate fi luata lista palindromurilor din limba romana.

Stiam ca cel mai lung palindrom al limbii romane este "aerisirea", doar ca el nu se regaseste in lista din fisierul de mai sus fiindca este un substantiv articulat.
Cel mai lung in cazul de fata este "rotitor", 7 litere.

Codul care le-a detectat, pun doar algoritmul de determinare isPalindrome, presupunand ca deja avem un array rezultat in splituirea continutului fisierului text cu cele 72933 cuvinte, este mai jos:

Cod: Selectaţi tot

// aTemp este un array cu cele 72933 cuvinte.

temp=""; // va contine string-ul cu rezultate, palindromurile pe cate un rand.

// Mergem cu un for prin toate valorile array-ului:
uint aTempLength=aTemp.length(); // determinam lungimea array-ului.

for(int i=0; i<aTempLength; i++) {
bool isPalindrome=true; // Il facem false cand e cazul, adica cel mai des.
string sTemp=aTemp[i]; // cuvantul actual in variabila sTemp.

/*
Acum mergem si verificam daca prima litera este la fel cu ultima, a doua cu penultima.
Pentru eficientizare, cum nu se potriveste o pereche se face un break.
*/
uint sTempLength=sTemp.length(); // lungimea cuvantului actual.
for(int j=0; j<sTempLength/2; j++) {
if(sTemp[j]!=sTemp[sTempLength-(j+1)]) {
isPalindrome=false;
break;
}
}

// Adaugam palindromul la temp daca e cazul::
if(isPalindrome) {
temp+=aTemp[i]+"\r\n";
}
} // sfarsit for care a mers prin toate cuvintele limbii romane..

// In final temp contine ceea ce trebuie scris intr-un fisier pentru a avea lista completa cu rezultate, fiecare pe un rand.

Re: Procesare cuvinte din dictionar, teste, algoritmi, codur

Scris: 16 Sep 2013, 14:57
de IonPop
In Perl este putin mai simplu, fiindca exista cateva module care fac si astfel de verificari, si pe langa asta mai pot verifica si daca elementele unui array reprezinta palindromuri.
Codul de mai jos citeste si fisierul si creaza array-ul cu cuvinte.

use String::Palindrome 'is_palindrome';
use File::Slurp;

my @cuv = read_file( 'cuv.txt' );
chomp @cuv;

for my $cuv ( @cuv ) {
print "$cuv\n" if is_palindrome( $cuv );
}

Se poate folosi chiar o linie de comanda cu tot programul:

perl -MFile::Slurp -MString::Palindrome=is_palindrome -e "@c=read_file 'cuv.txt'; chomp @c; for (@c) {print \"$_\n\" if is_palindrome($_)}"

Daca redirectez aceasta comanda catre programul wc, cu:
| wc -l
atunci tipareste numarul de linii care rezulta, adica 92.

Scris: 16 Sep 2013, 16:31
de Manu
Da, am retinut ca Perl e cel mai high level pentru procesare de text, poate prea high, se vede ca Larry Wall a fost lingvist. :)
Oare cum sunt in general dictionarele care au si toate flexiunile cuvintelor dintr-o limba, cele care se folosesc la corectare text din punct de vedere lexical?
Se folosesc reguli care determina posibilitatea existentei unei flexiuni sau exista o baza de date cu toate formele generate?

Scris: 16 Sep 2013, 18:53
de IonPop
Eu mi-am aruncat privirea candva peste un astfel de program cu ceva vreme in urma, dar mi-a trecut rapid pofta. :-)

Daca vrei, poti vedea mai multe informatii despre cum functioneaza accesand direct codul sursa la:

http://aspell.net/

Scris: 17 Sep 2013, 00:53
de Manu
Intr-adevar, nu cred ca au multi chef sa descifreze acel proiect, desi e bine organizat.
Cred ca intelegerea codului scris de altii inseamna o alta latura a programatorului, nu oricine reuseste pana foarte departe acest lucru, decat dupa o experienta indelungata si daca exista si comentarii bune, etc, etc.

Pentru www.dictionar.limbalatina.ro am inceput acum o vreme sa creez un program in PHP care sa genereze formele morfologice posibile pentru cuvinte.
Am terminat cu substantivul, va trebui sa continuu. Limba latina este insa mult mai exacta din punct de vedere morfologic, sunt reguli clare si exceptii.

Oare sa nu fie si fisier cu toate formele posibile pentru dictionarele T9 de exemplu? Ma indoiesc ca s-a introdus in telefoane un soft complex de generare flexiuni chiar si pentru limba romana, probabil ca este totusi o baza de date atotcuprinzatoare..

Imi trebuia asa ceva pentru ca, doar ca exercitiu, mai ales pentru invatarea Regular Expression, sa fac si eu pe calculator un simulator de T9.
Il fac intai fara Regular Expressions, apoi cu, astfel vad practic eficienta, avantaje / dezavantaje.
Ca tot veni vorba, si Java utilizeaza tot Perl Regular Expressions. Aici iar se vede ca Larry Wall a fost lingvist... cel putin a influentat dezvoltarea limbajului in acest sens, al imbunatatirilor excesive in ceea ce priveste operarea cu string-uri.

Editare mesaj:
Intre timp am citit si despre T9 (predictive text), se pare ca e o tehnologie preluata si detinuta in prezent de, cine oare, Nuance.
Utilizeaza simple dictionare in care conteaza si frecventa de utilizare a unui cuvant intr-o limba si in care se salveaza si ocurenta folosirii unui cuvant de catre utilizator astfel incat sa il sugereze pe acela mai intai atunci cand sunt mai multe potriviri.
Astia de la Nuance sunt pentru celelalte firme din domeniul IT precum Perl-ul pentru celelalte limbaje de programare. :)

Scris: 17 Sep 2013, 08:33
de IonPop
Si eu am fost interesat ca tine despre dictionare, adica cu speranta ca voi gasi liste cu toate formele flexionare pe care le-as putea eventual folosi cu usurinta. Asta in special pentru faptul ca regulile limbii romane nu sunt prea bine oficializate si promovate de Academia Romana, asa ca eventualele firme care au nevoie de astfel de reguli care sa poata fi transpuse usor si rapid in programe au mult de lucru, cum a fost si cazul firmei Baum.

Nu pot spune insa nici macar ca am facut o cercetare superficiala a acestui domeniu, ci doar ca am aruncat o privire peste unele site-uri si proiecte, insa am vazut totusi ca ele folosesc diversi algoritmi care cu siguranta ca se bazeaza pe anumite reguli care exista in toate limbile.

Insa eu cum nu sunt lingvist, desi am invatat la scoala cat de cat despre unii dintre termenii folositi, nu prea imi aduc bine aminte ce reprezinta ca sa imi pot face o imagine de ansamblu, si de altfel nici nu vroiam sa creez eu asa ceva, fiindca implica un efort destul de mare si nu am in plan nici un proiect in acest domeniu care sa fie profitabil.

Nu stiu sigur, insa ma gandesc ca daca exista reguli bine stabilite si mai ales daca nu exista prea multe exceptii, s-ar putea sa fie mai eficient un algoritm care face calcule decat un program care sa caute intr-o baza de date imensa cu toate formele posibile ale cuvintelor.
Asa ca este posibil sa se foloseasca si liste de cuvinte, si diversi algoritmi, si liste cu exceptii etc.

Apropos de Perl regular expressions, el este folosit si in C#, si in Python, Ruby si in PHP, insa nu peste tot este la fel, adica in Perl si cred ca si in Java se pot face fara probleme cautari/inlocuiri si folosind caractere Unicode, si nu doar caractere in sine, ci grupuri si blocuri de caractere Unicode cum ar fi "orice caracter de spatiere", "orice semn de punctuatie", "orice litera", "orice numar" si multe altele, indiferent daca este vorba despre alfabetul latin sau cel chinezesc sau arab, ebraic etc, dar in anumite limbaje lipsesc unele facilitati sau suportul suficient de bun pentru Unicode.


Pentru un dictionar cred ca metoda cea mai buna cu care poti sa oferi posibilitatea cautarii oricaror forme ale cuvintelor (caci asta banuiesc ca vrei sa faci) este intr-adevar sa creezi o lista cu cuvinte cu toate formele lor flexionare si sa asociezi apoi toate formele unui cuvant cu definitia acelui cuvant, sau cu toate definitiile daca exista mai multe.
Ar fi intr-adevar super daca am putea gasi de-a gata pentru toate limbile o lista cu toate cuvintele de baza si toate inflexiunile lor.

Scris: 17 Sep 2013, 13:46
de Manu
Am gasit un site care ofera toate formele flexionare ale cuvintelor.
Nu stiu cum or fi facut, dar sunt aratate la fiecare forma informatii amanuntite.
Am scris "frumos", iar unul dintre rezultate eeste:
FRUMOASELOR - adjectiv, gen feminin, număr plural, caz genitiv, articulat
Site: http://www.archeus.ro/lingvistica/Flex? ... os&lang=ro

Sigur este vorba despre lingvistica computationala, scrie la Despre site ca initial a fost un proiect incheiat din cauza lipsei de fonduri, iar ceea ce este pe site sunt rezultatele acelui proiect valorificate macar in acest fel (corector, cautare in Dex cu forme flexionare etc.).

Scris: 17 Sep 2013, 14:02
de IonPop
La un moment dat tin minte ca spunea Catalin Francu, cel care a creat site-ul dexonline.ro, ca lucra la un proiect de acest gen, dar nu vreau sa mint fiindca nu mai tin minte daca fix despre asta era vorba, insa parca asa imi amintesc. Nu sunt sigur si pentru ca dupa cate stiu eu pe site-ul dexonline.ro ei ofera diversele inflexiuni ale cuvintelor deja, dar nu stiu, poate ca acum e o treaba incompleta...

Sincer sa fiu, eu am fost interesat de o solutie rapida, nu de una completa, fiindca pe masura ce m-am informat mai bine am vazut ca asa ceva nu exista in domeniul lingvistic, si limbile se schimba incontinuu, si incontinuu apar noi cuvinte pe care le recunoaste si Academia, asa ca o astfel de munca ar fi o munca de cercetare de sisif care nu s-ar finaliza niciodata.

T9 algoritm

Scris: 20 Sep 2013, 17:07
de Manu
Pana la urma am apucat sa fac si algoritmul pentru T9, il pun in limbaj Java mai jos.
Voi reveni in topicul despre Java cu intreg programelul, am desenat chiar un telefon pe tastele caruia se poate da click pentru a scrie in stil T9, doar ca deocamdata nu e ceva cum trebuie, nu reusesc sa incarc repede un fisier text mare. In varianta standard cu BufferedReader si FileReader objects sta cam mult timp si inca nu inteleg de ce.

Daca e cineva curios, pun un ZIP cu un programel similar in BGT, se poate scrie de la blocul numeric, se poate scrie direct un sir numeric apasand F5. In acest caz, daca s-ar scrie sa zicem "52783" va fi afisat cuvantul "lapte".
Cu tasta Tab sau 0 de pe blocul numeric se pot schimba potrivirile, comutare intre cuvintele gasite, precum face tasta steluta in cazul telefoanelor.
Apasand R va fi repetat ultimul rezultat.
Apasand Escape se realizeaza o resetare pentru un alt cuvant.
Apasand K se comuta intre aranjament bloc numeric tip telefon si tip desktop.
T9Simulator.zip

Mai jos algoritmul in varianta Java, fara Regular Expressions, practic o functie / metoda care returneaza un array de cuvinte gasite pe baza unui sir numeric inserat ca parametru.

Cod: Selectaţi tot

/*
Parametrul este sirul de cifre pentru care se cauta potriviri,
ca de exemplu pentru sirul 8282, o potrivire poate fi cuvantul "tava":

Se presupune ca la apelarea acestei metode, exista deja un array static / global numit "words" care contine cuvintele limbii romane.
De asemenea exista deja un array static / global numit "chars" care cuprinde sirurile de litere de la fiecare tasta, tasta 2 cu string-ul "abc" fiind la index 3:
String[] chars = new String[] {"", "", "aăâbc", "def", "ghiî", ... "wxyz"};

Metoda va returna un array de cuvinte gasite.
*/

public String[] getT9Word(String nums) {
String temp=""; // va contine potrivirile delimitate de bara verticala.
		 
// Numarul de cuvinte existente in dictionar:
int numberOfWordsInDictionary = words.length;

// Determinam cate cifre au fost scrise, cate cuprinde nums de la parametru::
int numberOfDigits = nums.length();

// Mergem prin tot dictionarul, filtrand mai intai sa ramana doar cuvintele cu lungime egala cu nums:
for(int i=0; i<numberOfWordsInDictionary; i++) {
if(words[i].length()==numberOfDigits) {
String curWord=words[i];
boolean isWord=true;
for(int j=0; j<numberOfDigits; j++) {
boolean isChar=false;
int numIndex=Integer.parseInt(Character.toString(nums.charAt(j)));
String numChars=chars[numIndex];

// Vedem acum daca e un caracter posibil pe pozitie:
for(int k=0; k<numChars.length(); k++) {
if(curWord.charAt(j)==numChars.charAt(k)) {
isChar=true;
break;
}
}

if(!isChar) {
isWord=false;
break;
}
}

if(isWord) {
temp+=words[i]="|";
}
}
}

// Stergem ultima bara verticala:
if(temp.length()>0&&temp.charAt(temp.length()-1)=='|') {
temp = temp.substring(0, temp.length()-1);
}

// Array-ul de returnat:, rezultat in urma splituirii lui temp:
String[] word = temp.split("|");

return word;
}

Re: T9 algoritm

Scris: 20 Sep 2013, 19:59
de IonPop
Nu am folosit niciodata metoda T9 pana acum, si cred ca nici nu o voi folosi, fiindca imi place sa pot scrie ce vreau eu, nu ce mi se sugereaza.
Cred ca deja banuiai ca trebuie sa existe si un modul Perl si pentru asta. :-)
Am gasit modulul Text::T9.

Scris: 20 Sep 2013, 22:45
de Manu
Pai nici nu ai avea la ce sa o folosesti, era asa pentru a vedea un algoritm.
Chiar ma intrebam daca exista un modul si pentru asta in Perl, se pare ca e o comunitate dezvoltata care face diverse module si centralizeaza apoi tot.

Intre timp am gasit si solutie pentru citirea eficienta a unui fisier in Java, problema nu era citirea in sine, ci crearea stringului care sa cuprinda intreg textul continut.
Java lasa in memorie toate stringurile in cazul unei concatenari de tip:
string1+=string2;
cum era chemat string1 de zeci de mii de ori, pana nu intervenea Garbage Collector-ul, in RAM ajungea sa fie tot atatea stringuri ramase de izbeliste.
Trebuie folosita o clasa StringBuilder pentru a fi eficienta treaba.
Asadar, o metoda de returnare string complet dintr-un text ar fi cu trei obiecte diferite - BufferedReader, FileReader si StringBuilder:

Cod: Selectaţi tot

public string getFileContent(String fileName) {
BufferedReader br = new BufferedReader(new FileReader(fileName));
StringBuilder sb = new StringBuilder();
String line="";
String ls = System.getProperty("line.separator");
while((line = br.readLine()) += null) {
sb.append(line);
sb.append(ls);
}
return sb.toString();
}
Inainte faceam intr-un stil pe care il utilizam in alte limbaje, in while scriam temp+=line, astfel incat in final sa returnez temp, iar asa dura cam un minut pana reusea sa creeze un temp cu text in valoare de 700 si ceva de kilo.

Vad ca desi este un limbaj de nivel inalt, nu are nici o astfel de metoda built-in, metoda care exista cred in cam toate limbajele dynamic type.

Scris: 21 Sep 2013, 16:45
de IonPop
Intr-adevar, limbajul Perl are o comunitate in care oricine poate crea module intr-un format standard si le poate incarca pe site-ul CPAN, care are sute de servere mirror, pe toate continentele, inclusiv prin Romania.
Iar de acolo pachetele cu module pot fi descarcate si compilate/instalate manual, sau automat cu programe ca cpan, cpanplus sau cpanm (de la CPAN Minus).
Acest model de distributie a modulelor nu a fost folosit in primul rand pentru Perl, ci pentru un alt limbaj dar de care nu imi aduc aminte, insa in mod cert CPAN a avut cel mai mare succes dintre toate. In prezent si pentru alte limbaje se foloseste un model asemanator, adica pentru Python, Ruby, Node JS...
Insa CPAN este mai centralizat si avansat decat celelalte sisteme, fiindca in momentul instalarii automate se executa suita de teste, iar rezultatele acelor teste pot fi trimise automat catre CPAN, asa ca acolo se poate vedea pe ce versiuni ale sistemelor de instalare functioneaza un anumit modul, ce probleme au aparut la instalare, pentru ca cel care a creat modulul sa il poata repara. Exista si un API pentru CPAN pe metacpan.org cu care se pot face diverse interogari ale sistemului...

In legatura cu distinctia "nivel inalt" " sau nivel josnic" :-) ... nici nu stiu unde sa il clasific pe Perl in comparatie cu Java.
Daca luam in considerare doar programul perl (sau perl.exe sub Windows), adica fara modulele aditionale care il insotesc in distributia standard, el ofera in mod evident un limbaj de programare de nivel mult mai scazut decat Java.
Limbajul Perl are mai putin de 300 de functii dintre care destul de multe sunt rar folosite in mod direct.
Daca luam in considerare si modulele instalate implicit in distributia standard, atunci el devine de un nivel mult mai inalt. Dar ma rog, la fel cum si pentru Java nu exista doar o singura distributie standard, ci mai multe, si pentru Perl exista mai multe distributii, si unele includ un anumit set de module, altele includ mai multe module etc.
Dar oricum, fiindca este relativ simplu de instalat module de Perl in diverse moduri, cu programele cpan, ccpanm, cpanplus, sau module gata compilate cu ppm (in special pentru Windows), sau cu yum si apt-get pentru mai multe distributii de Linux, nu prea conteaza doar modulele din distributia standard, ci toate modulele de pe site-ul CPAN, iar acele module fac ca Perl sa devina un limbaj de nivel foarte inalt.

Insa este foarte flexibil si daca vrei poti sa lucrezi doar cu functiile sale de baza, fara ajutorul modulelor de nivel inalt, dar este de preferat sa folosesti module de nivel inalt daca exista, fiindca ai mult mai putin de lucru, si in plus multe dintre ele sunt utilizate de multi alti programatori, asa ca au fost testate, imbunatatite etc.
In plus, multe module de pe CPAN sau din distributia standard folosesc cod in C atunci cand trebuie sa execute foarte rapid ceva, asa ca utilizarea modulelor de nivel inalt va face ca programul sa ruleze mai rapid decat daca acelasi cod ar fi scris in Perl.

Perl ofera mai multe functii pentru deschiderea, citirea, scrierea si inchiderea fisierelor in mod low level, adica fara sa aiba nevoie de module pentru asta.

Exista un set de functii mai simple ca open, read, close, si un set mai complex ca sysopen si sysread.

Ca sa citesti linie cu linie un fisier text se foloseste un code de genul:

open $file, '<', 'c:/dir1/dir2/fisier.txt';

while ( $linie = <$in> ) {
#fa ceva cu variabila $linie
}

close $file;

Am vazut multi programatori in Perl care folosesc aceasta metoda cand vor sa preia intreg continutul fisierului intr-o singura variabila, concatenand apoi toate liniile preluate. Este foarte OK fiindca este super rapid, insa exista si alte metode mai bune si mai elegante.

Linia urmatoare citeste pe rand liniile din fisier:
$line = <$in>

Dar daca se doreste, se pot prelua toate liniile intr-un array, cu un cod ca:
@array = <$in>;

In Perl separatorul de linii este in mod implicit \n, dar se poate modifica, si asta poate fi util si pentru a citi fisiere cu o structura mai ciudata, dar si pentru a citi intreg fisierul ca si cum ar fi o singura linie.

Separatorul de linii la citire este pastrat in variabila speciala $/, iar daca se scrie:
$/ = undef;
$line = <$in>;

atunci variabila $line va contine intreg fisierul fiindca nu se mai tine cont de nici un sfarsit de linie.

Cu functiile read si sysread se pot citi rand pe rand un anumit numar de bytes dintr-un fisier adaugandu-se de obicei la un buffer.

Dar pe langa aceste metode exista multe module cu care fisierele se pot citi, scrie, edita mai usor.
De exemplu cu:

use File::Slurp;

$intreg_fisierul = read_file( "nume fisier.txt" );
sau
@array_cu_liniile_fisierului = read_file( "nume fisier.txt" );
si:
write_file( "fisier.txt", $continutul_fisierului );

Citirea si scrierea fisierelor este o operatiune foarte simpla, asa ca oricine ar putea crea un modul in Java care sa faca acest lucru cu o simpla metoda sau functie, insa ar trebui sa existe un sistem ca CPAN care sa permita instalarea acelui modul foarte usor si ar mai trebui sa existe o comunitate care sa fie obisnuita cu utilizarea codului scris de altii si in schimb sa ofere de asemenea alt cod open source.
Altfel... trebuie scris totul de la zero si inca in Java este si mai mult de scris decat in Perl...

Scris: 23 Sep 2013, 22:09
de Manu
In cele din urma am finalizat si eu micul simulator de scriere de tip T9 Dictionary.
Este practic o mica interfata care arata ca un telefon, cele 12 taste ale blocului numeric plus doua labels (etichete) care tin locul displayului.
Utilizand tastele de la 2 la 9 se poate scrie textul, de exemplu pentru "bal" sau "cal" se tasteaza "225".
Steluta este pentru a schimba potrivirile pentru un sir de cifre, diezul pentru a sterge ultima cifra tastata, iar 0 reseteaza, sterge toate cifrele tastate.
Am facut ca cele 3 taste de jos sa se activeze sau dezactiveze dupa caz, adica nu are sens sa fie valabila tasta steluta daca nu sunt mai multe potriviri pentru un sir de cifre.
Se poate scrie si cu Alt+X, unde x este un numar de la 2 la 9, deci pentru a scrie "pisica", se poate apasa tasta alt si pe rand 7, 4, 7, 4, 2, 2.
Nu am reusit inca sa fac ca apasand tasta Tab sa se ajunga si pe etichete, asa ca trebuie citite cu JAWS Cursor.

Am facut acest mic T9Simulator pentru exercitiu, altfel nu prea poti invata un limbaj nou.
Voi pune si codul sursa in topicul despre Java din sectiunea Programare a Forumului.

Sunt curios daca pe Mac se ajunge totusi pe etichete cu tasta Tab, altfel acolo nu vad cum s-ar citi un cuvant scris, nu stiu daca exista un fel de JAWS Cursor si in cazul Voice Over.

Descarcare fisier standalone: T9Simulator.jar
Are putin peste 200 KB.

Algoritm pentru Poker

Scris: 03 Noi 2014, 21:08
de Manu
De mai multa vreme tot lucrez la un pachet de jocuri pentru Android.
Sunt pe cale sa finalizez un al patrulea joculet, cel de Poker.
Dupa ce am facut verificarea mainilor de carti, ca e Careu, Full, Chinta, culoare etc, am o problema la diferentierea a doua maini cu Full si a doua maini cu doua perechi.

Practic, daca jocul vede ca doua maini sunt la fel, trece la diferentierea lor ca valoare, luand doua maini de Full, ar trebui sa vada care dintre ele contine carte mai mare dintre cele 3 la fel, apoi dintre cele doua la fel.
La doua perechi e la fel, a cincia carte aici neavand importanta.

Pentru verificari am sortat ascendent tot timpul intr-un array de 5 int-uri cele cinci valori care pot fi de la 2 la 14, 14 fiind valoarea unui as, 13 - popa, 12 - dama si 11 - valetul.
Daca ar fi doar carti de la 1 la 9 sa zicem, o metoda simpla ar fi sa iau valoarea cartii dintre cele 3 la fel si sa o concatenez cu cea a celor doua carti la fel; de exemplu un Full de nouari cu septari ar avea valoarea 97, iar un Full de septari cu nouari ar avea valoarea 79, deci la o comparatie ar fi castigatoare mana cu Full de nouari.
Ei bine, problemele apar cand cartile sunt mai mari de 9, la o simpla concatenare a celor doua int-uri ar iesi pentru un Full de valeti cu nouari 119, iar la un full de nouari cu valeti 911, deci ar castiga gresit a doua mana, care in realitate e mai slaba.

Nu as vrea sa schimb clasa mea PokerHan dacum, ci as vrea o solutie prin care sa creez un numar intreg din array-ul cu valorile cartilor dintr-o mana, astfel incat la comparatii sa iasa bine, indiferent de tipul Full-ului din mana.

Am facut initial o inmultire cu 10 a valorii mai mare de 9, dar intr-un final tot nu e bine pentru ca, un Full de valeti cu nouari ar iesi ca valoare de lucru la comparatii numarul 1109, iar un Full de nouari cu asi ar iesi 9140...
Nu e bine nici sa inmultesc cu 10 cartile mai mari de 9 doar daca e vorba de valoarea celor 3, asta pentru ca un Full de popi cu valeti ar da ca este mai bun decat un Full de asi cu nouari, valorile de comparatii ajungand sa fie 13011, respectiv 1409, asadar iese mai mare Fulul de popi.

Pe scurt, are cineva o idee cum sa ajung la un numar intreg dintr-o mana de Full de Poker, astfel incat sa o pot folosi la comparatie cu valoarea unei alte maini de Full, iar cea mai buna mana sa castige.
Stiu ca as putea verifica in doua ture separate, prima data valoarea cartilor care sunt 3 la numar, apoi valoarea cartilor care sunt doua la numar.
Sunt si alte solutii, dar eu ma gandeam sa vad daca nu este totusi una bazata pe un numar intreg realizat din valoarea cartilor din mana si atat.

Acum, cand am trimis mesajul am realizat ca as putea in functia care detecteaza acea valoare relativa sa folosesc radical din valoarea cartii, numarul rezultat fiind tot timpul mai mic de 10. Ca sa se ajunga la un numar intreg in final, ar trebui sa am rezultatul radicalului rotunjit la doua zecimale si apoi inmultit cu o suta...
Totusi, oare o metoda fara sa bag float-uri nu ar fi?

Re: Algoritm pentru Poker

Scris: 03 Noi 2014, 23:15
de IonPop
Eu am jucat putin poker cand eram mic, dar destul de putin, fiindca jocul asta nu imi placea deloc fiind bazat doar pe noroc.
Asa ca mai stiu doar cum e chinta, culoarea, careul, dar nu mai stiu ce carti fac un full.

Daca nu gasesti o alta metoda, poti eventual descarca modulul Perl Games::Cards::Poker si sa vezi in el cum se calculeaza scorurile. Poti citi cate ceva despre asta in documentatia modulului la:

http://search.cpan.org/~pip/Games-Cards ... 5/Poker.pm

Ma gandesc ca in el trebuie sa apara functii pentru calculul scoringului si poate ca nu sunt greu de inteles, fiindca banuiesc ca ar trebui sa fie doar matematica.

Sau poate modulul Games::Poker::HandEvaluator care face strict asta, evalueaza mainile ca sa poata fi comparate:

http://search.cpan.org/~simon/Games-Pok ... aluator.pm

Probabil ca asta e mai util si mai usor de inteles codul sursa....

Sau am mai vazut un modul numit Games::Poker::Omaha::Hutchison care se pare ca face un scoring dupa un algoritm bine stabilit. Am vazut ca in documentatia modulului apare si un link catre un site cu informatii despre acel algoritm. Poate algoritmul direct ti-ar fi mai util:

http://search.cpan.org/~tmtm/Games-Poke ... tchison.pm