Next page | Contents page |

Unicode for drawing cards

Before we get to the deal() method let's think about how to draw cards.

You are probably aware that Unicode has characters for the 4 suits and they can be specified in JS by using escape sequences \uabcd, where abcd would be 4 hexadecimal digits. For example, \u2665 is displayed as the symbol for hearts, .

Characters of text are normally stored in JS as 2 bytes each and so can be represented by 4 hex digits like that.

You are less likely to know that much higher in the Unicode sequence, requiring more than 4 hex digits, are complete graphics for playing cards. Also that there is a way to specify longer numbers for \u in JS. So we do not have to design our cards from scratch just using numbers and suit symbols.

There is a Wikipedia page about this. You will see that there are codes for the backs of cards and for jokers too. You might notice that there is a pattern to the codes for the main cards: 1f0MN is the hex code, where M means the suit (a = spades, b = hearts, c = diamonds, d = clubs) and N is the value (1 = ace, 2..a = 2..10, b = Jack, [c = Knight], d = Queen, e = King). Notice the slight complication of the Knight who does not appear in a normal 52-card pack.

The next question is how to put these codes into JS as characters. \u1f0a1 will not work. The interepreter will use the first 4 characters after u as one character and you will see 1 after that. Instead we need to use curly braces and write \u{1f0a1}.

Having noted that there is a pattern we can avoid having to list all 52 cards individually. But we cannot build up the string \u{1f0MN} by concatenating pieces (in loops for M and N) because the interpreter will give an error for the partial string. Instead, make the hex number itself and then use String.fromCodePoint(). See mdn fromcodepoint

Then we can put this method in cardA.js:

Card.prototype.getGlyph = function ()
{ if (!this.faceUp) return "\u{1f0a0}";// card back
  if (this.value === 0) return "\u{1f0cf}";// black joker
  var c = 0x1f000; // code point
  switch (this.suit)
  { case SUITS.CLUB: c += 0xd0; break;
    case SUITS.DIAMOND: c += 0xc0; break;
    case SUITS.HEART: c += 0xb0; break;
    case SUITS.SPADE: c += 0xa0; break;
  c += this.value;
  if (this.value > 11) c++; // skip Knight
  return String.fromCodePoint (c);

I have not mentioned the boolean property Card.faceUp yet. We will get to it soon.

The following is a screenshot showing how such cards will look. If you don't like the way each card has a solid border we could get rid of that with some image processing (still using JS). I plan to explain that in an appendix.

One important aspect that I have been unable to establish, despite online searching, is whether these unicode glyphs are available in the default sans-serif font on all systems. If they are not guaranteed to be available then we should provide images instead. I have written more about this on a later page (Unicode revisited).

Next page | Contents page |