Provided by: libdds-dev_2.4.2+ddd105-1_amd64 bug


       InitStart,   SolveBoard,   SolveBoardPBN,   CalcDDtable,   CalcDDtablePBN,  CalcAllTables,
       CalcAllTablesPBN, SolveAllBoards, CalcPar,  CalcParPBN  -  calculate  number  of  possible
       tricks in a Bridge hand


       #include <dds.h>

       void InitStart(int gb_ram, int ncores);

       int  SolveBoard(struct  deal,  int  target,  int  solutions, int mode, struct futureTricks
       *futp, int threadIndex);

       int SolveBoardPBN(struct dealPBN, int target, int solutions, int mode, struct futureTricks
       *futp, int threadIndex);

       int CalcDDtable(struct ddTableDeal tableDeal, struct ddTableResults *tablep);

       int CalcDDtablePBN(struct ddTableDealPBN tableDealPBN, struct ddTableResults *tablep);

       int  CalcAllTables(struct  ddTableDeals  *dealsp,  int  mode,  int  trumpFilter[5], struct
       ddTablesRes *resp, struct allParResults*presp);

       int CalcAllTablesPBN(struct ddTableDealsPBN *dealsp, int mode, int trumpFilter[5],  struct
       ddTablesRes *resp, struct allParResults *presp);

       int SolveAllBoards(struct boardsPBN *bop, struct solvedBoards *solvedp);

       int  CalcPar(struct ddTableDeal tableDeal, int vulnerable, struct ddTableResults * tablep,
       struct parResults *presp);

       int CalcParPBN(struct ddTableDealPBN tableDealPBN, struct  ddTableResults  *  tablep,  int
       vulnerable, struct parResults *presp);


       Short description of the DLL functions supported in Double Dummy Problem Solver 2.1.2


       Initialize data structures for SolveBoard.

       If  either  gb_ram  or ncores are zero, autoconfiguration is done.  This is currently only
       supported on Windows; other platforms exit fatally when attempted.


       Before SolveBoard can be called, a structure of type "futureTricks" must be declared.

       SolveBoard returns a status integer, "no fault" means the DLL supplies the trick  data  in
       the "futureTricks" type structure.  Status codes:
          1=No fault
         -1=Unknown fault
         -2=No of cards = 0
         -3=target > Number of tricks left
         -4=Duplicated cards
         -5=target < -1
         -7=target > 13
         -8=solutions < 1
         -9=solutions > 3
        -10=No of cards > 52
        -11=Not used
        -12=Suit or rank value out of range for deal.currentTrickSuit or deal.currentTrickRank
        -13=Card already played in the current trick is also defined as a remaining card to play
        -14=Wrong number of remaining cards for a hand
        -15=threadIndex  <  0  or  >=noOfThreads, noOfThreads is the configured maximum number of

       Structure ”deal” defines all data needed to describe the deal to be analyzed.
        struct deal {
          int trump;   /* I.e. which suit that is trump or if contract is NT, Spades=0, Hearts=1,
       Diamonds=2, Clubs=3,  NT=4 */
          int  first;       /*  0-3,  0=North,  1=East,  2=South,  3=West  , Leading hand for the
          int currentTrickSuit[3];  /* 0-2 for up to 3 cards in the order played */
          int currentTrickRank[3];  /* 2-14 for up to 3 cards */
          unsigned int remainCards[4][4]; /* 1st index hand (0-3), 2nd index suit  (0-3),  values
       as  bitstring  of  ranks bit 0=0, bit 1=0, bit 2=rank 2, ………. bit 14=rank 14, bit 15=0 for
       cards remaining after already played cards (cards already played to the current trick  are
       not included in this bitstring).
        The decimal value for a card then range between 4 (=rank 2) and 16384  (Ace=rank 14). */

       Parameter  ”target”  is  the number of tricks to be won by the side to play, -1 means that
       the program shall find the maximum number. For  equivalent   cards  only  the  highest  is

       Parameter ”solutions” defines how many card solutions that SolveBoard must return:

       target=1-13, solutions=1:
              Returns only one of the cards. Its returned score is the same as target when target
              or higher tricks can be won. Otherwise, score -1 is returned if  target  cannot  be
              reached, or score 0 if no tricks can be won.

       target=-1, solutions=1:
              Returns only one of the optimum cards and its score.

       target=0, solutions=1:
              Returns only one of the cards legal to play with score set to 0.

       target 1-13, solutions=2:
              Return  all cards meeting target. Their returned scores are the same as target when
              target or higher tricks can be won. Otherwise, only one card is returned with score
              -1 if target cannot be reached, or score 0 for all cards legal to play if no tricks
              can be won.

       target -1, solutions=2:
              Return all optimum cards with their scores.

       target=0, solutions=2:
              Return all cards legal to play with scores set to 0.

       target irrelevant, solutions=3:
              Return all cards that can be legally played with their scores in descending  order.

       Parameter ”mode” defines the DLL mode of operation.

       mode=0 Do not search to find the score if the hand to play has only  one  card,  including
              its  equivalents,  to play. Score is set to -2 for this card, indicating that there
              are no alternative cards. If there are multiple choices for cards to  play,  search
              is  done  to  find the score. This mode is very fast but you don’t always search to
              find the score.

       mode=1 Always search to find the score. Even when the hand to  play  has  only  one  card,
              with  possible  equivalents, to play.  For both mode=0 and mode=1: If the preceding
              SolveBoard call had the same trump suit and the same or similar  deal,  except  for
              deal.first,  then  the  transposition  table  contents is reused from the preceding
              SolveBoard call. Setting mode=2 is no longer needed in this case, but can still  be
              done for backwards compatibility.

       mode=2 As  for  mode=1,  but the transposition table contents is reused from the preceding
              SolveBoard call.  It is the responsibility of  the  programmer  using  the  DLL  to
              ensure that reusing the table is safe in the actual situation. Example: Deal is the
              same, except for deal.first. Trump suit is the same.
               1st call:  SolveBoard(deal, -1, 1, 1, &fut, 0),  deal.first=1, i.e. East leads.
               2nd call:  SolveBoard(deal, -1, 1, 2, &fut, 0),  deal.first=2, i.e. South leads.
               3rd call:  SolveBoard(deal, -1, 1, 2, &fut, 0),  deal.first=3, i.e. West leads.
               4th call:  SolveBoard(deal, -1, 1, 2, &fut, 0),  deal.first=0, i.e. North leads.

        struct futureTricks { /* The DLL provides the score (number of tricks) that can be won by
       the card to play defined by its suit and rank. Array of all alternative cards. */
          int nodes;         /* Number of searched nodes */
          int cards;         /*  No of alternative cards  */
          int suit[13];      /* 0=Spades, 1=Hearts, 2=Diamonds, 3=Clubs */
          int rank[13];      /* 2-14 for 2 through Ace */
          int  equals[13];     /* Bitstring of ranks for equivalent lower rank cards. The decimal
       value range between 4 (=2) and 8192 (King=rank 13).  When there are several ”equals”,  the
       value is the sum of each ”equal”. */
          int score[13];     /* -1 indicates that target was not reached, otherwise target or max
       numbe of tricks */

       Parameter ”threadIndex” defines the identity of the thread used when  calling  SolveBoard.
       A  configured  maximum number of threads can call SolveBoard in parallel, threadIndex must
       be an integer in the range 0..max number of threads - 1. This maximum number is configured
       at DLL initial start-up and cannot exceed 16.

       SolveBoard is thread-safe, so several threads (max 16) can call SolveBoard in parallel.


       In  SolveBoardPBN the remaining cards in the deal information are given in PBN text format
       (e.g. W:T5.K4.652.A98542 K6.QJT976.QT7.Q6 432.A.AKJ93.JT73  AQJ987.8532.84.K)  instead  of
       using bits 2-14 in an integer array. Otherwise, SolveboardPBN is identical to SolveBoard.

        struct dealPBN {
          int trump;
          int first;
          int currentTrickSuit[3];
          int currentTrickRank[3];
          char  remainCards[80];    /* First character identifies the hand having the cards given
                                        in the string, then the cards  of  the  other  hands  are
       given in a
                                        clock-wise order, see example above. Null characters fill
                                        the character array at the end. */


       CalcDDtable calculates the double dummy values of the initial 52  cards  for  all  the  20
       trump suit/declarer hand combinations.

       Before  CalcDDtable  can be called, a structure of type "ddTableResults" must be declared.
       CalcDDtable returns a status integer, "no fault" means the DLL supplies the  double  dummy
       scores in the "ddTableResults" type structure.  Status codes:
          1=No fault,
          Other status codes are errors, with codes equal to SolveBoard status codes.

       Structure ”ddTableDeal” defines the dealt cards to be analyzed.

        struct ddTableDeal {
          unsigned int cards[4][4];   /* 1st index is hand, 2nd index is suit, same coding as for
       deal.remainCards for SolveBoard. */

        struct ddTableResults { /* For each combination trump  suit  /  declarer  hand,  the  DLL
       provides the double dummy score. */
          int  resTable[5][4];   /*  1st index is trump (0=Spades, 1=Hearts, 2=Diamonds, 3=Clubs,
       4=No Trump 2nd index is declarer hand, 0=North, 1=East, 2=South, 3=West */


       In CalcDDtablePBN the remaining cards in the  deal  information  are  given  in  PBN  text
       format,  see  the  description  above  for  SolveBoardPBN.  Otherwise,  CalcDDtablePBN  is
       identical to CalcDDtable.

        struct ddTableDealPBN {
          char cards[80];


       CallAllTables  calculates  the  double  dummy  values  of  the  trump  suit/declarer  hand
       combinations  for a nu mber of DD tables in parallel. This increases the speed compared to
       calculating these values using a Ca lcDDtable call for each DD table.

       The maximum number of DD tables in a CallAllTables call depends on the number  of  strains
       (the  number  o f 5 trump alternatives, any of the 4 suits and no trump) to be part of the
       DD calculations. If all 5 st rains are included  there  are  20  declarer  hand  /  strain
       combinations.  The  maximum number of boards that can be calculated in parallel is 200, so
       the maximum number of DD tables that can be included in a Call AllTable  call  is  10.  At
       fewer strains the maximum number of DD tables in a call is higher:
        4 strains maximum 12 DD tables
        3 strains maximum 16 DD tables
        2 strains maximum 25 DD tables
        1 strain maximum 50 DD tables

       Before  CalcAllTables  can  be called, a structure of type "ddTablesRes" must be declared.
       CallAllTables returns a status integer, "no fault" means the DLL supplies the double dummy
       scores   in   t   he  "ddTablesRes"  type  structure.  Its  contained  structure  of  type
       “ddTableResults” is described for the  function  CalcDDtable.  The  variable  “noOfBoards”
       shows the number of solved boards (max 200).

        struct ddTablesRes {
          int noOfBoards;
          struct ddTableResults results[MAXNOOFBOARDS / 4];

       Status codes:
          1=No fault,
          -201=Error, all trump suits and the no trump suit alternative have been marked in the
              calling parameter trumpFilter to be left out (i.e. they have all been set to TRUE),
          -202=Error, too many DD tables in the call.

       Structure  “ddTableDeals”  contains  up  to  50  DD  table  deals,  each  in  a  structure
       “ddTableDeal”, described for the function CalcDDtable. The actual number  is  set  in  the
       “noOfTables” parameter.

        struct ddTableDeals {
          int noOfTables;
          struct ddTableDeal deals[MAXNOOFBOARDS / 4];

       Parameter  “mode”  specifies whether or not par score and par contracts will be calculated
       and if so, which sides that are vulnerable:
        -1:    no par calculation
        0:     par calculation, vulnerability None
        1:     par calculation, vulnerability All
        2:     par calculation, vulnerability NS only
        3:     par calculation, vulnerability EW only

       The results of the par calculations are given  in  the  structure  “allParResults”,  which
       contains  the  results  for  all  boards.  Each  board  results  are  given  in  structure
       “parResults”, described for the CalcPar function.

        struct allParResults {
          struct parResults presults[MAXNOOFBOARDS / 4];

       Parameter “trumpFilter” describes which, if any, of the trump suits or the no  trump  suit
       alternatives  that  will  be excluded from the calculations. They are defined in the order
       Spades, Hearts, Diamonds, Clubs and No Trumps. E.g. setting trumpFilter to {FALSE,  FALSE,
       TRUE, TRUE, TRUE} means that values will only be calculated for the trump suits Spades and


       As for CalcAllTables except that  the  deals  are  given  in  PBN  format.  The  structure
       “ddTableDealPBN” is described for the CalcDDtablePBN function.

        struct ddTableDealsPBN {
          int noOfTables;
          struct ddTableDealPBN deals[MAXNOOFBOARDS / 4];


       SolveAllBoards solves a number of boards in parallel for increased performance compared to
       solve them sequentionally using a SolveBoard call for each board.

       SolveAllBoards is called with a buffer containing board  data  for  a  number  of  boards,
       maximum  200  boards  per  call.  Each  board  is  defined  with the same input data as in
       SolveBoardPBN. The input data per board can be freely given independent  of  the  settings
       for  the  other deals. SolveAllBoards uses multi-thread calls to SolveBoardPBN for solving
       the buffered boards.

        struct boardsPBN {
          int noOfBoards;
          struct dealPBN deals[MAXNOOFBOARDS];
          int target[MAXNOOFBOARDS];
          int solutions[MAXNOOFBOARDS];
          int mode[MAXNOOFBOARDS];

        struct solvedBoards {
          int noOfBoards;
          struct futureTricks solvedBoard[MAXNOOFBOARDS];

       In the SolveAllBoards call, the cards are coded in  PBN  text  format  using  the  dealPBN
       structure.  The  number of boards to be solved must be defined in the boardsPBN structure,
       the number must not exceed MAXNOOFBOARDS which is 100.  In  the  returned  information  in
       struct  solvedBoards,  the number of solved boards are given. The futureTricks information
       is provided for all solved boards with the same returned information  per  board  as  with

       SolveAllBoards  returns  1  if the call succeeds, otherwise an error code identical to the
       SolveBoard error codes is given when there is a problem in the input information.

       Notes on DDS use for simulations

       SolveAllBoards is optimal when the input boards are dissimilar.  Adjacent  boards  in  the
       boards  buffer  that  are  similar  (same  trump,  very  minor  difference  between  cards
       distribution between hands) typically means that transposition table information cannot be
       reused.  That  is  because  these  boards  typically use different threads. In simulations
       involving different declarer hand alternatives and  possibly  also  different  suit  trump
       alternatives,  usage  of  CalcAllTables  is  a  more  convenient  and  probably  a  faster
       alternative.  E.g. if the task is to make simulations to find which of the major suits  is
       best  in  a  trump  contract  and  which hand is best as declarer, then such simulation is
       easily set up using CalcAllTables and most likely runs faster than with SolveAllBoards.


       CalcPar calculates the par score and par contracts of  a  given  deal.  It  also  includes
       calculation  and presentation of the double dummy values table otherwise calculated by the
       CalcDDtable function, since this table is a prerequisite for the  par  calculations.  Thus
       there is no need to make a CalcDDtable call before calling CalcPar.

       Before  CalcPar can be called, a structure of each type " ddTableResults" and “parResults”
       must be declared.  CalcPar returns a status integer, "no fault" means the DLL supplies the
       double  dummy  scores  in  the  "ddTableResults" type structure and the par results in the
       “parResults” structure.  Calling CalcPar with the structure of type “ddTableDeal” is  done
       in the same way as for calling CalcDDtable.

       Status codes:
          1=No fault,
          Other status codes are errors, with codes equal to SolveBoard status codes.

       Parameter “vulnerable” is set according to:
          0 = None
          1 = Both sides
          2 = North / South side vulnerable
          3 = East / West side vulnerable

       The  structure  types  “ddTableDeal”  and  “ddTableresults” are described for the function
       CalcDDtable.  The “parResults” structure type includes the par score and the par contracts
       results returned by the call to CalcPar:

        struct parResults {
          char parScore[2][16]; /* index = 0 is from NS view and index =1 is from EW view. */
          char  parContractsString[2][128];  /* index = 0 is NS view and index = 1 is EW view. By
       “view” is
               here meant which side that starts the bidding. */

       Par score is given as a text string, e.g NS -460. NS lost 460 points.  All  par  contracts
       for  different suits are listed with comma separating the suits.  Possible different trick
       levels of par score contracts are enumerated in the contract description, e.g the possible
       trick levels 3, 4 and 5 in No trumps, are given as 345N.

       Example of par contracts in different suits:
        NS:NS 23S,NS 23H This is from the NS view. North and South as declarer make 2 or 3 Spades
       and Hearts contracts, 2 Spades and 2 Hearts with an overtrick.  If only North could make 3
       Hearts, the text string would have looked:
        NS:NS  23S,N 23H NS before the colon refers to the assumed side that made the initial bid
       in the process for determining the par score / contracts.  Also, DDS  calculates  the  par
       score / contracts when the assumed side is EW:
        EW:NS  23S,N  23H Nearly always, the par score / contracts are the same for both starting
       points. One case where they are not is if both sides can make 1 NT but no other contract.


       The only difference compared to CalcPar is that the  structure  type  “ddTableDealPBN”  is
       used instead of “ddTableDeal”. For description of “ddTableDealPBN”, see CalcDDtablePBN.

Revision History

       Rev A, 2006-02-25   First issue.

       Rev B, 2006-03-20   Updated issue.

       Rev C, 2006-03-28   Updated issue. Addition of the SolveBoard parameter ”mode”.

       Rev  D,  2006-04-05   Updated issue. Usage of target=0 to list all cards that are legal to

       Rev E, 2006-05-29   Updated issue. New error code -10 for number of cards > 52.

       Rev F, 2006-08-09   Updated issue. New mode parameter value = 2. New error  code  -11  for
       calling SolveBoard with mode = 2 and forbidden values of other parameters.

       Rev  F1,  2006-08-14  Clarifications  on conditions for returning scores for the different
       combinations of the values for target and solutions.

       Rev F2, 2006-08-26  New error code -12 for wrongly set values of deal.currentTrickSuit and

       Rev G, 2007-01-04   New DDS release 1.1, otherwise no change compared to isse F2.

       Rev H, 2007-04-23   DDS release 1.4, changes for parameter mode=2.

       Rev I, 2010-04-10   DDS release 1.2, multi-thread support.

       Rev  J,  2010-05-29   DDS  release 2.1, OpenMP support, reuse of previous DD transposition
       table results of similar deals.

       Rev K, 2010-10-27   Correction of fault in the description:  2nd index in resTable of  the
       structure ddTableResults is declarer hand.

       Rev L, 2011-10-14   Added SolveBoardPBN and CalcDDtablePBN.

       Rev M, 2012-07-06   Added SolveAllBoards.

       Rev N, 2012-07-16   Max number of threads is 8.

       Rev  O,  2012-10-21   Max  number  of threads is configured at initial start-up, but never
       exceeds 16.

       Rev P, 2013-03-16   Added functions CalcPar and CalcParPBN.

       Rev Q, 2014-01-09   Added functions CalcAllTables/CalcAllTablesPBN.

       Rev R, 2014-01-13   Updated functions CalcAllTables/CalcAllTablesPBN.

       Rev S, 2014-01-13   Updated functions CalcAllTables/CalcAllTablesPBN.

                                             2014-01                                SolveBoard(3)