Skip to content

Commit

Permalink
historical commit dds 2.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
bohag authored and hostilefork committed Nov 25, 2014
1 parent 25a149b commit 03b485e
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 62 deletions.
40 changes: 20 additions & 20 deletions DLL-dds_20_i.rtf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\nowidctlpar\adjustright \f1\cgrid \snext0 Normal;}{
\s1\nowidctlpar\outlinelevel0\adjustright \f1\cgrid \sbasedon0 \snext0 heading 1;}{\s2\keepn\nowidctlpar\outlinelevel1\adjustright \b\f1\fs20\ul\cf1\lang1053\cgrid \sbasedon0 \snext0 heading 2;}{\s3\keepn\nowidctlpar\outlinelevel2\adjustright
\b\f1\fs20\cf1\lang1053\cgrid \sbasedon0 \snext0 heading 3;}{\*\cs10 \additive Default Paragraph Font;}{\*\cs15 \additive \b \sbasedon10 Strong;}}{\info{\title Bo Haglund, Bob Richardson}{\author Bo Haglund}{\operator Bo Haglund}
{\creatim\yr2007\mo4\dy23\hr19\min18}{\revtim\yr2010\mo4\dy24\hr8\min19}{\version29}{\edmins128}{\nofpages3}{\nofwords1128}{\nofchars6430}{\*\company }{\nofcharsws0}{\vern89}}\margl1417\margr1417\margt1417\margb1417
{\creatim\yr2007\mo4\dy23\hr19\min18}{\revtim\yr2010\mo5\dy16\hr22\min6}{\version32}{\edmins156}{\nofpages3}{\nofwords1128}{\nofchars6430}{\*\company }{\nofcharsws0}{\vern89}}\margl1417\margr1417\margt1417\margb1417
\widowctrl\ftnbj\aenddoc\hyphhotz425\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\hyphcaps0\viewkind4\viewscale100 \fet0\sectd \linex0\headery709\footery709\colsx709\sectdefaultcl {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}
{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}
{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9
Expand Down Expand Up @@ -51,33 +51,33 @@
\par }{\fs20\cf1\lang1053 int first; /* 0-3, 0=North, 1=East, 2=South, 3=West , Leading hand for the trick.*/}{\f0\fs20\cf1\lang1053
\par }{\fs20\cf1\lang1053 int currentTrickSuit[3]; /* 0-2 for up to 3 cards in the order played */
\par int currentTrickRank[3]; /* 2-14 for up to 3 cards */}{\f0\fs20\cf1\lang1053
\par }{\fs20\cf1\lang1053 unsigned int remainCards[4][4]; /* 1}{\fs20\cf1\lang1053\super st}{\fs20\cf1\lang1053 index hand (0-3), 2}{\fs20\cf1\lang1053\super nd}{\fs20\cf1\lang1053 in
dex suit (0-3), values as bitstring of ranks bit 0=0, bit 1=0, bit 2=rank 2, \'85\'85\'85. bit 14=rank 14, bit 15=0}{\f0\fs20\cf1\lang1053 }{\fs20\cf1\lang1053
for cards remaining after already played cards (cards already played to the current trick are not included in this bitstring). \line The decimal value for a card then range between 4 (=rank 2) and 16384 (Ace=rank 14). */}{\f0\fs20\cf1\lang1053
\par }{\fs20\cf1\lang1053 unsigned int remainCards[4][4]; /* 1}{\fs20\cf1\lang1053\super st}{\fs20\cf1\lang1053 index hand (0-3), 2}{\fs20\cf1\lang1053\super nd}{\fs20\cf1\lang1053
index suit (0-3), values as bitstring of ranks bit 0=0, bit 1=0, bit 2=rank 2, \'85\'85\'85. bit 14=rank 14, bit 15=0}{\f0\fs20\cf1\lang1053 }{\fs20\cf1\lang1053 for cards remaining after already played cards (cards alread
y played to the current trick are not included in this bitstring). \line The decimal value for a card then range between 4 (=rank 2) and 16384 (Ace=rank 14). */}{\f0\fs20\cf1\lang1053
\par }{\fs20\cf1\lang1053 \};}{\f0\fs20\cf1\lang1053 }{\fs20\cf1\lang1053
\par
\par Parameter \'94}{\b\fs20\cf1\lang1053 target}{\fs20\cf1\lang1053 \'94 is the number of tricks to be won by the side to play, -1 means that the program}{\f0\fs20\cf1\lang1053 }{\fs20\cf1\lang1053
shall find the maximum number. For equivalent cards only the highest is returned.
\par \line Parameter \'94}{\b\fs20\cf1\lang1053 solutions}{\fs20\cf1\lang1053 \'94 defines how many card solutions that SolveBoard must return:
\par target=1-13, solutions=1: Returns only one of the cards. Its returned score is the same as target whentarget or higher tricks can be won. Otherwise, score \endash 1 is returned if target cannot be reached, or score 0 if no tricks can be won. \line
target=-1, solutions=1: Returns only one of the optimum cards and its score.
\par }{\fs20\lang1053 target=0, solutions=1: Returns only one of the cards legal to play with score set to 0.}{\fs20\cf1\lang1053 \line 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 \endash
\par }{\fs20\lang1053 target=0, solutions=1: Returns only one of the cards legal to play with score set to 0.}{\fs20\cf1\lang1053 \line
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 \endash
1 if target cannot be reached, or score 0 for all cards legal to play if no tricks can be won.\line target \endash 1, solutions=2: Return all optimum cards with their scores.
\par }{\fs20\lang1053 target=0, solutions=2: Return all cards legal to play with scores set to 0}{\fs20\cf6\lang1053 .}{\fs20\cf1\lang1053 \line target irrelevant, solutions=3: Return all cards that can be legally played with
their scores in descending order.
\par
\par Parameter \'94}{\b\fs20\cf1\lang1053 mode}{\fs20\cf1\lang1053 \'94
defines the DLL mode of operation. This mode does not affect the DLL if there are multiple choices for cards to play. If there is just one card to play, or multiple cards that are all equivalent, this mo
de determines whether or not the DLL will search to find the score.\line 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 \endash
2 for this card, indicating that there are no alternative cards. This mode is very fast but you don\rquote t
\par mode=1: Always }{\fs20 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 tru
mp 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, but can still be done for backwards
\par compatibility.\line mode=2: As for mode=1, but the transposition table contents is reused from the preceding SolveBoard call. Deal must be the same, except for deal.first. Trump suit must be the same. Example:
\par }\pard \fi720\nowidctlpar\adjustright {\fs20 1}{\fs20\super st}{\fs20 call: SolveBoard(deal, -1, 1, 1, &fut), deal.first=1, i.e. East leads.
\par }\pard \nowidctlpar\adjustright {\fs20 \tab 2}{\fs20\super nd}{\fs20 call: SolveBoard(deal, -1, 1, 2, &fut), deal.first=2, i.e. South leads.
\par \tab 3rd call: SolveBoard(deal, -1, 1, 2, &fut), deal.first=3, i.e. West leads.
\par }\pard \fi720\nowidctlpar\adjustright {\fs20 4th call: SolveBoard(deal, -1, 1, 2, &fut), deal.first=0, i.e. North leads. }{\fs20\cf1\lang1053
\par }{\fs20\lang1053 target=0, solutions=2: Return all cards legal to play with scores set to 0}{\fs20\cf6\lang1053 .}{\fs20\cf1\lang1053 \line
target irrelevant, solutions=3: Return all cards that can be legally played with their scores in descending order.
\par
\par Parameter \'94}{\b\fs20\cf1\lang1053 mode}{\fs20\cf1\lang1053 \'94 defines the DLL mode of operation.\line 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 \endash
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\rquote t
\par mode=1: Always }{\fs20 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 deal, except for deal.first, then the transposition table cont
ents 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.\line
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.
\par }\pard \fi720\nowidctlpar\adjustright {\fs20 1}{\fs20\super st}{\fs20 call: SolveBoard(deal, -1, 1, 1, &fut, 0), deal.first=1, i.e. East leads.
\par }\pard \nowidctlpar\adjustright {\fs20 \tab 2}{\fs20\super nd}{\fs20 call: SolveBoard(deal, -1, 1, 2, &fut, 0), deal.first=2, i.e. South leads.
\par \tab 3rd call: SolveBoard(deal, -1, 1, 2, &fut, 0), deal.first=3, i.e. West leads.
\par }\pard \fi720\nowidctlpar\adjustright {\fs20 4th call: SolveBoard(deal, -1, 1, 2, &fut, 0), deal.first=0, i.e. North leads. }{\fs20\cf1\lang1053
\par }\pard \nowidctlpar\adjustright {\fs20\cf1\lang1053
\par struct }{\b\fs20\cf1\lang1053 futureTricks}{\fs20\cf1\lang1053 \{ /* 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. */}{\f0\fs20\cf1\lang1053
\par }{\fs20\cf1\lang1053 int nodes; /* Number of searched nodes */
Expand Down
109 changes: 71 additions & 38 deletions dds.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

/* DDS 2.0.0 A bridge double dummy solver. */
/* DDS 2.0.1 A bridge double dummy solver. */
/* Copyright (C) 2006-2010 by Bo Haglund */
/* Cleanups and porting to Linux and MacOSX (C) 2006 by Alex Martelli */
/* */
Expand All @@ -17,7 +17,7 @@
/* along with this program; if not, write to the Free Software */
/* Foundation, Inc, 51 Franklin Street, 5th Floor, Boston MA 02110-1301, USA. */

/*#include "stdafx.h" */ /* Needed by Visual C++ */
/*#include "stdafx.h"*/ /* Needed by Visual C++ */

#include "dll.h"

Expand Down Expand Up @@ -102,16 +102,20 @@ extern "C" BOOL APIENTRY DllMain(HMODULE hModule,
int STDCALL SolveBoard(struct deal dl, int target,
int solutions, int mode, struct futureTricks *futp, int thrId) {

int k, l, n, cardCount, found, totalTricks, tricks, last, checkRes;
int g, upperbound, lowerbound, first, i, j, h, forb, ind, flag, noMoves;
int k, n, cardCount, found, totalTricks, tricks, last, checkRes;
int g, upperbound, lowerbound, first, i, j, forb, ind, flag, noMoves;
int mcurr;
int noStartMoves;
int handRelFirst;
int noOfCardsPerHand[4];
int latestTrickSuit[4];
int latestTrickRank[4];
int maxHand=0, maxSuit=0, maxRank;
unsigned short int aggrRemain;
#ifdef SIMILARITYTEST
int playedHistory;
unsigned short int prevAggrRemain[4];
#endif
unsigned short int aggrRemain[4];
struct movePlyType temp;
struct moveType mv;

Expand Down Expand Up @@ -149,18 +153,36 @@ extern "C" BOOL APIENTRY DllMain(HMODULE hModule,

for (k=0; k<=3; k++)
noOfCardsPerHand[handId(dl.first, k)]=0;

#ifdef SIMILARITYTEST
playedHistory=TRUE;
#endif
for (j=0; j<=3; j++) {
aggrRemain[j]=0;
for (i=0; i<=3; i++)
aggrRemain[j]|=(dl.remainCards[i][j]>>2);
}
#ifdef SIMILARITYTEST
for (j=0; j<=3; j++) {
prevAggrRemain[j]=0;
for (i=0; i<=3; i++)
prevAggrRemain[j]|=localVar[thrId].game.suit[i][j];

if (aggrRemain[j]!=prevAggrRemain[j]) {
playedHistory=FALSE;
break;
}
}
#endif

for (k=0; k<=2; k++) {
if (dl.currentTrickRank[k]!=0) {
noOfCardsPerHand[handId(dl.first, k)]=1;
aggrRemain=0;
for (h=0; h<=3; h++)
aggrRemain|=(dl.remainCards[h][dl.currentTrickSuit[k]]>>2);
if ((aggrRemain & bitMapRank[dl.currentTrickRank[k]])!=0) {
DumpInput(-13, dl, target, solutions, mode);
return -13;
}
}
if (dl.currentTrickRank[k]!=0) {
noOfCardsPerHand[handId(dl.first, k)]=1;
if ((aggrRemain[dl.currentTrickSuit[k]] & bitMapRank[dl.currentTrickRank[k]])!=0) {
DumpInput(-13, dl, target, solutions, mode);
return -13;
}
}
}

if (target==-1)
Expand All @@ -169,28 +191,38 @@ extern "C" BOOL APIENTRY DllMain(HMODULE hModule,
localVar[thrId].tricksTarget=target;

localVar[thrId].newDeal=FALSE; localVar[thrId].newTrump=FALSE;
#ifdef SIMILARITYTEST
localVar[thrId].diffDeal=0; localVar[thrId].aggDeal=0;
#endif
cardCount=0;
for (i=0; i<=3; i++) {
for (j=0; j<=3; j++) {
localVar[thrId].diffDeal+=((dl.remainCards[i][j]>>2)^
cardCount+=counttable[dl.remainCards[i][j]>>2];
#ifdef SIMILARITYTEST
localVar[thrId].diffDeal+=((dl.remainCards[i][j]>>2)^
(localVar[thrId].game.suit[i][j]));
localVar[thrId].aggDeal+=(dl.remainCards[i][j]>>2);
#endif
if (localVar[thrId].game.suit[i][j]!=dl.remainCards[i][j]>>2) {
localVar[thrId].game.suit[i][j]=dl.remainCards[i][j]>>2;
localVar[thrId].newDeal=TRUE;
}
}
}

#ifdef SIMILARITYTEST
if (localVar[thrId].newDeal) {
if (localVar[thrId].diffDeal==0)
localVar[thrId].similarDeal=TRUE;
if (!playedHistory)
localVar[thrId].similarDeal=FALSE;
else if (localVar[thrId].diffDeal==0)
localVar[thrId].similarDeal=TRUE;
else if ((localVar[thrId].aggDeal/localVar[thrId].diffDeal)
>SIMILARDEALLIMIT)
localVar[thrId].similarDeal=TRUE;
else
localVar[thrId].similarDeal=FALSE;
localVar[thrId].similarDeal=TRUE;
else
localVar[thrId].similarDeal=FALSE;
}
#endif

if (dl.trump!=localVar[thrId].trump)
localVar[thrId].newTrump=TRUE;
Expand All @@ -200,17 +232,12 @@ extern "C" BOOL APIENTRY DllMain(HMODULE hModule,
noOfCardsPerHand[i]+=counttable[localVar[thrId].game.suit[i][j]];

for (i=1; i<=3; i++) {
if (noOfCardsPerHand[i]!=noOfCardsPerHand[0]) {
DumpInput(-14, dl, target, solutions, mode);
return -14;
}
if (noOfCardsPerHand[i]!=noOfCardsPerHand[0]) {
DumpInput(-14, dl, target, solutions, mode);
return -14;
}
}

cardCount=0;
for (k=0; k<=3; k++)
for (l=0; l<=3; l++)
cardCount+=counttable[localVar[thrId].game.suit[k][l]];

if (dl.currentTrickRank[2]) {
if ((dl.currentTrickRank[2]<2)||(dl.currentTrickRank[2]>14)
||(dl.currentTrickSuit[2]<0)||(dl.currentTrickSuit[2]>3)) {
Expand Down Expand Up @@ -443,21 +470,27 @@ extern "C" BOOL APIENTRY DllMain(HMODULE hModule,

return 1;
}


#ifdef SIMILARITYTEST
if ((mode!=2)&&
(((localVar[thrId].newDeal)&&(!localVar[thrId].similarDeal))
|| localVar[thrId].newTrump)) {
(((localVar[thrId].newDeal)&&(!localVar[thrId].similarDeal))
|| localVar[thrId].newTrump)) {
#else
if ((mode!=2)&&
((localVar[thrId].newDeal)
|| localVar[thrId].newTrump)) {
#endif
Wipe(thrId);
localVar[thrId].winSetSizeLimit=WINIT;
localVar[thrId].nodeSetSizeLimit=NINIT;
localVar[thrId].lenSetSizeLimit=LINIT;
localVar[thrId].allocmem=(WINIT+1)*sizeof(struct winCardType);
localVar[thrId].allocmem+=(NINIT+1)*sizeof(struct nodeCardsType);
localVar[thrId].allocmem+=(LINIT+1)*sizeof(struct posSearchType);
localVar[thrId].allocmem+=(NINIT+1)*sizeof(struct nodeCardsType);
localVar[thrId].allocmem+=(LINIT+1)*sizeof(struct posSearchType);
localVar[thrId].winCards=localVar[thrId].pw[0];
localVar[thrId].nodeCards=localVar[thrId].pn[0];
localVar[thrId].posSearch=localVar[thrId].pl[0];
localVar[thrId].wcount=0; localVar[thrId].ncount=0; localVar[thrId].lcount=0;
localVar[thrId].nodeCards=localVar[thrId].pn[0];
localVar[thrId].posSearch=localVar[thrId].pl[0];
localVar[thrId].wcount=0; localVar[thrId].ncount=0; localVar[thrId].lcount=0;
InitGame(0, FALSE, first, handRelFirst, thrId);
}
else {
Expand Down
14 changes: 12 additions & 2 deletions dll.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,19 @@

/* end of portability-macros section */

#define DDS_VERSION 20001 /* Version 2.0.1. Allowing for 2 digit
minor versions */
/*#define SIMILARITYTEST*/ /* Uncomment the SIMILARITYTEST definition to
reuse the transposition table contents when the
deal in the preceding SolveBoard call is similar to
the current deal. */
/*#define BENCH*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <cassert>
/*#include <cassert>*/
#include <math.h>

/*#define STAT*/ /* Define STAT to generate a statistics log, stat.txt */
Expand Down Expand Up @@ -75,7 +81,9 @@
#define WINIT 700000/*1000000*/
#define LINIT 50000

#ifdef SIMILARITYTEST
#define SIMILARDEALLIMIT 5
#endif

#define MAXNOOFBOARDS 20

Expand Down Expand Up @@ -283,10 +291,12 @@ struct localVarType {
int tricksTarget;
struct gameInfo game;
int newDeal;
int similarDeal;
int newTrump;
#ifdef SIMILARITYTEST
int similarDeal;
unsigned short int diffDeal;
unsigned short int aggDeal;
#endif
int estTricks[4];
FILE *fp2;
FILE *fp7;
Expand Down
2 changes: 1 addition & 1 deletion readme.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
DDS 2.0.0, Bo Haglund 2010-04-24
DDS 2.0.1, Bo Haglund 2010-05-15

For Win32, DDS compiles with Visual C++ 2005 Express edition
and the Mingw port of gcc.
Expand Down
12 changes: 11 additions & 1 deletion release_notes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,17 @@ A new function, CalcDDtable, has been added.
CalcDDtable calls SolveBoard using parallel threads. The number of
parallel threads is the same as the number of processor cores.
CalcDDtable calculates the double dummy values of the initial 52 cards
for all the 20 trump suit/leading hand combinations.
for all the 20 trump suit/leading hand combinations.


Release Notes DDS 2.0.1
-----------------------
In 2.0.0, the contents of the transposition table could be erronously
be reused when the previous position contained a different number of
cards. This was caused by an erroneous implementation of the
deal similarity test. This bug was fixed by removing the similarity test.

The DDS version number is defined by a #define statement in dll.h.



Expand Down

0 comments on commit 03b485e

Please sign in to comment.