Guide 7A14 Main |
| by Richard Pavlicek |
Working with huge amounts of bridge data is impractical in a text format, so I have designed various binary file formats to fit my needs. Some of these are documented here, so that others might adopt the methods or derive helpful ideas in designing their own formats.
ZBS | ZBD | ZDD | ZRD | ZRJ |
All my binary formats follow the Intel little endian architecture, wherein multi-byte values are stored least significant byte first. Bits are numbered from zero (least significant) upward to the end of each record.
ZBS (binary suit) is a way to store any suit layout, including unused cards, in the minimal space. I designed this circa 1988 for my now extinct Bridge Tutor program, because it allowed any bridge diagram (full deal, ending, paired hands, card combination, etc.) to be stored efficiently. (In those days of low memory and floppy disks, saving bytes was crucial.)
Each card can be in one of five places: West, North, East, South or unused. In a bit-mapping scheme this would require three bits per card (39 total bits) which is wasteful. Much better is a power-of-five algorithm, where the location of each card is shown by a 13-digit number in base five (each digit 0-4). The rightmost digit shows which hand (1-4) holds the ace, or 0 = unused; the next digit locates the king, etc., thru the leftmost digit to locate the two.* Conveniently, 5 to the 13th power = 1,220,703,125 (48C27395 hexadecimal) which stores in 31 bits, or 4 bytes with 1 bit left over. I use the extra bit as a flag to mean the next record belongs to the same deal, hence 32-bit records can stand alone to define a suit layout, or combine to form a diagram.
*Originally I used the reverse order (ace leftmost, two rightmost) but switched so that decoding extracts cards in ranking order (ace, king, queen) to facilitate and speed up some routines.
Encoding and decoding is straightforward. To encode, start with the two and its location (0-4); multiply by five and add the three location (0-4); multiply by five and add the four location (0-4), etc. To decode, just divide successively by five; the first remainder locates the ace; the next locates the king, etc. The record structure is shown below.
Bit | Value | Coding |
---|---|---|
0 | Flag | 0 = end of group; 1 = next record same group |
1-31 | Locator | 0 to 1,220,703,124 |
When records are combined, suits must be given in ranking order: spades, hearts, diamonds, clubs. For stand-alone records (single-suit layouts) suit identity doesnt matter (at least for my purposes) but spades is assumed.
A null record (all cards unused and end of group) would have no purpose to be included, so this fact can be used to terminate a list records, thus allowing end detection.
ZBD (binary deal) is a simple, compact way to store a complete deal. Each card must be in one of four places (West, North, East or South) so two bits of information are required for each card. Two × 52 = 104 bits, so each deal requires 13 bytes.* The bitmap of each record is shown below.
Bit | Value | Coding |
---|---|---|
0-1 | A | 0 = West; 1 = North; 2 = East; 3 = South |
2-3 | K | 0 = West; 1 = North; 2 = East; 3 = South |
4-103 | Likewise in order for Q-2 A-2 A-2 A-2 |
*In theory only 12 bytes are required per deal using my algorithm for Mapping Bridge Deals, but this requires significant overhead to code and decode each deal hardly worth the effort to save a single byte. Simplicity rules.
A record starting with 32 null bits is impossible (it would mean the first 16 cards go to West) so this fact can be used to terminate any list of records, thus allowing end detection.
Guide 7A14 Main | Top Binary File Formats |
ZDD is a simple, compact way to store double-dummy results for each hand in each strain. I designed this for my database of 10,485,760 random solved deals, a project that took almost two years of computer time to complete.
Each record is 10 bytes (80 bits). Each of the 20 results (5 strains × 4 hands) is stored as a nibble, or 4-bit value. The bitmap of each record is shown below.
Bit | Value | Coding |
---|---|---|
0-3 | NT by West | 0-13 (or 15 = unknown) |
4-7 | NT by North | 0-13 (or 15 = unknown) |
8-11 | NT by East | 0-13 (or 15 = unknown) |
12-15 | NT by South | 0-13 (or 15 = unknown) |
16-79 | Likewise in order for |
A record starting with 32 null bits is impossible (it would mean each hand makes zero tricks in notrump or spades) so this fact can be used to terminate a list of records, thus allowing end detection.
ZRD combines ZBD (binary deal) and ZDD (double-dummy results) into a single record.
Each record is 23 bytes (184 bits). The first 13 bytes (104 bits) follow the ZBD structure, and the last 10 bytes (80 bits) follow the ZDD structure. The bitmap of each record is shown below.
Bit | Value | Coding |
---|---|---|
0-1 | A | 0 = West; 1 = North; 2 = East; 3 = South |
2-3 | K | 0 = West; 1 = North; 2 = East; 3 = South |
4-103 | Likewise in order for Q-2 A-2 A-2 A-2 | |
104-107 | NT by West | 0-13 (or 15 = unknown) |
108-111 | NT by North | 0-13 (or 15 = unknown) |
112-115 | NT by East | 0-13 (or 15 = unknown) |
116-119 | NT by South | 0-13 (or 15 = unknown) |
120-183 | Likewise in order for |
A record starting with 32 null bits is impossible (it would mean the first 16 cards go to West) so this fact can be used to terminate any list of records, thus allowing end detection.
Guide 7A14 Main | Top Binary File Formats |
ZRJ is a way of storing essential information about a bridge deal card diagram, board number, dealer, vulnerability, contract, declarer, result, auction and play in a fixed format. Each record is 80 bytes in the following structure:
Offset | Value | Coding |
---|---|---|
0 | 2 2 2 2 | 2 bits per card (00=W 01=N 10=E 11=S) |
1-12 | ? ? ? ? | likewise for threes to aces |
13 | Board# minus 1 | 0-239 = Bd 1-240, 240-255 (dealer/vul only) |
14 | Contract | 0 = passout, 5-39 = 1 -7 NT (+40 if X, +80 if XX) |
15 | Tricks won, Declarer, Initial passes | bitmapped: TTTTDDII |
16 | Offset to end of calls (play start) | 18-63 |
17 | Offset to end of plays | 18-80 |
18 | Calls (starting with opening bid) | ?!LLLSSS (0=C 1=D 2=H 3=S 4=N 5=P 6=X 7=R) |
?? | Plays (rank and suit) | ?!RRRRSS (0=C 1=D 2=H 3=S) |
Length of call or play string (can be null) is determined by the offset pointers. In some cases the play string must be truncated, since the record space allows only 62 bytes for the two strings. The two high bits of each call or play indicate punctuation (! = good, ? = poor) and both set indicates an alert (*) or special meaning. Of course, no explanations fit in this format.
A record starting with 4 null bytes (32 bits) is impossible (it would mean the first 16 cards go to West) and can be used to terminate a list of records to allow end detection.
Guide 7A14 Main | Top Binary File Formats |
© 2016 Richard Pavlicek