Προς το περιεχόμενο

Console Video Poker σε C (Jacks or Better)


migf1

Προτεινόμενες αναρτήσεις

Δημοσ. (επεξεργασμένο)

Με αφορμή ένα νήμα στο φόρουμ του adsl.gr ( http://www.adslgr.co...mentation-fault ) έγραψα ένα μικρό Jacks or Better ποκερ κονσόλας/τερματικού, σε C (το Jacks or Better είναι το δημοφιλέστερο μηχάνημα πόκερ στα καζίνο, κυρίως στην Αμερική).

 

 

 

Betting

post-38307-0-33280300-1347005605_thumb.jpg

 

Dealing

post-38307-0-22841400-1347005608_thumb.jpg

 

Drawing

post-38307-0-63233400-1347005611_thumb.jpg

 

Help

post-38307-0-46949000-1347005615_thumb.jpg

 

 

 

Downloads:

 

EDIT: Τελικά το ανέβασα στην σελίδα μου: http://x-karagiannis.gr/prg/c-prog/c-games/cv-poker/. Σε τυχόν περαιτέρω βελτιώσεις (πολύ χλωμό) θα τις ανεβάζω εκεί και θα ενημερώνω εδώ. Ευχαριστώ όλους για το feedback. Αφήνω κι εδώ τα download links, να υπάρχουν.

 

cvpoker06_public.zip ( αλλάγές )

cvpoker05_public.zip

 

Σχετικά με την αρχική έκδοση (0.5)

 

Το έβαλα κι εδώ, γιατί νομίζω στο adsl.gr δεν μπορεί να κατέβει χωρίς εγγραφή στο φόρουμ (ούτε να μεγεθυνθούν οι εικόνες, αν δεν απατώμαι). Η σχετική δημοσίευση εκεί που εξηγεί και 5 πράγματα για τα περιεχόμενα του zip είναι αυτή εδώ: http://www.adslgr.co...286#post4801286 (εν ολίγοις, εκτός από τον κώδικα, περιέχει και εκτελέσιμα για Windows).

 

Στις προηγούμενες δημοσιεύσεις εκείνου του νήματος μπορεί κανείς να παρακολουθήσει το μικρό ιστορικό εξέλιξης με "καθαρό" κώδικα, χωρίς δηλαδή εντολές χρωματιστής εξόδου, που περιπλέκουν & μεγαλώνουν τον τελικό κώδικα. Btw, αυτό το τελευταίο γίνεται με μια ελαφρώς βελτιωμένη έκδοση του "con_color.h", του mini, x-platform C/C++ interface που είχα φτιάξει στα πλαίσια του HexViewer ).

 

Τέλος, σε αυτό εδώ το post: http://www.adslgr.co...742#post4797742 υπάρχει κώδικας που παίζει κι αξιολογεί από 1 έως 10 παίκτες ανά γύρο, αλλά έχει ένα bug σε περίπτωση ισοδυναμίας φύλλων 2 ή περισσότερων παικτών (εκτός αν έχουν ΟΛΟΙ ισοδύναμα φύλλα, οπότε λειτουργεί σωστά). Κάθε ιδέα επίλυσής του, καλοδεχούμενη.

 

ΥΓ. Ο αλγόριθμος αξιολόγησης των φύλλων είναι brute-force. Υπάρχουν έτοιμοι φοβεροί αλγόριθμοι, οι οποίοι ως επί το πλείστον χρησιμοποιούν έτοιμους πίνακες (έως και 260Mb για hands των 7 φύλλων, για 5 φύλλα είναι πολύ μικρότεροι) μετατρέποντας το κάθε hand σε έναν μοναδικό ακέραιο αξιολόγησης.

 

Χρησιμοποιούν επίσης bit-masks και bit-operations, αφού το κάθε χαρτί το αποθηκεύουν σε μόλις 2 ή 4 bytes, όπως για παράδειγμα ο Cactus Kev evaluator

 

Για όσους ενδιαφέρονται, το παραπάνω link είναι πολύ χρήσιμο μιας και αποτελεί μέρος ενός γενικότερου poker hand evaluators round-up.

Επεξ/σία από migf1
  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Καλο φαινεται, το δοκιμασα χωρις να ξερω να παιζω ποκερ. Την καλυτερη γνωμη θα σου την πει καποιος που ξερει να παιζει ποκερ και θα το δοκιμασει. H κονσολα παντα μου θυμιζει εποχη Ms-Dos. Πιστευω οτι αν το εκανες σε γραφικο περιβαλλον θα ηταν τελειο.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Καλο φαινεται, το δοκιμασα χωρις να ξερω να παιζω ποκερ. Την καλυτερη γνωμη θα σου την πει καποιος που ξερει να παιζει ποκερ και θα το δοκιμασει. H κονσολα παντα μου θυμιζει εποχη Ms-Dos. Πιστευω οτι αν το εκανες σε γραφικο περιβαλλον θα ηταν τελειο.

 

