9

Une main

  1. #include "OL.h"
  2.  
  3. extern class Hand;
  4.  
  5. extern void defclassHand();
  6.  
  7. #define NOTHING         0
  8. #define ONEPAIR         1
  9. #define TWOPAIRS        2
  10. #define THREEOFKIND     3
  11. #define STRAIGHT        4
  12. #define FLUSH           5
  13. #define FULLHOUSE       6
  14. #define FOUROFKIND      7
  15. #define STRAIGHTFLUSH   8

Inclut les définitions des types de données et les signatures des fonctions de l'Object Layer. Déclare la classe Hand et la fonction defclassHand qui la construit. Définit des constantes pour les différentes valeurs possibles d'une main.

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

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

  1. static int cardcmp(instance card1, instance card2) {
  2.     return sendmsg(card1, "compare", card2).i;
  3. }

La fonction cardcmp compare 2 cartes avec la méthode compare d'une Card. Elle est utilisée par la méthode reorder.

  1. static instance i_init(instance self, va_list va) {
  2.     instance card1 = va_arg(va, instance);
  3.     instance card2 = va_arg(va, instance);
  4.     instance card3 = va_arg(va, instance);
  5.     instance card4 = va_arg(va, instance);
  6.     instance card5 = va_arg(va, instance);
  7.  
  8.     supersend(Hand, self, "init");
  9.  
  10.     list cards = list_new();
  11.  
  12.     list_put(cards, 0, card1);
  13.     list_put(cards, 1, card2);
  14.     list_put(cards, 2, card3);
  15.     list_put(cards, 3, card4);
  16.     list_put(cards, 4, card5);
  17.  
  18.     sendmsg(self, "set", "cards", cards);
  19.  
  20.     return self;
  21. }

init prend 5 arguments, les 5 cartes de la main. Elle alloue un conteneur de type list, le remplit avec les cartes et initialise la propriété cards de self avec.

  1. static void i_free(instance self) {
  2.     list cards = sendmsg(self, "get", "cards").p;
  3.  
  4.     list_free(cards);
  5.  
  6.     supersend(Hand, self, "free");
  7. }

free libère la liste de cartes de self. Elle ne libère pas les cartes.

  1. static instance i_copy(instance self) {
  2.     instance copy = supersend(Hand, self, "copy").p;
  3.  
  4.     sendmsg(copy, "set", "cards", list_copy(sendmsg(self, "get", "cards").p));
  5.  
  6.     return copy;
  7. }

copy retourne une copie de self. Elle affecte à la propriété cards de copy une copie de la liste des cartes de self.

  1. static instance i_reorder(instance self) {
  2.     list cards = sendmsg(self, "get", "cards").p;
  3.  
  4.     list_sort(cards, (int (*)(void *, void *))cardcmp, 1);
  5.  
  6.     return self;
  7. }

reorder ordonne les cartes de self de la valeur la plus petite à la plus forte. 2 cartes sont comparées avec la fonction cardcmp en envoyant le message compare à une carte avec une autre en argument.

  1. static instance i_reset(instance self, va_list va) {
  2.     instance card1 = va_arg(va, instance);
  3.     instance card2 = va_arg(va, instance);
  4.     instance card3 = va_arg(va, instance);
  5.     instance card4 = va_arg(va, instance);
  6.     instance card5 = va_arg(va, instance);
  7.  
  8.     list cards = sendmsg(self, "get", "cards").p;
  9.  
  10.     list_put(cards, 0, card1);
  11.     list_put(cards, 1, card2);
  12.     list_put(cards, 2, card3);
  13.     list_put(cards, 3, card4);
  14.     list_put(cards, 4, card5);
  15.  
  16.     return self;
  17. }

reset remplit la liste de cartes de self avec les 5 cartes passées en argument.

  1. static instance i_card(instance self, va_list va) {
  2.     int n = va_arg(va, int);
  3.  
  4.     if (n < 1 || n > 5) {
  5.         return sendmsg(self, "invalidArgument", "card").p;
  6.     }
  7.  
  8.     list cards = sendmsg(self, "get", "cards").p;
  9.  
  10.     return (instance)list_get(cards, n-1);
  11. }

