A deck of cards
- #include "OL.h"
- extern class Deck;
- extern void defclassDeck();
Includes the definitions of the data types and the signatures of the functions of the Object Layer.
Declares the class Deck and the function defclassDeck
which builds it.
- #include "So-o.h"
- #include "Deck.h"
- #include "Hand.h"
- #include "Card.h"
- #include <string.h>
- class Deck;
Includes the signatures of the So-o functions. Includes the declarations of the class Deck. Defines the class 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
has 1 argument, a flag which indicates if the deck is automatically shuffled when all the cards have been drawn.
It initializes the property shuffleWhenEmpty of self
with the value of this parameter, then is allocates a container of type list
, fills it with the 52 cards of a whole deck and initializes the property cards of self
with it. It initializes the property top of self
which points to card which will be drawn next to 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
frees all the cards of self
then the list which contained them.
- static instance i_shuffle(instance self) {
- list_shuffle(sendmsg(self, "get", "cards").p);
- sendmsg(self, "set", "top", 0);
- return self;
- }
shuffle
shuffles the list which contains the cards of self
and resets its property top
to 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
returns the card on the top of the deck of cards of self
and sets the value of its property top
to the position of the next card in the deck.
If all the cards of deck have been drawn, the property top
of self
is reset to 0 and if the flag shuffleWhenEmpty
of self
is true, the deck is shuffled.
- 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
returns a new hand of 5 cards drawn from 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
initializes the hand passed as a parameter to 5 cards drawn from 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
returns a string showing the list of all the cards in self
and the card which will be drawn next.
This string is formatted in a static area. It must be used before this method is called again.
- 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);
- }
Initializes the class Deck. The class Deck inherits from the class Object. An instance has 3 propertie: cards, the 52 cards of the deck, top, the number of the card on the top of the deck, and shuffleWhenEmpty which indicates if the deck is automatically shuffled when all the cards have been drawn. An instance redefines the messages init, free and toString. It implements the messages shuffle, deal, hand and setHand.
TEST
Compile and run the unitary test:
$ 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
Comments