Ευχαριστώ για το feedback!

 

Πάντως είναι βαβούρα να μετατραπεί σε γραφικό περιβάλλον, για 2 βασικούς λόγους:

 

1. Η υπάρχουσα λογική του κώδικα όχι μόνο ΔΕΝ είναι event-driven, αλλά δεν διαχωρίζει καν το I/O από τον πυρήνα. Οπότε με εξαίρεση κάποιες ελάχιστες συναρτήσεις, όλος ο υπόλοιπος κώδικας πρέπει να ξαναγραφτεί από την αρχή.

 

2. Θα πρέπει να κάτσω να διαβάσω το API του όποιου γραφικού περιβάλλοντος, που για να τρέχει παντού με απλό re-compilation του κώδικα θα πρέπει να είναι cross-platform, και μιας και μιλάμε για C αυτό σημαίνει ούτε λίγο ούτε πολύ GTK+2 (μιας και το GTK+3 δεν υπάρχει για Windows).

 

Too much overhead για το συγκεκριμένο πρόγραμμα, IMHO. Το πρόγραμμα είναι πολύ απλοϊκά γραμμένο.

 

Για παράδειγμα δεν προβλέπει ρύθμιση των πιθανοτήτων νίκης του παίκτη (κανονικά θα πρέπει να ρυθμίζεται εσωτερικά), δεν παρέχει δυνατότητα συμβουλών στον παίκτη για το ποια χαρτιά να κρατήσει και ποια να απορρίψει (π.χ. αν δεις άλλες υλοποιήσεις, σου επιλέγουν αυτόματα ποια χαρτιά να κρατήσεις, όταν σου μοιράζονται ... ή έστω σου δίνουν τη δυνατότητα να επιλέξεις αν θες αυτού του είδους τη βοήθεια ή όχι) κλπ.

 

Παρεμπιπτόντως, επειδή ουσιαστικά είναι γραμμένο στο πόδι και ο κώδικας περιέχει λιγότερα από τα απαραίτητα σχόλια, μια μικρή σύνοψη του τρόπου που λειτουργεί υπάρχει σε αυτό το νήμα: http://www.adslgr.co...56#post4795856. Αναφέρεται στον κώδικα που διαχειρίζεται πολλούς παίκτες, αλλά η γενική ιδέα είναι η ίδια. Π.χ. η εξήγηση του τι είναι και τι κάνει το πεδίο: hand->groupedFaces[2];

 

Όπως και να 'χει, έτσι όπως είναι τώρα τουλάχιστον γίνεται compile σχεδόν σε οποιαδήποτε πλατφόρμα, με οποιονδήποτε C99 compiler (or at least that I hope :P )

 

ΥΓ. Πάνως αν θέλει κανείς να του βάλει γραφικό περιβάλλον, by all means do :)

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ωραίο φαινεται

 

Thanks, αν και έχει bug ... και μάλιστα και στο screenshot! Την κέντα στο 6 την αναφέρει ως κέντα στο 5 (STRAIGHT ON 5). Το ίδιο σφάλμα κάνει και στα αντίστοιχα φλος στο 6 (τα αναφέρει ως STRAIGHT FLUSH ON 5) . Οφείλεται στον κώδικα που προσπαθεί να εντοπίσει τον Άσο ως χαμηλό χαρτί στις κέντες και στα φλος.

 

Είναι το σώμα του case 1: στο switch της hand_eval_rank(). Πρέπει να φτιάχνει αν αντικατασταθεί με το παρακάτω κώδικα...

 

 

 