card retourne la carte n de self. Si n est < 1 ou > 5, une erreur InvalidArgument est déclenchée.

  1. static instance i_setCard(instance self, va_list va) {
  2.     int n = va_arg(va, int);
  3.     instance card = va_arg(va, instance);
  4.  
  5.     if (n < 1 || n > 5) {
  6.         return sendmsg(self, "invalidArgument", "setCard").p;
  7.     }
  8.  
  9.     list cards = sendmsg(self, "get", "cards").p;
  10.  
  11.     list_put(cards, n-1, card);
  12.  
  13.     return self;
  14. }

setCard met la carte n de self à card. Si n est < 1 ou > 5, une erreur InvalidArgument est déclenchée.

  1. static char *i_toString(instance self) {
  2.     static char *handnames[] = { "NOTHING", "ONEPAIR", "TWOPAIRS", "THREEOFKIND", "STRAIGHT", "FLUSH", "FULLHOUSE", "FOUROFKIND", "STRAIGHTFLUSH" };
  3.  
  4.     static char s[5*2+4+4+13+1];
  5.  
  6.     char *p = s;
  7.  
  8.     int eval = sendmsg(self, "evaluate").i;
  9.  
  10.     list cards = sendmsg(self, "get", "cards").p;
  11.  
  12.     for (int i = 0; i < list_length(cards); i++) {
  13.         if (i > 0)
  14.             *p++ = ',';
  15.         strcpy(p, (char *)sendmsg((instance)list_get(cards, i), "toString").p);
  16.         p += 2;
  17.     }
  18.  
  19.     sprintf(p, " -> %s", handnames[eval]);
  20.  
  21.     return s;
  22. }

toString retourne une chaîne de caractères contenant la valeur et la couleur des 5 cartes de self et la valeur de la main. Cette chaîne est formatée dans une zone statique. Il faut s'en servir avant de rappeler cette methode.

  1. static int i_evaluate(instance self) {
  2.     // sort or nothing works but don't reoder the hand!
  3.     list cards = list_sort(list_copy(sendmsg(self, "get", "cards").p), (int (*)(void *, void *))cardcmp, 1);
  4.  
  5.     instance card1 = list_get(cards, 0);
  6.     instance card2 = list_get(cards, 1);
  7.     instance card3 = list_get(cards, 2);
  8.     instance card4 = list_get(cards, 3);
  9.     instance card5 = list_get(cards, 4);
  10.  
  11.     int r1 = sendmsg(card1, "rank").i;
  12.     int r2 = sendmsg(card2, "rank").i;
  13.     int r3 = sendmsg(card3, "rank").i;
  14.     int r4 = sendmsg(card4, "rank").i;
  15.     int r5 = sendmsg(card5, "rank").i;
  16.  
  17.     int s1 = sendmsg(card1, "suit").i;
  18.     int s2 = sendmsg(card2, "suit").i;
  19.     int s3 = sendmsg(card3, "suit").i;
  20.     int s4 = sendmsg(card4, "suit").i;
  21.     int s5 = sendmsg(card5, "suit").i;
  22.  
  23.     int ret = NOTHING;
  24.  
  25.     // STRAIGHTFLUSH - a(a+1)(a+2)(a+3)(a+4)
  26.  
  27.     if (r5 == r4+1 && r4 == r3+1 && r3 == r2+1 && r2 == r1+1 &&
  28.         s1 == s2 && s2 == s3 && s3 == s4 && s4 == s5)
  29.         ret = STRAIGHTFLUSH;
  30.  
  31.     // FOUROFKIND - aaaab abbbb
  32.  
  33.     else if (r1 == r2 && r2 == r3 && r3 == r4)
  34.         ret = FOUROFKIND;
  35.  
  36.     else if (r2 == r3 && r3 == r4 && r4 == r5)
  37.         ret = FOUROFKIND;
  38.  
  39.     // FULLHOUSE - aaabb aabbb
  40.  
  41.     else if (r1 == r2 && r2 == r3 && r3 != r4 && r4 == r5)
  42.         ret = FULLHOUSE;
  43.  
  44.     else if (r1 == r2 && r2 != r3 && r3 == r4 && r4 == r5)
  45.         ret = FULLHOUSE;
  46.  
  47.     // FLUSH
  48.  
  49.     else if (s1 == s2 && s2 == s3 && s3 == s4 && s4 == s5)
  50.         ret = FLUSH;        // could be a straight flush
  51.  
  52.     // STRAIGHT - a(a+1)(a+2)(a+3)(a+4)
  53.  
  54.     else if (r5 == r4+1 && r4 == r3+1 && r3 == r2+1 && r2 == r1+1)
  55.         ret = STRAIGHT; // could be a straight flush
  56.  
  57.     // THREEOFKIND - aaabc abbbc abccc
  58.  
  59.     else if (r1 == r2 && r2 == r3 && r3 != r4 && r4 != r5)
  60.         ret = THREEOFKIND;
  61.  
  62.     else if (r1 != r2 && r2 == r3 && r3 == r4 && r4 != r5)
  63.         ret = THREEOFKIND;
  64.  
  65.     else if (r1 != r2 && r2 != r3 && r3 == r4 && r4 == r5)
  66.         ret = THREEOFKIND;
  67.  
  68.     // TWOPAIRS - aabbc aabcc abbcc
  69.  
  70.     else if (r1 == r2 && r2 != r3 && r3 == r4 && r4 != r5)
  71.         ret = TWOPAIRS;
  72.  
  73.     else if (r1 == r2 && r2 != r3 && r3 != r4 && r4 == r5)
  74.         ret = TWOPAIRS;
  75.  
  76.     else if (r1 != r2 && r2 == r3 && r3 != r4 && r4 == r5)
  77.         ret = TWOPAIRS;
  78.  
  79.     // ONEPAIR - aabcd abbcd abccd abcdd
  80.  
  81.     else if (r1 == r2 && r2 != r3 && r3 != r4 && r4 != r5)
  82.         ret = ONEPAIR;
  83.  
  84.     else if (r1 != r2 && r2 == r3 && r3 != r4 && r4 != r5)
  85.         ret = ONEPAIR;
  86.  
  87.     else if (r1 != r2 && r2 != r3 && r3 == r4 && r4 != r5)
  88.         ret = ONEPAIR;
  89.  
  90.     else if (r1 != r2 && r2 != r3 && r3 != r4 && r4 == r5)
  91.         ret = ONEPAIR;
  92.  
  93.     list_free(cards);
  94.  
  95.     return ret;
  96. }

