24

A hand

  1. import { defclass, sendmsg, supersend } from 'So-o';
  2.  
  3. import 'Card';
  4.  
  5. defclass('Hand', null, 1,
  6.     null,
  7.     ['cards'],
  8.     null,

The Hand class adds the instance property cards, redefines the instance messages init, copy and toString, adds the instance messages card, setCard, reorder, isOnePair, isTwoPairs, isThreeOfKind, isStraight, isFlush, isFullHouse, isFourOfKind, isStraightFlush and evaluate.

  1.     {   'init':
  2.             (self, cards) => {
  3.                 if (! (Array.isArray(cards) && cards.length == 5))
  4.                     throw new TypeError();
  5.    
  6.                 sendmsg(self, 'set', 'cards', cards);
  7.    
  8.                 return self;
  9.             },
  1.         'copy':
  2.             (self) => {
  3.                 let co = supersend(Hand, self, 'copy');
  4.                 let cards = sendmsg(co, 'get', 'cards');
  5.    
  6.                 return sendmsg(co, 'set', 'cards', cards.slice(0));
  7.             },
  1.         'reorder':
  2.             (self) => {
  3.                 let cards = sendmsg(self, 'get', 'cards');
  4.  
  5.                 cards.sort((c1, c2) => sendmsg(c1, 'compare', c2));
  6.  
  7.                 return self;
  8.             },
  1.         'card':
  2.             (self, n) => {
  3.                 if (! (Number.isInteger(n) && n >= 1 && n <= 5))
  4.                     throw new RangeError();
  5.  
  6.                 let cards = sendmsg(self, 'get', 'cards');
  7.  
  8.                 return cards[n-1];
  9.             },
  1.         'setCard':
  2.             (self, n, card) => {
  3.                 if (! (Number.isInteger(n) && n >= 1 && n <= 5))
  4.                     throw new RangeError();
  5.  
  6.                 let cards = sendmsg(self, 'get', 'cards');
  7.  
  8.                 cards[n-1] = card;
  9.  
  10.                 return self;
  11.             },
  1.         'isOnePair':
  2.             (self) => {
  3.                 // aabcd abbcd abccd abcdd
  4.                 let cards = sendmsg(self, 'get', 'cards');
  5.  
  6.                 let r1 = sendmsg(cards[0], 'rank');
  7.                 let r2 = sendmsg(cards[1], 'rank');
  8.                 let r3 = sendmsg(cards[2], 'rank');
  9.                 let r4 = sendmsg(cards[3], 'rank');
  10.                 let r5 = sendmsg(cards[4], 'rank');
  11.  
  12.                 if (r1 == r2 && r2 != r3 && r3 != r4 && r4 != r5)
  13.                     return true;
  14.  
  15.                 if (r1 != r2 && r2 == r3 && r3 != r4 && r4 != r5)
  16.                     return true;
  17.  
  18.                 if (r1 != r2 && r2 != r3 && r3 == r4 && r4 != r5)
  19.                     return true;
  20.  
  21.                 if (r1 != r2 && r2 != r3 && r3 != r4 && r4 == r5)
  22.                     return true;
  23.  
  24.                 return false;
  25.             },
  1.         'isTwoPairs':
  2.             (self) => {
  3.                 // aabbc aabcc abbcc
  4.                 let cards = sendmsg(self, 'get', 'cards');
  5.  
  6.                 let r1 = sendmsg(cards[0], 'rank');
  7.                 let r2 = sendmsg(cards[1], 'rank');
  8.                 let r3 = sendmsg(cards[2], 'rank');
  9.                 let r4 = sendmsg(cards[3], 'rank');
  10.                 let r5 = sendmsg(cards[4], 'rank');
  11.  
  12.                 if (r1 == r2 && r2 != r3 && r3 == r4 && r4 != r5)
  13.                     return true;
  14.  
  15.                 if (r1 == r2 && r2 != r3 && r3 != r4 && r4 == r5)
  16.                     return true;
  17.  
  18.                 if (r1 != r2 && r2 == r3 && r3 != r4 && r4 == r5)
  19.                     return true;
  20.  
  21.                 return false;
  22.             },
  1.         'isThreeOfKind':
  2.             (self) => {
  3.                 // aabbc aabcc abbcc
  4.                 let cards = sendmsg(self, 'get', 'cards');
  5.  
  6.                 let r1 = sendmsg(cards[0], 'rank');
  7.                 let r2 = sendmsg(cards[1], 'rank');
  8.                 let r3 = sendmsg(cards[2], 'rank');
  9.                 let r4 = sendmsg(cards[3], 'rank');
  10.                 let r5 = sendmsg(cards[4], 'rank');
  11.  
  12.                 if (r1 == r2 && r2 == r3 && r3 != r4 && r4 != r5)
  13.                     return true;
  14.  
  15.                 if (r1 != r2 && r2 == r3 && r3 == r4 && r4 != r5)
  16.                     return true;
  17.  
  18.                 if (r1 != r2 && r2 != r3 && r3 == r4 && r4 == r5)
  19.                     return true;
  20.  
  21.                 return false;
  22.             },
  1.         'isStraight':
  2.             (self) => {
  3.                 // a(a+1)(a+2)(a+3)(a+4)
  4.                 let cards = sendmsg(self, 'get', 'cards');
  5.  
  6.                 let r1 = sendmsg(cards[0], 'rank');
  7.                 let r2 = sendmsg(cards[1], 'rank');
  8.                 let r3 = sendmsg(cards[2], 'rank');
  9.                 let r4 = sendmsg(cards[3], 'rank');
  10.                 let r5 = sendmsg(cards[4], 'rank');
  11.  
  12.                 if (r5 == r4+1 && r4 == r3+1 && r3 == r2+1 && r2 == r1+1)
  13.                     return true;    // could be a straight flush
  14.  
  15.                 return false;
  16.             },
  1.         'isFlush':
  2.             (self) => {
  3.                 let cards = sendmsg(self, 'get', 'cards');
  4.  
  5.                 let s1 = sendmsg(cards[0], 'suit');
  6.                 let s2 = sendmsg(cards[1], 'suit');
  7.                 let s3 = sendmsg(cards[2], 'suit');
  8.                 let s4 = sendmsg(cards[3], 'suit');
  9.                 let s5 = sendmsg(cards[4], 'suit');
  10.  
  11.                 if (s1 == s2 && s2 == s3 && s3 == s4 && s4 == s5)
  12.                     return true;    // could be a straight flush
  13.  
  14.                 return false;
  15.             },
  1.         'isFullHouse':
  2.             (self) => {
  3.                 // aaabb aabbb
  4.                 let cards = sendmsg(self, 'get', 'cards');
  5.  
  6.                 let r1 = sendmsg(cards[0], 'rank');
  7.                 let r2 = sendmsg(cards[1], 'rank');
  8.                 let r3 = sendmsg(cards[2], 'rank');
  9.                 let r4 = sendmsg(cards[3], 'rank');
  10.                 let r5 = sendmsg(cards[4], 'rank');
  11.  
  12.                 if (r1 == r2 && r2 == r3 && r3 != r4 && r4 == r5)
  13.                     return true;
  14.  
  15.                 if (r1 == r2 && r2 != r3 && r3 == r4 && r4 == r5)
  16.                     return true;
  17.  
  18.                 return false;
  19.             },
  1.         'isFourOfKind':
  2.             (self) => {
  3.                 // aaaab abbbb
  4.                 let cards = sendmsg(self, 'get', 'cards');
  5.  
  6.                 let r1 = sendmsg(cards[0], 'rank');
  7.                 let r2 = sendmsg(cards[1], 'rank');
  8.                 let r3 = sendmsg(cards[2], 'rank');
  9.                 let r4 = sendmsg(cards[3], 'rank');
  10.                 let r5 = sendmsg(cards[4], 'rank');
  11.  
  12.                 if (r1 == r2 && r2 == r3 && r3 == r4)
  13.                     return true;
  14.  
  15.                 if (r2 == r3 && r3 == r4 && r4 == r5)
  16.                     return true;
  17.  
  18.  
  19.                 return false;
  20.             },
  1.         'isStraightFlush':
  2.             (self) => {
  3.                 // a(a+1)(a+2)(a+3)(a+4)
  4.                 if (sendmsg(self, 'isStraight') && sendmsg(self, 'isFlush'))
  5.                     return true;
  6.  
  7.                 return false;
  8.             },
  1.         'evaluate':
  2.             (self) => {
  3.                     // sort or nothing works!
  4.                     let copy = sendmsg(sendmsg(self, 'copy'), 'reorder');
  5.  
  6.                     // DON'T change order
  7.                     if (sendmsg(copy, 'isStraightFlush'))
  8.                         return Hand.STRAIGHTFLUSH;
  9.  
  10.                     if (sendmsg(copy, 'isFourOfKind'))
  11.                         return Hand.FOUROFKIND;
  12.  
  13.                     if (sendmsg(copy, 'isFullHouse'))
  14.                         return Hand.FULLHOUSE;
  15.  
  16.                     if (sendmsg(copy, 'isFlush'))
  17.                         return Hand.FLUSH;
  18.  
  19.                     if (sendmsg(copy, 'isStraight'))
  20.                         return Hand.STRAIGHT;
  21.  
  22.                     if (sendmsg(copy, 'isThreeOfKind'))
  23.                         return Hand.THREEOFKIND;
  24.  
  25.                     if (sendmsg(copy, 'isTwoPairs'))
  26.                         return Hand.TWOPAIRS;
  27.  
  28.                     if (sendmsg(copy, 'isOnePair'))
  29.                         return Hand.ONEPAIR;
  30.  
  31.                     return Hand.NOTHING;
  32.                 },
  1.         'toString':
  2.             (self) => {
  3.                 let val = sendmsg(self, 'evaluate');
  4.                 let cards = sendmsg(self, 'get', 'cards');
  5.                 let s = cards.map((c) => sendmsg(c, 'toString'));
  6.  
  7.                 return s.join(',', s) + ' -> ' + Hand.hand2s[val];
  8.             }
  9.     }
  10. );
  1. Hand.NOTHING        = 0;
  2. Hand.ONEPAIR        = 1;
  3. Hand.TWOPAIRS       = 2;
  4. Hand.THREEOFKIND    = 3;
  5. Hand.STRAIGHT       = 4;
  6. Hand.FLUSH          = 5;
  7. Hand.FULLHOUSE      = 6;
  8. Hand.FOUROFKIND     = 7;
  9. Hand.STRAIGHTFLUSH  = 8;
  1. Hand.hand2s = [
  2.     'NOTHING',
  3.     'ONEPAIR',
  4.     'TWOPAIRS',
  5.     'THREEOFKIND',
  6.     'STRAIGHT',
  7.     'FLUSH',
  8.     'FULLHOUSE',
  9.     'FOUROFKIND',
  10.     'STRAIGHTFLUSH',
  11. ];
  1. import { sendmsg } from 'So-o';
  2.  
  3. import 'Hand';
  4.  
  5. let card1 = sendmsg(Card, 'new', Card.ACE, Card.SPADES);
  6. let card2 = sendmsg(Card, 'new', Card.THREE, Card.CLUBS);
  7. let card3 = sendmsg(Card, 'new', Card.ACE, Card.DIAMONDS);
  8. let card4 = sendmsg(Card, 'new', Card.JACK, Card.HEARTS);
  9. let card5 = sendmsg(Card, 'new', Card.SIX, Card.SPADES);
  10.  
  11. let hand = sendmsg(Hand, 'new', [card1, card2, card3, card4, card5]);
  12.  
  13. console.log(sendmsg(hand, 'toString'));
  14. sendmsg(hand, 'reorder');
  15. console.log(sendmsg(hand, 'toString'));
  16. console.log(sendmsg(sendmsg(hand, 'card', 1), 'toString'));
  17. sendmsg(hand, 'setCard', 2, sendmsg(Card, 'new', Card.ACE, Card.HEARTS));
  18. console.log(sendmsg(hand, 'toString'));
  19.  
  20. let testhands = [
  21.     [[Card.JACK, Card.SPADES], [Card.KING, Card.HEARTS], [Card.ACE, Card.DIAMONDS], [Card.TWO, Card.CLUBS], [Card.FIVE, Card.SPADES]],
  22.     [[Card.ACE, Card.SPADES], [Card.THREE, Card.CLUBS], [Card.FOUR, Card.DIAMONDS], [Card.THREE, Card.HEARTS], [Card.SIX, Card.SPADES]],
  23.     [[Card.SEVEN, Card.SPADES], [Card.KING, Card.HEARTS], [Card.SEVEN, Card.DIAMONDS], [Card.JACK, Card.CLUBS], [Card.JACK, Card.SPADES]],
  24.     [[Card.FOUR, Card.SPADES], [Card.NINE, Card.HEARTS], [Card.NINE, Card.DIAMONDS], [Card.EIGHT, Card.CLUBS], [Card.NINE, Card.SPADES]],
  25.     [[Card.KING, Card.HEARTS], [Card.JACK, Card.DIAMONDS], [Card.QUEEN, Card.CLUBS], [Card.TEN, Card.SPADES], [Card.ACE, Card.DIAMONDS]],
  26.     [[Card.FOUR, Card.HEARTS], [Card.NINE, Card.HEARTS], [Card.ACE, Card.HEARTS], [Card.SEVEN, Card.HEARTS], [Card.QUEEN, Card.HEARTS]],
  27.     [[Card.FOUR, Card.SPADES], [Card.TEN, Card.HEARTS], [Card.TEN, Card.DIAMONDS], [Card.FOUR, Card.CLUBS], [Card.TEN, Card.SPADES]],
  28.     [[Card.KING, Card.DIAMONDS], [Card.JACK, Card.DIAMONDS], [Card.QUEEN, Card.DIAMONDS], [Card.TEN, Card.DIAMONDS], [Card.ACE, Card.DIAMONDS]],
  29. ];
  30.  
  31. for (let h of testhands) {
  32.     let cards = h.map((c) => sendmsg(Card, 'perform', 'new', c));
  33.  
  34.     console.log(sendmsg(sendmsg(Hand, 'new', cards), 'toString'));
  35. }
$ ln poker/testHand.js testHand.mjs
$ nodejs --experimental-modules testHand
As,3c,Ad,Jh,6s -> ONEPAIR
3c,6s,Jh,As,Ad -> ONEPAIR
3c
3c,Ah,Jh,As,Ad -> THREEOFKIND
Js,Kh,Ad,2c,5s -> 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
Kd,Jd,Qd,Td,Ad -> STRAIGHTFLUSH
SEE ALSO

The JavaScript manual, A deck of cards

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