Bo Haglund, Soren Hein, Bob Richardson
Rev
X, 2014-11-16
Latest
DLL issue with this description is available at http://www.bahnhof.se/wb758135/
The callable functions are all preceded with extern
"C" __declspec(dllimport) int __stdcall. The prototypes are available in dll.h in the
“include” directory.
Return codes are given at the end.
Not all functions are
present in all versions of the DLL. For
historical reasons, the function names are not entirely consistent with respect
to the input format. Functions accepting
binary deals will end on Bin, and those accepting PBN deals will end on PBN in
the future. At some point existing
function names may be changed as well, so use the new names!
The
Basic Functions
The basic functions
SolveBoard and SolveBoardPBN each solve a single hand and are thread-safe, making
it possible to use them for solving several hands in parallel. The other
callable functions use the SolveBoard functions either directly or indirectly.
The
Multi-Thread Double Dummy Solver Functions
The double dummy trick
values for all 5 × 4 = 20 possible combinations of a hand’s trump strain and
declarer hand alternatives are solved by a single call to one of the functions
CalcDDtable and CalcDDtablePBN. Threads
are allocated per strain in order to save computations.
To obtain better
utilization of available threads, the double dummy (DD) tables can be grouped
using one of the functions CalcAllTables and CalcAllTablesPBN.
Solving hands can be done
much more quickly using one of the multi-thread alternatives for calling SolveBoard.
Then a number of hands are grouped for a single call to one of the functions SolveAllBoards,
SolveAllChunksBin and SolveAllChunksPBN.
The hands are then solved in parallel using the available threads.
The number of threads is
automatically configured by DDS on Windows, taking into account the number of
processor cores and available memory. The
number of threads can be influenced by calling SetMaxThreads. This function should probably always be
called on Linux/Mac, with a zero argument for auto-configuration.
Calling FreeMemory causes
DDS to give up its dynamically allocated memory.
The
PAR Calculation Functions
The PAR calculation
functions find the optimal contract(s) assuming open cards and optimal bidding
from both sides. In very rare cases it matters which side or hand that starts
the bidding, i.e. which side or hand that is first to bid its optimal contract.
Two alternatives are given:
The presentation of the
par score and contracts are given in alternative formats.
The functions Par, SidesPar
and DealerPar do the par calculation; their call must be preceded by a function
call calculating the double dummy table values.
The functions SidesParBin
and DealerParBin provide binary output of the par results, making it easy to
tailor-make the output text format. Two
such functions, ConvertToSidesTextFormat and ConvertToDealerTextFormat, are
included as examples.
It is possible as an
option to perform par calculation in CalcAllTables and CalcAllTablesPBN.
The par calculation is executed
using a single thread. But the calculation is very fast and its duration is
negligible compared to the double dummy calculation duration.
Double
Dummy Value Analyser Functions
The functions
AnalysePlayBin, AnalysePlayPBN, AnalyseAllPlaysBin and AnalyseAllPlaysPBN take
the played cards in a game or games and calculate and present their double
dummy values.
|
Function |
Arguments |
Format |
Comment |
|
SolveBoard |
struct deal dl, int target, int solutions, int mode, struct futureTricks *futp, int threadIndex |
Binary |
The most basic function, solves a single hand from the beginning
or from later play |
|
SolveBoardPBN |
struct dealPBN dlPBN, int target, int solutions, int mode, struct futureTricks *futp, int threadIndex |
PBN |
As SolveBoard, but with PBN deal format. |
|
CalcDDtable |
struct ddTableDeal tableDeal,
* tablep |
Binary |
Solves an initial hand for all possible declarers and
denominations (up to 20 combinations) |
|
CalcDDtablePBN |
struct ddTableDealPBN struct ddTableResults * tablep |
PBN |
As CalcDDtable, but with PBN deal format. |
|
CalcAllTables |
struct ddTableDeals * dealsp, int mode, int trumpFilter[5], struct ddTablesRes *resp, struct allParResults * presp |
Binary |
Solves a number of hands in parallel. Multi-threaded. |
|
CalcAllTablesPBN |
struct ddTableDealsPBN *dealsp, int mode, int trumpFilter[5], struct ddTablesRes *resp, struct allParResults * presp |
PBN |
As CalcAllTables, but with PBN deal format. |
|
SolveAllBoards |
struct boardsPBN *bop, struct solvedBoards * solvedp |
PBN |
Consider using this instead of the next 3 “Chunk” functions”! |
|
SolveAllChunksBin |
struct boards *bop, struct solvedBoards *solvedp, int chunkSize |
Binary |
Solves a number of hands in parallel. Multi-threaded. |
|
SolveAllChunks |
struct boardsPBN *bop, struct solvedBoards * solvedp, int chunkSize |
PBN |
Alias for SolveAllChunksPBN; don’t use! |
|
SolveAllChunksPBN |
struct boardsPBN *bop, struct solvedBoards * solvedp, int chunkSize |
PBN |
Solves a number of hands in parallel. Multi-threaded. |
|
Par |
struct ddTableResults * tablep, struct parResults *presp, int vulnerable |
No format |
Solves for the par contracts given a DD result table. |
|
DealerPar |
struct ddTableResults * tablep, struct parResultsDealer * presp, int dealer, int vulnerable |
No format |
Similar to Par(), but requires and uses knowledge of the dealer. |
|
DealerParBin |
struct ddTableResults * tablep, struct parResultsMaster * presp, int dealer, int vulnerable |
Binary |
Similar to DealerPar, but with binary output. |
|
ConvertToDealerTextFormat |
struct parResultsMaster * pres, char *resp |
Text |
Example of text output from DealerParBin. |
|
SidesPar |
struct ddTableResults *tablep, struct parResultsDealer * presp, int vulnerable |
No format |
Par results are given for sides with the DealerPar output
format. |
|
SidesParBin |
struct ddTableResults struct parResultsMaster sidesRes[2], int vulnerable |
Binary |
Similar to SidesPar, but with binary output. |
|
ConvertToSidesTextFormat |
struct parResultsMaster * pres, struct parTextResults * resp |
Text |
Example of text output from SidesParBin. |
|
CalcPar |
struct ddTableDeal tableDeal, int vulnerable, struct ddTableResults * tablep, struct parResults * presp |
Binary |
Solves for both the DD result table and the par contracts. Is
deprecated, use a CalcDDtable function plus Par() instead! |
|
CalcParPBN |
struct ddTableDealPBN tableDealPBN, struct ddTableResults * tablep, int vulnerable, struct parResults * presp |
PBN |
As CalcPar, but with PBN input format. Is deprecated, use a
CalcDDtable function plus Par() instead! |
|
AnalysePlayBin |
struct deal dl, struct playTraceBin play, struct solvedPlay * solvedp, int thrId |
Binary |
Returns the par result after each card in a particular play
sequence |
|
AnalysePlayPBN |
struct dealPBN dlPBN, struct playTracePBN playPBN, struct solvedPlay * solvedp, int thrId |
PBN |
As AnalysePlayBin, but with PBN deal format. |
|
AnalyseAllPlaysBin |
struct boards *bop, struct playTracesBin *plp, struct solvedPlays * solvedp, int chunkSize |
Binary |
Solves a number of hands with play sequences in parallel. Multi-threaded. |
|
AnalyseAllPlaysPBN |
struct boardsPBN *bopPBN, struct playTracesPBN * plpPBN, struct solvedPlays * solvedp, int chunkSize |
PBN |
As AnalyseAllPlaysBin, but with PBN deal format. |
|
SetMaxThreads |
int userThreads |
|
Used at initial start and can also be called with a request for
allocating memory for a specified number of threads. Is apparently mandatory on Linux and Mac
(optional on Windows) |
|
FreeMemory |
void |
|
Frees all allocated dynamical memory. |
|
GetDDSInfo |
DDSInfo * info |
|
|
|
ErrorMessage |
int code, char line[80] |
|
Turns a return code into an error message string |
Common encodings are as follows.
|
Encoding |
Element |
Value |
|
Spades Hearts Diamonds Clubs NT |
0 1 2 3 4 |
|
|
North East South West |
0 1 2 3 |
|
|
None Both NS only EW only |
0 1 2 3 |
|
|
N-S E-W |
0 1 |
|
|
Bit 2 … Bit 13 Bit 14 |
Rank of deuce Rank of king Rank of ace |
|
|
A value
of 16388 = 16384 + 4 is the encoding for the holding “A2” (ace and deuce). The two
lowest bits are always zero. |
||
|
Whole
hand |
Example: W:T5.K4.652.A98542
K6.QJT976.QT7.Q6 432.A.AKJ93.JT73 AQJ987.8532.84.K |
|
|
struct |
Field |
Comment |
|
int trump; |
Suit
encoding |
|
|
|
int first; |
The hand leading to the trick.
Hand
encoding |
|
|
int currentTrickSuit[3]; |
Up to 3 cards may already have been played to the trick. Suit
encoding. Set to 0 if no card has been played. |
|
|
int currentTrickRank[3]; |
Up to 3 cards may already have been played to the trick. Value range 2-14. Set to 0 if no card has been played. |
|
|
unsigned int remainCards[4][4]; |
1st index is Hand, 2nd
index is Suit. remainCards uses Holding encoding. |
|
struct |
Field |
Comment |
|
int trump; |
Suit
encoding |
|
|
|
int first; |
The hand leading to the trick.
Hand
encoding |
|
|
int currentTrickSuit[3]; |
Up to 3 cards may already have been played to the trick. Suit
encoding. |
|
|
int currentTrickRank[3]; |
Up to 3 cards may already have been played to the trick. Value
range 2-14. Set to 0 if no card has been played. |
|
|
char remainCards[80]; |
Remaining cards. PBN
encoding. |
|
struct |
Field |
Comment |
|
unsigned int cards[4][4]; |
Encodes a deal. First
index is hand. Hand encoding. Second index is suit. Suit
encoding. |
|
struct |
Field |
Comment |
|
char cards[80]; |
Encodes a deal. PBN
encoding. |
|
struct |
Field |
Comment |
|
int noOfTables; |
Number of DD table deals in structure, at most MAXNOOFTABLES |
|
|
|
struct ddTableDeal deals[X]; |
X = MAXNOOFTABLES * DDS_STRAINS |
|
struct |
Field |
Comment |
|
int noOfTables; |
Number of DD table deals in structure |
|
|
|
struct ddTableDealPBN deals[X]; |
X = MAXNOOFTABLES * DDS_STRAINS |
|
struct |
Field |
Comment |
|
int noOfBoards; |
Number of boards |
|
|
|
struct deal [MAXNOOFBOARDS]; |
|
|
|
int target [MAXNOOFBOARDS]; |
See SolveBoard |
|
|
int solutions [MAXNOOFBOARDS]; |
See SolveBoard |
|
|
int mode [MAXNOOFBOARDS]; |
See SolveBoard |
|
struct |
Field |
Comment |
|
int noOfBoards; |
Number of boards |
|
|
|
struct dealPBN [MAXNOOFBOARDS]; |
|
|
|
int target [MAXNOOFBOARDS]; |
See SolveBoard |
|
|
int solutions [MAXNOOFBOARDS]; |
See SolveBoard |
|
|
int mode [MAXNOOFBOARDS]; |
See SolveBoard |
|
struct |
Field |
Comment |
|
int nodes; |
Number of nodes searched by the DD solver |
|
|
|
int cards; |
Number of cards for which a result is returned. May be all the cards, but equivalent ranks
are omitted, so for a holding of KQ76 only the cards K and 7 would be
returned, and the “equals” field below would be 2048 (Q) for the king and 54
(6) for the 7. |
|
|
int suit[13]; |
Suit of the each returned card.
Suit
encoding |
|
|
int rank[13]; |
Rank of the returned card. Value range 2-14. |
|
|
int equals[13]; |
Lower-ranked equals. Holding encoding. |
|
|
int score[13]; |
-1: target not reached. Otherwise: Target of maximum number of tricks. |
|
struct |
Field |
Comment |
|
int noOfBoards; |
|
|
|
|
struct futureTricks solvedBoard [MAXNOOFBOARDS]; |
|
|
Struct |
Field |
Comment |
|
int resTable[5][4]; |
Encodes the solution of a deal for combinations of denomination
and declarer. First index is
denomination. Suit
encoding. Second index is
declarer. Hand
encoding. Each entry is a number of
tricks. |
|
Struct |
Field |
Comment |
|
int noOfBoards; |
Number of DD table deals in structure, at most MAXNOOFTABLES |
|
|
|
struct ddTableResults results[X]; |
X = MAXNOOFTABLES * DDS_STRAINS |
|
struct |
Field |
Comment |
|
char parScore[2][16]; |
First index is NS/EW. Side
encoding. |
|
|
|
char parContractsString [2][128]; |
First index is NS/EW. Side
encoding. |
|
struct |
Field |
Comment |
|
struct parResults [MAXNOOFTABLES]; |
There are up to 20 declarer/strain combinations per DD table |
|
Field |
Comment |
|
|
parResultsDealer |
int number; |
|
|
|
int score; |
|
|
|
char contracts[10][10]; |
|
|
struct |
Field |
Comment |
|
int score; |
|
|
|
|
int number; |
|
|
|
struct contractType contracts[10]; |
|
|
struct |
Field |
Comment |
|
int underTricks; |
|
|
|
|
int overTricks; |
|
|
|
int level; |
|
|
|
int denom; |
|
|
|
int seats; |
|
|
struct |
Field |
Comment |
|
char parText[2][128]; |
|
|
|
|
int equal; |
|
|
struct |
Field |
Comment |
|
int major, minor patch; |
|
|
|
|
char versionString[10]; |
Printable version string |
|
|
int system; |
0 unknown, 1 Windows, 2 Cygwin, 3 Linux, 4 Apple |
|
|
int compiler; |
0 unknown, 1 Microsoft Visual C++, 2 mingw, 3 GNU g++, 4 clang |
|
|
int constructor; |
0 none, 1 DLLMain, 2 Unix-style |
|
|
int threading; |
0 none, 1 Windows, 2 OpenMP |
|
|
int noOfThreads; |
|
|
|
char systemString[512]; |
Printable summary string |
|
struct |
Field |
Comment |
|
int number; |
Number of cards in the play trace, starting from the beginning
of the hand |
|
|
|
int suit[52]; |
Suit
encoding. |
|
|
int rank[52]; |
Encoding 2 .. 14 (not Card
encoding). |
|
struct |
Field |
Comment |
|
int number; |
Number of cards in the play trace, starting from the beginning
of the hand |
|
|
|
int cards[106]; |
String of cards with no space in between, also not between
tricks. Each card consists of a suit
(C/D/H/S) and then a rank (2 .. A). The
string must be null-terminated. |
|
struct |
Field |
Comment |
|
int noOfBoards; |
|
|
|
|
struct playTraceBin plays[MAXNOOFBOARDS]; |
|
|
struct |
Field |
Comment |
|
int noOfBoards; |
|
|
|
|
Struct playTracePBN plays[MAXNOOFBOARDS]; |
|
|
struct |
Field |
Comment |
|
int number; |
|
|
|
|
int tricks[53]; |
Starting position and up to 52 cards |
|
struct |
Field |
Comment |
|
int noOfBoards; |
|
|
|
|
struct solvedPlay solved[MAXNOOFBOARDS]; |
|
SolveBoard
struct deal dl, int target, int solutions, int mode, struct futureTricks *futp, int threadIndex |
SolveBoardPBN
struct dealPBN dl, int target, int solutions, int mode, struct futureTricks *futp, int threadIndex
|
SolveBoard is thread-safe,
so several threads can call SolveBoard in parallel. Thus the user of DDS can
create threads and call SolveBoard in parallel over them. The maximum number of
threads is fixed in the DLL at compile time and is currently 16. So “threadIndex” must be between 0 and 15
inclusive; see also the function SetMaxThreads.
Together with the PlayAnalyse functions, this is the only function that
exposes the thread number to the user.
There is a “transposition
table” memory associated with each thread.
Each node in the table is effectively a position after certain cards
have been played and other certain cards remain. The table is not deleted automatically after
each call to SolveBoard, so it can be reused from call to call. However, it only really makes sense to reuse
the table when the hand is very similar in the two calls. The function will still run if this is not
the case, but it won’t be as efficient.
The reuse of the transposition table can be controlled by the “mode” parameter, but normally
this is not needed and should not be done.
The three parameters “target”, “solutions” and “mode” together control the
function. Generally speaking, the target
is the number of tricks to be won (at least) by the side to play; solutions
controls how many solutions should be returned; and mode controls the search
behavior. See next page for definitions.
For equivalent cards, only
the highest is returned, and lower equivalent cards are encoded in the futureTricks structure (see “equals”).
|
target |
solutions |
Comment |
|
-1 |
1 |
Find the maximum number
of tricks for the side to play. Return only one of the
optimum cards and its score. |
|
-1 |
2 |
Find the maximum number
of tricks for the side to play. Return all optimum cards
and their scores. |
|
0 |
1 |
Return only one of the cards legal
to play, with score set to 0. |
|
0 |
2 |
Return all cards that legal to play,
with score set to 0. |
|
1 .. 13 |
1 |
If score is -1: Target
cannot be reached. If score is 0: In fact no tricks at all can be won. If score is > 0: score will always equal target, even if
more tricks can be won. One of the cards
achieving the target is returned. |
|
1 .. 13 |
2 |
Return all cards meeting
(at least) the target. If the target cannot be
achieved, only one card is returned with the score set as above. |
|
any |
3 |
Return all cards meeting
(at least) the target. ottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;
mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt;
mso-border-alt:solid windowtext .5pt;padding:0cm 5.4pt 0cm 5.4pt'>
@ ?1r 1.4ptw:datn Locked="false" Priority="50" Name="List Table 5 Dark Accent 4"/>
REF futureTricks \h REF futureTricks \h REF futureTricks \h REF futureTricks \h REF futureTricks \h REF futureTricks \h |