Un jeu de cartes

  1. #include "OL.h"
  2.  
  3. extern class Deck;
  4.  
  5. extern void defclassDeck();

Inclut les définitions des types de données et les signatures des fonctions de l'Object Layer. Déclare la classe Deck et la fonction defclassDeck qui la construit.

  1. #include "So-o.h"
  2.  
  3. #include "Deck.h"
  4. #include "Hand.h"
  5. #include "Card.h"
  6.  
  7. #include <string.h>
  8.  
  9. class Deck;

Inclut les signatures des fonctions de So-o. Inclut les déclarations de la classe Deck. Définit la classe Deck.

  1. static instance i_init(instance self, va_list va) {
  2.     int swe = va_arg(va, int);
  3.  
  4.     supersend(Deck, self, "init");
  5.  
  6.     sendmsg(self, "set", "shuffleWhenEmpty", swe ? 1 : 0);
  7.  
  8.     list cards = list_new();
  9.  
  10.     for (int s = 0; s < 4; s++)
  11.         for (int r = 0; r < 13; r++)
  12.             list_put(cards, 13*s+r, sendmsg(Card, "new", r, s).p);
  13.  
  14.     sendmsg(self, "set", "cards", cards);
  15.     sendmsg(self, "set", "top", 0);
  16.  
  17.     return self;
  18. }

init a 1 argument, un drapeau qui indique si le jeu est automatiquement mélangé quand toutes les cartes ont été tirées. Elle initialise la propriété shuffleWhenEmpty de self avec la valeur de ce paramètre, puis elle alloue un conteneur de type list, le remplit avec les 52 cartes d'un jeu complet et initialise la propriété cards de self avec. Elle initialise la propriété top de self qui pointe sur la prochaine carte qui sera tirée à 0.

  1. static void i_free(instance self) {
  2.     list cards = sendmsg(self, "get", "cards").p;
  3.  
  4.     for (int n = 0; n < 52; n++)
  5.         sendmsg(list_get(cards, n), "free");
  6.  
  7.     list_free(cards);
  8.  
  9.     supersend(Deck, self, "free");
  10. }

free libère toutes les cartes de self puis la liste qui les contenait.

  1. static instance i_shuffle(instance self) {
  2.     list_shuffle(sendmsg(self, "get", "cards").p);
  3.  
  4.     sendmsg(self, "set", "top", 0);
  5.  
  6.     return self;
  7. }

shuffle mélange la liste qui contient les cartes de self et remet sa propriété top à 0.

  1. static instance i_deal(instance self) {
  2.     list cards = sendmsg(self, "get", "cards").p;
  3.     int top = sendmsg(self, "get", "top").i;
  4.  
  5.     instance c = list_get(cards, top);
  6.  
  7.     if (++top >= 52) {
  8.         if (sendmsg(self, "get", "shuffleWhenEmpty").i)
  9.             sendmsg(self, "shuffle");
  10.         top = 0;
  11.     }
  12.  
  13.     sendmsg(self, "set", "top", top);
  14.  
  15.     return c;
  16. }

deal retourne la carte en haut de la pile du jeu de cartes de self et met la valeur de sa propriété top à la position de la prochaine carte dans le jeu. Si toutes les cartes du jeu ont été tirées, la propriété top de self est remise à 0 et si le drapeau shuffleWhenEmpty de self est vrai, le jeu est mélangé.

  1. static instance i_hand(instance self) {
  2.     instance card1 = sendmsg(self, "deal").p;
  3.     instance card2 = sendmsg(self, "deal").p;
  4.     instance card3 = sendmsg(self, "deal").p;
  5.     instance card4 = sendmsg(self, "deal").p;
  6.     instance card5 = sendmsg(self, "deal").p;
  7.  
  8.     return sendmsg(Hand, "new", card1, card2, card3, card4, card5).p;
  9. }

hand retourne une nouvelle main de 5 cartes tirées de self.

  1. static instance i_setHand(instance self, va_list va) {
  2.     instance hand = va_arg(va, instance);
  3.  
  4.     instance card1 = sendmsg(self, "deal").p;
  5.     instance card2 = sendmsg(self, "deal").p;
  6.     instance card3 = sendmsg(self, "deal").p;
  7.     instance card4 = sendmsg(self, "deal").p;
  8.     instance card5 = sendmsg(self, "deal").p;
  9.  
  10.     return sendmsg(hand, "reset", card1, card2, card3, card4, card5).p;
  11. }

setHand initialise la main passée en paramètre avec 5 cartes tirées de self.

  1. static char *i_toString(instance self) {
  2.     static char s[52*2+51+3+1];
  3.  
  4.     list cards = sendmsg(self, "get", "cards").p;
  5.     int top = sendmsg(self, "get", "top").i;
  6.  
  7.     char *p = s;
  8.  
  9.     sprintf(s, "%s -> ", (char *)sendmsg(list_get(cards, top), "toString").p);
  10.  
  11.     p += strlen(s);
  12.  
  13.     for (int i = 0; i < list_length(cards); i++) {
  14.         if (i > 0)
  15.             *p++ = ',';
  16.         strcpy(p, sendmsg(list_get(cards, i), "toString").p);
  17.         p += 2;
  18.     }
  19.  
  20.     return s;
  21. }

toString retourne une chaîne de caractères montrant la liste toutes les cartes de self et la prochaine carte qui sera tirée. Cette chaîne est formatée dans une zone statique. Il faut s'en servir avant de rappeler cette methode.

  1. void defclassDeck() {
  2.     property _i_properties[] = {
  3.         "cards",
  4.         "top",
  5.         "shuffleWhenEmpty",
  6.         0, 0
  7.     };
  8.     selector _i_messages[] = {
  9.         "init",     METHOD(i_init),
  10.         "free",     METHOD(i_free),
  11.         "shuffle",  METHOD(i_shuffle),
  12.         "deal",     METHOD(i_deal),
  13.         "hand",     METHOD(i_hand),
  14.         "setHand",  METHOD(i_setHand),
  15.         "toString", METHOD(i_toString),
  16.         0, 0
  17.     };
  18.  
  19.     Deck = defclass("Deck", 0, 1, 0, _i_properties, 0, _i_messages);
  20. }

Initialise la classe Deck. La classe Deck hérite de la classe Object. Une instance a 3 propriétés : cards, les 52 cartes du jeu, top, le numéro de la carte en haut de la pile du jeu, i.e. la prochaine carte qui sera tirée, et shuffleWhenEmpty qui indique si le jeu est automatiquement mélangé lorsque toutes les cartes ont été tirées. Une instance redéfinit les messages init, free et toString. Elle implémente les messages shuffle, deal, hand et setHand.

TEST

Compilez et exécutez le test unitaire :

$ make test-Deck
gcc -g -I.. -Wno-missing-braces -O -fstrength-reduce -finline-functions -fomit-frame-pointer -c test-Deck.c
gcc -g -I.. -Wno-missing-braces -O -fstrength-reduce -finline-functions -fomit-frame-pointer -c Deck.c
gcc -g test-Deck.o Deck.o Hand.o Card.o ../libso-o.a -o test-Deck$ test-Deck
$ test-Deck

Total non-mmapped bytes (arena):       675840
# of free chunks (ordblks):            1
Total allocated space (uordblks):      555616
Total free space (fordblks):           120224
Topmost releasable block (keepcost):   120096

2c -> 2c,3c,4c,5c,6c,7c,8c,9c,Tc,Jc,Qc,Kc,Ac,2d,3d,4d,5d,6d,7d,8d,9d,Td,Jd,Qd,Kd,Ad,2h,3h,4h,5h,6h,7h,8h,9h,Th,Jh,Qh,Kh,Ah,2s,3s,4s,5s,6s,7s,8s,9s,Ts,Js,Qs,Ks,As
2c
3c
Js -> Js,Jc,7d,Ad,Ks,8h,6c,8c,Qh,4d,Qd,Qc,5d,3c,7h,Ah,5h,2d,2s,9h,Ac,7s,Ts,6h,Kh,8s,8d,5c,3d,Qs,9d,7c,4h,Tc,6s,Jh,2c,Td,As,Kd,Jd,4c,Kc,5s,9s,4s,2h,9c,6d,Th,3s,3h
Js,Jc,7d,Ad,Ks -> ONEPAIR
8h,6c,8c,Qh,4d -> ONEPAIR
Qd,Qc,5d,3c,7h -> ONEPAIR
Ah,5h,2d,2s,9h -> ONEPAIR
Ac,7s,Ts,6h,Kh -> NOTHING
8s,8d,5c,3d,Qs -> ONEPAIR
9d,7c,4h,Tc,6s -> NOTHING
Jh,2c,Td,As,Kd -> NOTHING
Jd,4c,Kc,5s,9s -> NOTHING
4s,2h,9c,6d,Th -> NOTHING
Dealing 1000000 hands.......... in 3.27 s!
       NOTHING -> 50.63% 506317
       ONEPAIR -> 41.51% 415135
      TWOPAIRS ->  4.46% 44609
   THREEOFKIND ->  2.35% 23460
      STRAIGHT ->  0.49% 4896
         FLUSH ->  0.25% 2516
     FULLHOUSE ->  0.15% 1465
    FOUROFKIND ->  0.03% 306
 STRAIGHTFLUSH ->  0.13% 1296

Total non-mmapped bytes (arena):       675840
# of free chunks (ordblks):            1
Total allocated space (uordblks):      561232
Total free space (fordblks):           114608
Topmost releasable block (keepcost):   32352
VOIR AUSSI

Card, Hand

Commentaires

Votre commentaire :
[p] [b] [i] [u] [s] [quote] [pre] [br] [code] [url] [email] strip aide 2000

Entrez un maximum de 2000 caractères.
Améliorez la présentation de votre texte avec les balises de formatage suivantes :
[p]paragraphe[/p], [b]gras[/b], [i]italique[/i], [u]souligné[/u], [s]barré[/s], [quote]citation[/quote], [pre]tel quel[/pre], [br]à la ligne,
[url]http://www.izend.org[/url], [url=http://www.izend.org]site[/url], [email]izend@izend.org[/email], [email=izend@izend.org]izend[/email],
[code]commande[/code], [code=langage]code source en c, java, php, html, javascript, xml, css, sql, bash, dos, make, etc.[/code].