Guide 7A14   Main


Binary File Formats


  by Richard Pavlicek

Working with large 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.

ZBSZBDZDDZRDZRJ

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 Format

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.

BitValueCoding
0Flag0 = end of group; 1 = next record same group
1-31Locator0 to 1220703124

When records are combined, suits must be given in ranking order: spades, hearts, diamonds, clubs. For stand-alone records (single-suit layouts) suit identity doesn’t 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 Format

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.

BitValueCoding
0-1S A0 = West; 1 = North; 2 = East; 3 = South
2-3S K0 = West; 1 = North; 2 = East; 3 = South
4-103Likewise in order for S Q-2 H A-2 D A-2 C 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   MainTop   Binary File Formats

ZDD Format

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.

BitValueCoding
0-3NT by West0-13 (or 15 = unknown)
4-7NT by North0-13 (or 15 = unknown)
8-11NT by East0-13 (or 15 = unknown)
12-15NT by South0-13 (or 15 = unknown)
16-79Likewise in order for S H D C

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 Format

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.

BitValueCoding
0-1S A0 = West; 1 = North; 2 = East; 3 = South
2-3S K0 = West; 1 = North; 2 = East; 3 = South
4-103 Likewise in order for S Q-2 H A-2 D A-2 C A-2
104-107NT by West0-13 (or 15 = unknown)
108-111NT by North0-13 (or 15 = unknown)
112-115NT by East0-13 (or 15 = unknown)
116-119NT by South0-13 (or 15 = unknown)
120-183 Likewise in order for S H D C

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   MainTop   Binary File Formats

ZRJ Format

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:

OffsetValueCoding
0S 2 H 2 D 2 C 22 bits per card (00=W 01=N 10=E 11=S)
1-12S ? H ? D ? C ?likewise for threes to aces
13Board# minus 10-255 (also determines dealer and vul)
14Contract5-39 = 1 C-7 NT (0=passout) +40 if X, +80 if XX
15Tricks won, Declarer, Initial passesTTTTDDII
16Offset to end of calls (play start)18-80
17Offset to end of plays18-80
18Calls (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   MainTop   Binary File Formats

© 2016 Richard Pavlicek