ACBLgamedump Software
ACBLgamedump is a free (open source) software written by Matthew Kidd that directly reads an ACBLscore binary game file into a Perl data structure or an equivalent JSON data structure. Contracts, results, and opening leads can also be integrated from Bridgemate, BridgePad, and BridgeScorer electronic scoring systems. ACBLgamedump is intended as a utility for other programs.
Introduction
Parsing ACBLscore text based reports can be tedious. The problem is made worse by a multiplicity of report formats, variations in the report formats that arise rarely (e.g. an Adjustment column when a pair is penalized), and the lack of ACBLscore command line options to generate whichever reports your software is setup to parse. For systematic processing of ACBLscore data, directly reading the ACBLscore binary game files is highly preferable. But until recently, this was approach was also problematic because the binary game file format was not documented. Recently game file format reverse engineering has advanced far enough to make this approach robust.
ACBLgamedump decodes the ACBLscore objects and properties that are most useful for report generation and data analysis. The program removes layers of indirection that are only useful to the internal working of ACBLscore; for example the indirection to support editing pair numbers or movements (ACBLscore EDMOV command). It also skips internal details that speed up ACBLscore report generation, for example the linked list traversal of masterpoint winners.
Starting with version 1.0.2, contracts, results, and opening leads from the Bridgemate, BridgePad, and BridgeScorer electronic scoring systems can also be incorporated into the output structure or JSON.
Using the program
The actual decoding is done in a Perl package, ACBLgamedecode.pm. If you are programming in Perl, you can use this package as shown in the following code snippet.
ACBLgamedecode.pm is a Perl package but it is not “installed” as a package is when installed using PPM or CPAN. This means it will not automatically be on the Perl library search path. The first two program lines above tell Perl to search the directory that your Perl program is running from, using the FindBin package that is usually included with Perl installations. This way you can keep ACBLgamedecode.pm in the same directory as your Perl programs.
If you are not programming in Perl, run ACBLgamedump.pl to generate equivalent JSON output which can then be processed by JavaScript or any other language.
Multiple files can be processed at once:
In the second example the output is piped to another program.
Since multiple files can be processed at once, the JSON data structure has an extra outer array layer, where each element corresponds to the parsed result for one game file.
The JSON output is stripped of white space to minimize the output size, unless the -pp (“pretty print”) switch is specified. The JSON Lite Add-On for Firefox by Lauri Rooden will display JSON in a pretty printed tree where branches can be selectively viewed or hidden. Similar add-ons exist for other browsers.
Including electronic scoring results
Contracts, results, and opening leads may be incorporated into the output by specifying the Bridgemate, BridgePad, or BridgeScore electronic scoring (.bws) file using the -b switch. For example:
If you are not sure which BWS file contains the results for a given game file, you may repeat the -b switch to have the program search multiple files. This is helpful for regionals where there are many events and the BWS files often have non-obvious names.
BWS files are searched by section letter. If a game files has section A in it and two of the BWS files contain results for section A, the data from the last BWS file containing section A will be used. This means it is inadvisable to toss all your BWS files into the mix. A future version of ACBLgamedump.pl may implement smarter matching by date and session.
On Windows, Perl uses ODBC to read the electronic scoring file. The ODBC driver needed can only be accessed from 32-bit Perl. If the -b switch is used with 64-bit Perl, the program will exit with an error message. On Unix / Linux and Mac OS, the open source mdbtools package is used to read the electronic scoring file. The exact way to install this package on Unix or Linux depends on your operating system. On Ubuntu (Debian) use one of the following commands or use the Synaptic package manager.
apt-get install mdbtools | (if running as root) |
sudo apt-get install mdbtools | (if you are allowed to install packages) |
For Max OS X, the easiest thing to do is to download this supplemental zip file of the mdbtools executables and their library dependencies. Copy mdb-export, mdb-schema, and mdb-tables from the zip archive to /usr/local/bin and copy the libmdb.1.dylib, libglib-2.0.0.dylib, and libintl.8.dylib dynamic libraries to /usr/local/lib. These directories may not exist. If not, create them as follows by starting a BASH shell using the Terminal app and entering the following commands:
sudo chmod 775 /usr/local
sudo chgrp admin /usr/local
mkdir /usr/local/bin
mkdir /usr/local/lib
You will need to enter your account password the first time you use sudo.
Installing the JSON::PP package
JSON::PP has been a Perl core module since Perl 5.14 so it should be included with standard Perl distributions. But see below if you need to install it.
If you are using the ActiveState Perl distribution on Windows, the JSON wrapper package should already be included. But if not, you can install it from the Windows command line using the Perl Package Manager (PPM) as follows:
The JSON package is a wrapper that chooses either JSON::XS, the C/C++ performance enhanced package if available, or the JSON::PP (Pure Perl) package if it is not.
Modern Macs ship with Perl installed. The shipped Perl distribution includes the JSON::PP package but not the JSON wrapper package. ACBLgamedump 1.0.1 and later use JSON:PP to avoid problems.
On Unix or Linux use CPAN if it is necessary to install the JSON::PP package:
Notes on the output structure
The output structure is fairly self-explanatory in conjunction with ACBLscore Game Files Decoded documentation. However, in some places brevity is chosen over pedantic readability.
- Board results
The result on each board is given as an array instead of a hash. The elements are:
Round #, Table #, N-S Pair #, N-S Raw Score, N-S Score, E-W Pair #, E-W Raw Score, E-W Score, Contract Level, Contract Denomination, Declarer, Contract Result, Opening Lead
A raw score is something like -620. The score is matchpoints or IMPs depending on the scoring type in event[].event_scoring. N-S Raw Score and E-W Raw Score are normally opposite and N-S score and E-W score normally sum to either the matchpoint top or zero (for IMP Pairs) but rare split scores from a director ruling can change this. Scores can also be one of the following strings: “Ave-”, “Ave”, “Ave+”, “Late Play”, “Not Played”. Scores from foul groups are indicated with the suffix F# where # (1-7) is the foul group number; for example -140F1 means a raw score of -140 for foul group 1. In the era of dealing machines, fouled scores are rare and it is even rarer for more than one foul group to be used. Nonetheless it is still possible for players to foul a board by exchanging card between hands before returning them to the tray or for a board to be change mid-session if a player recognizes it from a previous session.
The fields in blue are only included if electronic scoring information has been included. Contract Level is 1-7 or PASS. Contract Denomination is C, D, H, S, or N. Declarer is N, E, S, or W. The Contract Result is relative to the Contract Level; for example 1 means one overtrick and -2 means down two. The opening lead has the format suit-rank, e.g. D3 for the ♦3, or is an empty string if the opening lead was not recorded. If the contract was passed out the Contract Denomination, Declarer, and Contract Result fields will be empty strings and the Opening Lead will be undef.
For Board-a-Match (BAM) events, the fields listed as N-S Pair # and E-W Pair # above are instead the team numbers.
For Individual events (check event[].event_type), there are separate results for each seat. The elements are:
Round #, Table #, North #, North Raw Score, North Score, East #, East Raw Score, East Score, South #, South Raw Score, South Score, West #, West Raw Score, West Score, Contract Level, Contract Denomination, Declarer, Contract Result, Opening Lead
- Entries
An entry refers to a tournament entry, either an individual, pair, or team depending on the event type (check event[].event_type). For a Mitchell movement, entries are indexed by number and direction (N → North-South, E → East-West), e.g. 3E. For a Howell movement, entries are indexed by a number. Check section{}.is_howell.
For board results (see #1), pair numbers are numeric. Postfix the pair number with N or E for Mitchell movements to get the index of the pair entries.
- Award subfields are an array of arrays.
Masterpoint awards are assigned at both the entry level and player level, i.e. entry{}.award and entry{}.player.award. This is to accommodate team play where players on five or six man teams can end up with differing awards depending on how many and which matches they play in. The award field supports multi-session events via the fields previous, current, and total.
Masterpoint awards can be a combination of up to three pigmentation types where the pigmentations are Black (B), Silver (S), Red (R), Gold (G), and Platinum (P). Accordingly, the outer array will be 0-3 elements depending on the number of pigmentation type. Each inner array, contains the following fields:
Masterpoints, Pigmentation Letter, Award Reason, Award Reason CodeThe Award Reason Code is the ACBLscore internal representation of the Award Reason. For example, a code of 12 always means a section ranking (1) in the second strat (2). Usually this will translate to an Award Reason of “SB”; however strats designations can vary, for example AX or DEF concurrent with a separately flighted ABC event. See event[].strat[].letter for the letter (or even sometimes a digit) used for each strat of an event.
Putting this altogether, here are examples of referencing the total masterpoint award and pigmentation type for the first pigmentation.
$pair = $gm->{'event'}[0]{'section'}{'B'}{'entry'}{'3E'}; $mp = $pair->{'award'}{'total'}[0][0]; $pg = $pair->{'award'}{'total'}[0][1];For handicapped events that are ranked both with and without the handicap, the award for the ranking with the handicap is stored in the first position and the award for the ranking without the handicap is stored in the second position. If a pair only receives an award without the handicap, the masterpoint award for the first position will be zero. For handicapped events, the masterpoint pigmentation type will be the same in each position unlike the normal case above where the pigmentation type is different for each position. If a pair receives an award both with and without the handicap, their total award is the sum of the two masterpoint awards as indicated in these fields. For example, consider a pair that third after the handicap is applied and ranks 1st without the handicap, where the awards are 0.18 MP and 0.53 MP. The pair receives the better of these awards, 0.53 MP. However internally, the awards are stored as 0.18 MP and 0.35 MP respectively, as though the award without the handicap were an inferior pigmentation even though the pigmentation is the same.
- Award field is not included if an entry received no award.
When no masterpoint are awarded in any of the previous, current, and total categories, the award field will not be included. In Perl, attempts to reference the missing fields, will return undef, for example player[].award[].total[0][0] will return undef for the masterpoints and this will be interpreted as 0 in a numeric context which is usually what one wants, though a warning will be generated if Perl is invoked with the -w (warnings) switch. Other languages may not be as tolerant. It may be necessary to check for the existence of the award member once the JSON code has been loaded as an object in a particular language.
- Combining and Ranking sections together
For scoring, sections within an event may be combined together, producing a higher top. Sections that are combined together may also be ranked together. Ranking Together means the section awards are across all N-S sections and all E-W sections respectively instead of within individual sections. The field event[].combining_and_ranking is an array of arrays indicating how the sections are combined and ranked together. For example:
[ [ ["J"], ["K"] ], [ ["L", "M"] ], [ ["Q"] ] ]In this five section example, sections J and K are combined but ranked separately, sections L and M are combined and ranked together, and section Q is separate.
- Datetime format
Timestamps are encoded using the ISO 8601 format, e.g. 2014-08-29T14:05:17. Note that a time zone designator is not included because ACBL game files do not include time zone information.
- Important fields
Many fields are decoded (or derived). For accurate parsing pay careful attention to the ones listed below.
Field Explanation event.type_id
event.typeUse either. type_id is ACBLscore’s internal value. Allowed values are 0 → Pairs, 1 → Teams, 2 → Individual, 3 → Home Style Pairs, 4 → BAM, 5 → Series Winner. event.scoring_id
event.scoringUse either. scoring_id is ACBLscore’s internal value. Allowed values are 0 → Matchpoints, 1 → IMPs with computed datum, 2 → Average IMPs, 3 → Total IMPs, 4 → Instant Matchpoints, 5 → BAM Teams, 6 → Win/Loss, 7 → Victory Points, 8 → Knockout, 10 → Series Winners, 16 → BAM Matchpoints, 18 → Compact KO. event.rating_id
event.ratingUse either. rating_id is ACBLscore’s internal value. Sample values: 0 → No Masterpoints, 1 → Club Masterpoints, 2 → Club Championship. See Event Rating Enum for the full list. event.tournament_flag 1 → tournament, 0 → club game event.session_num Session number event.nsessions Total number of sessions event.final_session_flag Derived from previous two fields. If zero, the masterpoint awards shown are not final. Do not tally these awards in computing masterpoint totals. event.handicap_type_id
event.handicap_type
event.handicap_scoringIf the event is handicapped, the ACBLscore internal value handicap_type_id will be non-zero. In this case the event.handicap_type_id (“Percentage”, “Matchpoints”, “Boards”) and handicap_scoring (“single-ranking” or “double-ranking”) will be decoded. event.tournament
event.clubHave first field for tournaments, second for club games event.city
event.directorHave first field for tournaments, second for club games section.board_top Top on a board for Matchpoint scoring (probably set to 100 for Instant Matchpoints). Not included for team games. section.nboards Total number of boards in play. A pair may not play all the boards. For example a 10 table Mitchell will use 30 boards where each pair plays 27 (9 rounds × 3 boards / round). section.is_howell Indicates whether movement is a Howell movement. This affects how entries are indexed. section.nteams Number of teams (only included for team games).
Limiting Output
When using ACBLgamedump.pl, the amount of data dumped may be limited by the -sc (section level only), -nb (no board dump), and -ne (no entry dump) switches. When ACBLgamedecode.pm is used directly, a second $opt parameter can be passed to ACBLgamedecode::decode where setting $opt->{'sectionsonly'}, $opt->{'noboards'}, and $opt->{'noentries'} to a non-zero value respectively is equivalent to the previous switches.
Other options
The -pp (“pretty print”) switch causes the output JSON to include white space and new lines for easy human interpretation. The -bv (“binary values”) causes the output to include fields which have a binary value, currently only the db_key field of the player structure. When ACBLgamedecode.pm is used directly, these -bv option invoked by setting $opt->{'binaryonly'} to a non-zero value; the -pp option is not applicable at level of ACBLgamedump.pm.
Version history
Older versions of ACBLgamedump can be downloaded by clicking on the download arrow next to the version. The latest version is also always available from the Download Now button at the top of the page as well as here.
Version | Date | Major Changes |
---|---|---|
![]() | 11-Apr-2018 |
|
![]() | 05-Dec-2015 |
|
![]() | 02-Nov-2015 |
|
![]() | 08-Oct-2015 |
|
![]() | 12-Mar-2015 |
|
![]() | 06-Feb-2015 |
|
![]() | 12-Nov-2014 |
|
![]() | 05-Nov-2014 | Original release. |
Files included in the software distribution
The current program archive contains the files listed in the table below.
Filename | Purpose |
---|---|
ACBLgamedump.pl | Perl program |
ACBLgamedecode.pm | Perl package |
Command Line Help
Command line arguments inside [ ] are optional.
Usage: $bname fname [fname...] [-b bfname [...]] [-o ofname] fname : ACBLscore game filename bfname : BWS filename (electronic scoring file) ofname : Output filename (default is STDOUT) Options -sc : Dump to section level only -nb : Don't dump board -ne : Don't dump entries (individual, pairs, teams) -bv : Include binary values (db_key parameter) -pp : Pretty print JSON output -vr : Display version number Partially decodes one or more ACBLscore game files, outputting result as JSON. Can also integrate contracts, results, and opening leads from Bridgemate, BridgePad, and BridgeScorer systems. Online documentation is located at: http://lajollabridge.com/Software/ACBLgamedump/ACBLgamedump-About.htm See http://lajollabridge.com/Articles/ACBLscoreGameFilesDecoded.htm for details of ACBLscore game file format.