Une main
- #include "OL.h"
- extern class Hand;
- extern void defclassHand();
- #define NOTHING 0
- #define ONEPAIR 1
- #define TWOPAIRS 2
- #define THREEOFKIND 3
- #define STRAIGHT 4
- #define FLUSH 5
- #define FULLHOUSE 6
- #define FOUROFKIND 7
- #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.
- #include "So-o.h"
- #include "Hand.h"
- #include <string.h>
- class Hand;
Inclut les signatures des fonctions de So-o. Inclut les déclarations de la classe Hand. Définit la classe Hand.
- static int cardcmp(instance card1, instance card2) {
- return sendmsg(card1, "compare", card2).i;
- }
La fonction cardcmp
compare 2 cartes avec la méthode compare
d'une Card
.
Elle est utilisée par la méthode reorder
.
- static instance i_init(instance self, va_list va) {
- instance card1 = va_arg(va, instance);
- instance card2 = va_arg(va, instance);
- instance card3 = va_arg(va, instance);
- instance card4 = va_arg(va, instance);
- instance card5 = va_arg(va, instance);
- supersend(Hand, self, "init");
- list cards = list_new();
- list_put(cards, 0, card1);
- list_put(cards, 1, card2);
- list_put(cards, 2, card3);
- list_put(cards, 3, card4);
- list_put(cards, 4, card5);
- sendmsg(self, "set", "cards", cards);
- return self;
- }
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.
- static void i_free(instance self) {
- list cards = sendmsg(self, "get", "cards").p;
- list_free(cards);
- supersend(Hand, self, "free");
- }
free
libère la liste de cartes de self
.
Elle ne libère pas les cartes.
- static instance i_copy(instance self) {
- instance copy = supersend(Hand, self, "copy").p;
- sendmsg(copy, "set", "cards", list_copy(sendmsg(self, "get", "cards").p));
- return copy;
- }
copy
retourne une copie de self
.
Elle affecte à la propriété cards
de copy
une copie de la liste des cartes de self
.
- static instance i_reorder(instance self) {
- list cards = sendmsg(self, "get", "cards").p;
- list_sort(cards, (int (*)(void *, void *))cardcmp, 1);
- return self;
- }
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.
- static instance i_reset(instance self, va_list va) {
- instance card1 = va_arg(va, instance);
- instance card2 = va_arg(va, instance);
- instance card3 = va_arg(va, instance);
- instance card4 = va_arg(va, instance);
- instance card5 = va_arg(va, instance);
- list cards = sendmsg(self, "get", "cards").p;
- list_put(cards, 0, card1);
- list_put(cards, 1, card2);
- list_put(cards, 2, card3);
- list_put(cards, 3, card4);
- list_put(cards, 4, card5);
- return self;
- }
reset
remplit la liste de cartes de self
avec les 5 cartes passées en argument.
- static instance i_card(instance self, va_list va) {
- int n = va_arg(va, int);
- if (n < 1 || n > 5) {
- return sendmsg(self, "invalidArgument", "card").p;
- }
- list cards = sendmsg(self, "get", "cards").p;
- return (instance)list_get(cards, n-1);
- }
card
retourne la carte n
de self
.
Si n
est < 1 ou > 5, une erreur InvalidArgument
est déclenchée.
- static instance i_setCard(instance self, va_list va) {
- int n = va_arg(va, int);
- instance card = va_arg(va, instance);
- if (n < 1 || n > 5) {
- return sendmsg(self, "invalidArgument", "setCard").p;
- }
- list cards = sendmsg(self, "get", "cards").p;
- list_put(cards, n-1, card);
- return self;
- }
setCard
met la carte n
de self
à card
.
Si n
est < 1 ou > 5, une erreur InvalidArgument
est déclenchée.
- static char *i_toString(instance self) {
- static char *handnames[] = { "NOTHING", "ONEPAIR", "TWOPAIRS", "THREEOFKIND", "STRAIGHT", "FLUSH", "FULLHOUSE", "FOUROFKIND", "STRAIGHTFLUSH" };
- static char s[5*2+4+4+13+1];
- char *p = s;
- int eval = sendmsg(self, "evaluate").i;
- list cards = sendmsg(self, "get", "cards").p;
- for (int i = 0; i < list_length(cards); i++) {
- if (i > 0)
- *p++ = ',';
- strcpy(p, (char *)sendmsg((instance)list_get(cards, i), "toString").p);
- p += 2;
- }
- sprintf(p, " -> %s", handnames[eval]);
- return s;
- }
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.
- static int i_evaluate(instance self) {
- // sort or nothing works but don't reoder the hand!
- list cards = list_sort(list_copy(sendmsg(self, "get", "cards").p), (int (*)(void *, void *))cardcmp, 1);
- instance card1 = list_get(cards, 0);
- instance card2 = list_get(cards, 1);
- instance card3 = list_get(cards, 2);
- instance card4 = list_get(cards, 3);
- instance card5 = list_get(cards, 4);
- int r1 = sendmsg(card1, "rank").i;
- int r2 = sendmsg(card2, "rank").i;
- int r3 = sendmsg(card3, "rank").i;
- int r4 = sendmsg(card4, "rank").i;
- int r5 = sendmsg(card5, "rank").i;
- int s1 = sendmsg(card1, "suit").i;
- int s2 = sendmsg(card2, "suit").i;
- int s3 = sendmsg(card3, "suit").i;
- int s4 = sendmsg(card4, "suit").i;
- int s5 = sendmsg(card5, "suit").i;
- int ret = NOTHING;
- // STRAIGHTFLUSH - a(a+1)(a+2)(a+3)(a+4)
- if (r5 == r4+1 && r4 == r3+1 && r3 == r2+1 && r2 == r1+1 &&
- s1 == s2 && s2 == s3 && s3 == s4 && s4 == s5)
- ret = STRAIGHTFLUSH;
- // FOUROFKIND - aaaab abbbb
- else if (r1 == r2 && r2 == r3 && r3 == r4)
- ret = FOUROFKIND;
- else if (r2 == r3 && r3 == r4 && r4 == r5)
- ret = FOUROFKIND;
- // FULLHOUSE - aaabb aabbb
- else if (r1 == r2 && r2 == r3 && r3 != r4 && r4 == r5)
- ret = FULLHOUSE;
- else if (r1 == r2 && r2 != r3 && r3 == r4 && r4 == r5)
- ret = FULLHOUSE;
- // FLUSH
- else if (s1 == s2 && s2 == s3 && s3 == s4 && s4 == s5)
- ret = FLUSH; // could be a straight flush
- // STRAIGHT - a(a+1)(a+2)(a+3)(a+4)
- else if (r5 == r4+1 && r4 == r3+1 && r3 == r2+1 && r2 == r1+1)
- ret = STRAIGHT; // could be a straight flush
- // THREEOFKIND - aaabc abbbc abccc
- else if (r1 == r2 && r2 == r3 && r3 != r4 && r4 != r5)
- ret = THREEOFKIND;
- else if (r1 != r2 && r2 == r3 && r3 == r4 && r4 != r5)
- ret = THREEOFKIND;
- else if (r1 != r2 && r2 != r3 && r3 == r4 && r4 == r5)
- ret = THREEOFKIND;
- // TWOPAIRS - aabbc aabcc abbcc
- else if (r1 == r2 && r2 != r3 && r3 == r4 && r4 != r5)
- ret = TWOPAIRS;
- else if (r1 == r2 && r2 != r3 && r3 != r4 && r4 == r5)
- ret = TWOPAIRS;
- else if (r1 != r2 && r2 == r3 && r3 != r4 && r4 == r5)
- ret = TWOPAIRS;
- // ONEPAIR - aabcd abbcd abccd abcdd
- else if (r1 == r2 && r2 != r3 && r3 != r4 && r4 != r5)
- ret = ONEPAIR;
- else if (r1 != r2 && r2 == r3 && r3 != r4 && r4 != r5)
- ret = ONEPAIR;
- else if (r1 != r2 && r2 != r3 && r3 == r4 && r4 != r5)
- ret = ONEPAIR;
- else if (r1 != r2 && r2 != r3 && r3 != r4 && r4 == r5)
- ret = ONEPAIR;
- list_free(cards);
- return ret;
- }
evaluate
retourne la valeur de self
.
- void defclassHand() {
- property _i_properties[] = {
- "cards",
- 0, 0
- };
- selector _i_messages[] = {
- "init", METHOD(i_init),
- "free", METHOD(i_free),
- "copy", METHOD(i_copy),
- "reorder", METHOD(i_reorder),
- "reset", METHOD(i_reset),
- "card", METHOD(i_card),
- "setCard", METHOD(i_setCard),
- "evaluate", METHOD(i_evaluate),
- "toString", METHOD(i_toString),
- 0, 0
- };
- Hand = defclass("Hand", 0, 1, 0, _i_properties, 0, _i_messages);
- }
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
Commentaires