slacky Skrevet 5. februar 2012 Del Skrevet 5. februar 2012 (endret) Heisann. Har nå lenge vudrdert å starte et prosjekt, for å lage en "pokerbot" til Texas Hold'em, i første fase ønsker jeg å lage noe enkelt. Ingen AI. Bare den grunleggende mattematikken, og "slik".. for å få boten til å "spille". Jeg ble litt blank på hvordan jeg skulle gå frem får å finne mulige hender, basert på de 2 kortene på hånden, og de ~5 kortene på bordet. Jeg er mye klar over at en slik bot vil ha bedre utbytte av å programmeres i raskere språk, som C,Cpp,delphi etc.. Men har for lite erfaring i disse språkene. Kan hende jeg må ta meg til å gjøre noe i C/Cpp, men håper ikke det. Jeg har alt laget et rammeverk som tar seg av macro-delen, med OCR (google tesseract), bildegjenkjenning, mus, tastatur, og mye annet som kan komme til nytte. Dette er for å lese av verdiene og slik, det uten å måtte "hacke" selve programmet Nå trenger jeg bare et kraftig dytt i riktig retning, da jeg må vite om det er noen smart måte å gå frem for å lese hånden ved.. Flop -> 2 kort på hånden, 3 kort på bordet Turn -> 2 kort på hånden, 4 kort på bordet River -> 2 kort på hånden, 5 kort på bordet Nå må jeg ut i fra kortne jeg har fått tildelt (pluss de på bordet) finne alle mulige hender. 52 kort = 4 typer (Clubs,Hearts,Spade,Dimond), 13(14) rangeringer (A,2,3,4..Q,K,A) Så har vi alle hender: 1 > Royal Flush 2 > Straight Flush 3 > Four-of-a-Kind 4 > Full House 5 > Flush 6 > Straight 7 > Three-of-a-Kind 8 > Two Pair 9 > Pair 10> High Card #Ikke kjenskap til disse/dette? Følg denne lenken. Det å søke etter alle disse forskjellige kombinasjonene ser jeg ikke helt hvordan jeg burde/kan gjøre.. Hadde ikke tenkt meg at det skulle bli så vanskelig, men det blir bare "yalla-kode" om jeg ikke får litt hjelp fra dere :-) Er flott selv med hjelp til å "bare" lese enkelte kombinasjoner, en start er en start! Slik løste jeg ett par, og to par.. Halvfungerende "yallekode" Må være en bedre måte å gjøre dette på? Blir forferdelige greir dette! '''~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ || FindPokerHand ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~''' def Find_Pair(cards): result = False #Loop for one pair for x in xrange(0,len(cards)): for y in xrange(0,len(cards)): if(cards[x][:-1] == cards[y][:-1]) and (x!=y): result=(cards[x],cards[y]) break return result def Find_TwoPair(cards): result = False #Loop for one more pair (two pairs) for x in xrange(0,len(cards)): for y in xrange(0,len(cards)): if(cards[x][:-1] == cards[y][:-1]) and (x!=y): if(cards[y][:-1]!=pair[0][:-1]) and (cards[y][:-1]!=pair[1][:-1]): if(cards[x][:-1]!=pair[0][:-1]) and (cards[x][:-1]!=pair[1][:-1]): result=(pair[0],pair[1],cards[x],cards[y]) break return result '''~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ || Look for hands ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~''' hand = ["Qd","7c","5d", "2d", "As", "8d", "Qc"] pair = Find_Pair(hand) two_pair = Find_TwoPair(hand) print pair print two_pair Endret 5. februar 2012 av warpie Lenke til kommentar
zotbar1234 Skrevet 5. februar 2012 Del Skrevet 5. februar 2012 (endret) Heisann. Har nå lenge vudrdert å starte et prosjekt, for å lage en "pokerbot" til Texas Hold'em, i første fase ønsker jeg å lage noe enkelt. Ingen AI. Bare den grunleggende mattematikken, og "slik".. for å få boten til å "spille". Ta en titt for generell inspirasjon. Jeg ble litt blank på hvordan jeg skulle gå frem får å finne mulige hender, basert på de 2 kortene på hånden, og de ~5 kortene på bordet. Aller først tror jeg det er lurt å spørre seg "Hva ønsker jeg å få ut av de opptil 7 kort totalt?". Hvis man ønsker en eller annen form for handling (f.eks. vedde eller stoppe), så er det rimelig å tilordne en eller annen verdi til dette utvalget, hvor verdien bestemmes av spillets regler. Jeg er mye klar over at en slik bot vil ha bedre utbytte av å programmeres i raskere språk, som C,Cpp,delphi etc. 1) Det er meningsløst å snakke om raskere språk. Viktig å få med seg det. 2) På det stadiet som du beskriver er hastigheten komplett uinteressant. (Hastigheten _kan_ bli interessant når man har et veldig stort søkerom. Og da kan det lønne seg å velge en implementasjon (ikke et språk) som har høy ytelse. Foreløpig er fleksibilitet veldig mye mer interessant. I så måte er Python, Perl, Ruby, CL uendelig mye bedre enn C eller C++, uansett implementasjon). Nå må jeg ut i fra kortne jeg har fått tildelt (pluss de på bordet) finne alle mulige hender. Hvorfor må du det? Hvis du har royal flush, hva pokker skal du med å finne ut noe som helst annet? (Hvis du derimot ønsker å finne ut hvilke utfall er mulige og sannsynligheten for det, gitt det ikke-komplette utvalget du har, så blir det en annen sak). Det å søke etter alle disse forskjellige kombinasjonene ser jeg ikke helt hvordan jeg burde/kan gjøre For å sjekke hvilke kombinasjoner du _har_, kjører du en test for hvert av rankingpunktene, fra de mest verdifulle til de minst verdifulle. Så kan man stoppe såsnart man har et svar, evt. kjøre alle kombinasjoner som ikke er gjensidig utelukkende og samle alle svar ("royal flush" - "ace high", f.eks, mens "full-house" og "four-of-a-kind" trenger man ikke å teste for engang, når man har "royal flush"). Slik løste jeg ett par, og to par.. Halvfungerende "yallekode" Må være en bedre måte å gjøre dette på? Blir forferdelige greir dette! Koden din slår meg som for komplisert og for lite generisk (selv om det aldri (?) er behov for mer enn 2 par, burde ikke denne kunnskapen hardkodes i kodestrukturen). Det aller første steget er å finne en saklig representasjon for kort internt i koden (der "saklig" bestemmes av operasjonene på kortene i dette tilfellet), samt konvertering fra menneskevennlig format til denne representasjonen og tilbake. Jeg valgte par (rank, suit), siden deloppgaven er så enkel som å generere alle par gitt en sekvens av kort: def generate_pairs(seq_of_cards): return combinations(seq_of_cards, 2) # end generate_pairs def all_pairs(sequence): normalised = [str2card(c) for c in sequence] # rank -> all cards of that rank tmp = defaultdict(list) for card in normalised: tmp[card[0]].append(card) return chain.from_iterable(generate_pairs(same_rank) for same_rank in tmp.itervalues()) # end all_pairs Så til kjøringen: $ python poker-pairs.py QD 7C 5D 2D 7S 8D QC [(('Q', 'D'), ('Q', 'C')), ((7, 'C'), (7, 'S'))] 2 par, QD+QC og 7C+7S (Blir litt vel mange tupler i resultatet, så det kan tenkes at en liten klasse for kort som kan opptre som et tuppel ikke er så dumt). Hvis man bare er interessert i _antall_ par, så er oppgaven enklere, da man kan droppe generate_pairs() over og erstatte den med å summere \choose{2}{P} over tmp, der P er antall kort av samme rank. Tilsvarende kode kan skrives for hver av de poenggivene håndtypene. Så må man "bare" lage en rangeringsfunksjon som vektlegger hånd. Det er nok en mye mer komplisert oppgave, siden man ikke vil jo ha komplett informasjon og vil måtte vektlegge hender basert på sannsynlighet. edit: dammit. Velge dumme variabelnavn kan virke mot sin hensikt. Endret 5. februar 2012 av zotbar1234 1 Lenke til kommentar
slacky Skrevet 5. februar 2012 Forfatter Del Skrevet 5. februar 2012 (endret) Her var det gode svar å få Det er sant at eksempelet mitt var hardkodet, og ikke mye optimalt.. Men, det var vel det jeg mente med "Yallakode" => "Det kan gjøres MYE bedre", jeg viste bare ikke hvordan. Det virker som en mye bedre måte å gå frem på, det du viser til av kode. Jeg har problemer med å forstå hva som faktisk skjer der, da jeg ikke kjenner til mangen av disse funksjonene du bruker. normalised = [str2card(c) for c in sequence] # Aldri hørt om defaultdict(list), hvordan fungerer dette? tmp = defaultdict(list) for card in normalised: (...) chain.from_iterable() #Chain, og from_iterable har jeg ikke kjenskap til.. Noen kloke ord? Det kansje ikke dumt å kjekke om ett eller to av kortne er i egen hånd eller ikke. Dermed vite om dette er "globalt" (alle har paret/parene), eller gjelder dette sansynligvis bare meg. Dette blir selvføgleig gjort etterpå, ved å se om ett, eller to av kortene i paret/parene finnes i egen hånd. Ellers, om du eller noen andre har et tips eller to å komme med, så spytt ut! Endret 7. februar 2012 av warpie Lenke til kommentar
Yumekui Skrevet 5. februar 2012 Del Skrevet 5. februar 2012 (endret) # Aldri hørt om defaultdict(list), hvordan fungerer dette? http://docs.python.org/library/collections.html#defaultdict-objects Den bruker argumentet (i dette tilfellet list) på verdien du prøver å assigne til en ikke-eksisterende key. d = defaultdict(list) d["Liste1"].append("element") Dette bruker .append() på listen som er verdien til key "Liste1" dersom key "Liste1" finnes. Dersom key "Liste1" ikke finnes, ville den lagt til key "Liste1" med verdi som ["element"] === Jeg vet dog ikke helt hvorfor dette blir ["element"] og ikke ["e", "l", "e", "m", "e", "n", "t"] Endret 5. februar 2012 av Yumekui Lenke til kommentar
zotbar1234 Skrevet 5. februar 2012 Del Skrevet 5. februar 2012 (endret) Det virker som en mye bedre måte å gå frem på, det du viser til av kode. Jeg har problemer med å forstå hva som faktisk skjer der, da jeg ikke kjenner til mangen av disse funksjonene du bruker. chain.from_iterable() #Chain, og from_iterable har jeg ikke kjenskap til.. Noen kloke ord? Prøvd den offisielle dokumentasjonen? (str2card og slikt er noe jeg lagde, men som er overhodet ikke relevant for budskapet mitt). Det kansje ikke dumt å kjekke om ett eller to av kortne er på hånden eller ikke. Jeg aner ikke hva du etterspør. Den bruker argumentet (i dette tilfellet list) på verdien du prøver å assigne til en ikke-eksisterende key. Nei, det gjør den alldeles ikke, noe dokumentasjonen er veldig tydelig på -- "The first argument provides the initial value for the default_factory attribute". Jeg vet dog ikke helt hvorfor dette blir ["element"] og ikke ["e", "l", "e", "m", "e", "n", "t"] Fordi det er slik list.append() virker. lst.append(T) => [T,] for en tom liste lst. Hvorfor mener du at det skulle være noe annet enn ["element",] ? (Den defaultdict'en bruker list() når en ikke-eksisterende nøkkel blir nevnt og _det_ i sin tur setter inn en list() (jfr det 1. argumentet) inn for den aktuelle nøkkelen. Derfor virker d[k].append(), for en ikke-eksisterende k i d). Endret 5. februar 2012 av zotbar1234 Lenke til kommentar
Yumekui Skrevet 5. februar 2012 Del Skrevet 5. februar 2012 (endret) Da tror jeg jeg har misforstått veldig hvordan den fungerer. ;_; Beklager. Det gir for øvrig mening at det blir ["element"] dersom en tom liste legges til først for ikke-eksisterende keys, før den forsøker hva enn en spurte om, om jeg har skjønt det riktig nå, ja? Endret 5. februar 2012 av Yumekui Lenke til kommentar
zotbar1234 Skrevet 5. februar 2012 Del Skrevet 5. februar 2012 Det gir for øvrig mening at det blir ["element"] dersom en tom liste legges til først for ikke-eksisterende keys, før den forsøker hva enn en spurte om, om jeg har skjønt det riktig nå, ja? Jepp. Lenke til kommentar
kim009 Skrevet 16. april 2012 Del Skrevet 16. april 2012 Noe info som de gir for ett prosjekt i et fag på NTNU som går ut på å lage en poker AI. Min sugde da jeg feilberegna kraftig på hvor lang til jeg ville bruke (hadd eikke brukt python før heller). div materiale pdf assignment cards.py Lenke til kommentar
slacky Skrevet 23. april 2012 Forfatter Del Skrevet 23. april 2012 Se der, ja! Får vel takke for linkene - skal se over det. Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå