Un jeu de cartes
- #include "OL.h"
- extern class Deck;
- 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.
- #include "So-o.h"
- #include "Deck.h"
- #include "Hand.h"
- #include "Card.h"
- #include <string.h>
- class Deck;
Inclut les signatures des fonctions de So-o. Inclut les déclarations de la classe Deck. Définit la classe Deck.
- static instance i_init(instance self, va_list va) {
- int swe = va_arg(va, int);
- supersend(Deck, self, "init");
- sendmsg(self, "set", "shuffleWhenEmpty", swe ? 1 : 0);
- list cards = list_new();
- for (int s = 0; s < 4; s++)
- for (int r = 0; r < 13; r++)
- list_put(cards, 13*s+r, sendmsg(Card, "new", r, s).p);
- sendmsg(self, "set", "cards", cards);
- sendmsg(self, "set", "top", 0);
- return self;
- }
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.
- static void i_free(instance self) {
- list cards = sendmsg(self, "get", "cards").p;
- for (int n = 0; n < 52; n++)
- sendmsg(list_get(cards, n), "free");
- list_free(cards);
- supersend(Deck, self, "free");
- }
free
libère toutes les cartes de self
puis la liste qui les contenait.
- static instance i_shuffle(instance self) {
- list_shuffle(sendmsg(self, "get", "cards").p);
- sendmsg(self, "set", "top", 0);
- return self;
- }
shuffle
mélange la liste qui contient les cartes de self
et remet sa propriété top
à 0.
- static instance i_deal(instance self) {
- list cards = sendmsg(self, "get", "cards").p;
- int top = sendmsg(self, "get", "top").i;
- instance c = list_get(cards, top);
- if (++top >= 52) {
- if (sendmsg(self, "get", "shuffleWhenEmpty").i)
- sendmsg(self, "shuffle");
- top = 0;
- }
- sendmsg(self, "set", "top", top);
- return c;
- }
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é.
- static instance i_hand(instance self) {
- instance card1 = sendmsg(self, "deal").p;
- instance card2 = sendmsg(self, "deal").p;
- instance card3 = sendmsg(self, "deal").p;
- instance card4 = sendmsg(self, "deal").p;
- instance card5 = sendmsg(self, "deal").p;
- return sendmsg(Hand, "new", card1, card2, card3, card4, card5).p;
- }
hand
retourne une nouvelle main de 5 cartes tirées de self
.
- static instance i_setHand(instance self, va_list va) {
- instance hand = va_arg(va, instance);
- instance card1 = sendmsg(self, "deal").p;
- instance card2 = sendmsg(self, "deal").p;
- instance card3 = sendmsg(self, "deal").p;
- instance card4 = sendmsg(self, "deal").p;
- instance card5 = sendmsg(self, "deal").p;
- return sendmsg(hand, "reset", card1, card2, card3, card4, card5).p;
- }
setHand
initialise la main passée en paramètre avec 5 cartes tirées de self
.
- static char *i_toString(instance self) {
- static char s[52*2+51+3+1];
- list cards = sendmsg(self, "get", "cards").p;
- int top = sendmsg(self, "get", "top").i;
- char *p = s;
- sprintf(s, "%s -> ", (char *)sendmsg(list_get(cards, top), "toString").p);
- p += strlen(s);
- for (int i = 0; i < list_length(cards); i++) {
- if (i > 0)
- *p++ = ',';
- strcpy(p, sendmsg(list_get(cards, i), "toString").p);
- p += 2;
- }
- return s;
- }
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.
- void defclassDeck() {
- property _i_properties[] = {
- "cards",
- "top",
- "shuffleWhenEmpty",
- 0, 0
- };
- selector _i_messages[] = {
- "init", METHOD(i_init),
- "free", METHOD(i_free),
- "shuffle", METHOD(i_shuffle),
- "deal", METHOD(i_deal),
- "hand", METHOD(i_hand),
- "setHand", METHOD(i_setHand),
- "toString", METHOD(i_toString),
- 0, 0
- };
- Deck = defclass("Deck", 0, 1, 0, _i_properties, 0, _i_messages);
- }
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
Commentaires