10

A deck of cards

  1. #include "OL.h"
  2.  
  3. extern class Deck;
  4.  
  5. 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.

  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;

Includes the signatures of the So-o functions. Includes the declarations of the class Deck. Defines the class 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 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.

  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 frees all the cards of self then the list which contained them.

  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 shuffles the list which contains the cards of self and resets its property top to 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 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.

  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 returns a new hand of 5 cards drawn from 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 initializes the hand passed as a parameter to 5 cards drawn from 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 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.

  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. }

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
SEE ALSO

Card, Hand

Comments

Your comment:
[p] [b] [i] [u] [s] [quote] [pre] [br] [code] [url] [email] strip help 2000

Enter a maximum of 2000 characters.
Improve the presentation of your text with the following formatting tags:
[p]paragraph[/p], [b]bold[/b], [i]italics[/i], [u]underline[/u], [s]strike[/s], [quote]citation[/quote], [pre]as is[/pre], [br]line break,
[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]command[/code], [code=language]source code in c, java, php, html, javascript, xml, css, sql, bash, dos, make, etc.[/code].