Uncle Sean's Electronix Fun Page
Home
Contact
Links
Legal

Drawing

Drawing is guided by the player's choice of what cards to hold. Since there are five cards, and each of them may either be held or not held, the choice can be expressed as a 5-bit binary number called Held. Assume a “1” bit means that a card will be held. Then if bit 0 is set in Held, that means the player wants to hold card 0, etc.

Since Held is 5 bits, there are 32 possible configurations. These range from 00000 (no cards held) to 11111 (all cards held).

How Drawing Actually Works

Given Held and a 10-card hand, it's easy to construct the new hand.

Note that since card 0 is drawn leftmost, and bit 0 of binary numbers are drawn rightmost, Held appears to be backwards (rightmost bit corresponds to leftmost card).

The process involves a handy assembly trick I call Mask Rolling, used to test bits one by one in a byte. The PIC is able to test individual bits in a byte using the BTFSC / BTFSS instructions, but they require that you specify which bit you're testing at compile time – you can test bit 0, or bit 1, or whatever, but you can't test bit X. Instead, you have to test by bitwise masking. That is, if you want to test bit X in byte B, do a bitwise AND of B and a “mask” which is a byte with only the bit of interest set. If the result is zero, that bit is clear in B; if nonzero, the bit is set in B.

  1. Set Mask to 1 (binary 00000001). This makes it so bit zero is the only one set, and card zero is the first one we'll check.

  2. Set Hand Pointer to point to the first card in the hand (card 0), and Draw Pointer to the first card in the draw set (card 5, sixth in the 10-card hand).

  3. For each of the 5 cards:

    1. perform a bitwise AND of Held and Mask.

    2. If the result is nonzero, that means the bit corresponding to the one set bit in Mask is also a one, so the card is held. Go to step (d).

    3. Otherwise, the corresponding bit is not set, so the card is not held. Replace it from the draw set like this:

      1. Copy the card pointed to by the Draw Pointer to the slot pointed to by the Hand pointer.

      2. Advance the Draw Pointer to the next card in the draw set.

    4. Advance the Hand Pointer to the next card in the hand.

    5. Shift Mask left one bit. So, if it had been 00000001, it's now 00000010, ready to check bit 1 (corresponding to card 1).

Here's an example. Say the 10-card hand consists of ABCDEPQRST. The pat hand, then, is ABCDE, and the draw set is PQRST. The Hand Pointer starts out pointing at A, and the Draw Pointer at P. Assume the player wants to hold cards 0 and 3 (A and D).

10-card hand

Held

Mask

ANDed

Action

ABCDE–PQRST

01001

00001

00001

Card is held, so leave it alone.

ABCDE–PQRST

01001

00010

00000

Card not held; replace B with P and advance Draw Pointer.

APCDE–PQRST

01001

00100

00000

Not held, replace C with Q and advance Draw Pointer.

APQDE–PQRST

01001

01000

01000

Held, do nothing.

APQDE–PQRST

01001

10000

00000

Not held – replace E with R. Done!

So the final hand is A P Q D R.

There isn't a separate unit test for drawing; it's covered in the scoring test on the next page.