>
...
       case 1:    // either RoyalFlush or StraightFlush or Flush or Straight or HighCard
       {
           bool isConsecutive = hand_is_consecutive( hand );
           bool isSameSuit = hand_is_samesuit( hand );
           bool isLowAce    = isConsecutive    
                   && 0 == hand->cards[0]->face    // is hand's lowest face a TWO?
                   && NFACES-1 == hand->maxface;    // is hand's highest face an ACE?

           if ( isLowAce ) {
               hand->imax     = HAND_NCARDS - 2;
               hand->maxface     = hand->cards[ hand->imax ]->face;
               hand->rank     = isSameSuit
                           ? HR_STRAIGHT_FLUSH
                           : HR_STRAIGHT;
           }
           else if ( isConsecutive && isSameSuit ) {
               hand->rank     = NFACES-1 == hand->maxface
                           ? HR_ROYAL_FLUSH
                           : HR_STRAIGHT_FLUSH;
           }
           else if ( isSameSuit ) {
               hand->rank = HR_FLUSH;
           }
           else if ( isConsecutive ) {
               hand->rank = HR_STRAIGHT;
           }
           else {
               hand->rank = HR_HIGH_CARD;
           }
           break;
       }

...

 

 

 

Μια ερώτηση ομως. Γιατι δεν χρησιμοποιειες αυτα :

 

Διότι δεν υπάρχουν σε όλες τις ANSI κωδικοσελίδες στην κονσόλα των Windows (η οποία έχει θέματα και με το Unicode, οπότε θα έπρεπε να γράψω Windows specific κώδικα).

 

Παρεμπιπτόντως, μια γρήγορη αλλά ελλιπής προσθήκη για να κάνει Hold αυτόματα τυχόν ζευγάρια, τριπλές, φουλ και καρέ στην πρώτη μοιρασιά (dealing) είναι η εξής ρουτίνα...

 

 

 

>
/* ***********************************************
*
*/
bool hand_auto_hold( const Hand *hand )
{
   if ( !hand )
       return false;

   for (int i=0; i < HAND_NCARDS; i++)
       for (int j=0; j < HAND_MAXGROUPS; j++)
           if ( hand->cards[i]->face == hand->groupedFaces[j] )
               hand->cards[i]->isHeld = true;
   return true;
}

 

 

 

η οποία μπορεί να καλεστεί στο for-loop της main(), αμέσως πριν την εκτύπωση των σχετικών επιλογών με την print_hold_menu() ...

 

>
...
       for (;                // hold-options loop
       {
           status_print_info_bar( &status );
           hand_display( &hand );
       hand_auto_hold( &hand );
           print_hold_menu( &hand );
...

 

Είναι ελλιπής όμως διότι κανονικά πρέπει να προστεθεί κι άλλος κώδικας, ώστε να επιλέγει αυτόματα κι άλλες περιπτώσεις, π.χ. όταν υπάρχουν 4 χαρτιά με ίδια suits (για χρώμα ή φλος), ή όταν υπάρχουν 4 συνεχόμενα χαρτιά με διαφορετικά suits (για κέντα) κλπ.

 

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)

Προσέθεσα στο 1ο ποστ του νήματος βελτιωμένο κώδικα. Φτιάχνει το bug με τον Άσο ως χαμηλό φύλλο στις κέντες/φλος και πλέον "προτείνει" ποια χαρτιά να κρατήσει ο παίκτης μετά από κάθε μοίρασμα, εμφανίζοντάς τα κρατημένα αυτόματα (auto-held).

 

Οι αλγόριθμοι των...

 

>
bool hand_eval_auto_hold( Hand *hand );
bool hand_hold_4_to_straight( Hand *hand );

 

είναι ολίγον (έως πολύ) για κλωστιές, αλλά δεν υπήρχε περίπτωση να φτιάξω στο πόδι κανονικό video strategy calculator για Jacks or Better. Μπορείτε πάντως να συγκρίνεται τα αποτελέσματα του calculator του CVPoker (λέμε και καμια... m@l@ki@ να περάσει η ώρα :lol: ) με κάποιον από τους διάφορους διαθέσιμους, π.χ. αυτόν: http://www.beatingbonuses.com/vp.php.

 

Πέρα από τη πλάκα πάντως, στις συνήθεις περιπτώσεις δεν βγάζει και τόσο αίσχος αποτελέσματα (παρόλο που είναι γραμμένος τελείως... νουμπάδικα).

 

Έχω βάλει σχόλια στον κώδικα των παραπάνω συναρτήσεων, για όποιον έχει την περιέργεια να δει... αλλά είναι παράδειγμα προς αποφυγή για κανονικό game!

 

EDIT: διόρθωση του link.

Επεξ/σία από migf1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Το 'βαλα τελικά στην σελίδα μου το παιχνιδάκι, κι έγραψα και 5 παραπάνω πράγματα για τις δομές δεδομένων που χρησιμοποιεί, σε περίπτωση που θελήσει κανείς να το βελτιώσει. Έβαλα και σχετικό EDIT στο 1ο ποστ αυτού του νήματος. Thanks άπαντες για το feedback.

 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...