evaluate retourne la valeur de self.

  1. void defclassHand() {
  2.     property _i_properties[] = {
  3.         "cards",
  4.         0, 0
  5.     };
  6.     selector _i_messages[] = {
  7.         "init",             METHOD(i_init),
  8.         "free",             METHOD(i_free),
  9.         "copy",             METHOD(i_copy),
  10.         "reorder",          METHOD(i_reorder),
  11.         "reset",            METHOD(i_reset),
  12.         "card",             METHOD(i_card),
  13.         "setCard",          METHOD(i_setCard),
  14.         "evaluate",         METHOD(i_evaluate),
  15.         "toString",         METHOD(i_toString),
  16.         0, 0
  17.     };
  18.  
  19.     Hand = defclass("Hand", 0, 1, 0, _i_properties, 0, _i_messages);
  20. }

Initialise la classe Hand. La classe Hand hérite de la classe Object. Une instance a 1 propriété : cards, les cartes qu'elle contient. Une instance redéfinit les messages init, free, copy et toString. Elle implémente les messages reorder, reset, card, setCard et evaluate.

TEST

Compilez et exécutez le test unitaire :

$ make test-Hand
gcc -g -I.. -Wno-missing-braces -O -fstrength-reduce -finline-functions -fomit-frame-pointer -c test-Hand.c
gcc -g -I.. -Wno-missing-braces -O -fstrength-reduce -finline-functions -fomit-frame-pointer -c Hand.c
gcc -g test-Hand.o Hand.o Card.o ../libso-o.a -o test-Hand
$ test-Hand
As,3c,Ad,Jh,6s -> ONEPAIR
3c,6s,Jh,As,Ad -> ONEPAIR
3c
3c,Ah,Jh,As,Ad -> THREEOFKIND
Js,Kd,8d,4h,Tc -> NOTHING
As,3c,4d,3h,6s -> ONEPAIR
7s,Kh,7d,Jc,Js -> TWOPAIRS
4s,9h,9d,8c,9s -> THREEOFKIND
Kh,Jd,Qc,Ts,Ad -> STRAIGHT
4h,9h,Ah,7h,Qh -> FLUSH
4s,Th,Td,4c,Ts -> FULLHOUSE
5s,5h,5d,Qc,5c -> FOUROFKIND
Kd,Jd,Qd,Td,Ad -> STRAIGHTFLUSH
VOIR AUSSI

Card, Deck

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