diff -Nru deal-3.0.8/additive.c deal-3.1.4/additive.c --- deal-3.0.8/additive.c 2001-02-19 23:17:23.000000000 +0530 +++ deal-3.1.4/additive.c 2008-05-15 05:49:24.000000000 +0530 @@ -64,7 +64,7 @@ typedef struct additivecounter { int (*func) PROTO((int /* holding */, void * /* data */)); void *data; - int (*freefunc) PROTO((void * /* data */)); + Tcl_CmdDeleteProc *freefunc; } *AdditiveFunction; #define AddFuncCall(addfunc,holding) \ @@ -72,7 +72,7 @@ static AdditiveFunction newAdditiveFunction(func,data,freefunc) int (*func) PROTO((int /* holding */, void * /* data */)); - int (*freefunc) PROTO((void * /* data */)); + Tcl_CmdDeleteProc *freefunc; void *data; { AdditiveFunction result=(AdditiveFunction) diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/CHANGES /tmp/sFHmVEdqkv/deal-3.1.4/CHANGES --- deal-3.0.8/CHANGES 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/CHANGES 2008-06-11 02:20:09.000000000 +0530 @@ -1,3 +1,51 @@ +Changes in Deal 3.1.4 + + * Added -trick flag to dds + + * Allowed for inclusion of Tcl release libraries + + * Moved most of deal.tcl to lib/features.tcl + +Changes in Deal 3.1.3 + + * Fixed performance issue in DDS that I introduced in Deal 3.1.0. + + * Added -x command line flag + +Changes in Deal 3.1.2 + + * Added dds command for more control over the double dummy solver + + * Added 'universal' target to Makefile for building Mac universal binaries + + * Added tests for double-dummy solver, including Great 88 file + + * Performance tweaks to the double-dummy solver + + * Fixed a typo bug in deal.tcl + + * Added full_deal command + + * Added unicode output option for default format (to put out suit symbols) + + * Changed to allow "-" as void in inputs + + * Fixed seeding with seed_deal command + + * Updated documentation and built a documentation-management system + +Changes in Deal 3.1.1 + + * Implemented deal::tricks for caching of double dummy data + and uniform interface to double dummy tricks data + + * Changed call to Haglund's solver to re-use data when processing + contracts in the same denomination and different declarers. + +Changes in Deal 3.1 + + * Added Bo Haglund's Double Dummy Solver + Changes in Deal 3.0.8 [ No binary changes ] diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/counttable.c /tmp/sFHmVEdqkv/deal-3.1.4/counttable.c --- deal-3.0.8/counttable.c 2001-10-09 20:54:52.000000000 +0530 +++ deal-3.1.4/counttable.c 1970-01-01 05:30:00.000000000 +0530 @@ -1,514 +0,0 @@ -int counttable[]={ - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 8, 9, 9, 10, 9, 10, 10, 11, 9, 10, 10, 11, 10, 11, 11, 12, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 8, 9, 9, 10, 9, 10, 10, 11, 9, 10, 10, 11, 10, 11, 11, 12, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 8, 9, 9, 10, 9, 10, 10, 11, 9, 10, 10, 11, 10, 11, 11, 12, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 8, 9, 9, 10, 9, 10, 10, 11, 9, 10, 10, 11, 10, 11, 11, 12, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 8, 9, 9, 10, 9, 10, 10, 11, 9, 10, 10, 11, 10, 11, 11, 12, - 5, 6, 6, 7, 6, 7, 7, 8, 6, 7, 7, 8, 7, 8, 8, 9, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 8, 9, 9, 10, 9, 10, 10, 11, 9, 10, 10, 11, 10, 11, 11, 12, - 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 8, 9, 8, 9, 9, 10, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 8, 9, 9, 10, 9, 10, 10, 11, 9, 10, 10, 11, 10, 11, 11, 12, - 7, 8, 8, 9, 8, 9, 9, 10, 8, 9, 9, 10, 9, 10, 10, 11, - 8, 9, 9, 10, 9, 10, 10, 11, 9, 10, 10, 11, 10, 11, 11, 12, - 8, 9, 9, 10, 9, 10, 10, 11, 9, 10, 10, 11, 10, 11, 11, 12, - 9, 10, 10, 11, 10, 11, 11, 12, 10, 11, 11, 12, 11, 12, 12, 13 -}; diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/dds.cpp /tmp/sFHmVEdqkv/deal-3.1.4/dds.cpp --- deal-3.0.8/dds.cpp 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/dds.cpp 2008-06-09 01:55:38.000000000 +0530 @@ -0,0 +1,4557 @@ + +/* DDS 1.1.8 A bridge double dummy solver. */ +/* Copyright (C) 2006-2008 by Bo Haglund */ +/* Cleanups and porting to Linux and MacOSX (C) 2006 by Alex Martelli */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU General Public License */ +/* as published by the Free software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc, 51 Franklin Street, 5th Floor, Boston MA 02110-1301, USA. */ + +#include "dds.h" + +extern "C" unsigned short int counttable[]; + +const int ContractInfo::nextSuitArray[4][4] = { + { 1, 2, 3, 4}, + { 2, 0, 3, 4}, + { 1, 3, 0, 4}, + { 1, 2, 4, 0} +}; + +inline int HandStore(int hand, int relative) { + return (hand + relative)&3; +} + +GLOBALS Globals; + +int nodeTypeStore[4]; +unsigned short int lowestWin[50][4]; +int nodes; +int trickNodes; +int no[50]; +int iniDepth; +int handToPlay; +int payOff, val; +struct pos iniPosition, position; +struct pos lookAheadPos; /* Is initialized for starting + alpha-beta search */ +struct moveType forbiddenMoves[14]; +struct moveType initialMoves[4]; +struct moveType cd; +struct movePlyType movePly[50]; +int tricksTarget; +struct gameInfo game; +int estTricks[4]; +FILE *fp2, *fp7, *fp11; +struct moveType * bestMove; +struct winCardType * temp_win; +int hiwinSetSize=0, hinodeSetSize=0; +int hilenSetSize=0; +int MaxnodeSetSize=0; +int MaxwinSetSize=0; +int MaxlenSetSize=0; +int nodeSetSizeLimit=0; +int winSetSizeLimit=0; +int lenSetSizeLimit=0; +LONGLONG maxmem, allocmem, summem; +int wmem, nmem, lmem; +int maxIndex; +int wcount, ncount, lcount; +int clearTTflag=FALSE, windex=-1; +int ttCollect=FALSE; +int suppressTTlog=FALSE; +unsigned char cardRank[15], cardSuit[5], cardHand[4]; +LONGLONG suitLengths=0; +struct posSearchType *rootnp[14][4]; +struct winCardType **pw; +struct nodeCardsType **pn; +struct posSearchType **pl; + +#ifdef CANCEL +int cancelOrdered=FALSE; +int cancelStarted=FALSE; +int threshold=CANCELCHECK; +#endif + + +#ifdef _MANAGED +#pragma managed(push, off) +#endif + +inline holding_t smallestRankInSuit(holding_t h) { + return (h & -h); +} + +extern "C" inline holding_t distinctUnplayedCards(holding_t origHolding, holding_t played,holding_t *sequence) { + holding_t bitRank; + holding_t unplayed = origHolding & (~played); + holding_t result = 0; + int inSequence=0; + *sequence = 0; + + if (unplayed) { + for (bitRank = (1<<12); bitRank; bitRank >>= 1) { + if (unplayed & bitRank) { + if (inSequence) { + *sequence |= bitRank; + } else { + result |= bitRank; + inSequence = 1; + } + } else { + if (!(played & bitRank)) { + inSequence = 0; + } + } + } + //cout << "Got result " << result << " for holding " << origHolding << " and played cards " << played << endl; + } + return result; +} + +struct UnplayedCardsFinder { +protected: + holding_t starting[4][4]; + +public: + + UnplayedCardsFinder() {} + + void initialize(const holding_t init[4][4]) { + for (int hand=0; hand<4; hand++) { + for (int suit=0; suit<4; suit++) { + starting[hand][suit] = init[hand][suit]; + } + } + } + + + inline holding_t getUnplayed(int hand, int suit, holding_t played,holding_t &sequence) { + holding_t holding = starting[hand][suit]; + return distinctUnplayedCards(holding,played,&sequence); + } + +} unplayedFinder; + + +#ifdef _MANAGED +#pragma managed(pop) +#endif + + int SolveBoard(struct deal dl, int target, + int solutions, int mode, struct futureTricks *futp) { + + 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 latestTrickSuit[4]; + int latestTrickRank[4]; + int maxHand=0, maxSuit=0, maxRank; + struct movePlyType temp; + struct moveType mv; + /*FILE *fp;*/ + + /*InitStart();*/ /* Include InitStart() if inside SolveBoard, + but preferable InitStart should be called outside + SolveBoard like in DllMain for Windows. */ + + for (k=0; k<=13; k++) { + forbiddenMoves[k].rank=0; + forbiddenMoves[k].suit=0; + } + + if (target<-1) { + DumpInput(-5, dl, target, solutions, mode); + return -5; + } + if (target>13) { + DumpInput(-7, dl, target, solutions, mode); + return -7; + } + if (solutions<1) { + DumpInput(-8, dl, target, solutions, mode); + return -8; + } + if (solutions>3) { + DumpInput(-9, dl, target, solutions, mode); + return -9; + } + + if (target==-1) + tricksTarget=99; + else + tricksTarget=target; + + cardCount=0; + for (i=0; i<=3; i++) { + for (j=0; j<=3; j++) { + game.suit[i][j]=dl.remainCards[i][j]>>2; + cardCount+=CountOnes(game.suit[i][j]); + } + } + + if (dl.currentTrickRank[2]) { + if ((dl.currentTrickRank[2]<2)||(dl.currentTrickRank[2]>14) + ||(dl.currentTrickSuit[2]<0)||(dl.currentTrickSuit[2]>3)) { + DumpInput(-12, dl, target, solutions, mode); + return -12; + } + handToPlay=HandStore(dl.first,3); + handRelFirst=3; + noStartMoves=3; + if (cardCount<=4) { + for (k=0; k<=3; k++) { + if (game.suit[handToPlay][k]!=0) { + latestTrickSuit[handToPlay]=k; + latestTrickRank[handToPlay]= + InvBitMapRank(game.suit[handToPlay][k]); + break; + } + } + latestTrickSuit[HandStore(dl.first,2)]=dl.currentTrickSuit[2]; + latestTrickRank[HandStore(dl.first,2)]=dl.currentTrickRank[2]; + latestTrickSuit[HandStore(dl.first,1)]=dl.currentTrickSuit[1]; + latestTrickRank[HandStore(dl.first,1)]=dl.currentTrickRank[1]; + latestTrickSuit[HandStore(dl.first,0)]=dl.currentTrickSuit[0]; + latestTrickRank[HandStore(dl.first,0)]=dl.currentTrickRank[0]; + } + } else if (dl.currentTrickRank[1]) { + if ((dl.currentTrickRank[1]<2)||(dl.currentTrickRank[1]>14) + ||(dl.currentTrickSuit[1]<0)||(dl.currentTrickSuit[1]>3)) { + DumpInput(-12, dl, target, solutions, mode); + return -12; + } + handToPlay=HandStore(dl.first,2); + handRelFirst=2; + noStartMoves=2; + if (cardCount<=4) { + for (k=0; k<=3; k++) { + if (game.suit[handToPlay][k]!=0) { + latestTrickSuit[handToPlay]=k; + latestTrickRank[handToPlay]= + InvBitMapRank(game.suit[handToPlay][k]); + break; + } + } + for (k=0; k<=3; k++) { + if (game.suit[HandStore(dl.first,3)][k]!=0) { + latestTrickSuit[HandStore(dl.first,3)]=k; + latestTrickRank[HandStore(dl.first,3)]= + InvBitMapRank(game.suit[HandStore(dl.first,3)][k]); + break; + } + } + latestTrickSuit[HandStore(dl.first,1)]=dl.currentTrickSuit[1]; + latestTrickRank[HandStore(dl.first,1)]=dl.currentTrickRank[1]; + latestTrickSuit[HandStore(dl.first,0)]=dl.currentTrickSuit[0]; + latestTrickRank[HandStore(dl.first,0)]=dl.currentTrickRank[0]; + } + } else if (dl.currentTrickRank[0]) { + if ((dl.currentTrickRank[0]<2)||(dl.currentTrickRank[0]>14) + ||(dl.currentTrickSuit[0]<0)||(dl.currentTrickSuit[0]>3)) { + DumpInput(-12, dl, target, solutions, mode); + return -12; + } + handToPlay=HandStore(dl.first,1); + handRelFirst=1; + noStartMoves=1; + if (cardCount<=4) { + for (k=0; k<=3; k++) { + if (game.suit[handToPlay][k]!=0) { + latestTrickSuit[handToPlay]=k; + latestTrickRank[handToPlay]= + InvBitMapRank(game.suit[handToPlay][k]); + break; + } + } + for (k=0; k<=3; k++) { + if (game.suit[HandStore(dl.first,3)][k]!=0) { + latestTrickSuit[HandStore(dl.first,3)]=k; + latestTrickRank[HandStore(dl.first,3)]= + InvBitMapRank(game.suit[HandStore(dl.first,3)][k]); + break; + } + } + for (k=0; k<=3; k++) { + if (game.suit[HandStore(dl.first,2)][k]!=0) { + latestTrickSuit[HandStore(dl.first,2)]=k; + latestTrickRank[HandStore(dl.first,2)]= + InvBitMapRank(game.suit[HandStore(dl.first,2)][k]); + break; + } + } + latestTrickSuit[dl.first]=dl.currentTrickSuit[0]; + latestTrickRank[dl.first]=dl.currentTrickRank[0]; + } + } else { + handToPlay=dl.first; + handRelFirst=0; + noStartMoves=0; + if (cardCount<=4) { + for (k=0; k<=3; k++) { + if (game.suit[handToPlay][k]!=0) { + latestTrickSuit[handToPlay]=k; + latestTrickRank[handToPlay]= + InvBitMapRank(game.suit[handToPlay][k]); + break; + } + } + for (k=0; k<=3; k++) { + if (game.suit[HandStore(dl.first,3)][k]!=0) { + latestTrickSuit[HandStore(dl.first,3)]=k; + latestTrickRank[HandStore(dl.first,3)]= + InvBitMapRank(game.suit[HandStore(dl.first,3)][k]); + break; + } + } + for (k=0; k<=3; k++) { + if (game.suit[HandStore(dl.first,2)][k]!=0) { + latestTrickSuit[HandStore(dl.first,2)]=k; + latestTrickRank[HandStore(dl.first,2)]= + InvBitMapRank(game.suit[HandStore(dl.first,2)][k]); + break; + } + } + for (k=0; k<=3; k++) { + if (game.suit[HandStore(dl.first,1)][k]!=0) { + latestTrickSuit[HandStore(dl.first,1)]=k; + latestTrickRank[HandStore(dl.first,1)]= + InvBitMapRank(game.suit[HandStore(dl.first,1)][k]); + break; + } + } + } + } + + game.contract=100+10*(dl.trump+1); + game.first=dl.first; + first=dl.first; + game.noOfCards=cardCount; + if (dl.currentTrickRank[0]!=0) { + game.leadHand=dl.first; + game.leadSuit=dl.currentTrickSuit[0]; + game.leadRank=dl.currentTrickRank[0]; + } else { + game.leadHand=0; + game.leadSuit=0; + game.leadRank=0; + } + + for (k=0; k<=2; k++) { + initialMoves[k].suit=255; + initialMoves[k].rank=255; + } + + for (k=0; k52) { + DumpInput(-10, dl, target, solutions, mode); + return -10; + } + if (totalTricksnodes=0; + #ifdef BENCH + futp->totalNodes=0; + #endif + futp->cards=1; + futp->suit[0]=latestTrickSuit[handToPlay]; + futp->rank[0]=latestTrickRank[handToPlay]; + futp->equals[0]=0; + if ((target==0)&&(solutions<3)) { + futp->score[0]=0; + } else if ((handToPlay==maxHand)|| + (partner(handToPlay)==maxHand)) { + futp->score[0]=1; + } else { + futp->score[0]=0; + } + return 1; + } + + if (mode!=2) { + Wipe(); + winSetSizeLimit=WINIT; + nodeSetSizeLimit=NINIT; + lenSetSizeLimit=LINIT; + allocmem=(WINIT+1)*sizeof(struct winCardType); + allocmem+=(NINIT+1)*sizeof(struct nodeCardsType); + allocmem+=(LINIT+1)*sizeof(struct posSearchType); + winCards=pw[0]; + nodeCards=pn[0]; + posSearch=pl[0]; + wcount=0; ncount=0; lcount=0; + InitGame(0, FALSE, first, handRelFirst); + } else { + InitGame(0, TRUE, first, handRelFirst); + /*fp2=fopen("dyn.txt", "a"); + fprintf(fp2, "wcount=%d, ncount=%d, lcount=%d\n", + wcount, ncount, lcount); + fprintf(fp2, "winSetSize=%d, nodeSetSize=%d, lenSetSize=%d\n", + winSetSize, nodeSetSize, lenSetSize); + fclose(fp2);*/ + } + + unplayedFinder.initialize(game.suit); + + nodes=0; trickNodes=0; + iniDepth=cardCount-4; + hiwinSetSize=0; + hinodeSetSize=0; + + if (mode==0) { + MoveGen(&lookAheadPos, iniDepth); + if (movePly[iniDepth].last==0) { + futp->nodes=0; + #ifdef BENCH + futp->totalNodes=0; + #endif + futp->cards=1; + futp->suit[0]=movePly[iniDepth].move[0].suit; + futp->rank[0]=movePly[iniDepth].move[0].rank; + futp->equals[0]= + movePly[iniDepth].move[0].sequence<<2; + futp->score[0]=-2; + return 1; + } + } + + if ((target==0)&&(solutions<3)) { + MoveGen(&lookAheadPos, iniDepth); + futp->nodes=0; + #ifdef BENCH + futp->totalNodes=0; + #endif + for (k=0; k<=movePly[iniDepth].last; k++) { + futp->suit[k]=movePly[iniDepth].move[k].suit; + futp->rank[k]=movePly[iniDepth].move[k].rank; + futp->equals[k]= + movePly[iniDepth].move[k].sequence<<2; + futp->score[k]=0; + } + if (solutions==1) + futp->cards=1; + else + futp->cards=movePly[iniDepth].last+1; + return 1; + } + + if ((target!=-1)&&(solutions!=3)) { + val=ABsearch(&lookAheadPos, tricksTarget, iniDepth); + #ifdef CANCEL + if (cancelStarted) { + cancelOrdered=FALSE; + cancelStarted=FALSE; + return 2; + } + #endif + temp=movePly[iniDepth]; + last=movePly[iniDepth].last; + noMoves=last+1; + hiwinSetSize=winSetSize; + hinodeSetSize=nodeSetSize; + hilenSetSize=lenSetSize; + if (nodeSetSize>MaxnodeSetSize) + MaxnodeSetSize=nodeSetSize; + if (winSetSize>MaxwinSetSize) + MaxwinSetSize=winSetSize; + if (lenSetSize>MaxlenSetSize) + MaxlenSetSize=lenSetSize; + if (val==1) + payOff=tricksTarget; + else + payOff=0; + futp->cards=1; + ind=2; + + if (payOff<=0) { + futp->suit[0]=movePly[game.noOfCards-4].move[0].suit; + futp->rank[0]=movePly[game.noOfCards-4].move[0].rank; + futp->equals[0]=(movePly[game.noOfCards-4].move[0].sequence)<<2; + if (tricksTarget>1) + futp->score[0]=-1; + else + futp->score[0]=0; + } else { + futp->suit[0]=bestMove[game.noOfCards-4].suit; + futp->rank[0]=bestMove[game.noOfCards-4].rank; + futp->equals[0]=(bestMove[game.noOfCards-4].sequence)<<2; + futp->score[0]=payOff; + } + } else { + g=estTricks[handToPlay]; + upperbound=(game.noOfCards+3)/4; + lowerbound=0; + do { + if (g==lowerbound) { + tricks=g+1; + } else { + tricks=g; + } + val=ABsearch(&lookAheadPos, tricks, iniDepth); +#ifdef CANCEL + if (cancelStarted) { + cancelOrdered=FALSE; + cancelStarted=FALSE; + return 2; + } +#endif + if (val==TRUE) { + mv=bestMove[game.noOfCards-4]; + } + hiwinSetSize=Max(hiwinSetSize, winSetSize); + hinodeSetSize=Max(hinodeSetSize, nodeSetSize); + hilenSetSize=Max(hilenSetSize, lenSetSize); + if (nodeSetSize>MaxnodeSetSize) + MaxnodeSetSize=nodeSetSize; + if (winSetSize>MaxwinSetSize) + MaxwinSetSize=winSetSize; + if (lenSetSize>MaxlenSetSize) + MaxlenSetSize=lenSetSize; + if (val==FALSE) { + upperbound=tricks-1; + g=upperbound; + } else { + lowerbound=tricks; + g=lowerbound; + } + InitSearch(&iniPosition, game.noOfCards-4, + initialMoves, first, TRUE); + } while (lowerboundcards=1; + if (payOff<=0) { + futp->score[0]=0; + futp->suit[0]=movePly[game.noOfCards-4].move[0].suit; + futp->rank[0]=movePly[game.noOfCards-4].move[0].rank; + futp->equals[0]=(movePly[game.noOfCards-4].move[0].sequence)<<2; + } else { + futp->score[0]=payOff; + futp->suit[0]=bestMove[game.noOfCards-4].suit; + futp->rank[0]=bestMove[game.noOfCards-4].rank; + futp->equals[0]=(bestMove[game.noOfCards-4].sequence)<<2; + } + tricksTarget=payOff; + } + + if ((solutions==2)&&(payOff>0)) { + forb=1; + ind=forb; + while ((payOff==tricksTarget)&&(ind<(temp.last+1))) { + forbiddenMoves[forb].suit=bestMove[game.noOfCards-4].suit; + forbiddenMoves[forb].rank=bestMove[game.noOfCards-4].rank; + forb++; ind++; + /* All moves before bestMove in the move list shall be + moved to the forbidden moves list, since none of them reached + the target */ + mcurr=movePly[iniDepth].current; + for (k=0; k<=movePly[iniDepth].last; k++) + if ((bestMove[iniDepth].suit==movePly[iniDepth].move[k].suit) + &&(bestMove[iniDepth].rank==movePly[iniDepth].move[k].rank)) + break; + for (i=0; iMaxnodeSetSize) + MaxnodeSetSize=nodeSetSize; + if (winSetSize>MaxwinSetSize) + MaxwinSetSize=winSetSize; + if (lenSetSize>MaxlenSetSize) + MaxlenSetSize=lenSetSize; + if (val==TRUE) { + payOff=tricksTarget; + futp->cards=ind; + futp->suit[ind-1]=bestMove[game.noOfCards-4].suit; + futp->rank[ind-1]=bestMove[game.noOfCards-4].rank; + futp->equals[ind-1]=(bestMove[game.noOfCards-4].sequence)<<2; + futp->score[ind-1]=payOff; + } + else + payOff=0; + } + } else if ((solutions==2)&&(payOff==0)&&((target==-1)||(tricksTarget==1))) { + futp->cards=noMoves; + /* Find the cards that were in the initial move list + but have not been listed in the current result */ + n=0; + for (i=0; isuit[0])&& + (temp.move[i].rank==futp->rank[0])) { + found=TRUE; + } + if (!found) { + futp->suit[1+n]=temp.move[i].suit; + futp->rank[1+n]=temp.move[i].rank; + futp->equals[1+n]=(temp.move[i].sequence)<<2; + futp->score[1+n]=0; + n++; + } + } + } + + if ((solutions==3)&&(payOff>0)) { + forb=1; + ind=forb; + for (i=0; iMaxnodeSetSize) + MaxnodeSetSize=nodeSetSize; + if (winSetSize>MaxwinSetSize) + MaxwinSetSize=winSetSize; + if (lenSetSize>MaxlenSetSize) + MaxlenSetSize=lenSetSize; + if (val==FALSE) { + upperbound=tricks-1; + g=upperbound; + } else { + lowerbound=tricks; + g=lowerbound; + } + if (0) { + InitSearch(&iniPosition, game.noOfCards-4, + initialMoves, first, FALSE); + } else { + InitSearch(&iniPosition, game.noOfCards-4, + initialMoves, first, TRUE); + } + } while (lowerboundcards=temp.last+1; + for (j=0; j<=last; j++) { + futp->suit[ind-1+j]=movePly[game.noOfCards-4].move[j].suit; + futp->rank[ind-1+j]=movePly[game.noOfCards-4].move[j].rank; + futp->equals[ind-1+j]=(movePly[game.noOfCards-4].move[j].sequence)<<2; + futp->score[ind-1+j]=payOff; + } + break; + } else { + bestMove[game.noOfCards-4]=mv; + + futp->cards=ind; + futp->suit[ind-1]=bestMove[game.noOfCards-4].suit; + futp->rank[ind-1]=bestMove[game.noOfCards-4].rank; + futp->equals[ind-1]=(bestMove[game.noOfCards-4].sequence)<<2; + futp->score[ind-1]=payOff; + } + } + } else if ((solutions==3)&&(payOff==0)) { + futp->cards=noMoves; + /* Find the cards that were in the initial move list + but have not been listed in the current result */ + n=0; + for (i=0; isuit[0])&& + (temp.move[i].rank==futp->rank[0])) { + found=TRUE; + } + + if (!found) { + futp->suit[1+n]=temp.move[i].suit; + futp->rank[1+n]=temp.move[i].rank; + futp->equals[1+n]=(temp.move[i].sequence)<<2; + futp->score[1+n]=0; + n++; + } + } + } + + for (k=0; k<=13; k++) { + forbiddenMoves[k].suit=0; + forbiddenMoves[k].rank=0; + } + + futp->nodes=trickNodes; + #ifdef BENCH + futp->totalNodes=nodes; + #endif + /*if ((wcount>0)||(ncount>0)||(lcount>0)) { + fp2=fopen("dyn.txt", "a"); + fprintf(fp2, "wcount=%d, ncount=%d, lcount=%d\n", + wcount, ncount, lcount); + fprintf(fp2, "winSetSize=%d, nodeSetSize=%d, lenSetSize=%d\n", + winSetSize, nodeSetSize, lenSetSize); + fprintf(fp2, "\n"); + fclose(fp2); + }*/ + return 1; +} + +const RelativeRanksFinder &rel=Globals.rel; +struct ttStoreType * ttStore; +struct nodeCardsType * nodeCards; +struct winCardType * winCards; +struct posSearchType * posSearch; +holding_t iniRemovedRanks[4]; +int nodeSetSize=0; /* Index with range 0 to nodeSetSizeLimit */ +int winSetSize=0; /* Index with range 0 to winSetSizeLimit */ +int lenSetSize=0; /* Index with range 0 to lenSetSizeLimit */ +int lastTTstore=0; + +int _initialized=0; + +extern "C" void DDSInitStart(void) { + InitStart(); +} + +void InitStart(void) { + int k; + + if (_initialized) + return; + _initialized = 1; + + nodeSetSizeLimit=NINIT; + winSetSizeLimit=WINIT; + lenSetSizeLimit=LINIT; + + maxmem=2*(5000001*sizeof(struct nodeCardsType)+ + 15000001*sizeof(struct winCardType)+ + 200001*sizeof(struct posSearchType)); + + bestMove = (struct moveType *)calloc(50, sizeof(struct moveType)); + /*bestMove = new moveType [50];*/ + if (bestMove==NULL) + exit(1); + + cardRank[2]='2'; cardRank[3]='3'; cardRank[4]='4'; cardRank[5]='5'; + cardRank[6]='6'; cardRank[7]='7'; cardRank[8]='8'; cardRank[9]='9'; + cardRank[10]='T'; cardRank[11]='J'; cardRank[12]='Q'; cardRank[13]='K'; + cardRank[14]='A'; + + cardSuit[0]='S'; cardSuit[1]='H'; cardSuit[2]='D'; cardSuit[3]='C'; + cardSuit[4]='N'; + + cardHand[0]='N'; cardHand[1]='E'; cardHand[2]='S'; cardHand[3]='W'; + + temp_win = (struct winCardType *)calloc(5, sizeof(struct winCardType)); + if (temp_win==NULL) + exit(1); + + summem=(WINIT+1)*sizeof(struct winCardType)+ + (NINIT+1)*sizeof(struct nodeCardsType)+ + (LINIT+1)*sizeof(struct posSearchType); + wmem=(WSIZE+1)*sizeof(struct winCardType); + nmem=(NSIZE+1)*sizeof(struct nodeCardsType); + lmem=(LSIZE+1)*sizeof(struct posSearchType); + maxIndex=(int)(maxmem-summem)/((WSIZE+1) * sizeof(struct winCardType)); + + pw = (struct winCardType **)calloc(maxIndex+1, sizeof(struct winCardType *)); + if (pw==NULL) + exit(1); + pn = (struct nodeCardsType **)calloc(maxIndex+1, sizeof(struct nodeCardsType *)); + if (pn==NULL) + exit(1); + pl = (struct posSearchType **)calloc(maxIndex+1, sizeof(struct posSearchType *)); + if (pl==NULL) + exit(1); + for (k=0; k<=maxIndex; k++) { + if (pw[k]) + free(pw[k]); + pw[k]=NULL; + } + for (k=0; k<=maxIndex; k++) { + if (pn[k]) + free(pn[k]); + pn[k]=NULL; + } + for (k=0; k<=maxIndex; k++) { + if (pl[k]) + free(pl[k]); + pl[k]=NULL; + } + + pw[0] = (struct winCardType *)calloc(winSetSizeLimit+1, sizeof(struct winCardType)); + if (pw[0]==NULL) + exit(1); + allocmem=(winSetSizeLimit+1)*sizeof(struct winCardType); + winCards=pw[0]; + pn[0] = (struct nodeCardsType *)calloc(nodeSetSizeLimit+1, sizeof(struct nodeCardsType)); + if (pn[0]==NULL) + exit(1); + allocmem+=(nodeSetSizeLimit+1)*sizeof(struct nodeCardsType); + nodeCards=pn[0]; + pl[0] = (struct posSearchType *)calloc(lenSetSizeLimit+1, sizeof(struct posSearchType)); + if (pl[0]==NULL) + exit(1); + allocmem+=(lenSetSizeLimit+1)*sizeof(struct posSearchType); + posSearch=pl[0]; + wcount=0; ncount=0; lcount=0; + + ttStore = (struct ttStoreType *)calloc(SEARCHSIZE, sizeof(struct ttStoreType)); + /*ttStore = new ttStoreType[SEARCHSIZE];*/ + if (ttStore==NULL) + exit(1); + + /* rel = (struct relRanksType *)calloc(16384, sizeof(struct relRanksType)); */ + /*rel = new relRanksType[16384];*/ + + /*fp2=fopen("dyn.txt", "w"); + fclose(fp2);*/ + /*fp2=fopen("dyn.txt", "a"); + fprintf(fp2, "maxIndex=%ld\n", maxIndex); + fclose(fp2);*/ + + return; +} + + +void InitGame(int gameNo, int moveTreeFlag, int first, int handRelFirst) { + + int k, temp1, temp2,m; + /*int points[4], tricks; + int addNS, addEW, addMAX, trumpNS, trumpEW; + struct gameInfo gm;*/ + + #ifdef STAT + fp2=fopen("stat.txt","w"); + #endif + + #ifdef TTDEBUG + if (!suppressTTlog) { + fp7=fopen("storett.txt","w"); + fp11=fopen("rectt.txt", "w"); + fclose(fp11); + ttCollect=TRUE; + } + #endif + + for (k=0; k<=3; k++) { + for (m=0; m<=3; m++) { + iniPosition.rankInSuit[k][m]=game.suit[k][m]; + } + } + + iniPosition.stack[game.noOfCards-4].first=first; + iniPosition.handRelFirst=handRelFirst; + lookAheadPos=iniPosition; + + + Globals.rel.initialize(game); + + temp1=game.contract/100; + temp2=game.contract-100*temp1; + int trump=temp2/10-1; + Globals.setContract(trump); + + estTricks[1]=6; + estTricks[3]=6; + estTricks[0]=7; + estTricks[2]=7; + /*end: tricksest */ + + #ifdef STAT + fprintf(fp2, "Estimated tricks for hand to play:\n"); + fprintf(fp2, "hand=%d est tricks=%d\n", + handToPlay, estTricks[handToPlay]); + #endif + + InitSearch(&lookAheadPos, game.noOfCards-4, initialMoves, first, + moveTreeFlag); + return; +} + + +void InitSearch(struct pos * posPoint, int depth, struct moveType startMoves[], int first, int mtd) { + + int s, d, h, max, hmax=0, handRelFirst; + int k, noOfStartMoves; /* Number of start moves in the 1st trick */ + int hand[3], suit[3], rank[3]; + struct moveType move; + unsigned short int startMovesBitMap[4][4]; /* Indices are hand and suit */ + const ContractInfo contract = Globals.getContract(); + + for (h=0; h<=3; h++) + for (s=0; s<=3; s++) + startMovesBitMap[h][s]=0; + + handRelFirst=posPoint->handRelFirst; + noOfStartMoves=handRelFirst; + + for (k=0; k<=2; k++) { + hand[k]=HandStore(first,k); + suit[k]=startMoves[k].suit; + rank[k]=startMoves[k].rank; + if (kstack[depth].first=first; + posPoint->handRelFirst=k; + posPoint->tricksMAX=0; + + if (k>0) { + posPoint->stack[depth+k].move=startMoves[k-1]; + move=startMoves[k-1]; + } + + posPoint->stack[depth+k].high=first; + + while (k>0) { + movePly[depth+k].current=0; + movePly[depth+k].last=0; + movePly[depth+k].move[0].suit=startMoves[k-1].suit; + movePly[depth+k].move[0].rank=startMoves[k-1].rank; + if (kstack[depth+k].move.suit=startMoves[k-1].suit; + posPoint->stack[depth+k].move.rank=startMoves[k-1].rank; + posPoint->stack[depth+k].high=HandStore(first,noOfStartMoves-k); + move=posPoint->stack[depth+k].move; + } else { + posPoint->stack[depth+k].move=posPoint->stack[depth+k+1].move; + posPoint->stack[depth+k].high=posPoint->stack[depth+k+1].high; + } + } + k--; + } + + for (s=0; s<=3; s++) + posPoint->removedRanks[s]=0; + + for (s=0; s<=3; s++) /* Suit */ + for (h=0; h<=3; h++) /* Hand */ + posPoint->removedRanks[s] |= posPoint->rankInSuit[h][s]; + + for (s=0; s<=3; s++) + posPoint->removedRanks[s] = 8191 & ~(posPoint->removedRanks[s]); + + for (s=0; s<=3; s++) /* Suit */ + for (h=0; h<=3; h++) /* Hand */ + posPoint->removedRanks[s] &= (~startMovesBitMap[h][s]); + + for (s=0; s<=3; s++) + iniRemovedRanks[s]=posPoint->removedRanks[s]; + + /* Initialize winning rank */ + for (s=0; s<=3; s++) { + posPoint->winner[s].rank=0; + posPoint->winner[s].hand=0; + } + + if (noOfStartMoves>=1) { + for (k=noOfStartMoves; k>=0; k--) { + s=movePly[depth+k].move[0].suit; + if (movePly[depth+k].move[0].rank>posPoint->winner[s].rank) + posPoint->winner[s].rank=movePly[depth+k].move[0].rank; + } + } + + for (s=0; s<=3; s++) { + k=posPoint->winner[s].rank; + max=k; + while (k<=14) { + for (h=0; h<=3; h++) { + if ((posPoint->rankInSuit[h][s] & BitRank(k)) != 0) { + max=k; + hmax=h; + break; + } + } + k++; + } + posPoint->winner[s].rank=max; + posPoint->winner[s].hand=hmax; + } + + /* Initialize second best rank */ + for (s=0; s<=3; s++) { + posPoint->secondBest[s].rank=0; + posPoint->secondBest[s].hand=0; + } + + if (noOfStartMoves>=1) { + for (k=noOfStartMoves; k>=0; k--) { + s=movePly[depth+k].move[0].suit; + if ((movePly[depth+k].move[0].rank>posPoint->secondBest[s].rank)&& + (movePly[depth+k].move[0].rankwinner[s].rank)) + posPoint->secondBest[s].rank=movePly[depth+k].move[0].rank; + } + } + + for (s=0; s<=3; s++) { + k=posPoint->secondBest[s].rank; + max=k; + while (k<=14) { + for (h=0; h<=3; h++) { + if (((posPoint->rankInSuit[h][s] & BitRank(k)) != 0)&& + (kwinner[s].rank)) { + max=k; + hmax=h; + break; + } + } + k++; + } + posPoint->secondBest[s].rank=max; + posPoint->secondBest[s].hand=hmax; + } + + for (s=0; s<=3; s++) { + for (h=0; h<=3; h++) { + posPoint->length[h][s]= + (unsigned char)CountOnes(posPoint->rankInSuit[h][s]); + } + } + + #ifdef STAT + for (d=0; d<=49; d++) { + score1Counts[d]=0; + score0Counts[d]=0; + c1[d]=0; c2[d]=0; c3[d]=0; c4[d]=0; c5[d]=0; c6[d]=0; c7[d]=0; + c8[d]=0; + no[d]=0; + } + #endif + + if (!mtd) { + lenSetSize=0; + for (k=0; k<=13; k++) { + for (h=0; h<=3; h++) { + rootnp[k][h]=&posSearch[lenSetSize]; + posSearch[lenSetSize].suitLengths=0; + posSearch[lenSetSize].posSearchPoint=NULL; + posSearch[lenSetSize].left=NULL; + posSearch[lenSetSize].right=NULL; + lenSetSize++; + } + } + nodeSetSize=0; + winSetSize=0; + } + + #ifdef TTDEBUG + if (!suppressTTlog) + lastTTstore=0; + #endif + + recInd=0; + + return; +} + +inline unsigned short int CountOnes(unsigned short int b) { + return counttable[b]; + /* + unsigned short int numb; + + for (numb=0; b!=0; numb++, b&=(b-1)); + return numb; + */ +} + +int mexists, ready, hfirst; +int mcurrent, qtricks, out, sout, hout; +int res; +unsigned char cind; +int minimum, sopFound, nodeFound; +int score1Counts[50], score0Counts[50]; +int sumScore1Counts, sumScore0Counts; +int c1[50], c2[50], c3[50], c4[50], c5[50], c6[50], c7[50], c8[50], c9[50]; +int sumc1, sumc2, sumc3, sumc4, sumc5, sumc6, sumc7, sumc8, sumc9; +int scoreFlag; +int tricks, n; +int hh, ss, rr, mm, dd, fh; +int mcount, /*hand, */suit, rank, order; +int k, cardFound, currHand, a, found; +struct evalType evalData; +struct winCardType * np; +struct posSearchType * pp; +struct nodeCardsType * sopP; +struct nodeCardsType * tempP; +holding_t aggr[4]; +holding_t tricksLeft; +holding_t ranks; + +int ABsearch(struct pos * posPoint, int target, int depth) { + /* posPoint points to the current look-ahead position, + target is number of tricks to take for the player, + depth is the remaining search length, must be positive, + the value of the subtree is returned. */ + + int moveExists, value; + struct makeType makeData; + struct nodeCardsType * cardsP; + const ContractInfo contract = Globals.getContract(); + + struct evalType Evaluate(const struct pos * posPoint); + struct makeType Make(struct pos * posPoint, int depth); + void Undo(struct pos * posPoint, int depth); + + #ifdef CANCEL + if (nodes > threshold) { + if (cancelOrdered) { + cancelStarted=TRUE; + return FALSE; + } else { + threshold+=CANCELCHECK; + } + } + #endif + + /*cardsP=NULL;*/ + const int hand=HandStore(posPoint->stack[depth].first,posPoint->handRelFirst); + + nodes++; + if (posPoint->handRelFirst==0) { + trickNodes++; + if (posPoint->tricksMAX>=target) { + for (ss=0; ss<=3; ss++) + posPoint->stack[depth].winRanks[ss]=0; + + #ifdef STAT + c1[depth]++; + + score1Counts[depth]++; + if (depth==iniDepth) { + fprintf(fp2, "score statistics:\n"); + for (dd=iniDepth; dd>=0; dd--) { + fprintf(fp2, "d=%d s1=%d s0=%d c1=%d c2=%d c3=%d c4=%d", dd, + score1Counts[dd], score0Counts[dd], c1[dd], c2[dd], + c3[dd], c4[dd]); + fprintf(fp2, " c5=%d c6=%d c7=%d c8=%d\n", c5[dd], + c6[dd], c7[dd], c8[dd]); + } + } + #endif + + return TRUE; + } + if (((posPoint->tricksMAX+(depth>>2)+1)0)) { + for (ss=0; ss<=3; ss++) + posPoint->stack[depth].winRanks[ss]=0; + + #ifdef STAT + c2[depth]++; + score0Counts[depth]++; + if (depth==iniDepth) { + fprintf(fp2, "score statistics:\n"); + for (dd=iniDepth; dd>=0; dd--) { + fprintf(fp2, "d=%d s1=%d s0=%d c1=%d c2=%d c3=%d c4=%d", dd, + score1Counts[dd], score0Counts[dd], c1[dd], c2[dd], + c3[dd], c4[dd]); + fprintf(fp2, " c5=%d c6=%d c7=%d c8=%d\n", c5[dd], + c6[dd], c7[dd], c8[dd]); + } + } + #endif + + return FALSE; + } + + if (nodeTypeStore[hand]==MAXNODE) { + qtricks=QuickTricks(posPoint, hand, depth, target, &res); + if (res) { + if (qtricks==0) { /* Tricks for MIN side gave cutoff */ + return FALSE; + } else { + return TRUE; + } +#ifdef STAT + c3[depth]++; + score1Counts[depth]++; + if (depth==iniDepth) { + fprintf(fp2, "score statistics:\n"); + for (dd=iniDepth; dd>=0; dd--) { + fprintf(fp2, "d=%d s1=%d s0=%d c1=%d c2=%d c3=%d c4=%d", dd, + score1Counts[dd], score0Counts[dd], c1[dd], c2[dd], + c3[dd], c4[dd]); + fprintf(fp2, " c5=%d c6=%d c7=%d c8=%d\n", c5[dd], + c6[dd], c7[dd], c8[dd]); + } + } +#endif + } + if (!LaterTricksMIN(posPoint,hand,depth,target)) { + return FALSE; + } + } else { + qtricks=QuickTricks(posPoint, hand, depth, target, &res); + if (res) { + if (qtricks==0) { /* Tricks for MAX side gave cutoff */ + return TRUE; + } else { + return FALSE; + } +#ifdef STAT + c4[depth]++; + score0Counts[depth]++; + if (depth==iniDepth) { + fprintf(fp2, "score statistics:\n"); + for (dd=iniDepth; dd>=0; dd--) { + fprintf(fp2, "d=%d s1=%d s0=%d c1=%d c2=%d c3=%d c4=%d", dd, + score1Counts[dd], score0Counts[dd], c1[dd], c2[dd], + c3[dd], c4[dd]); + fprintf(fp2, " c5=%d c6=%d c7=%d c8=%d\n", c5[dd], + c6[dd], c7[dd], c8[dd]); + } + } +#endif + } + if (LaterTricksMAX(posPoint,hand,depth,target)) { + return TRUE; + } + } + } else if (posPoint->handRelFirst==1) { + ss=posPoint->stack[depth+1].move.suit; + ranks=posPoint->rankInSuit[hand][ss] | + posPoint->rankInSuit[partner(hand)][ss]; + found=FALSE; rr=0; qtricks=0; + if ( ranks >(BitRank(posPoint->stack[depth+1].move.rank) | + posPoint->rankInSuit[lho(hand)][ss])) { + /* Own side has highest card in suit */ + if (!contract.trumpContract || ((ss==contract.trump) || + (posPoint->rankInSuit[lho(hand)][contract.trump]==0) + || (posPoint->rankInSuit[lho(hand)][ss]!=0))) { + for (rr=14; rr>=2; rr--) { + if ((ranks & BitRank(rr))!=0) { + found=TRUE; + qtricks=1; + break; + } + } + if (!found) { + rr=0; + } + } + } else if (contract.notTrumpWithTrump(ss) && + (((posPoint->rankInSuit[hand][ss]==0) + && (posPoint->rankInSuit[hand][contract.trump]!=0))|| + ((posPoint->rankInSuit[partner(hand)][ss]==0) + && (posPoint->rankInSuit[partner(hand)][contract.trump]!=0)))) { + /* Own side can ruff */ + if ((posPoint->rankInSuit[lho(hand)][ss]!=0)|| + (posPoint->rankInSuit[lho(hand)][contract.trump]==0)) { + found=TRUE; + qtricks=1; + } + } + if (nodeTypeStore[hand]==MAXNODE) { + if ((posPoint->tricksMAX+qtricks>=target)&&(found)&& + (depth!=iniDepth)) { + for (k=0; k<=3; k++) + posPoint->stack[depth].winRanks[k]=0; + if (rr!=0) + posPoint->stack[depth].winRanks[ss] |= BitRank(rr); + return TRUE; + } + } else { + if (((posPoint->tricksMAX+((depth)>>2)+3-qtricks)<=target)&& + (found)&&(depth!=iniDepth)) { + for (k=0; k<=3; k++) + posPoint->stack[depth].winRanks[k]=0; + if (rr!=0) + posPoint->stack[depth].winRanks[ss] |= BitRank(rr); + return FALSE; + } + } + } + + if (posPoint->handRelFirst==0) { + for (ss=0; ss<=3; ss++) { + aggr[ss]=0; + for (hh=0; hh<=3; hh++) { + aggr[ss] |= posPoint->rankInSuit[hh][ss]; + } + posPoint->orderSet[ss]=rel(ss,aggr[ss]).aggrRanks; + } + tricks=depth>>2; + posPoint->getSuitLengths(suitLengths); + + pp=SearchLenAndInsert(rootnp[tricks][hand], suitLengths, FALSE, &res); + /* Find node that fits the suit lengths */ + if (pp!=NULL) { + np=pp->posSearchPoint; + if (np==NULL) { + cardsP=NULL; + } else { + cardsP=FindSOP(posPoint, np, hand, target, tricks, &scoreFlag); + } + + if ((cardsP!=NULL)&&(depth!=iniDepth)) { + if (scoreFlag==1) { + WinAdapt(posPoint, depth, cardsP, aggr); + + if (cardsP->bestMoveRank!=0) { + bestMove[depth].suit=cardsP->bestMoveSuit; + bestMove[depth].rank=cardsP->bestMoveRank; + } +#ifdef STAT + c5[depth]++; + if (scoreFlag==1) { + score1Counts[depth]++; + } else { + score0Counts[depth]++; + } + if (depth==iniDepth) { + fprintf(fp2, "score statistics:\n"); + for (dd=iniDepth; dd>=0; dd--) { + fprintf(fp2, "d=%d s1=%d s0=%d c1=%d c2=%d c3=%d c4=%d", dd, + score1Counts[dd], score0Counts[dd], c1[dd], c2[dd], + c3[dd], c4[dd]); + fprintf(fp2, " c5=%d c6=%d c7=%d c8=%d\n", c5[dd], + c6[dd], c7[dd], c8[dd]); + } + } +#endif + +#ifdef TTDEBUG + if (!suppressTTlog) { + if (lastTTstorebestMoveRank!=0) { + bestMove[depth].suit=cardsP->bestMoveSuit; + bestMove[depth].rank=cardsP->bestMoveRank; + } +#ifdef STAT + c6[depth]++; + if (scoreFlag==1) { + score1Counts[depth]++; + } else { + score0Counts[depth]++; + } + if (depth==iniDepth) { + fprintf(fp2, "score statistics:\n"); + for (dd=iniDepth; dd>=0; dd--) { + fprintf(fp2, "d=%d s1=%d s0=%d c1=%d c2=%d c3=%d c4=%d", dd, + score1Counts[dd], score0Counts[dd], c1[dd], c2[dd], c3[dd], + c4[dd]); + fprintf(fp2, " c5=%d c6=%d c7=%d c8=%d\n", c5[dd], + c6[dd], c7[dd], c8[dd]); + } + } +#endif + +#ifdef TTDEBUG + if (!suppressTTlog) { + if (lastTTstore=target) { + value=TRUE; + } else { + value=FALSE; + } + for (ss=0; ss<=3; ss++) { + posPoint->stack[depth].winRanks[ss]=evalData.winRanks[ss]; + +#ifdef STAT + c7[depth]++; + if (value==1) { + score1Counts[depth]++; + } else { + score0Counts[depth]++; + } + if (depth==iniDepth) { + fprintf(fp2, "score statistics:\n"); + for (dd=iniDepth; dd>=0; dd--) { + fprintf(fp2, "d=%d s1=%d s0=%d c1=%d c2=%d c3=%d c4=%d", dd, + score1Counts[dd], score0Counts[dd], c1[dd], c2[dd], c3[dd], + c4[dd]); + fprintf(fp2, " c5=%d c6=%d c7=%d c8=%d\n", c5[dd], + c6[dd], c7[dd], c8[dd]); + } + } +#endif + } + return value; + } else { /* Not at maximum depth */ + moveExists=MoveGen(posPoint, depth); + + if ((posPoint->handRelFirst==3)&&(depth>=/*29*/33/*37*/)&&(depth!=iniDepth)) { + movePly[depth].current=0; + mexists=TRUE; + ready=FALSE; + while (mexists) { + makeData=Make(posPoint, depth); + depth--; + + for (ss=0; ss<=3; ss++) { + aggr[ss]=0; + for (hh=0; hh<=3; hh++) { + aggr[ss] |= posPoint->rankInSuit[hh][ss]; + } + /* New algo */ + posPoint->orderSet[ss]=rel(ss,aggr[ss]).aggrRanks; + } + tricks=depth/4; + hfirst=posPoint->stack[depth].first; + posPoint->getSuitLengths(suitLengths); + + pp=SearchLenAndInsert(rootnp[tricks][hfirst], suitLengths, FALSE, &res); + /* Find node that fits the suit lengths */ + if (pp!=NULL) { + np=pp->posSearchPoint; + if (np==NULL) { + tempP=NULL; + } else { + tempP=FindSOP(posPoint, np, hfirst, target, tricks, &scoreFlag); + } + + if (tempP!=NULL) { + if ((nodeTypeStore[hand]==MAXNODE)&&(scoreFlag==1)) { + WinAdapt(posPoint, depth+1, tempP, aggr); + if (tempP->bestMoveRank!=0) { + bestMove[depth+1].suit=tempP->bestMoveSuit; + bestMove[depth+1].rank=tempP->bestMoveRank; + } + for (ss=0; ss<=3; ss++) { + posPoint->stack[depth+1].winRanks[ss] |= makeData.winRanks[ss]; + } + Undo(posPoint, depth+1); + return TRUE; + } else if ((nodeTypeStore[hand]==MINNODE)&&(scoreFlag==0)) { + WinAdapt(posPoint, depth+1, tempP, aggr); + if (tempP->bestMoveRank!=0) { + bestMove[depth+1].suit=tempP->bestMoveSuit; + bestMove[depth+1].rank=tempP->bestMoveRank; + } + for (ss=0; ss<=3; ss++) { + posPoint->stack[depth+1].winRanks[ss] |= makeData.winRanks[ss]; + } + Undo(posPoint, depth+1); + return FALSE; + } else { + movePly[depth+1].move[movePly[depth+1].current].weight+=100; + ready=TRUE; + } + } + } + depth++; + Undo(posPoint, depth); + if (ready) { + break; + } + if (movePly[depth].currentstack[depth].winRanks[ss]=0; + } + + while (moveExists) { + makeData=Make(posPoint, depth); /* Make current move */ + + value=ABsearch(posPoint, target, depth-1); + +#ifdef CANCEL + if (cancelStarted) { + return FALSE; + } +#endif + + Undo(posPoint, depth); /* Retract current move */ + if (value==TRUE) { + /* A cut-off? */ + for (ss=0; ss<=3; ss++) { + posPoint->stack[depth].winRanks[ss] = + posPoint->stack[depth-1].winRanks[ss] | makeData.winRanks[ss]; + } + mcurrent=movePly[depth].current; + bestMove[depth]=movePly[depth].move[mcurrent]; + goto ABexit; + } + for (ss=0; ss<=3; ss++) { + posPoint->stack[depth].winRanks[ss] |= + posPoint->stack[depth-1].winRanks[ss] | makeData.winRanks[ss]; + } + + moveExists=DismissX(posPoint, depth); + } + } else { /* A minnode */ + value=TRUE; + for (ss=0; ss<=3; ss++) { + posPoint->stack[depth].winRanks[ss]=0; + } + + while (moveExists) { + makeData=Make(posPoint, depth); /* Make current move */ + + value=ABsearch(posPoint, target, depth-1); + +#ifdef CANCEL + if (cancelStarted) { + return FALSE; + } +#endif + + Undo(posPoint, depth); /* Retract current move */ + if (value==FALSE) { + /* A cut-off? */ + for (ss=0; ss<=3; ss++) { + posPoint->stack[depth].winRanks[ss]=posPoint->stack[depth-1].winRanks[ss] | + makeData.winRanks[ss]; + } + mcurrent=movePly[depth].current; + bestMove[depth]=movePly[depth].move[mcurrent]; + goto ABexit; + } + for (ss=0; ss<=3; ss++) { + posPoint->stack[depth].winRanks[ss] |= + posPoint->stack[depth-1].winRanks[ss] | makeData.winRanks[ss]; + } + + moveExists=DismissX(posPoint, depth); + } + } + } + + ABexit: + if (depth>=4) { + if(posPoint->handRelFirst==0) { + tricks=depth>>2; + /*hand=posPoint->first[depth-1];*/ + if (value) { + k=target; + } else { + k=target-1; + } + BuildSOP(posPoint, tricks, hand, target, depth,value, k); + if (clearTTflag) { + /* Wipe out the TT dynamically allocated structures + except for the initially allocated structures. + Set the TT limits to the initial values. + Reset TT array indices to zero. + Reset memory chunk indices to zero. + Set allocated memory to the initial value. */ + + Wipe(); + winSetSizeLimit=WINIT; + nodeSetSizeLimit=NINIT; + lenSetSizeLimit=LINIT; + lcount=0; + allocmem=(lenSetSizeLimit+1)*sizeof(struct posSearchType); + lenSetSize=0; + posSearch=pl[lcount]; + for (k=0; k<=13; k++) { + for (hh=0; hh<=3; hh++) { + rootnp[k][hh]=&posSearch[lenSetSize]; + posSearch[lenSetSize].suitLengths=0; + posSearch[lenSetSize].posSearchPoint=NULL; + posSearch[lenSetSize].left=NULL; + posSearch[lenSetSize].right=NULL; + lenSetSize++; + } + } + nodeSetSize=0; + winSetSize=0; + wcount=0; ncount=0; + allocmem+=(winSetSizeLimit+1)*sizeof(struct winCardType); + winCards=pw[wcount]; + allocmem+=(nodeSetSizeLimit+1)*sizeof(struct nodeCardsType); + nodeCards=pn[ncount]; + clearTTflag=FALSE; + windex=-1; + } + } + } +#ifdef STAT + c8[depth]++; + if (value==1) { + score1Counts[depth]++; + } else { + score0Counts[depth]++; + } + if (depth==iniDepth) { + if (fp2==NULL) { + exit(0); + } + fprintf(fp2, "\n"); + fprintf(fp2, "top level cards:\n"); + for (hh=0; hh<=3; hh++) { + fprintf(fp2, "hand=%c\n", cardHand[hh]); + for (ss=0; ss<=3; ss++) { + fprintf(fp2, "suit=%c", cardSuit[ss]); + for (rr=14; rr>=2; rr--) + if (posPoint->rankInSuit[hh][ss] & BitRank(rr)) + fprintf(fp2, " %c", cardRank[rr]); + fprintf(fp2, "\n"); + } + fprintf(fp2, "\n"); + } + fprintf(fp2, "top level winning cards:\n"); + for (ss=0; ss<=3; ss++) { + fprintf(fp2, "suit=%c", cardSuit[ss]); + for (rr=14; rr>=2; rr--) { + if (posPoint->stack[depth].winRanks[ss] & BitRank(rr)) { + fprintf(fp2, " %c", cardRank[rr]); + } + } + fprintf(fp2, "\n"); + } + fprintf(fp2, "\n"); + fprintf(fp2, "\n"); + + fprintf(fp2, "score statistics:\n"); + sumScore0Counts=0; + sumScore1Counts=0; + sumc1=0; sumc2=0; sumc3=0; sumc4=0; + sumc5=0; sumc6=0; sumc7=0; sumc8=0; sumc9=0; + for (dd=iniDepth; dd>=0; dd--) { + fprintf(fp2, "depth=%d s1=%d s0=%d c1=%d c2=%d c3=%d c4=%d", dd, + score1Counts[dd], score0Counts[dd], c1[dd], c2[dd], c3[dd], c4[dd]); + fprintf(fp2, " c5=%d c6=%d c7=%d c8=%d\n", c5[dd], c6[dd], + c7[dd], c8[dd]); + sumScore0Counts=sumScore0Counts+score0Counts[dd]; + sumScore1Counts=sumScore1Counts+score1Counts[dd]; + sumc1=sumc1+c1[dd]; + sumc2=sumc2+c2[dd]; + sumc3=sumc3+c3[dd]; + sumc4=sumc4+c4[dd]; + sumc5=sumc5+c5[dd]; + sumc6=sumc6+c6[dd]; + sumc7=sumc7+c7[dd]; + sumc8=sumc8+c8[dd]; + sumc9=sumc9+c9[dd]; + } + fprintf(fp2, "\n"); + fprintf(fp2, "score sum statistics:\n"); + fprintf(fp2, "\n"); + fprintf(fp2, "sumScore0Counts=%d sumScore1Counts=%d\n", + sumScore0Counts, sumScore1Counts); + fprintf(fp2, "nodeSetSize=%d winSetSize=%d\n", nodeSetSize, + winSetSize); + fprintf(fp2, "sumc1=%d sumc2=%d sumc3=%d sumc4=%d\n", + sumc1, sumc2, sumc3, sumc4); + fprintf(fp2, "sumc5=%d sumc6=%d sumc7=%d sumc8=%d sumc9=%d\n", + sumc5, sumc6, sumc7, sumc8, sumc9); + fprintf(fp2, "\n"); + fprintf(fp2, "\n"); + fprintf(fp2, "No of searched nodes per depth:\n"); + for (dd=iniDepth; dd>=0; dd--) { + fprintf(fp2, "depth=%d nodes=%d\n", dd, no[dd]); + } + fprintf(fp2, "\n"); + fprintf(fp2, "Total nodes=%d\n", nodes); + } +#endif + + return value; +} + + +struct makeType Make(struct pos * posPoint, int depth) { + int r, s, t, u, w, firstHand; + int suit, /*rank, */count, mcurr, h, q, done; + struct makeType trickCards; + struct moveType mo1, mo2; + const ContractInfo contract = Globals.getContract(); + struct posStackItem ¤t = posPoint->stack[depth]; + const struct posStackItem &previous = posPoint->stack[depth+1]; + + for (suit=0; suit<=3; suit++) { + trickCards.winRanks[suit]=0; + } + + firstHand=current.first; + r=movePly[depth].current; + + if (posPoint->handRelFirst==3) { /* This hand is last hand */ + mo1 = movePly[depth].move[r]; + mo2 = previous.move; + if (contract.betterMove(mo1,mo2)) { + current.move=mo1; + current.high=HandStore(firstHand,3); + } else { + current.move=mo2; + current.high=previous.high; + } + + /* Is the trick won by rank? */ + suit=current.move.suit; + /*rank=posPoint->stack[depth+h].stack[depth].move.rank;*/ + count=0; + for (h=0; h<=3; h++) { + mcurr=movePly[depth+h].current; + if (movePly[depth+h].move[mcurr].suit==suit) { + count++; + } + } + + if (nodeTypeStore[current.high]==MAXNODE) + posPoint->tricksMAX++; + posPoint->stack[depth-1].first=current.high; + /* Defines who is first in the next move */ + + t=HandStore(firstHand,3); + posPoint->handRelFirst=0; /* Hand pointed to by posPoint->first + will lead the next trick */ + + done=FALSE; + for (s=3; s>=0; s--) { + q=HandStore(firstHand,3-s); + /* Add the moves to removed ranks */ + r=movePly[depth+s].current; + w=movePly[depth+s].move[r].rank; + u=movePly[depth+s].move[r].suit; + posPoint->removeRank(u,w); + + if (s==0) + posPoint->rankInSuit[t][u] &= + (~BitRank(w)); + + if (w==posPoint->winner[u].rank) { + UpdateWinner(posPoint, u); + } else if (w==posPoint->secondBest[u].rank) { + UpdateSecondBest(posPoint, u); + } + + /* Determine win-ranked cards */ + if ((q==current.high)&&(!done)) { + done=TRUE; + if (count>=2) { + trickCards.winRanks[u]=BitRank(w); + /* Mark ranks as winning if they are part of a sequence */ + trickCards.winRanks[u] |= movePly[depth+s].move[r].sequence; + } + } + } + } else if (posPoint->handRelFirst==0) { /* Is it the 1st hand? */ + posPoint->stack[depth-1].first=firstHand; /* First hand is not changed in + next move */ + current.high=firstHand; + current.move=movePly[depth].move[r]; + + t=firstHand; + posPoint->handRelFirst=1; + r=movePly[depth].current; + u=movePly[depth].move[r].suit; + w=movePly[depth].move[r].rank; + posPoint->rankInSuit[t][u] &= (~BitRank(w)); + } else { /* Second or third hand in trick */ + mo1=movePly[depth].move[r]; + mo2=previous.move; + if (contract.betterMove(mo1,mo2)) { + current.move=mo1; + current.high=HandStore(firstHand,posPoint->handRelFirst); + } else { + current.move=previous.move; + current.high=previous.high; + } + + t=HandStore(firstHand,posPoint->handRelFirst); + posPoint->handRelFirst++; /* Current hand is stepped */ + posPoint->stack[depth-1].first=firstHand; /* First hand is not changed in + next move */ + r=movePly[depth].current; + u=movePly[depth].move[r].suit; + w=movePly[depth].move[r].rank; + posPoint->rankInSuit[t][u] &= (~BitRank(w)); + } + + posPoint->length[t][u]--; + + no[depth]++; + + return trickCards; +} + + +void Undo(struct pos * posPoint, int depth) { + int r, s, t, u, w, firstHand; + + firstHand=posPoint->stack[depth].first; + + switch (posPoint->handRelFirst) { + case 3: case 2: case 1: + posPoint->handRelFirst--; + break; + case 0: + posPoint->handRelFirst=3; + } + + if (posPoint->handRelFirst==0) { /* 1st hand which won the previous + trick */ + t=firstHand; + r=movePly[depth].current; + u=movePly[depth].move[r].suit; + w=movePly[depth].move[r].rank; + } else if (posPoint->handRelFirst==3) { /* Last hand */ + for (s=3; s>=0; s--) { + /* Delete the moves from removed ranks */ + r=movePly[depth+s].current; + w=movePly[depth+s].move[r].rank; + u=movePly[depth+s].move[r].suit; + //posPoint->removedRanks[u]=posPoint->removedRanks[u] & (~BitRank(w)); + posPoint->restoreRank(u,w); + + if (w>posPoint->winner[u].rank) { + posPoint->secondBest[u].rank=posPoint->winner[u].rank; + posPoint->secondBest[u].hand=posPoint->winner[u].hand; + posPoint->winner[u].rank=w; + posPoint->winner[u].hand=HandStore(firstHand,3-s); + } else if (w>posPoint->secondBest[u].rank) { + posPoint->secondBest[u].rank=w; + posPoint->secondBest[u].hand=HandStore(firstHand,3-s); + } + } + t=HandStore(firstHand,3); + + + if (nodeTypeStore[posPoint->stack[depth-1].first]==MAXNODE) { + /* First hand of next trick is winner of the current trick */ + posPoint->tricksMAX--; + } + } else { + t=HandStore(firstHand,posPoint->handRelFirst); + r=movePly[depth].current; + u=movePly[depth].move[r].suit; + w=movePly[depth].move[r].rank; + } + + posPoint->rankInSuit[t][u] |= BitRank(w); + + posPoint->length[t][u]++; + + return; +} + + + +struct evalType Evaluate(const struct pos * posPoint) { + int s, smax=0, k, firstHand, count; + unsigned short int max; + struct evalType eval; + const ContractInfo contract = Globals.getContract(); + + firstHand=posPoint->stack[0].first; + + for (s=0; s<=3; s++) { + eval.winRanks[s]=0; + } + + /* Who wins the last trick? */ + if (contract.trumpContract) { /* Highest trump card wins */ + max=0; + count=0; + for (s=0; s<=3; s++) { + if (posPoint->rankInSuit[s][contract.trump]!=0) { + count++; + } + if (posPoint->rankInSuit[s][contract.trump]>max) { + smax=s; + max=posPoint->rankInSuit[s][contract.trump]; + } + } + + if (max>0) { /* Trumpcard wins */ + if (count>=2) { + eval.winRanks[contract.trump]=max; + } + + if (nodeTypeStore[smax]==MAXNODE) { + goto maxexit; + } else { + goto minexit; + } + } + } + + /* Who has the highest card in the suit played by 1st hand? */ + + k=0; + while (k<=3) { /* Find the card the 1st hand played */ + if (posPoint->rankInSuit[firstHand][k]!=0) { /* Is this the card? */ + break; + } + k++; + } + + count=0; + max=0; + for (s=0; s<=3; s++) { + if (posPoint->rankInSuit[s][k]!=0) { + count++; + } + if (posPoint->rankInSuit[s][k]>max) { + smax=s; + max=posPoint->rankInSuit[s][k]; + } + } + + if (count>=2) { + eval.winRanks[k]=max; + } + + if (nodeTypeStore[smax]==MAXNODE) { + goto maxexit; + } else { + goto minexit; + } + + maxexit: + eval.tricks=posPoint->tricksMAX+1; + return eval; + + minexit: + eval.tricks=posPoint->tricksMAX; + return eval; +} + + + +void UpdateWinner(struct pos * posPoint, int suit) { + int k; + int h, hmax=0, flag; + + posPoint->winner[suit]=posPoint->secondBest[suit]; + + k=posPoint->secondBest[suit].rank-1; + while (k>=2) { + flag=TRUE; + for (h=0; h<=3; h++) + if ((posPoint->rankInSuit[h][suit] & BitRank(k)) != 0) { + hmax=h; + flag=FALSE; + break; + } + if (flag) { + k--; + } else { + break; + } + } + if (k<2) { + posPoint->secondBest[suit].rank=0; + posPoint->secondBest[suit].hand=0; + } else { + posPoint->secondBest[suit].rank=k; + posPoint->secondBest[suit].hand=hmax; + } + return; +} + + +void UpdateSecondBest(struct pos * posPoint, int suit) { + int k; + int h, hmax=0, flag; + + k=posPoint->secondBest[suit].rank-1; + while (k>=2) { + flag=TRUE; + for (h=0; h<=3; h++) { + if ((posPoint->rankInSuit[h][suit] & BitRank(k)) != 0) { + hmax=h; + flag=FALSE; + break; + } + } + if (flag) { + k--; + } else { + break; + } + } + if (k<2) { + posPoint->secondBest[suit].rank=0; + posPoint->secondBest[suit].hand=0; + } + else { + posPoint->secondBest[suit].rank=k; + posPoint->secondBest[suit].hand=hmax; + } + return; +} + + +int QuickTricks(struct pos * posPoint, const int hand, + const int depth, const int target, int *result) { + holding_t ranks; + int suit, sum, qtricks, commPartner, commRank=0, commSuit=-1, found=FALSE; + int opps; + int countLho, countRho, countPart, countOwn, lhoTrumpRanks=0, rhoTrumpRanks=0; + int cutoff, k, lowestQtricks=0, count=0; + const ContractInfo contract = Globals.getContract(); + + *result=TRUE; + qtricks=0; + for (suit=0; suit<=3; suit++) { + posPoint->stack[depth].winRanks[suit]=0; + } + + if ((depth<=0)||(depth==iniDepth)) { + *result=FALSE; + return qtricks; + } + + if (nodeTypeStore[hand]==MAXNODE) { + cutoff=target-posPoint->tricksMAX; + } else { + cutoff=posPoint->tricksMAX-target+(depth>>2)+2; + } + + commPartner=FALSE; + for (suit=0; suit<=3; suit++) { + if (contract.notTrumpWithTrump(suit)) { + /* Trump contract, suit is not trump */ + if (posPoint->winner[suit].hand==partner(hand)) { + /* Partner has winning card */ + if (posPoint->rankInSuit[hand][suit]!=0) { + /* Own hand has card in suit */ + if (((posPoint->rankInSuit[lho(hand)][suit]!=0) || + /* LHO not void */ + (posPoint->rankInSuit[lho(hand)][contract.trump]==0)) + /* LHO has no trump */ + && ((posPoint->rankInSuit[rho(hand)][suit]!=0) || + /* RHO not void */ + (posPoint->rankInSuit[rho(hand)][contract.trump]==0))) { + /* RHO has no trump */ + commPartner=TRUE; + commSuit=suit; + commRank=posPoint->winner[suit].rank; + break; + } + } + } else if (posPoint->secondBest[suit].hand==partner(hand)) { + if ((posPoint->winner[suit].hand==hand)&& + (posPoint->length[hand][suit]>=2)&&(posPoint->length[partner(hand)][suit]>=2)) { + if (((posPoint->rankInSuit[lho(hand)][suit]!=0) || + (posPoint->rankInSuit[lho(hand)][contract.trump]==0)) + && ((posPoint->rankInSuit[rho(hand)][suit]!=0) || + (posPoint->rankInSuit[rho(hand)][contract.trump]==0))) { + commPartner=TRUE; + commSuit=suit; + commRank=posPoint->secondBest[suit].rank; + break; + } + } + } + } else if (!contract.trumpContract) { + if (posPoint->winner[suit].hand==partner(hand)) { + /* Partner has winning card */ + if (posPoint->rankInSuit[hand][suit]!=0) { + /* Own hand has card in suit */ + commPartner=TRUE; + commSuit=suit; + commRank=posPoint->winner[suit].rank; + break; + } + } else if (posPoint->secondBest[suit].hand==partner(hand)) { + if ((posPoint->winner[suit].hand==hand)&& + (posPoint->length[hand][suit]>=2)&&(posPoint->length[partner(hand)][suit]>=2)) { + commPartner=TRUE; + commSuit=suit; + commRank=posPoint->secondBest[suit].rank; + break; + } + } + } + } + + //int s; + + if (contract.trumpContract && (!commPartner) && + (posPoint->rankInSuit[hand][contract.trump]!=0) && + (posPoint->winner[contract.trump].hand==partner(hand))) { + commPartner=TRUE; + commSuit=contract.trump; + commRank=posPoint->winner[contract.trump].rank; + } + + + if (contract.trumpContract) { + lhoTrumpRanks=posPoint->length[lho(hand)][contract.trump]; + rhoTrumpRanks=posPoint->length[rho(hand)][contract.trump]; + } + + for (suit=contract.firstSuit(); suit<4; suit=contract.nextSuit(suit)) { + countOwn=posPoint->length[hand][suit]; + countLho=posPoint->length[lho(hand)][suit]; + countRho=posPoint->length[rho(hand)][suit]; + countPart=posPoint->length[partner(hand)][suit]; + opps=countLho | countRho; + + if (!opps && (countPart==0)) { + if (countOwn==0) { + continue; + } + if (contract.notTrumpWithTrump(suit)) { + if ((lhoTrumpRanks==0) && + /* LHO has no trump */ + (rhoTrumpRanks==0)) { + /* RHO has no trump */ + qtricks=qtricks+countOwn; + if (qtricks>=cutoff) { + return qtricks; + } + continue; + } else { + continue; + } + } else { + qtricks=qtricks+countOwn; + if (qtricks>=cutoff) { + return qtricks; + } + + continue; + } + } else { + if (!opps && contract.isTrump(suit)) { + sum=Max(countOwn, countPart); + for (int suit2=0; suit2<=3; suit2++) { + if ((sum>0)&&(suit2!=contract.trump)&&(countOwn>=countPart)&&(posPoint->length[hand][suit2]>0)&& + (posPoint->length[partner(hand)][suit2]==0)) { + sum++; + break; + } + } + if (sum>=cutoff) { + return sum; + } + } else if (!opps) { + sum=Min(countOwn,countPart); + if (!contract.trumpContract) { + if (sum>=cutoff) { + return sum; + } + } else if ((suit!=contract.trump)&&(lhoTrumpRanks==0)&&(rhoTrumpRanks==0)) { + if (sum>=cutoff) { + return sum; + } + } + } + + if (commPartner) { + if (!opps && (countOwn==0)) { + if (contract.notTrumpWithTrump(suit)) { + if ((lhoTrumpRanks==0) && + /* LHO has no trump */ + (rhoTrumpRanks==0)) { + /* RHO has no trump */ + qtricks=qtricks+countPart; + posPoint->stack[depth].winRanks[commSuit] |= BitRank(commRank); + if (qtricks>=cutoff) { + return qtricks; + } + continue; + } else { + continue; + } + } else { + qtricks=qtricks+countPart; + posPoint->stack[depth].winRanks[commSuit]=posPoint->stack[depth].winRanks[commSuit] | + BitRank(commRank); + if (qtricks>=cutoff) + return qtricks; + continue; + } + } else { + if (!opps && contract.isTrump(suit)) { + sum=Max(countOwn, countPart); + for (int suit2=0; suit2<=3; suit2++) { + if ((sum>0)&&(suit2!=contract.trump)&&(countOwn<=countPart)&&(posPoint->length[partner(hand)][suit2]>0)&& + (posPoint->length[hand][suit2]==0)) { + sum++; + break; + } + } + if (sum>=cutoff) { + posPoint->stack[depth].winRanks[commSuit] |= BitRank(commRank); + return sum; + } + } else if (!opps) { + sum=Min(countOwn,countPart); + if (!contract.trumpContract) { + if (sum>=cutoff) + return sum; + } else if ((suit!=contract.trump)&&(lhoTrumpRanks==0)&&(rhoTrumpRanks==0)) { + if (sum>=cutoff) + return sum; + } + } + } + } + } + /* 08-01-30 */ + if (posPoint->winner[suit].rank==0) { + continue; + } + + if (posPoint->winner[suit].hand==hand) { + /* Winner found in own hand */ + if (contract.notTrumpWithTrump(suit)) { + if (((countLho!=0) || + /* LHO not void */ + (lhoTrumpRanks==0)) + /* LHO has no trump */ + && ((countRho!=0) || + /* RHO not void */ + (rhoTrumpRanks==0))) { + /* RHO has no trump */ + posPoint->stack[depth].winRanks[suit]=posPoint->stack[depth].winRanks[suit] + | BitRank(posPoint->winner[suit].rank); + qtricks++; /* A trick can be taken */ + /* 06-12-14 */ + if (qtricks>=cutoff) + return qtricks; + + if ((countLho<=1)&&(countRho<=1)&&(countPart<=1)&& + (lhoTrumpRanks==0)&&(rhoTrumpRanks==0)) { + qtricks=qtricks+countOwn-1; + if (qtricks>=cutoff) { + return qtricks; + } + continue; + } + } + if (posPoint->secondBest[suit].hand==hand) { + /* Second best found in own hand */ + if ((lhoTrumpRanks==0)&& + (rhoTrumpRanks==0)) { + /* Opponents have no trump */ + posPoint->stack[depth].winRanks[suit]=posPoint->stack[depth].winRanks[suit] + | BitRank(posPoint->secondBest[suit].rank); + qtricks++; + if ((countLho<=2)&&(countRho<=2)&&(countPart<=2)) { + qtricks=qtricks+countOwn-2; + if (qtricks>=cutoff) + return qtricks; + continue; + } + } + } else if ((posPoint->secondBest[suit].hand==partner(hand)) + &&(countOwn>1)&&(countPart>1)) { + /* Second best at partner and suit length of own + hand and partner > 1 */ + if ((lhoTrumpRanks==0)&& + (rhoTrumpRanks==0)) { + /* Opponents have no trump */ + posPoint->stack[depth].winRanks[suit]=posPoint->stack[depth].winRanks[suit] + | BitRank(posPoint->secondBest[suit].rank); + qtricks++; + if ((countLho<=2)&&(countRho<=2)&&((countPart<=2)||(countOwn<=2))) { + /* 07-06-10 */ + qtricks=qtricks+Max(countOwn-2, countPart-2); + if (qtricks>=cutoff) { + return qtricks; + } + continue; + } + } + } + } else { + posPoint->stack[depth].winRanks[suit] |= BitRank(posPoint->winner[suit].rank); + qtricks++; + /* 06-12-14 */ + if (qtricks>=cutoff) { + return qtricks; + } + + if ((countLho<=1)&&(countRho<=1)&&(countPart<=1)) { + qtricks=qtricks+countOwn-1; + if (qtricks>=cutoff) { + return qtricks; + } + continue; + } + + if (posPoint->secondBest[suit].hand==hand) { + /* Second best found in own hand */ + posPoint->stack[depth].winRanks[suit]=posPoint->stack[depth].winRanks[suit] + | BitRank(posPoint->secondBest[suit].rank); + qtricks++; + if ((countLho<=2)&&(countRho<=2)&&(countPart<=2)) { + qtricks=qtricks+countOwn-2; + if (qtricks>=cutoff) { + return qtricks; + } + continue; + } + } else if ((posPoint->secondBest[suit].hand==partner(hand)) + &&(countOwn>1)&&(countPart>1)) { + /* Second best at partner and suit length of own + hand and partner > 1 */ + posPoint->stack[depth].winRanks[suit] |= BitRank(posPoint->secondBest[suit].rank); + qtricks++; + if ((countLho<=2)&&(countRho<=2)&&((countPart<=2)||(countOwn<=2))) { + /* 07-06-10 */ + qtricks=qtricks+Max(countOwn-2,countPart-2); + if (qtricks>=cutoff) { + return qtricks; + } + continue; + } + } + } + } else { + /* It was not possible to take a quick trick by own winning card in + the suit */ + /* Partner winning card? */ + if ((posPoint->winner[suit].hand==partner(hand))&&(countPart>0)) { + /* Winner found at partner*/ + if (commPartner) { + /* There is communication with the partner */ + if (contract.notTrumpWithTrump(suit)) { + if (((countLho!=0) || + /* LHO not void */ + (lhoTrumpRanks==0)) + /* LHO has no trump */ + && ((countRho!=0) || + /* RHO not void */ + (rhoTrumpRanks==0))) + /* RHO has no trump */ + { + posPoint->stack[depth].winRanks[suit]=posPoint->stack[depth].winRanks[suit] + | BitRank(posPoint->winner[suit].rank); + posPoint->stack[depth].winRanks[commSuit]=posPoint->stack[depth].winRanks[commSuit] | + BitRank(commRank); + qtricks++; /* A trick can be taken */ + /* 06-12-14 */ + if (qtricks>=cutoff) { + return qtricks; + } + if ((countLho<=1)&&(countRho<=1)&&(countOwn<=1)&& + (lhoTrumpRanks==0)&& + (rhoTrumpRanks==0)) { + qtricks=qtricks+countPart-1; + continue; + } + } + if (posPoint->secondBest[suit].hand==partner(hand)) { + /* Second best found in partners hand */ + if ((lhoTrumpRanks==0)&& + (rhoTrumpRanks==0)) { + /* Opponents have no trump */ + posPoint->stack[depth].winRanks[suit] |= BitRank(posPoint->secondBest[suit].rank); + posPoint->stack[depth].winRanks[commSuit] |= BitRank(commRank); + qtricks++; + if ((countLho<=2)&&(countRho<=2)&&(countOwn<=2)) { + continue; + } + } + } else if ((posPoint->secondBest[suit].hand==hand)&& + (countPart>1)&&(countOwn>1)) { + /* Second best found in own hand and suit + lengths of own hand and partner > 1*/ + if ((lhoTrumpRanks==0)&& + (rhoTrumpRanks==0)) { + /* Opponents have no trump */ + posPoint->stack[depth].winRanks[suit]=posPoint->stack[depth].winRanks[suit] + | BitRank(posPoint->secondBest[suit].rank); + posPoint->stack[depth].winRanks[commSuit]=posPoint->stack[depth].winRanks[commSuit] | + BitRank(commRank); + qtricks++; + if ((countLho<=2)&&(countRho<=2)&& + ((countOwn<=2)||(countPart<=2))) { /* 07-06-10 */ + qtricks=qtricks+ + Max(countPart-2,countOwn-2); + if (qtricks>=cutoff) { + return qtricks; + } + continue; + } + } + } + /* 06-08-24 */ + else if ((suit==commSuit)&&(posPoint->secondBest[suit].hand + ==lho(hand))&&((countLho>=2)||(lhoTrumpRanks==0))&& + ((countRho>=2)||(rhoTrumpRanks==0))) { + ranks=0; + for (k=0; k<=3; k++) + ranks=ranks | posPoint->rankInSuit[k][suit]; + for (rr=posPoint->secondBest[suit].rank-1; rr>=2; rr--) { + /* 3rd best at partner? */ + if ((ranks & BitRank(rr))!=0) { + if ((posPoint->rankInSuit[partner(hand)][suit] & + BitRank(rr))!=0) { + found=TRUE; + break; + } + else { + found=FALSE; + break; + } + } + found=FALSE; + } + if (found) { + posPoint->stack[depth].winRanks[suit]=posPoint->stack[depth].winRanks[suit] | BitRank(rr); + posPoint->stack[depth].winRanks[commSuit]=posPoint->stack[depth].winRanks[commSuit] | + BitRank(commRank); + qtricks++; + if ((countOwn<=2)&&(countLho<=2)&&(countRho<=2)&& + (lhoTrumpRanks==0)&&(rhoTrumpRanks==0)) + qtricks=qtricks+countPart-2; + } + } + } + else { + posPoint->stack[depth].winRanks[suit]=posPoint->stack[depth].winRanks[suit] + | BitRank(posPoint->winner[suit].rank); + posPoint->stack[depth].winRanks[commSuit]=posPoint->stack[depth].winRanks[commSuit] | + BitRank(commRank); + qtricks++; + /* 06-12-14 */ + if (qtricks>=cutoff) { + return qtricks; + } + + if ((countLho<=1)&&(countRho<=1)&&(countOwn<=1)) { + qtricks=qtricks+countPart-1; + if (qtricks>=cutoff) { + return qtricks; + } + continue; + } + if ((posPoint->secondBest[suit].hand==partner(hand))&&(countPart>0)) { + /* Second best found in partners hand */ + posPoint->stack[depth].winRanks[suit]=posPoint->stack[depth].winRanks[suit] + | BitRank(posPoint->secondBest[suit].rank); + posPoint->stack[depth].winRanks[commSuit]=posPoint->stack[depth].winRanks[commSuit] | + BitRank(commRank); + qtricks++; + if ((countLho<=2)&&(countRho<=2)&&(countOwn<=2)) { + qtricks=qtricks+countPart-2; + if (qtricks>=cutoff) + return qtricks; + continue; + } + } + /* 06-08-19 */ + else if ((posPoint->secondBest[suit].hand==hand) + &&(countPart>1)&&(countOwn>1)) { + /* Second best found in own hand and own and + partner's suit length > 1 */ + posPoint->stack[depth].winRanks[suit]=posPoint->stack[depth].winRanks[suit] + | BitRank(posPoint->secondBest[suit].rank); + posPoint->stack[depth].winRanks[commSuit]=posPoint->stack[depth].winRanks[commSuit] | + BitRank(commRank); + qtricks++; + if ((countLho<=2)&&(countRho<=2)&&((countOwn<=2)||(countPart<=2))) { /* 07-06-10 */ + qtricks=qtricks+Max(countPart-2,countOwn-2); + if (qtricks>=cutoff) { + return qtricks; + } + continue; + } + } + /* 06-08-24 */ + else if ((suit==commSuit)&&(posPoint->secondBest[suit].hand + ==lho(hand))) { + ranks=0; + for (k=0; k<=3; k++) + ranks=ranks | posPoint->rankInSuit[k][suit]; + for (rr=posPoint->secondBest[suit].rank-1; rr>=2; rr--) { + /* 3rd best at partner? */ + if ((ranks & BitRank(rr))!=0) { + if ((posPoint->rankInSuit[partner(hand)][suit] & + BitRank(rr))!=0) { + found=TRUE; + break; + } + else { + found=FALSE; + break; + } + } + found=FALSE; + } + if (found) { + posPoint->stack[depth].winRanks[suit]=posPoint->stack[depth].winRanks[suit] | BitRank(rr); + posPoint->stack[depth].winRanks[commSuit]=posPoint->stack[depth].winRanks[commSuit] | + BitRank(commRank); + qtricks++; + if ((countOwn<=2)&&(countLho<=2)&&(countRho<=2)) { + qtricks=qtricks+countPart-2; + } + } + } + } + } + } + } + + if (contract.notTrumpWithTrump(suit) &&(countOwn>0)&&(lowestQtricks==0)&& + ((qtricks==0)||((posPoint->winner[suit].hand!=hand)&& + (posPoint->winner[suit].hand!=partner(hand))&& + (posPoint->winner[contract.trump].hand!=hand)&& + (posPoint->winner[contract.trump].hand!=partner(hand))))) { + if ((countPart==0)&&(posPoint->length[partner(hand)][contract.trump]>0)) { + if (((countRho>0)||(posPoint->length[rho(hand)][contract.trump]==0))&& + ((countLho>0)||(posPoint->length[lho(hand)][contract.trump]==0))) { + lowestQtricks=1; + if (1>=cutoff) { + return 1; + } + continue; + } else if ((countRho==0)&&(countLho==0)) { + if ((posPoint->rankInSuit[lho(hand)][contract.trump] | + posPoint->rankInSuit[rho(hand)][contract.trump]) < + posPoint->rankInSuit[partner(hand)][contract.trump]) { + lowestQtricks=1; + for (rr=14; rr>=2; rr--) { + if ((posPoint->rankInSuit[partner(hand)][contract.trump] & + BitRank(rr))!=0) { + posPoint->stack[depth].winRanks[contract.trump] |= BitRank(rr); + break; + } + } + if (1>=cutoff) { + return 1; + } + } + continue; + } else if (countLho==0) { + if (posPoint->rankInSuit[lho(hand)][contract.trump] < + posPoint->rankInSuit[partner(hand)][contract.trump]) { + lowestQtricks=1; + for (rr=14; rr>=2; rr--) { + if ((posPoint->rankInSuit[partner(hand)][contract.trump] & BitRank(rr))!=0) { + posPoint->stack[depth].winRanks[contract.trump] |= BitRank(rr); + break; + } + } + if (1>=cutoff) { + return 1; + } + } + continue; + } else if (countRho==0) { + if (posPoint->rankInSuit[rho(hand)][contract.trump] < + posPoint->rankInSuit[partner(hand)][contract.trump]) { + lowestQtricks=1; + for (rr=14; rr>=2; rr--) { + if ((posPoint->rankInSuit[partner(hand)][contract.trump] & + BitRank(rr))!=0) { + posPoint->stack[depth].winRanks[contract.trump] |= BitRank(rr); + break; + } + } + if (1>=cutoff) { + return 1; + } + } + continue; + } + } + } + + if (qtricks>=cutoff) { + return qtricks; + } + + } + + if (qtricks==0) { + if ((!contract.trumpContract)||(posPoint->winner[contract.trump].rank==0)) { + found=FALSE; + for (ss=0; ss<=3; ss++) { + if (posPoint->winner[ss].rank==0) + continue; + hh=posPoint->winner[ss].hand; + if (nodeTypeStore[hh]==nodeTypeStore[hand]) { + if (posPoint->length[hand][ss]>0) { + found=TRUE; + break; + } + } + else if ((posPoint->length[partner(hand)][ss]>0)&& + (posPoint->length[hand][ss]>0)&& + (posPoint->length[partner(hh)][ss]>0)) { + count++; + } + } + if (!found) { + if (nodeTypeStore[hand]==MAXNODE) { + if ((posPoint->tricksMAX+(depth>>2)-Max(0,count-1))length[hand][ss]>0) + &&(nodeTypeStore[posPoint->winner[ss].hand]==MINNODE)) + posPoint->stack[depth].winRanks[ss]= + BitRank(posPoint->winner[ss].rank); + else + posPoint->stack[depth].winRanks[ss]=0; + } + return 0; + } + } + else { + if ((posPoint->tricksMAX+1+Max(0,count-1))>=target) { + for (ss=0; ss<=3; ss++) { + if ((posPoint->length[hand][ss]>0) + &&(nodeTypeStore[posPoint->winner[ss].hand]==MAXNODE)) + posPoint->stack[depth].winRanks[ss]= + BitRank(posPoint->winner[ss].rank); + else + posPoint->stack[depth].winRanks[ss]=0; + } + return 0; + } + } + } + } + } + + *result=FALSE; + return qtricks; +} + + +int LaterTricksMIN(struct pos *posPoint, const int hand, const int depth, const int target) { + int hh, ss, sum=0; + + const ContractInfo contract = Globals.getContract(); + + if ((!contract.trumpContract)||(posPoint->winner[contract.trump].rank==0)) { + for (ss=0; ss<=3; ss++) { + hh=posPoint->winner[ss].hand; + if (nodeTypeStore[hh]==MAXNODE) + sum+=Max(posPoint->length[hh][ss], posPoint->length[partner(hh)][ss]); + } + if ((posPoint->tricksMAX+sum0)&&(depth>0)&&(depth!=iniDepth)) { + if ((posPoint->tricksMAX+(depth>>2)winner[ss].hand]==MINNODE) + posPoint->stack[depth].winRanks[ss]=BitRank(posPoint->winner[ss].rank); + else + posPoint->stack[depth].winRanks[ss]=0; + } + return FALSE; + } + } + } else if (contract.trumpContract && (posPoint->winner[contract.trump].rank!=0) && + (nodeTypeStore[posPoint->winner[contract.trump].hand]==MINNODE)) { + if ((posPoint->length[hand][contract.trump]==0)&& + (posPoint->length[partner(hand)][contract.trump]==0)) { + if (((posPoint->tricksMAX+(depth>>2)+1- + Max(posPoint->length[lho(hand)][contract.trump], + posPoint->length[rho(hand)][contract.trump]))0)&&(depth!=iniDepth)) { + for (ss=0; ss<=3; ss++) { + posPoint->stack[depth].winRanks[ss]=0; + } + return FALSE; + } + } else if (((posPoint->tricksMAX+(depth>>2))0)&&(depth!=iniDepth)) { + for (ss=0; ss<=3; ss++) + posPoint->stack[depth].winRanks[ss]=0; + posPoint->stack[depth].winRanks[contract.trump]= + BitRank(posPoint->winner[contract.trump].rank); + return FALSE; + } else { + hh=posPoint->secondBest[contract.trump].hand; + if ((nodeTypeStore[hh]==MINNODE)&&(posPoint->secondBest[contract.trump].rank!=0)) { + if (((posPoint->length[hh][contract.trump]>1) || + (posPoint->length[partner(hh)][contract.trump]>1))&& + ((posPoint->tricksMAX+(depth>>2)-1)0)&&(depth!=iniDepth)) { + for (ss=0; ss<=3; ss++) + posPoint->stack[depth].winRanks[ss]=0; + posPoint->stack[depth].winRanks[contract.trump]= + BitRank(posPoint->winner[contract.trump].rank) | + BitRank(posPoint->secondBest[contract.trump].rank) ; + return FALSE; + } + } + } + } else if (contract.trumpContract) { + hh=posPoint->secondBest[contract.trump].hand; + if ((nodeTypeStore[hh]==MINNODE)&& + (posPoint->length[hh][contract.trump]>1)&& + (posPoint->winner[contract.trump].hand==rho(hh)) + &&(posPoint->secondBest[contract.trump].rank!=0)) { + if (((posPoint->tricksMAX+(depth>>2))0)&&(depth!=iniDepth)) { + for (ss=0; ss<=3; ss++) { + posPoint->stack[depth].winRanks[ss]=0; + } + posPoint->stack[depth].winRanks[contract.trump]= BitRank(posPoint->secondBest[contract.trump].rank) ; + return FALSE; + } + } + } + return TRUE; +} + + +int LaterTricksMAX(struct pos *posPoint, const int hand, const int depth, const int target) { + int hh, ss, sum=0; + const ContractInfo contract = Globals.getContract(); + + if ((!contract.trumpContract)||(posPoint->winner[contract.trump].rank==0)) { + for (ss=0; ss<=3; ss++) { + hh=posPoint->winner[ss].hand; + if (nodeTypeStore[hh]==MINNODE) + sum+=Max(posPoint->length[hh][ss], posPoint->length[partner(hh)][ss]); + } + if ((posPoint->tricksMAX+(depth>>2)+1-sum>=target)&& + (sum>0)&&(depth>0)&&(depth!=iniDepth)) { + if ((posPoint->tricksMAX+1>=target)) { + for (ss=0; ss<=3; ss++) { + if (nodeTypeStore[posPoint->winner[ss].hand]==MAXNODE) + posPoint->stack[depth].winRanks[ss]=BitRank(posPoint->winner[ss].rank); + else + posPoint->stack[depth].winRanks[ss]=0; + } + return TRUE; + } + } + } else if (contract.trumpContract && (posPoint->winner[contract.trump].rank!=0) && + (nodeTypeStore[posPoint->winner[contract.trump].hand]==MAXNODE)) { + if ((posPoint->length[hand][contract.trump]==0)&& + (posPoint->length[partner(hand)][contract.trump]==0)) { + if (((posPoint->tricksMAX+Max(posPoint->length[lho(hand)][contract.trump], + posPoint->length[rho(hand)][contract.trump]))>=target) + &&(depth>0)&&(depth!=iniDepth)) { + for (ss=0; ss<=3; ss++) + posPoint->stack[depth].winRanks[ss]=0; + return TRUE; + } + } else if (((posPoint->tricksMAX+1)>=target) &&(depth>0)&&(depth!=iniDepth)) { + for (ss=0; ss<=3; ss++) { + posPoint->stack[depth].winRanks[ss]=0; + } + posPoint->stack[depth].winRanks[contract.trump] = BitRank(posPoint->winner[contract.trump].rank); + return TRUE; + } + else { + hh=posPoint->secondBest[contract.trump].hand; + if ((nodeTypeStore[hh]==MAXNODE)&&(posPoint->secondBest[contract.trump].rank!=0)) { + if (((posPoint->length[hh][contract.trump]>1) || + (posPoint->length[partner(hh)][contract.trump]>1))&& + ((posPoint->tricksMAX+2)>=target)&&(depth>0)&&(depth!=iniDepth)) { + for (ss=0; ss<=3; ss++) { + posPoint->stack[depth].winRanks[ss]=0; + } + posPoint->stack[depth].winRanks[contract.trump]= + BitRank(posPoint->winner[contract.trump].rank) | + BitRank(posPoint->secondBest[contract.trump].rank) ; + return TRUE; + } + } + } + } else if (contract.trumpContract) { + hh=posPoint->secondBest[contract.trump].hand; + if ((nodeTypeStore[hh]==MAXNODE)&& + (posPoint->length[hh][contract.trump]>1)&&(posPoint->winner[contract.trump].hand==rho(hh)) + &&(posPoint->secondBest[contract.trump].rank!=0)) { + if (((posPoint->tricksMAX+1)>=target)&&(depth>0)&&(depth!=iniDepth)) { + for (ss=0; ss<=3; ss++) + posPoint->stack[depth].winRanks[ss]=0; + posPoint->stack[depth].winRanks[contract.trump]= + BitRank(posPoint->secondBest[contract.trump].rank) ; + return TRUE; + } + } + /*found=FALSE; + for (ss=0; ss<=3; ss++) { + if ((ss!=contract.trump)&&(posPoint->winner[ss].rank!=0)) { + hh=posPoint->winner[ss].hand; + if ((nodeTypeStore[hh]==MINNODE)|| + (posPoint->length[hand][ss]==0)|| + (posPoint->length[partner(hand)][ss]==0)) { + found=TRUE; + break; + } + } + } + if (!found) { + sum=Max(posPoint->length[hand][contract.trump], + posPoint->length[partner(hand)][contract.trump]); + if ((posPoint->tricksMAX+(depth>>2)+1-sum>=target)&& + (depth>0)&&(depth!=iniDepth)) { + if ((posPoint->tricksMAX+1>=target)&&(sum>0)) { + for (ss=0; ss<=3; ss++) { + if (ss!=contract.trump) { + if (nodeTypeStore[posPoint->winner[ss].hand]==MAXNODE) + posPoint->stack[depth].winRanks[ss]=BitRank(posPoint->winner[ss].rank); + else + posPoint->stack[depth].winRanks[ss]=0; + } + else + posPoint->stack[depth].winRanks[ss]=0; + } + return TRUE; + } + } + }*/ + } + return FALSE; +} + + +int recInd=0; + +int MoveGen(const struct pos * posPoint, const int depth) { + + int suit, k, m, n, r, s, t; + int scount[4]; + int WeightAlloc(const struct pos *, struct moveType * mp, int depth, + int notVoidInSuit,int q, int first); + + for (k=0; k<4; k++) + lowestWin[depth][k]=0; + + m=0; + r=posPoint->handRelFirst; + const int first=posPoint->stack[depth].first; + const int q=HandStore(first,r); + + s=movePly[depth+r].current; /* Current move of first hand */ + t=movePly[depth+r].move[s].suit; /* Suit played by first hand */ + const holding_t ris = posPoint->rankInSuit[q][t]; + + if ((r!=0)&&(ris!=0)) { + /* Not first hand and not void in suit */ + holding_t sequences; + holding_t unplayedCardsRank; + holding_t allCards, bitRank; + holding_t sequence = 0; + + unplayedCardsRank = + unplayedFinder.getUnplayed(q,t, + (holding_t)posPoint->removedRanks[t], + sequences); + allCards = unplayedCardsRank | sequences; + while (allCards) { + bitRank = smallestRankInSuit(allCards); + allCards ^= bitRank; + if (unplayedCardsRank & bitRank) { + movePly[depth].move[m].suit=t; + movePly[depth].move[m].rank=InvBitMapRank(bitRank); + movePly[depth].move[m].sequence= sequence; + sequence = 0; + m++; + } else { + sequence |= bitRank; + } + } + + if (m!=1) { + for (k=0; k<=m-1; k++) + movePly[depth].move[k].weight=WeightAlloc(posPoint, + &movePly[depth].move[k], depth, ris,q,first); + } + + movePly[depth].last=m-1; + if (m!=1) + InsertSort(m, depth); + if (depth!=iniDepth) + return m; + else { + m=AdjustMoveList(); + return m; + } + } else { /* First hand or void in suit */ + holding_t sequences; + holding_t unplayedCardsRank; + holding_t bitRank; + holding_t allCards; + holding_t sequence = 0; + for (suit=0; suit<=3; suit++) { + unplayedCardsRank = + unplayedFinder.getUnplayed(q,suit, + (holding_t)(posPoint->removedRanks[suit]), + sequences); + allCards = unplayedCardsRank | sequences; + while (allCards) { + bitRank = smallestRankInSuit(allCards); + allCards ^= bitRank; + if (unplayedCardsRank & bitRank) { + movePly[depth].move[m].suit=suit; + movePly[depth].move[m].rank=InvBitMapRank(bitRank); + movePly[depth].move[m].sequence=sequence; + sequence = 0; + m++; + } else { + sequence |= bitRank; + } + } + + } + + for (k=0; k<=m-1; k++) + movePly[depth].move[k].weight=WeightAlloc(posPoint, + &movePly[depth].move[k], depth, ris,q,first); + + movePly[depth].last=m-1; + InsertSort(m, depth); + if (r==0) { + for (n=0; n<=3; n++) + scount[n]=0; + for (k=0; k<=m-1; k++) { + if (scount[movePly[depth].move[k].suit]==2) + continue; + else { + movePly[depth].move[k].weight+=500; + scount[movePly[depth].move[k].suit]++; + } + } + InsertSort(m, depth); + } + else { + for (n=0; n<=3; n++) + scount[n]=0; + for (k=0; k<=m-1; k++) { + if (scount[movePly[depth].move[k].suit]==1) + continue; + else { + movePly[depth].move[k].weight+=500; + scount[movePly[depth].move[k].suit]++; + } + } + InsertSort(m, depth); + } + if (depth!=iniDepth) + return m; + else { + m=AdjustMoveList(); + return m; + } + } +} + + +int WeightAlloc(const struct pos * posPoint, struct moveType * mp, const int depth, const int notVoidInSuit,const int q, const int first) { + int weight=0, suitAdd=0, leadSuit; + holding_t k,l,kk,ll; + int suitWeightDelta; + int suitBonus=0; + int winMove=FALSE; + unsigned short suitCount, suitCountLH, suitCountRH; + int countLH, countRH; + const ContractInfo contract = Globals.getContract(); + + const int suit=mp->suit; + + if ((!notVoidInSuit)||(posPoint->handRelFirst==0)) { + suitCount=posPoint->length[q][suit]; + suitAdd=suitCount+suitCount; + } + + switch (posPoint->handRelFirst) { + case 0: + suitCountLH=posPoint->length[lho(q)][suit]; + suitCountRH=posPoint->length[rho(q)][suit]; + + if (contract.notTrumpWithTrump(suit) && + (((posPoint->rankInSuit[lho(q)][suit]==0) && + (posPoint->rankInSuit[lho(q)][contract.trump]!=0)) || + ((posPoint->rankInSuit[rho(q)][suit]==0) && + (posPoint->rankInSuit[rho(q)][contract.trump]!=0)))) + suitBonus=-12/*15*/; + + if (suitCountLH!=0) + countLH=(suitCountLH<<2); + else + countLH=depth+4; + if (suitCountRH!=0) + countRH=(suitCountRH<<2); + else + countRH=depth+4; + + suitWeightDelta=suitBonus-((countLH+countRH)<<1); + + if (posPoint->winner[suit].rank==mp->rank) { + if (contract.notTrumpWithTrump(suit)) { + if ((posPoint->length[partner(first)][suit]!=0)|| + (posPoint->length[partner(first)][contract.trump]==0)) { + if (((posPoint->length[lho(first)][suit]!=0)|| + (posPoint->length[lho(first)][contract.trump]==0))&& + ((posPoint->length[rho(first)][suit]!=0)|| + (posPoint->length[rho(first)][contract.trump]==0))) + winMove=TRUE; + } + else if (((posPoint->length[lho(first)][suit]!=0)|| + (posPoint->rankInSuit[partner(first)][contract.trump]> + posPoint->rankInSuit[lho(first)][contract.trump]))&& + ((posPoint->length[rho(first)][suit]!=0)|| + (posPoint->rankInSuit[partner(first)][contract.trump]> + posPoint->rankInSuit[rho(first)][contract.trump]))) + winMove=TRUE; + } + else + winMove=TRUE; + } + else if (posPoint->rankInSuit[partner(first)][suit] > + (posPoint->rankInSuit[lho(first)][suit] | + posPoint->rankInSuit[rho(first)][suit])) { + if (contract.notTrumpWithTrump(suit)) { + if (((posPoint->length[lho(first)][suit]!=0)|| + (posPoint->length[lho(first)][contract.trump]==0))&& + ((posPoint->length[rho(first)][suit]!=0)|| + (posPoint->length[rho(first)][contract.trump]==0))) + winMove=TRUE; + } + else + winMove=TRUE; + } + else if (contract.notTrumpWithTrump(suit)) { + if ((posPoint->length[partner(first)][suit]==0)&& + (posPoint->length[partner(first)][contract.trump]!=0)) { + if ((posPoint->length[lho(first)][suit]==0)&& + (posPoint->length[lho(first)][contract.trump]!=0)&& + (posPoint->length[rho(first)][suit]==0)&& + (posPoint->length[rho(first)][contract.trump]!=0)) { + if (posPoint->rankInSuit[partner(first)][contract.trump]> + (posPoint->rankInSuit[lho(first)][contract.trump] | + posPoint->rankInSuit[rho(first)][contract.trump])) + winMove=TRUE; + } + else if ((posPoint->length[lho(first)][suit]==0)&& + (posPoint->length[lho(first)][contract.trump]!=0)) { + if (posPoint->rankInSuit[partner(first)][contract.trump] + > posPoint->rankInSuit[lho(first)][contract.trump]) + winMove=TRUE; + } + else if ((posPoint->length[rho(first)][suit]==0)&& + (posPoint->length[rho(first)][contract.trump]!=0)) { + if (posPoint->rankInSuit[partner(first)][contract.trump] + > posPoint->rankInSuit[rho(first)][contract.trump]) + winMove=TRUE; + } + else + winMove=TRUE; + } + } + + if (winMove) { + if (((posPoint->winner[suit].hand==lho(first))&&(suitCountLH==1)) + ||((posPoint->winner[suit].hand==rho(first))&&(suitCountRH==1))) + weight=suitWeightDelta+40-(mp->rank); + else if (posPoint->winner[suit].hand==first) { + if (posPoint->secondBest[suit].hand==partner(first)) + weight=suitWeightDelta+50-(mp->rank); + else if (posPoint->winner[suit].rank==mp->rank) + weight=suitWeightDelta+31; + else + weight=suitWeightDelta+19-(mp->rank); + } + else if (posPoint->winner[suit].hand==partner(first)) { + /* If partner has winning card */ + if (posPoint->secondBest[suit].hand==first) + weight=suitWeightDelta+50-(mp->rank); + else + weight=suitWeightDelta+35-(mp->rank); + } + else if ((mp->sequence)&& + (mp->rank==posPoint->secondBest[suit].rank)) + weight=suitWeightDelta+40/*35*/-(mp->rank); + else + weight=suitWeightDelta+30-(mp->rank); + if ((bestMove[depth].suit==mp->suit)&& + (bestMove[depth].rank==mp->rank)) + weight+=50/*45*//*35*/; + } + else { + if (((posPoint->winner[suit].hand==lho(first))&&(suitCountLH==1)) + ||((posPoint->winner[suit].hand==rho(first))&&(suitCountRH==1))) + weight=suitWeightDelta+20-(mp->rank); + else if (posPoint->winner[suit].hand==first) { + if (posPoint->secondBest[suit].hand==partner(first)) + weight=suitWeightDelta+35-(mp->rank); + else if (posPoint->winner[suit].rank==mp->rank) + weight=suitWeightDelta+16; + else + weight=suitWeightDelta+4-(mp->rank); + } + else if (posPoint->winner[suit].hand==partner(first)) { + /* If partner has winning card */ + if (posPoint->secondBest[suit].hand==first) + weight=suitWeightDelta+35-(mp->rank); + else + weight=suitWeightDelta+20-(mp->rank); + } + else if ((mp->sequence)&& + (mp->rank==posPoint->secondBest[suit].rank)) + weight=suitWeightDelta+20-(mp->rank); + else + weight=suitWeightDelta+4-(mp->rank); + if ((bestMove[depth].suit==mp->suit)&& + (bestMove[depth].rank==mp->rank)) + weight+=30/*25*//*35*/; + } + + break; + + case 1: + leadSuit=posPoint->stack[depth+1].move.suit; + if (leadSuit==suit) { + if (BitRank(mp->rank)> + (BitRank(posPoint->stack[depth+1].move.rank) | + posPoint->rankInSuit[partner(first)][suit])) { + if (contract.notTrumpWithTrump(suit)) { + if ((posPoint->length[partner(first)][suit]!=0)|| + (posPoint->length[partner(first)][contract.trump]==0)) + winMove=TRUE; + else if ((posPoint->length[rho(first)][suit]==0) + &&(posPoint->length[rho(first)][contract.trump]!=0) + &&(posPoint->rankInSuit[rho(first)][contract.trump]> + posPoint->rankInSuit[partner(first)][contract.trump])) + winMove=TRUE; + } + else + winMove=TRUE; + } + else if (posPoint->rankInSuit[rho(first)][suit]> + (BitRank(posPoint->stack[depth+1].move.rank) | + posPoint->rankInSuit[partner(first)][suit])) { + if (contract.notTrumpWithTrump(suit)) { + if ((posPoint->length[partner(first)][suit]!=0)|| + (posPoint->length[partner(first)][contract.trump]==0)) { + winMove=TRUE; + } + } + else + winMove=TRUE; + } + else if (BitRank(posPoint->stack[depth+1].move.rank) > + (posPoint->rankInSuit[rho(first)][suit] | + posPoint->rankInSuit[partner(first)][suit] | + BitRank(mp->rank))) { + if (contract.notTrumpWithTrump(suit)) { + if ((posPoint->length[rho(first)][suit]==0)&& + (posPoint->length[rho(first)][contract.trump]!=0)) { + if ((posPoint->length[partner(first)][suit]!=0)|| + (posPoint->length[partner(first)][contract.trump]==0)) { + winMove=TRUE; + } else if (posPoint->rankInSuit[rho(first)][contract.trump] + > posPoint->rankInSuit[partner(first)][contract.trump]) { + winMove=TRUE; + } + } + } + } else { /* winnerHand is partner to first */ + if (contract.notTrumpWithTrump(suit)) { + if ((posPoint->length[rho(first)][suit]==0)&& + (posPoint->length[rho(first)][contract.trump]!=0)) + winMove=TRUE; + } + } + } + else { + /* Leading suit differs from suit played by LHO */ + if (contract.isTrump(suit)) { + if (posPoint->length[partner(first)][leadSuit]!=0) + winMove=TRUE; + else if (BitRank(mp->rank)> + posPoint->rankInSuit[partner(first)][contract.trump]) + winMove=TRUE; + else if ((posPoint->length[rho(first)][leadSuit]==0) + &&(posPoint->length[rho(first)][contract.trump]!=0)&& + (posPoint->rankInSuit[rho(first)][contract.trump] > + posPoint->rankInSuit[partner(first)][contract.trump])) + winMove=TRUE; + } + else if (contract.notTrumpWithTrump(leadSuit)) { + /* Neither suit nor leadSuit is trump */ + if (posPoint->length[partner(first)][leadSuit]!=0) { + if (posPoint->rankInSuit[rho(first)][leadSuit] > + (posPoint->rankInSuit[partner(first)][leadSuit] | + BitRank(posPoint->stack[depth+1].move.rank))) + winMove=TRUE; + else if ((posPoint->length[rho(first)][leadSuit]==0) + &&(posPoint->length[rho(first)][contract.trump]!=0)) + winMove=TRUE; + } + /* Partner to leading hand is void in leading suit */ + else if ((posPoint->length[rho(first)][leadSuit]==0) + &&(posPoint->rankInSuit[rho(first)][contract.trump]> + posPoint->rankInSuit[partner(first)][contract.trump])) + winMove=TRUE; + else if ((posPoint->length[partner(first)][contract.trump]==0) + &&(posPoint->rankInSuit[rho(first)][leadSuit] > + BitRank(posPoint->stack[depth+1].move.rank))) + winMove=TRUE; + } + else { + /* Either no trumps or leadSuit is trump, side with + highest rank in leadSuit wins */ + if (posPoint->rankInSuit[rho(first)][leadSuit] > + (posPoint->rankInSuit[partner(first)][leadSuit] | + BitRank(posPoint->stack[depth+1].move.rank))) + winMove=TRUE; + } + } + + kk=posPoint->rankInSuit[partner(first)][leadSuit]; + ll=posPoint->rankInSuit[rho(first)][leadSuit]; + k=kk & (-kk); l=ll & (-ll); /* Only least significant 1 bit */ + if (winMove) { + if (!notVoidInSuit) { + if (contract.isTrump(suit)) { + weight=30-(mp->rank)+suitAdd; + } else { + weight=60-(mp->rank)+suitAdd; /* Better discard than ruff since rho + wins anyway */ + } + } else if (k > BitRank(mp->rank)) { + weight=45-(mp->rank); /* If lowest card for partner to leading hand + is higher than lho played card, playing as low as + possible will give the cheapest win */ + } else if ((ll > BitRank(posPoint->stack[depth+1].move.rank))&& + (posPoint->rankInSuit[first][leadSuit] > ll)) { + weight=60-(mp->rank); /* If rho has a card in the leading suit that + is higher than the trick leading card but lower + than the highest rank of the leading hand, then + lho playing the lowest card will be the cheapest + win */ + } else if (mp->rank > posPoint->stack[depth+1].move.rank) { + if (BitRank(mp->rank) < ll) + weight=75-(mp->rank); /* If played card is lower than any of the cards of + rho, it will be the cheapest win */ + else if (BitRank(mp->rank) > kk) + weight=70-(mp->rank); /* If played card is higher than any cards at partner + of the leading hand, rho can play low, under the + condition that he has a lower card than lho played */ + else { + if (mp->sequence) + weight=60-(mp->rank); + else + weight=45-(mp->rank); + } + } + else if (posPoint->length[rho(first)][leadSuit]>0) { + if (mp->sequence) + weight=50-(mp->rank); /* Plyiang a card in a sequence may promote a winner */ + else + weight=45-(mp->rank); + } + else + weight=45-(mp->rank); + } + else { + if (!notVoidInSuit) { + if (contract.isTrump(suit)) { + /*if (ll > BitRank(posPoint->stack[depth+1].move.rank)) + weight=-10-(mp->rank)+suitAdd; + else*/ + weight=15-(mp->rank)+suitAdd; /* Ruffing is preferred, makes the trick + costly for the opponents */ + } + else + weight=-(mp->rank)+suitAdd; + } + else if ((k > BitRank(mp->rank))|| + (l > BitRank(mp->rank))) + weight=-(mp->rank); /* If lowest rank for either partner to leading hand + or rho is higher than played card for lho, + lho should play as low card as possible */ + else if (mp->rank > posPoint->stack[depth+1].move.rank) { + if (mp->sequence) + weight=20-(mp->rank); + else + weight=10-(mp->rank); + } + else + weight=-(mp->rank); + } + + break; + + case 2: + + leadSuit=posPoint->stack[depth+2].move.suit; + if (WinningMove(*mp, (posPoint->stack[depth+1].move))) { + if (suit==leadSuit) { + if (contract.notTrumpWithTrump(leadSuit)) { + if (((posPoint->length[rho(first)][suit]!=0)|| + (posPoint->length[rho(first)][contract.trump]==0))&& + (BitRank(mp->rank) > + posPoint->rankInSuit[rho(first)][suit])) + winMove=TRUE; + } + else if (BitRank(mp->rank) > + posPoint->rankInSuit[rho(first)][suit]) + winMove=TRUE; + } + else { /* Suit is trump */ + if (posPoint->length[rho(first)][leadSuit]==0) { + if (BitRank(mp->rank) > + posPoint->rankInSuit[rho(first)][contract.trump]) + winMove=TRUE; + } + else + winMove=TRUE; + } + } + else if (posPoint->stack[depth+1].high==first) { + if (posPoint->length[rho(first)][leadSuit]!=0) { + if (posPoint->rankInSuit[rho(first)][leadSuit] + < BitRank(posPoint->stack[depth+2].move.rank)) + winMove=TRUE; + } else if (!contract.trumpContract) { + winMove=TRUE; + } else if (contract.isTrump(leadSuit)) { + winMove=TRUE; + } else if (contract.notTrumpWithTrump(leadSuit) && + (posPoint->length[rho(first)][contract.trump]==0)) { + winMove=TRUE; + } + } + + if (winMove) { + if (!notVoidInSuit) { + if (posPoint->stack[depth+1].high==first) { + if (contract.isTrump(suit)) { + weight=30-(mp->rank)+suitAdd; /* Ruffs partner's winner */ + } else { + weight=60-(mp->rank)+suitAdd; + } + } else if (WinningMove(*mp, (posPoint->stack[depth+1].move))) { + /* Own hand on top by ruffing */ + weight=70-(mp->rank)+suitAdd; + } else if (contract.isTrump(suit)) { + /* Discard a trump but still losing */ + weight=15-(mp->rank)+suitAdd; + } else { + weight=30-(mp->rank)+suitAdd; + } + } else { + weight=60-(mp->rank); + } + } else { + if (!notVoidInSuit) { + if (WinningMove(*mp, (posPoint->stack[depth+1].move))) + /* Own hand on top by ruffing */ + weight=40-(mp->rank)+suitAdd; + else if (contract.isTrump(suit)) { + /* Discard a trump but still losing */ + weight=-15-(mp->rank)+suitAdd; + } else { + weight=-(mp->rank)+suitAdd; + } + } + else { + if (WinningMove(*mp, (posPoint->stack[depth+1].move))) { + if (mp->rank==posPoint->secondBest[leadSuit].rank) + weight=25/*35*/; + else if (mp->sequence) + weight=20/*30*/-(mp->rank); + else + weight=10/*20*/-(mp->rank); + } + else + weight=-10/*0*/-(mp->rank); + } + } + + break; + + case 3: + if (!notVoidInSuit) { + if ((posPoint->stack[depth+1].high)==lho(first)) { + /* If the current winning move is given by the partner */ + if (contract.isTrump(suit)) { + /* Ruffing partners winner? */ + weight=14-(mp->rank)+suitAdd; + } else { + weight=30-(mp->rank)+suitAdd; + } + } + else if (WinningMove(*mp, posPoint->stack[depth+1].move)) { + /* Own hand ruffs */ + weight=30-(mp->rank)+suitAdd; + } else if (suit==contract.trump) { + weight=-(mp->rank); + } else { + weight=14-(mp->rank)+suitAdd; + } + } + else if ((posPoint->stack[depth+1].high)==(lho(first))) { + /* If the current winning move is given by the partner */ + if (contract.isTrump(suit)) { + /* Ruffs partners winner */ + weight=24-(mp->rank); + } else { + weight=30-(mp->rank); + } + } else if (WinningMove(*mp, posPoint->stack[depth+1].move)) { + /* If present move is superior to current winning move and the + current winning move is not given by the partner */ + weight=30-(mp->rank); + } else { + /* If present move is not superior to current winning move and the + current winning move is not given by the partner */ + if (contract.isTrump(suit)) { + /* Ruffs but still loses */ + weight=-(mp->rank); + } else { + weight=14-(mp->rank); + } + } + } + return weight; +} + +/* Shell-1 */ +/* K&R page 62: */ +/*void shellSort(int n, int depth) { + int gap, i, j; + struct moveType temp; + + if (n==2) { + if (movePly[depth].move[0].weight>1; gap>0; gap>>=1) + for (i=gap; i=0 && movePly[depth].move[j].weight< + movePly[depth].move[j+gap].weight; j-=gap) { + temp=movePly[depth].move[j]; + movePly[depth].move[j]=movePly[depth].move[j+gap]; + movePly[depth].move[j+gap]=temp; + } +} */ + +/* Shell-2 */ +/*void shellSort(int n, int depth) +{ + int i, j, increment; + struct moveType temp; + + if (n==2) { + if (movePly[depth].move[0].weight 0) + { + for (i=0; i < n; i++) + { + j = i; + temp = movePly[depth].move[i]; + while ((j >= increment) && (movePly[depth].move[j-increment].weight < temp.weight)) + { + movePly[depth].move[j] = movePly[depth].move[j - increment]; + j = j - increment; + } + movePly[depth].move[j] = temp; + } + if ((increment>>1) != 0) + increment>>=1; + else if (increment == 1) + increment = 0; + else + increment = 1; + } +} */ + + +/* Insert-1 */ +void InsertSort(int n, int depth) { + int i, j; + struct moveType a, temp; + + if (n==2) { + if (movePly[depth].move[0].weighta.weight) { + temp=a; + a=movePly[depth].move[i]; + movePly[depth].move[i]=temp; + } + movePly[depth].move[0]=a; + for (i=2; i<=n-1; i++) { + j=i; + a=movePly[depth].move[i]; + while (a.weight>movePly[depth].move[j-1].weight) { + movePly[depth].move[j]=movePly[depth].move[j-1]; + j--; + } + movePly[depth].move[j]=a; + } +} + +/* Insert-2 */ +/*void InsertSort(int n, int depth) { + int i, j; + struct moveType a; + + if (n==2) { + if (movePly[depth].move[0].weight=0)&&(movePly[depth].move[i].weightlbound==-1) { /* This bound values for + this leading hand has not yet been determined */ + *result=FALSE; + return nodep; + } + else if ((posPoint->tricksMAX + nodep->lbound)>=target) { + *value=TRUE; + *result=TRUE; + return nodep; + } + else if ((posPoint->tricksMAX + nodep->ubound)ubound==-1) { /* This bound values for + this leading hand has not yet been determined */ + *result=FALSE; + return nodep; + } + else if ((posPoint->tricksMAX + (tricks + 1 - nodep->ubound))>=target) { + *value=TRUE; + *result=TRUE; + return nodep; + } + else if ((posPoint->tricksMAX + (tricks + 1 - nodep->lbound))lbound > nodep->lbound) || + (nodep->lbound==-1)) + nodep->lbound=posPoint->lbound; + if ((posPoint->ubound < nodep->ubound) || + (nodep->ubound==-1)) + nodep->ubound=posPoint->ubound; + + nodep->bestMoveSuit=posPoint->bestMoveSuit; + nodep->bestMoveRank=posPoint->bestMoveRank; + + return nodep; +} + + +struct nodeCardsType * FindSOP(struct pos * posPoint, + struct winCardType * nodeP, int firstHand, + int target, int tricks, int * valp) { + struct nodeCardsType * sopP; + struct winCardType * np; + int s; + + np=nodeP; s=0; + while ((np!=NULL)&&(s<4)) { + if ((np->winMask & posPoint->orderSet[s])== + np->orderSet) { + /* Winning rank set fits position */ + if (s==3) { + sopP=CheckSOP(posPoint, np->first, target, tricks, &res, &val); + *valp=val; + if (res) { + return sopP; + } + else { + if (np->next!=NULL) { + np=np->next; + } + else { + np=np->prevWin; + s--; + if (np==NULL) + return NULL; + while (np->next==NULL) { + np=np->prevWin; + s--; + if (np==NULL) /* Previous node is header node? */ + return NULL; + } + np=np->next; + } + } + } + else if (s<4) { + np=np->nextWin; + s++; + } + } + else { + if (np->next!=NULL) { + np=np->next; + } + else { + np=np->prevWin; + s--; + if (np==NULL) + return NULL; + while (np->next==NULL) { + np=np->prevWin; + s--; + if (np==NULL) /* Previous node is header node? */ + return NULL; + } + np=np->next; + } + } + } + return NULL; +} + + +struct nodeCardsType * BuildPath(struct pos * posPoint, + struct posSearchType *nodep, int * result) { + /* If result is TRUE, a new SOP has been created and BuildPath returns a + pointer to it. If result is FALSE, an existing SOP is used and BuildPath + returns a pointer to the SOP */ + + int found, suit; + struct winCardType * np, * p2, * nprev, * fnp, *pnp; + struct winCardType temp; + struct nodeCardsType * sopP=0, * p; + + np=nodep->posSearchPoint; + nprev=NULL; + suit=0; + + /* If winning node has a card that equals the next winning card deduced + from the position, then there already exists a (partial) path */ + + if (np==NULL) { /* There is no winning list created yet */ + /* Create winning nodes */ + p2=&winCards[winSetSize]; + AddWinSet(); + p2->next=NULL; + p2->nextWin=NULL; + p2->prevWin=NULL; + nodep->posSearchPoint=p2; + p2->winMask=posPoint->winMask[suit]; + p2->orderSet=posPoint->winOrderSet[suit]; + p2->first=NULL; + np=p2; /* Latest winning node */ + suit++; + while (suit<4) { + p2=&winCards[winSetSize]; + AddWinSet(); + np->nextWin=p2; + p2->prevWin=np; + p2->next=NULL; + p2->nextWin=NULL; + p2->winMask=posPoint->winMask[suit]; + p2->orderSet=posPoint->winOrderSet[suit]; + p2->first=NULL; + np=p2; /* Latest winning node */ + suit++; + } + p=&nodeCards[nodeSetSize]; + AddNodeSet(); + np->first=p; + *result=TRUE; + return p; + } + else { /* Winning list exists */ + while (1) { /* Find all winning nodes that correspond to current + position */ + found=FALSE; + while (1) { /* Find node amongst alternatives */ + if ((np->winMask==posPoint->winMask[suit])&& + (np->orderSet==posPoint->winOrderSet[suit])) { + /* Part of path found */ + found=TRUE; + nprev=np; + break; + } + if (np->next!=NULL) + np=np->next; + else + break; + } + if (found) { + suit++; + if (suit>3) { + sopP=UpdateSOP(posPoint, np->first); + + if (np->prevWin!=NULL) { + pnp=np->prevWin; + fnp=pnp->nextWin; + } + else + fnp=nodep->posSearchPoint; + + temp.orderSet=np->orderSet; + temp.winMask=np->winMask; + temp.first=np->first; + temp.nextWin=np->nextWin; + np->orderSet=fnp->orderSet; + np->winMask=fnp->winMask; + np->first=fnp->first; + np->nextWin=fnp->nextWin; + fnp->orderSet=temp.orderSet; + fnp->winMask=temp.winMask; + fnp->first=temp.first; + fnp->nextWin=temp.nextWin; + + *result=FALSE; + return sopP; + } + else { + np=np->nextWin; /* Find next winning node */ + continue; + } + } + else + break; /* Node was not found */ + } /* End outer while */ + + /* Create additional node, coupled to existing node(s) */ + p2=&winCards[winSetSize]; + AddWinSet(); + /*np->next=p2;*/ + p2->prevWin=nprev; + if (nprev!=NULL) { + p2->next=nprev->nextWin; + nprev->nextWin=p2; + } + else { + p2->next=nodep->posSearchPoint; + nodep->posSearchPoint=p2; + } + p2->nextWin=NULL; + /*p2->next=NULL;*/ + p2->winMask=posPoint->winMask[suit]; + p2->orderSet=posPoint->winOrderSet[suit]; + p2->first=NULL; + np=p2; /* Latest winning node */ + suit++; + + /* Rest of path must be created */ + while (suit<4) { + p2=&winCards[winSetSize]; + AddWinSet();/*winSetSize++;*/ + np->nextWin=p2; + p2->prevWin=np; + p2->next=NULL; + p2->winMask=posPoint->winMask[suit]; + p2->orderSet=posPoint->winOrderSet[suit]; + p2->first=NULL; + p2->nextWin=NULL; + np=p2; /* Latest winning node */ + suit++; + } + + /* All winning nodes for SOP have been traversed and new created */ + p=&nodeCards[nodeSetSize]; + AddNodeSet(); + np->first=p; + *result=TRUE; + return p; + } +} + + +struct posSearchType * SearchLenAndInsert(struct posSearchType + * rootp, LONGLONG key, int insertNode, int *result) { +/* Search for node which matches with the suit length combination + given by parameter key. If no such node is found, NULL is + returned if parameter insertNode is FALSE, otherwise a new + node is inserted with suitLengths set to key, the pointer to + this node is returned. + The algorithm used is defined in Knuth "The art of computer + programming", vol.3 "Sorting and searching", 6.2.2 Algorithm T, + page 424. */ + + struct posSearchType *np, *p; + + np=rootp; + while (1) { + if (key==np->suitLengths) { + *result=TRUE; + return np; + } + else if (key < np->suitLengths) { + if (np->left!=NULL) + np=np->left; + else if (insertNode) { + p=&posSearch[lenSetSize]; + AddLenSet();/*lenSetSize++;*/ + np->left=p; + p->posSearchPoint=NULL; + p->suitLengths=key; + p->left=NULL; p->right=NULL; + *result=TRUE; + return p; + } + else { + *result=FALSE; + return NULL; + } + } + else { /* key > suitLengths */ + if (np->right!=NULL) + np=np->right; + else if (insertNode) { + p=&posSearch[lenSetSize]; + AddLenSet();/*lenSetSize++;*/ + np->right=p; + p->posSearchPoint=NULL; + p->suitLengths=key; + p->left=NULL; p->right=NULL; + *result=TRUE; + return p; + } + else { + *result=FALSE; + return NULL; + } + } + } +} + +/* New algo */ + +void BuildSOP(struct pos * posPoint, int tricks, int firstHand, int target, + const int depth, int scoreFlag, int score) { + int ss, hh, res, wm; + unsigned short int w; + holding_t temp[4][4]; + holding_t aggr[4]; + struct nodeCardsType * cardsP; + struct posSearchType * np; + + for (ss=0; ss<=3; ss++) { + w=posPoint->stack[depth].winRanks[ss]; + if (w==0) { + posPoint->winMask[ss]=0; + posPoint->winOrderSet[ss]=0; + posPoint->leastWin[ss]=0; + for (hh=0; hh<=3; hh++) + temp[hh][ss]=0; + } + else { + w=smallestRankInSuit(w); /* Only lowest win */ + for (hh=0; hh<=3; hh++) { + temp[hh][ss]=posPoint->rankInSuit[hh][ss] & (-w); + } + + aggr[ss]=0; + for (hh=0; hh<=3; hh++) { + aggr[ss]=aggr[ss] | temp[hh][ss]; + } + + posPoint->winMask[ss]=rel(ss,aggr[ss]).winMask; + posPoint->winOrderSet[ss]=rel(ss,aggr[ss]).aggrRanks; + wm=posPoint->winMask[ss]; + wm=smallestRankInSuit(wm); + posPoint->leastWin[ss]=InvWinMask(wm); + } + } + + /* 07-04-22 */ + if (scoreFlag) { + if (nodeTypeStore[0]==MAXNODE) { + posPoint->ubound=tricks+1; + posPoint->lbound=target-posPoint->tricksMAX; + } + else { + posPoint->ubound=tricks+1-target+posPoint->tricksMAX; + posPoint->lbound=0; + } + } + else { + if (nodeTypeStore[0]==MAXNODE) { + posPoint->ubound=target-posPoint->tricksMAX-1; + posPoint->lbound=0; + } + else { + posPoint->ubound=tricks+1; + posPoint->lbound=tricks+1-target+posPoint->tricksMAX+1; + } + } + + posPoint->getSuitLengths(suitLengths); + + np=SearchLenAndInsert(rootnp[tricks][firstHand], suitLengths, TRUE, &res); + + cardsP=BuildPath(posPoint, np, &res); + if (res) { + cardsP->ubound=posPoint->ubound; + cardsP->lbound=posPoint->lbound; + if (((nodeTypeStore[firstHand]==MAXNODE)&&(scoreFlag))|| + ((nodeTypeStore[firstHand]==MINNODE)&&(!scoreFlag))) { + cardsP->bestMoveSuit=bestMove[depth].suit; + cardsP->bestMoveRank=bestMove[depth].rank; + } + else { + cardsP->bestMoveSuit=0; + cardsP->bestMoveRank=0; + } + posPoint->bestMoveSuit=bestMove[depth].suit; + posPoint->bestMoveRank=bestMove[depth].rank; + for (ss=0; ss<=3; ss++) + cardsP->leastWin[ss]=posPoint->leastWin[ss]; + } + + #ifdef STAT + c9[depth]++; + #endif + + #ifdef TTDEBUG + if ((res) && (ttCollect) && (!suppressTTlog)) { + fprintf(fp7, "cardsP=%d\n", (int)cardsP); + fprintf(fp7, "nodeSetSize=%d\n", nodeSetSize); + fprintf(fp7, "ubound=%d\n", cardsP->ubound); + fprintf(fp7, "lbound=%d\n", cardsP->lbound); + fprintf(fp7, "target=%d\n", target); + fprintf(fp7, "first=%c nextFirst=%c\n", + cardHand[posPoint->stack[depth].first], cardHand[posPoint->stack[depth-1].first]); + fprintf(fp7, "bestMove: suit=%c rank=%c\n", cardSuit[bestMove.suit], + cardRank[bestMove[depth].rank]); + fprintf(fp7, "\n"); + fprintf(fp7, "Last trick:\n"); + fprintf(fp7, "1st hand=%c\n", cardHand[posPoint-]); + for (k=3; k>=0; k--) { + mcurrent=movePly[depth+k+1].current; + fprintf(fp7, "suit=%c rank=%c\n", + cardSuit[movePly[depth+k+1].move[mcurrent].suit], + cardRank[movePly[depth+k+1].move[mcurrent].rank]); + } + fprintf(fp7, "\n"); + for (hh=0; hh<=3; hh++) { + fprintf(fp7, "hand=%c\n", cardHand[hh]); + for (ss=0; ss<=3; ss++) { + fprintf(fp7, "suit=%c", cardSuit[ss]); + for (rr=14; rr>=2; rr--) + if (posPoint->rankInSuit[hh][ss] & BitRank(rr)) + fprintf(fp7, " %c", cardRank[rr]); + fprintf(fp7, "\n"); + } + fprintf(fp7, "\n"); + } + fprintf(fp7, "\n"); + + for (hh=0; hh<=3; hh++) { + fprintf(fp7, "hand=%c\n", cardHand[hh]); + for (ss=0; ss<=3; ss++) { + fprintf(fp7, "suit=%c", cardSuit[ss]); + for (rr=1; rr<=13; rr++) + if (posPoint->relRankInSuit[hh][ss] & BitRank(15-rr)) + fprintf(fp7, " %c", cardRank[rr]); + fprintf(fp7, "\n"); + } + fprintf(fp7, "\n"); + } + fprintf(fp7, "\n"); + } + #endif +} + + +int CheckDeal(struct moveType * cardp) { + int h, s, k, found; + holding_t temp[4][4]; + + for (h=0; h<=3; h++) + for (s=0; s<=3; s++) + temp[h][s]=game.suit[h][s]; + + /* Check that all ranks appear only once within the same suit. */ + for (s=0; s<=3; s++) + for (k=2; k<=14; k++) { + found=FALSE; + for (h=0; h<=3; h++) { + if ((temp[h][s] & BitRank(k))!=0) { + if (found) { + cardp->suit=s; + cardp->rank=k; + return 1; + } + else + found=TRUE; + } + } + } + + return 0; +} + + +/* New algo */ + +void WinAdapt(struct pos * posPoint, const int depth, const struct nodeCardsType * cp, + holding_t aggr[]) { + int ss, rr, k; + + for (ss=0; ss<=3; ss++) { + posPoint->stack[depth].winRanks[ss]=0; + if (cp->leastWin[ss]==0) + continue; + k=1; + for (rr=14; rr>=2; rr--) { + if ((aggr[ss] & BitRank(rr))!=0) { + if (k<=cp->leastWin[ss]) { + posPoint->stack[depth].winRanks[ss]|=BitRank(rr); + k++; + } + else + break; + } + } + } + return; +} + + +int DismissX(struct pos *posPoint, const int depth) { + int mcurrent; + holding_t lw; + struct moveType currMove; + + mcurrent=movePly[depth].current; + currMove=movePly[depth].move[mcurrent]; + + if (lowestWin[depth][currMove.suit]==0) { + lw=posPoint->stack[depth].winRanks[currMove.suit]; + if (lw!=0) { + lw=smallestRankInSuit(lw); /* LSB */ + } else { + lw=BitRank(15); + } + if (BitRank(currMove.rank)= + lowestWin[depth][movePly[depth].move[mcurrent].suit]) + return TRUE; + } + return FALSE; + } + else if (movePly[depth].current<=movePly[depth].last-1) { + movePly[depth].current++; + return TRUE; + } + else + return FALSE; + } + else { + while (movePly[depth].current<=movePly[depth].last-1) { + movePly[depth].current++; + mcurrent=movePly[depth].current; + if (BitRank(movePly[depth].move[mcurrent].rank) >= + lowestWin[depth][movePly[depth].move[mcurrent].suit]) + return TRUE; + } + return FALSE; + } +} + + +int DumpInput(int errCode, struct deal dl, int target, + int solutions, int mode) { + + FILE *fp; + int i, j, k; + + fp=fopen("dump.txt", "w"); + if (fp==NULL) + return -1; + fprintf(fp, "Error code=%d\n", errCode); + fprintf(fp, "\n"); + fprintf(fp, "Deal data:\n"); + fprintf(fp, "trump=%d\n", dl.trump); + fprintf(fp, "first=%d\n", dl.trump); + for (k=0; k<=2; k++) + fprintf(fp, "index=%d currentTrickSuit=%d currentTrickRank=%d\n", + k, dl.currentTrickSuit[k], dl.currentTrickRank[k]); + for (i=0; i<=3; i++) + for (j=0; j<=3; j++) + fprintf(fp, "index1=%d index2=%d remainCards=%d\n", + i, j, dl.remainCards[i][j]); + fprintf(fp, "\n"); + fprintf(fp, "target=%d\n", target); + fprintf(fp, "solutions=%d\n", solutions); + fprintf(fp, "mode=%d\n", mode); + fclose(fp); + return 0; +} + + +void Wipe(void) { + int k; + + for (k=1; k<=wcount; k++) { + if (pw[k]) + free(pw[k]); + pw[k]=NULL; + } + for (k=1; k<=ncount; k++) { + if (pn[k]) + free(pn[k]); + pn[k]=NULL; + } + for (k=1; k<=lcount; k++) { + if (pl[k]) + free(pl[k]); + pl[k]=NULL; + } + + allocmem=summem/*(WINIT+1)*sizeof(struct winCardType)+ + (NINIT+1)*sizeof(struct nodeCardsType)+ + (LINIT+1)*sizeof(struct posSearchType)*/; + + return; +} + + +void AddWinSet(void) { + if (clearTTflag) { + windex++; + winSetSize=windex; + /*fp2=fopen("dyn.txt", "a"); + fprintf(fp2, "windex=%d\n", windex); + fclose(fp2);*/ + winCards=&temp_win[windex]; + } + else if (winSetSize>=winSetSizeLimit) { + /* The memory chunk for the winCards structure will be exceeded. */ + if ((allocmem+wmem)>maxmem) { + /* Already allocated memory plus needed allocation overshot maxmem */ + windex++; + winSetSize=windex; + /*fp2=fopen("dyn.txt", "a"); + fprintf(fp2, "windex=%d\n", windex); + fclose(fp2);*/ + clearTTflag=TRUE; + winCards=&temp_win[windex]; + } + else { + wcount++; winSetSizeLimit=WSIZE; + pw[wcount] = (struct winCardType *)calloc(winSetSizeLimit+1, sizeof(struct winCardType)); + if (pw[wcount]==NULL) { + clearTTflag=TRUE; + windex++; + winSetSize=windex; + winCards=&temp_win[windex]; + } + else { + allocmem+=(winSetSizeLimit+1)*sizeof(struct winCardType); + winSetSize=0; + winCards=pw[wcount]; + } + } + } + else + winSetSize++; + return; +} + +void AddNodeSet(void) { + if (nodeSetSize>=nodeSetSizeLimit) { + /* The memory chunk for the nodeCards structure will be exceeded. */ + if ((allocmem+nmem)>maxmem) { + /* Already allocated memory plus needed allocation overshot maxmem */ + clearTTflag=TRUE; + } + else { + ncount++; nodeSetSizeLimit=NSIZE; + pn[ncount] = (struct nodeCardsType *)calloc(nodeSetSizeLimit+1, sizeof(struct nodeCardsType)); + if (pn[ncount]==NULL) { + clearTTflag=TRUE; + } + else { + allocmem+=(nodeSetSizeLimit+1)*sizeof(struct nodeCardsType); + nodeSetSize=0; + nodeCards=pn[ncount]; + } + } + } + else + nodeSetSize++; + return; +} + +void AddLenSet(void) { + if (lenSetSize>=lenSetSizeLimit) { + /* The memory chunk for the nodeCards structure will be exceeded. */ + if ((allocmem+lmem)>maxmem) { + /* Already allocated memory plus needed allocation overshot maxmem */ + clearTTflag=TRUE; + } + else { + lcount++; lenSetSizeLimit=LSIZE; + pl[lcount] = (struct posSearchType *)calloc(lenSetSizeLimit+1, sizeof(struct posSearchType)); + if (pl[lcount]==NULL) { + clearTTflag=TRUE; + } + else { + allocmem+=(lenSetSizeLimit+1)*sizeof(struct posSearchType); + lenSetSize=0; + posSearch=pl[lcount]; + } + } + } + else + lenSetSize++; + return; +} + +#ifdef TTDEBUG + +void ReceiveTTstore(struct pos *posPoint, struct nodeCardsType * cardsP, + int target, int depth) { +/* Stores current position information and TT position value in table + ttStore with current entry lastTTStore. Also stores corresponding + information in log rectt.txt. */ + tricksLeft=0; + for (hh=0; hh<=3; hh++) + for (ss=0; ss<=3; ss++) + tricksLeft=tricksLeft+posPoint->length[hh][ss]; + tricksLeft=tricksLeft/4; + ttStore[lastTTstore].tricksLeft=tricksLeft; + ttStore[lastTTstore].cardsP=cardsP; + ttStore[lastTTstore].first=posPoint->stack[depth].first; + if ((handToPlay==posPoint->stack[depth].first)|| + (handToPlay==partner(posPoint->stack[depth].first))) { + ttStore[lastTTstore].target=target-posPoint->tricksMAX; + ttStore[lastTTstore].ubound=cardsP->ubound[handToPlay]; + ttStore[lastTTstore].lbound=cardsP->lbound[handToPlay]; + } + else { + ttStore[lastTTstore].target=tricksLeft- + target+posPoint->tricksMAX+1; + } + for (hh=0; hh<=3; hh++) + for (ss=0; ss<=3; ss++) + ttStore[lastTTstore].suit[hh][ss]= + posPoint->rankInSuit[hh][ss]; + fp11=fopen("rectt.txt", "a"); + if (lastTTstoretricksMAX); + fprintf(fp11, "leftTricks=%d\n", + ttStore[lastTTstore].tricksLeft); + fprintf(fp11, "cardsP=%d\n", + ttStore[lastTTstore].cardsP); + fprintf(fp11, "ubound=%d\n", + ttStore[lastTTstore].ubound); + fprintf(fp11, "lbound=%d\n", + ttStore[lastTTstore].lbound); + fprintf(fp11, "first=%c\n", + cardHand[ttStore[lastTTstore].first]); + fprintf(fp11, "target=%d\n", + ttStore[lastTTstore].target); + fprintf(fp11, "\n"); + for (hh=0; hh<=3; hh++) { + fprintf(fp11, "hand=%c\n", cardHand[hh]); + for (ss=0; ss<=3; ss++) { + fprintf(fp11, "suit=%c", cardSuit[ss]); + for (rr=14; rr>=2; rr--) + if (ttStore[lastTTstore].suit[hh][ss] + & BitRank(rr)) + fprintf(fp11, " %c", cardRank[rr]); + fprintf(fp11, "\n"); + } + fprintf(fp11, "\n"); + } + for (hh=0; hh<=3; hh++) { + fprintf(fp11, "hand=%c\n", cardHand[hh]); + for (ss=0; ss<=3; ss++) { + fprintf(fp11, "suit=%c", cardSuit[ss]); + for (rr=1; rr<=13; rr++) + if (posPoint->relRankInSuit[hh][ss] & BitRank(15-rr)) + fprintf(fp11, " %c", cardRank[rr]); + fprintf(fp11, "\n"); + } + fprintf(fp11, "\n"); + } + } + fclose(fp11); + lastTTstore++; +} +#endif + + + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/dds.h /tmp/sFHmVEdqkv/deal-3.1.4/dds.h --- deal-3.0.8/dds.h 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/dds.h 2008-06-09 01:55:38.000000000 +0530 @@ -0,0 +1,574 @@ +/* portability-macros header prefix */ +#ifdef __cplusplus +#include +using namespace std; +#endif + +#include "ddsInterface.h" +#include "Holding.h" + +#define LONGLONG long long + +/* end of portability-macros section */ + +/*#define BENCH*/ + +#include +#include +#include +#include + +/*#define STAT*/ /* Define STAT to generate a statistics log, stat.txt */ +/*#define TTDEBUG*/ /* Define TTDEBUG to generate transposition table debug information */ +/*#define CANCEL*/ /* Define CANCEL to get support for cancelling ongoing search */ + +#ifdef TTDEBUG +#define SEARCHSIZE 20000 +#else +#define SEARCHSIZE 1 +#endif + +#define CANCELCHECK 200000 + +#if defined(INFINITY) +# undef INFINITY +#endif +#define INFINITY 32000 + +#define MAXNODE 1 +#define MINNODE 0 + +#define TRUE 1 +#define FALSE 0 + +#define MOVESVALID 1 +#define MOVESLOCKED 2 + +#define NSIZE 100000 +#define WSIZE 100000 +#define LSIZE 20000 +#define NINIT 2*250000/*400000*/ +#define WINIT 2*700000/*1000000*/ +#define LINIT 2*50000 + +#define Max(x, y) (((x) >= (y)) ? (x) : (y)) +#define Min(x, y) (((x) <= (y)) ? (x) : (y)) + + +inline int partner(int hand) { + return (hand^2); /* slightly faster */ +} + +inline int lho(int hand) { + return (hand+1)&3; +} + +inline int rho(int hand) { + return (hand+3)&3; +} + +struct gameInfo { /* All info of a particular deal */ + int vulnerable; + int declarer; + int contract; + int leadHand; + int leadSuit; + int leadRank; + int first; + int noOfCards; + holding_t suit[4][4]; + /* 1st index is hand id, 2nd index is suit id */ +}; + +struct dealType { + holding_t deal[4][4]; +}; + +struct moveType { + unsigned char suit; + unsigned char rank; + holding_t sequence; /* Whether or not this move is + the first in a sequence */ + short int weight; /* Weight used at sorting */ + + inline moveType() { + suit=0; + rank=0; + sequence=0; + weight=0; + } +}; + +struct movePlyType { + struct moveType move[14]; + int current; + int last; +}; + +struct highCardType { + int rank; + int hand; +}; + +struct makeType { + holding_t winRanks[4]; +}; + +//static const holding_t bitMapRank[] = { 0, 0, 0x1, 0x2,0x4,0x8,0x10,0x20,0x40,0x80,0x100,0x200,0x400,0x800,0x1000,0x2000,0x4000 }; + +inline holding_t BitRank(int rank) { + /* + * Trick calculation + * Equivalent to 1<<(rank-2) for rank>=2, and 0 for rank<2. + */ + return (1<>2; +} + +struct posStackItem { + int first; /* Hand that leads the trick for each ply*/ + int high; /* Hand that is presently winning the trick */ + struct moveType move; /* Presently winning move */ + holding_t winRanks[4]; /* Cards that win by rank, + indices are depth and suit */ +#if 0 + holding_t removed[4]; + + inline void initializeRemoved(const posStackItem &prev) { + for (int suit=0; suit<4; suit++) { + removed[suit] = prev.removed[suit]; + } + } + + inline void removeCard(const moveType &aMove) { + removed[aMove.suit] |= BitRank(aMove.rank); + } + + inline int isRemoved(int suit,int rank) const { + return removed[suit] & BitRank(rank); + } +#endif + +}; + +struct pos { + struct posStackItem stack[50]; + holding_t rankInSuit[4][4]; /* 1st index is hand, 2nd index is + suit id */ + int orderSet[4]; + int winOrderSet[4]; + int winMask[4]; + int leastWin[4]; + holding_t removedRanks[4]; /* Ranks removed from board, + index is suit */ + unsigned char length[4][4]; + char ubound; + char lbound; + char bestMoveSuit; + char bestMoveRank; + int handRelFirst; /* The current hand, relative first hand */ + int tricksMAX; /* Aggregated tricks won by MAX */ + struct highCardType winner[4]; /* Winning rank of the trick, + index is suit id. */ + struct highCardType secondBest[4]; /* Second best rank, index is suit id. */ + + inline void removeBitRank(int suit,holding_t bitRank) { + removedRanks[suit] |= bitRank; + } + + inline void removeRank(int suit,int rank) { + removeBitRank(suit,BitRank(rank)); + } + + inline void restoreBitRank(int suit, holding_t bitRank) { + removedRanks[suit] &= (~bitRank); + } + + inline void restoreRank(int suit,int rank) { + restoreBitRank(suit,BitRank(rank)); + } + + inline int isRemovedBitRank(int suit, holding_t bitRank) const { + return (removedRanks[suit] & bitRank); + } + + inline int isRemoved(int suit, int rank) const { + return isRemovedBitRank(suit,BitRank(rank)); + } + + inline int hasCardBitRank(int hand, int suit, holding_t bitRank) const { + return (rankInSuit[hand][suit] & bitRank); + } + + inline int hasCard(int hand,int suit, int rank) const { + return hasCardBitRank(hand,suit,BitRank(rank)); + } + + inline void getSuitLengths(LONGLONG &lengths,int relHand = 0) const { + int hand, suit; + lengths = 0; + for (suit=0; suit<=2; suit++) { + for (hand=0; hand<=3; hand++) { + lengths = lengths << 4; + lengths |= length[(relHand+hand)%4][suit]; + } + } + } + +#if 0 + inline void removeCard(int depth,const moveType &move) { + stack[depth].removeCard(move); + } + + inline int isRemoved(int depth, int suit,int rank) const { + return stack[depth].isRemoved(suit,rank); + } +#endif + +}; + +struct posSearchType { + struct winCardType * posSearchPoint; + LONGLONG suitLengths; + struct posSearchType * left; + struct posSearchType * right; +}; + + +struct nodeCardsType { + char ubound; /* ubound and + lbound for the N-S side */ + char lbound; + char bestMoveSuit; + char bestMoveRank; + char leastWin[4]; +}; + +struct winCardType { + int orderSet; + int winMask; + struct nodeCardsType * first; + struct winCardType * prevWin; + struct winCardType * nextWin; + struct winCardType * next; +}; + + +struct evalType { + int tricks; + unsigned short int winRanks[4]; +}; + +struct relRanksType { + int aggrRanks; + int winMask; +}; + +class RelativeRanksFinder { + protected: + struct { + relRanksType suits[4]; + } relative[8192]; + + holding_t originalsBySuitFirst[4][4]; + + public: + inline RelativeRanksFinder() { + for (int suit=0; suit<4; suit++) { + for (int hand=0; hand<4; hand++) { + originalsBySuitFirst[suit][hand]=0; + } + } + } + + inline const struct relRanksType &operator ()(int suit,holding_t index) const { + return relative[index&8191].suits[suit]; + } + + inline void initialize(const struct gameInfo &game) { + int newDiagram = 0; + int hand, suit; + + for (suit=0; suit<4; suit++) { + for (hand=0; hand<4; hand++) { + if (game.suit[hand][suit] != originalsBySuitFirst[suit][hand]) { + newDiagram = 1; + } + originalsBySuitFirst[suit][hand]=game.suit[hand][suit]; + } + } + + if (newDiagram) { + holding_t topBitRank = 1; + for (int suit=0; suit<4; suit++) { + relative[0].suits[suit].aggrRanks = 0; + relative[0].suits[suit].winMask = 0; + } + + for (int ind=1; ind<8192; ind++) { + if (ind&(topBitRank<<1)) { + topBitRank <<= 1; + } + compute(ind, topBitRank); + } + } + } + +protected: + inline void compute(const holding_t ind,const holding_t topBitRank) { + int hand, suit; + + relative[ind] = relative[ind^topBitRank]; + + for (suit=0; suit<=3; suit++) { + struct relRanksType &relRanks = relative[ind].suits[suit]; + + for (hand=0; hand<=3; hand++) { + if (originalsBySuitFirst[suit][hand] & topBitRank) { + relRanks.aggrRanks = (relRanks.aggrRanks >> 2) | (hand << 24); + relRanks.winMask = (relRanks.winMask >> 2) | (3 << 24); + break; + } + } + } + } + +}; + + +struct ttStoreType { + struct nodeCardsType * cardsP; + char tricksLeft; + char target; + char ubound; + char lbound; + unsigned char first; + unsigned short int suit[4][4]; +}; + +struct ContractInfo { + const static int nextSuitArray[4][4]; + int trumpContract; + int trump; + int _firstSuit; + const int *_nextSuit; + + + inline void initialize(int trumpContract,int trump) { + this->trumpContract = trumpContract; + this->trump = trump; + if (!trumpContract ) { + _firstSuit = 0; + _nextSuit = nextSuitArray[0]; + } else { + _firstSuit = trump; + _nextSuit = nextSuitArray[trump]; + } + + } + + inline ContractInfo() { + initialize(0,-1); + } + + inline ContractInfo(const ContractInfo &contract) { + trumpContract = contract.trumpContract; + trump = contract.trump; + _firstSuit = contract._firstSuit; + _nextSuit = contract._nextSuit; + } + + inline int isTrump(int suit) const { + return (trumpContract && (trump==suit)); + } + + inline int notTrumpWithTrump(int suit) const { + return (trumpContract && (trump!=suit)); + } + + inline int firstSuit() const { + return _firstSuit; + } + + inline int nextSuit(int suit) const { + return _nextSuit[suit]; + } + + inline int betterMove(const struct moveType &nextMove,const struct moveType &bestMove) const { + if (bestMove.suit==nextMove.suit) { + if (nextMove.rank>bestMove.rank) { + return TRUE; + } else { + return FALSE; + } + } else if (isTrump(nextMove.suit)) { + return TRUE; + } else { + return FALSE; + } + } + +#if 0 + inline int nextSuit(int suit) const { + if (isTrump(suit)) { + return firstNonTrumpSuit(suit); + } else { + return nextNonTrumpSuit(suit); + } + } + + inline int firstSuit() const { + if (trumpContract) { + return trump; + } else { + return 0; + } + } + + inline int firstNonTrumpSuit(int suit) const { + if (trump==0) { + return 1; + } else { + return 0; + } + } + + inline int nextNonTrumpSuit(int suit) const { + suit++; + if (isTrump(suit)) { + suit++; + } + return suit; + } +#endif + +}; + +struct GLOBALS { +protected: +public: + ContractInfo _contract; + RelativeRanksFinder rel; + + inline void setContract(int trump=-1) { + _contract.initialize(trump>=0 && trump<=3,trump); + } + + inline const ContractInfo &getContract() const { + return _contract; + } + +}; + +extern struct gameInfo game; +extern struct gameInfo * gameStore; +extern struct ttStoreType * ttStore; +extern struct nodeCardsType * nodeCards; +extern struct winCardType * winCards; +extern struct pos position, iniPosition, lookAheadPos; +/* extern struct moveType move[13]; */ +extern struct movePlyType movePly[50]; +extern struct posSearchType * posSearch; +extern struct searchType searchData; +extern struct moveType forbiddenMoves[14]; /* Initial depth moves that will be + excluded from the search */ +extern struct moveType initialMoves[4]; +extern struct moveType highMove; +extern struct moveType * bestMove; +extern const RelativeRanksFinder &rel; +extern struct winCardType **pw; +extern struct nodeCardsType **pn; +extern struct posSearchType **pl; + +extern holding_t iniRemovedRanks[4]; +extern holding_t relRankInSuit[4][4]; +extern int sum; +extern int score1Counts[50], score0Counts[50]; +extern int c1[50], c2[50], c3[50], c4[50], c5[50], c6[50], c7[50], + c8[50], c9[50]; +extern int nodeTypeStore[4]; /* Look-up table for determining if + node is MAXNODE or MINNODE */ +#if 0 +extern int lho[4], rho[4], partner[4]; +#endif +extern int nodes; /* Number of nodes searched */ +extern int no[50]; /* Number of nodes searched on each + depth level */ +extern int payOff; +extern int iniDepth; +extern int treeDepth; +extern int tricksTarget; /* No of tricks for MAX in order to + meet the game goal, e.g. to make the + contract */ +extern int tricksTargetOpp; /* Target no of tricks for MAX + opponent */ +extern int targetNS; +extern int targetEW; +extern int handToPlay; +extern int nodeSetSize; +extern int winSetSize; +extern int lenSetSize; +extern int lastTTstore; +extern int searchTraceFlag; +extern int countMax; +extern int depthCount; +extern int highHand; +extern int nodeSetSizeLimit; +extern int winSetSizeLimit; +extern int lenSetSizeLimit; +extern int estTricks[4]; +extern int recInd; +extern int suppressTTlog; +extern unsigned char suitChar[4]; +extern unsigned char rankChar[15]; +extern unsigned char handChar[4]; +extern int cancelOrdered; +extern int cancelStarted; +extern int threshold; +extern unsigned char cardRank[15], cardSuit[5], cardHand[4]; + +extern FILE * fp2, *fp7, *fp11; + /* Pointers to logs */ + +void InitStart(void); +void InitGame(int gameNo, int moveTreeFlag, int first, int handRelFirst); +void InitSearch(struct pos * posPoint, int depth, + struct moveType startMoves[], int first, int mtd); +int ABsearch(struct pos * posPoint, int target, int depth); +struct makeType Make(struct pos * posPoint, int depth); +int MoveGen(const struct pos * posPoint, int depth); +void InsertSort(int n, int depth); +void UpdateWinner(struct pos * posPoint, int suit); +void UpdateSecondBest(struct pos * posPoint, int suit); +inline int WinningMove(const struct moveType &mvp1,const struct moveType &mvp2); +inline unsigned short int CountOnes(unsigned short int b); +int AdjustMoveList(void); +int QuickTricks(struct pos * posPoint, int hand, + int depth, int target, int *result); +int LaterTricksMIN(struct pos *posPoint, int hand, int depth, int target); +int LaterTricksMAX(struct pos *posPoint, int hand, int depth, int target); +struct nodeCardsType * CheckSOP(struct pos * posPoint, struct nodeCardsType + * nodep, int target, int tricks, int * result, int *value); +struct nodeCardsType * UpdateSOP(struct pos * posPoint, struct nodeCardsType + * nodep); +struct nodeCardsType * FindSOP(struct pos * posPoint, + struct winCardType * nodeP, int firstHand, + int target, int tricks, int * valp); +struct nodeCardsType * BuildPath(struct pos * posPoint, + struct posSearchType *nodep, int * result); +void BuildSOP(struct pos * posPoint, int tricks, int firstHand, int target, + int depth, int scoreFlag, int score); +struct posSearchType * SearchLenAndInsert(struct posSearchType + * rootp, LONGLONG key, int insertNode, int *result); +void Undo(struct pos * posPoint, int depth); +int CheckDeal(struct moveType * cardp); +void WinAdapt(struct pos * posPoint, int depth, const struct nodeCardsType * cp, + holding_t aggr[]); +inline int InvBitMapRank(holding_t bitMap); +int InvWinMask(int mask); +void ReceiveTTstore(struct pos *posPoint, struct nodeCardsType * cardsP, int target, int depth); +int DismissX(struct pos *posPoint, int depth); +int DumpInput(int errCode, struct deal dl, int target, int solutions, int mode); +void Wipe(void); +void AddNodeSet(void); +void AddLenSet(void); +void AddWinSet(void); diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/ddsInterface.h /tmp/sFHmVEdqkv/deal-3.1.4/ddsInterface.h --- deal-3.0.8/ddsInterface.h 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/ddsInterface.h 2008-05-22 06:43:53.000000000 +0530 @@ -0,0 +1,59 @@ +/* + * Broken out from dds.h + * This file is the essential external "C" face to the dds.cpp file + */ +#ifndef __DDSINTERFACE_H__ +#define __DDSINTERFACE_H__ + +#if 0 +#define BENCH +#endif + +#if defined(_WIN32) +# define DLLEXPORT __declspec(dllexport) +# define STDCALL __stdcall +#else +# define DLLEXPORT +# define STDCALL +# define INT8 char +#endif + +#ifdef __cplusplus +# define EXTERN_C extern "C" +#else +# define EXTERN_C +#endif + +typedef unsigned int holding_t; + + +struct deal { + int trump; + int first; + int currentTrickSuit[3]; + int currentTrickRank[3]; + unsigned int remainCards[4][4]; +}; + +struct futureTricks { + int nodes; +#ifdef BENCH + int totalNodes; +#endif + int cards; + int suit[13]; + int rank[13]; + int equals[13]; + int score[13]; +}; + +#include + +EXTERN_C int SolveBoard(struct deal dl, + int target, int solutions, int mode, struct futureTricks *futp); + +EXTERN_C void DDSInitStart(); + +EXTERN_C holding_t distinctUnplayedCards(holding_t origHolding, holding_t played,holding_t *sequence); +#endif + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/deal.c /tmp/sFHmVEdqkv/deal-3.1.4/deal.c --- deal-3.0.8/deal.c 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/deal.c 2008-05-15 05:49:24.000000000 +0530 @@ -190,7 +190,7 @@ #if USE_RAND48 return dealt+(int) (drand48() *(double)(52-dealt)); #else - return dealt+(int) (fast_mod((unsigned) random() , (52-dealt))); + return dealt+(int) (fast_mod(random() , (52-dealt))); #endif } diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/deal.h /tmp/sFHmVEdqkv/deal-3.1.4/deal.h --- deal-3.0.8/deal.h 2001-02-19 23:20:16.000000000 +0530 +++ deal-3.1.4/deal.h 2008-05-15 05:49:24.000000000 +0530 @@ -45,7 +45,7 @@ extern char suits[]; extern char cards[]; -extern const int counttable[]; +extern const unsigned short int counttable[]; /* These exist for backward compatibility, and are @@ -82,6 +82,7 @@ int Vector_Init PROTO((Tcl_Interp *)); int HandCmd_Init PROTO((Tcl_Interp *)); int DealControl_Init PROTO((Tcl_Interp *)); +int DDS_Init PROTO((Tcl_Interp *)); int count_controls PROTO((int /* holding */, void */* dummy */)); int count_hcp PROTO((int /* holding */, void */* dummy */)); diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/deal.tcl /tmp/sFHmVEdqkv/deal-3.1.4/deal.tcl --- deal-3.0.8/deal.tcl 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/deal.tcl 2008-06-11 02:18:21.000000000 +0530 @@ -3,6 +3,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: deal.tcl,v 1.14 2008/06/10 20:48:21 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -17,103 +19,15 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -source /usr/share/deal/format/default - -namespace eval deal { - - variable metadata - # - # Put data in the cache, to be unset at next call - # to deal_deck - # - proc metadata {name code} { - variable metadata - if {![info exists metadata($name)]} { - if {[catch {set metadata($name) [uplevel $code]}]} { - global errorInfo - puts stderr "Error: $errorInfo" - } else { - deal_reset_cmds [list unset ::deal::metadata($name)] - } - } - return $metadata($name) - } - - proc loop {} { - next - write - } - - proc input {format args} { - uplevel #0 [list source "/usr/share/deal/input/$format.tcl" ] - set command [list "${format}::set_input"] - foreach arg $args { - lappend command $arg - } - uplevel #0 $command - } - proc debug {args} { - puts stderr $args - } +# Mac default value for tcl_library +#set tcl_library /System/Library/Frameworks/Tcl.framework/Versions/8.4/Resources/Scripts - # Cause an error if any hand stacking has occured - proc nostacking {} { - set format [uplevel {namespace current}] - proc ::stack_hand {args} \ - "error \"No hand stacking with input format $format\"" - proc ::stack_cards {args} \ - "error \"No card stacking with input format $format\"" - foreach hand {south north east west} { - foreach holding [stacked $hand] { - if {[holding length $holding]!=0} { - error "Stacking cards is not consistent with input format $format" - } - } - } - } +# Windows default value for tcl_library +if {[string first "Windows" $tcl_platform(os)]>=0} { + set tcl_library C:/tcl/lib/tcl8.5 } -# These two routines used to be defined in C, but it's better for them -# to fit the pattern of shape functions. - -shapecond balanced {($h<5)&&($s<5)&&($s*$s+$h*$h+$d*$d+$c*$c)<=47} -shapecond semibalanced {$h<=5&&$s<=5&&$d<=6&&$c<=6&&$c>=2&&$d>=2&&$h>=2&&$s>=2} -shapecond AnyShape {1} - -# -# The three routines, joinclass, negateclass, intersectclass, used to be -# implemented in C, but were never documented and recently crashed Deal 3.0.x -# when called. I've reimplemented them here in pure Tcl. -# -proc joinclass {newclass args} { - set values [list 0] - foreach class $args { - lappend values "\[$class eval \$s \$h \$d \$c\]" - } - - shapecond ___tempclass [join $values "||"] - - # make sure it is compiled first - use temporary name - # in case we are re-using an old name for a class - ___tempclass eval 13 0 0 0 - rename ___tempclass $newclass -} - -proc negateclass {newclass class} { - shapecond ___tempclass "!\[$class eval \$s \$h \$d \$c\]" - ___tempclass eval 13 0 0 0 - rename ___tempclass $newclass -} - -proc intersectclass {newclass args} { - - set values [list 1] - foreach class $args { - lappend values "\[$class eval \$s \$h \$d \$c\]" - } - shapecond ___tempclass [join $values "&&"] - ___tempclass eval 13 0 0 0 - rename ___tempclass $newclass -} +catch { deal_init_tcl } +source lib/features.tcl diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/dealtypes.c /tmp/sFHmVEdqkv/deal-3.1.4/dealtypes.c --- deal-3.0.8/dealtypes.c 2001-02-19 22:41:34.000000000 +0530 +++ deal-3.1.4/dealtypes.c 2008-05-31 00:52:54.000000000 +0530 @@ -182,6 +182,12 @@ char *cardCursor=cards; int hnum=0,spots=0; int cardnum=0; + if (*string == '-' && string[1]==0) { + holding->internalRep.longValue = 0; + holding->typePtr = &HoldingType; + return TCL_OK; + } + while (*cardCursor && *string) { if (*cardCursor==toupper(*string)) { hnum |= (1<<(12-cardnum)); @@ -342,6 +348,7 @@ Keyword_addKey("hearts"); Keyword_addKey("diamonds"); Keyword_addKey("clubs"); + Keyword_addKey("notrump"); northId=Keyword_addKey("north"); Keyword_addKey("east"); Keyword_addKey("south"); @@ -362,6 +369,17 @@ } +int getDenomNumFromObj(Tcl_Interp *interp, Tcl_Obj *denom) { + int denomNum; + if (denom->typePtr!=&KeywordType) { + int res=Tcl_ConvertToType(interp,denom,&KeywordType); + if (res!=TCL_OK) { return NOSUIT; } + } + denomNum=(int)denom->internalRep.longValue-spadeId; + if (denomNum>=0 && denomNum<=4) { return denomNum; } + return -1; +} + int getSuitNumFromObj(Tcl_Interp *interp, Tcl_Obj *suit) { int suitNum; if (suit->typePtr!=&KeywordType) { diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/dealtypes.h /tmp/sFHmVEdqkv/deal-3.1.4/dealtypes.h --- deal-3.0.8/dealtypes.h 2001-02-19 22:41:40.000000000 +0530 +++ deal-3.1.4/dealtypes.h 2008-05-15 05:49:24.000000000 +0530 @@ -30,6 +30,7 @@ Tcl_Obj *getLengthObj(int i); int getSuitNumFromObj(Tcl_Interp *interp, Tcl_Obj *suit); +int getDenomNumFromObj(Tcl_Interp *interp, Tcl_Obj *suit); int getCardNumFromObj(Tcl_Interp *interp, Tcl_Obj *card); int getHoldingNumFromObj(Tcl_Interp *interp, Tcl_Obj *card); Tcl_Obj *Tcl_NewHoldingObj(int holding); diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/debian/changelog /tmp/sFHmVEdqkv/deal-3.1.4/debian/changelog --- deal-3.0.8/debian/changelog 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/debian/changelog 2008-08-04 15:31:44.000000000 +0530 @@ -1,3 +1,21 @@ +deal (3.1.4-1ubuntu1) intrepid; urgency=low + + * Merge from debian unstable, remaining changes (LP: #254593) + - debian/control: Bump standards version to 3.8.0 with changes to +the homepage field. + + -- Bhavani Shankar Mon, 04 Aug 2008 15:20:28 +0530 + +deal (3.1.4-1) unstable; urgency=low + + * New upstream release. (Closes: #488598) + Thanks to Travis Crump for spotting, the watch file didn't notice. + * Update upstream website location in control and watch files. + * Use libdds.a instead of the shipped dds.cpp copy. + * Convert to quilt (except for an overzealous clean target in the Makefile). + + -- Christoph Berg Sun, 06 Jul 2008 00:57:45 +0200 + deal (3.0.8-4ubuntu1) feisty; urgency=low * Rebuild for ldbl128 change (powerpc, sparc). diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/debian/control /tmp/sFHmVEdqkv/deal-3.1.4/debian/control --- deal-3.0.8/debian/control 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/debian/control 2008-08-04 15:31:44.000000000 +0530 @@ -4,7 +4,8 @@ Maintainer: Ubuntu MOTU Developers XSBC-Original-Maintainer: Christoph Berg Build-Depends: debhelper (>= 4.0.0), tcl8.4-dev -Standards-Version: 3.7.2 +Standards-Version: 3.8.0 +Homepage: http://bridge.thomasoandrews.com/deal/ Package: deal Architecture: any @@ -15,5 +16,4 @@ or other user-definable properties. Hands can be output in various formats, like pbn for feeding to other bridge programs, deal itself, or split up into a file per player for practise. Extensible via Tcl. - . - http://thomaso.best.vwh.net/bridge/deal/ + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/debian/dirs /tmp/sFHmVEdqkv/deal-3.1.4/debian/dirs --- deal-3.0.8/debian/dirs 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/debian/dirs 2008-08-04 15:31:44.000000000 +0530 @@ -1,5 +1,5 @@ usr/games -usr/share/doc/deal/graphics +usr/share/doc/deal/html/graphics usr/share/doc/deal/html/ex usr/share/deal/input usr/share/deal/format diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/debian/patches/absolute-paths /tmp/sFHmVEdqkv/deal-3.1.4/debian/patches/absolute-paths --- deal-3.0.8/debian/patches/absolute-paths 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/debian/patches/absolute-paths 2008-08-04 15:31:44.000000000 +0530 @@ -0,0 +1,187 @@ +--- a/deal.tcl ++++ b/deal.tcl +@@ -30,4 +30,4 @@ if {[string first "Windows" $tcl_platfor + + catch { deal_init_tcl } + +-source lib/features.tcl ++source /usr/share/deal/lib/features.tcl +--- a/tcl_deal.c ++++ b/tcl_deal.c +@@ -453,7 +453,7 @@ DEAL31_API int *Deal_Init(Tcl_Interp *in + + Tcl_CreateObjCommand(interp,"deal_init_tcl",tcl_init,NULL,NULL); + +- result=Tcl_VarEval(interp,"source deal.tcl",NULL); ++ result=Tcl_VarEval(interp,"source /usr/share/deal/deal.tcl",NULL); + if (result==TCL_ERROR) { + tcl_error(interp); + } +--- a/input/smartstack.tcl ++++ b/input/smartstack.tcl +@@ -17,7 +17,7 @@ + # along with this program; if not, write to the Free Software + # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + # +-source lib/handFactory.tcl ++source /usr/share/deal/lib/handFactory.tcl + + namespace eval smartstack { + +--- a/input/giblib.tcl ++++ b/input/giblib.tcl +@@ -17,7 +17,7 @@ + # along with this program; if not, write to the Free Software + # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + # +-source lib/gib.tcl ++source /usr/share/deal/lib/gib.tcl + + # + # The giblib implements the ability to read files of the +--- a/lib/ddeval.tcl ++++ b/lib/ddeval.tcl +@@ -18,7 +18,7 @@ + # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + # + +-source lib/handProc.tcl ++source /usr/share/deal/lib/handProc.tcl + + namespace eval ddeval { + variable ddData +--- a/lib/binky.tcl ++++ b/lib/binky.tcl +@@ -18,7 +18,7 @@ + # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + # + +-source lib/handProc.tcl ++source /usr/share/deal/lib/handProc.tcl + + namespace eval binky { + variable binkyData +--- a/lib/parscore.tcl ++++ b/lib/parscore.tcl +@@ -18,7 +18,7 @@ + # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + # + +-source lib/score.tcl ++source /usr/share/deal/lib/score.tcl + + proc rlist {A B C D} {list $D $C $B $A} + +--- a/format/gibpar ++++ b/format/gibpar +@@ -1 +1 @@ +-source format/par ++source /usr/share/deal/format/par +--- a/format/par ++++ b/format/par +@@ -17,7 +17,7 @@ + # along with this program; if not, write to the Free Software + # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + # +-source lib/parscore.tcl ++source /usr/share/deal/lib/parscore.tcl + + namespace eval par { + +--- a/format/parArticle ++++ b/format/parArticle +@@ -20,7 +20,7 @@ + # along with this program; if not, write to the Free Software + # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + # +-source lib/parscore.tcl ++source /usr/share/deal/lib/parscore.tcl + + set particle(num) 0 + set particle(dealer) [list north east south west] +--- a/ex/3nt-nostack.tcl ++++ b/ex/3nt-nostack.tcl +@@ -13,7 +13,7 @@ + # This is slower than the smart-stacking version by an order of magnitude + # when requesting 1000 deals. + # +-source format/none ++source /usr/share/deal/format/none + + south is "AK K52 98765 962" + +--- a/ex/3nt-stack.tcl ++++ b/ex/3nt-stack.tcl +@@ -13,7 +13,7 @@ + # + # Obviously, they shouldn't be exactly the same, but they should be similar. + +-source format/none ++source /usr/share/deal/format/none + + source ex/3nt-common.tcl + +--- a/html/ex/3nt-nostack.txt ++++ b/html/ex/3nt-nostack.txt +@@ -13,7 +13,7 @@ + # This is slower than the smart-stacking version by an order of magnitude + # when requesting 1000 deals. + # +-source format/none ++source /usr/share/deal/format/none + + south is "AK K52 98765 962" + +--- a/html/ex/3nt-stack.txt ++++ b/html/ex/3nt-stack.txt +@@ -13,7 +13,7 @@ + # + # Obviously, they shouldn't be exactly the same, but they should be similar. + +-source format/none ++source /usr/share/deal/format/none + + shapecond gam3NT.shape {$s<=3&&$h<=3&&(($d>=7&&$c<=4)||($c>=7&&$d<=4))} + +--- a/lib/features.tcl ++++ b/lib/features.tcl +@@ -55,7 +55,7 @@ namespace eval deal { + + + proc input {format args} { +- uplevel #0 [list source "input/$format.tcl" ] ++ uplevel #0 [list source "/usr/share/deal/input/$format.tcl" ] + set command [list "${format}::set_input"] + foreach arg $args { + lappend command $arg +@@ -93,7 +93,7 @@ if {[string equal [info commands dds_res + shapecond balanced {($h<5)&&($s<5)&&($s*$s+$h*$h+$d*$d+$c*$c)<=47} + shapecond semibalanced {$h<=5&&$s<=5&&$d<=6&&$c<=6&&$c>=2&&$d>=2&&$h>=2&&$s>=2} + shapecond AnyShape {1} +-source format/default ++source /usr/share/deal/format/default + + # + # The three routines, joinclass, negateclass, intersectclass, used to be +--- a/ex/7.tcl ++++ b/ex/7.tcl +@@ -8,7 +8,7 @@ + # to define opening bids and later check to see if a hand + # fits the conditions + +-source lib/bid.tcl ++source /usr/share/deal/lib/bid.tcl + + defvector AKQ 4 3 2 + defvector Top4 1 1 1 1 +--- a/html/ex/7.txt ++++ b/html/ex/7.txt +@@ -8,7 +8,7 @@ + # to define opening bids and later check to see if a hand + # fits the conditions + +-source lib/bid.tcl ++source /usr/share/deal/lib/bid.tcl + + defvector AKQ 4 3 2 + defvector Top4 1 1 1 1 diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/debian/patches/libdds-dev /tmp/sFHmVEdqkv/deal-3.1.4/debian/patches/libdds-dev --- deal-3.0.8/debian/patches/libdds-dev 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/debian/patches/libdds-dev 2008-08-04 15:31:44.000000000 +0530 @@ -0,0 +1,34 @@ +--- a/Makefile ++++ b/Makefile +@@ -27,7 +27,7 @@ TCL_INCL=/usr/include/tcl + TCL_LIB=$(TCL_DIR)/lib + + ###### +-LDFLAGS= -L$(TCL_LIB) -ltcl -lm ++LDFLAGS= -L$(TCL_LIB) -ltcl -lm -ldds + + + +@@ -54,11 +54,11 @@ EXTRA_OBJS= + + COMPILE.c= $(CC) $(CFLAGS) -c + +-CFLAGS+= $(DEBUG_FLAGS) -I$(TCL_INCL) $(EXTRA_CFLAGS) ++CFLAGS+= $(DEBUG_FLAGS) -I$(TCL_INCL) $(EXTRA_CFLAGS) -DDDSInitStart=InitStart + + + OBJS=random.o additive.o hand.o deal.o formats.o tcl_deal.o maindeal.o stat.o counttable.o \ +- vector.o dist.o stringbox.o dealtypes.o keywords.o holdings.o tcl_dds.o dds.o $(EXTRA_OBJS) ++ vector.o dist.o stringbox.o dealtypes.o keywords.o holdings.o tcl_dds.o $(EXTRA_OBJS) + SRCS=additive.c hand.c deal.c formats.c tcl_deal.c dist.c vector.c stat.c counttable.c stringbox.c dealtypes.c holdings.c keywords.c maindeal.c random.c dds.cpp + SRCKIT=additive.c hand.c deal.c formats.c tcl_deal.c dist.c vector.c stat.c makecounttable.c stringbox.c dealtypes.c holdings.c keywords.c maindeal.c random.c tcl_dds.c dds.cpp + HFILES=deck.h deal.h tcl_incl.h vector.h stat.h tcl_dist.h dist.h formats.h additive.h stringbox.h dealtypes.h holdings.h keywords.h ansidecl.h dds.h ddsInterface.h Holding.h +@@ -74,7 +74,7 @@ UUKIT=$(EXAMPLES) $(OTHERFILES) deal + BINARY=./deal + + deal: $(OBJS) +- g++ $(CFLAGS) $(OBJS) -o deal $(LDFLAGS) ++ gcc $(CFLAGS) $(OBJS) -o deal $(LDFLAGS) + + universal: + $(MAKE) clean diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/debian/patches/seed-getpid /tmp/sFHmVEdqkv/deal-3.1.4/debian/patches/seed-getpid --- deal-3.0.8/debian/patches/seed-getpid 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/debian/patches/seed-getpid 2008-08-04 15:31:44.000000000 +0530 @@ -0,0 +1,25 @@ +deal (3.0.8-4) unstable; urgency=low + + * Xor the seed with getpid() to make deals more random. + + -- Christoph Berg Wed, 30 Aug 2006 01:37:28 +0200 + +--- a/tcl_deal.c ++++ b/tcl_deal.c +@@ -24,6 +24,8 @@ + #include + #include + #include ++#include ++#include + + #include "deal.h" + #include "vector.h" +@@ -483,6 +485,7 @@ int old_main(argc,argv) + extern char *optarg; + + time(&for_seeding); ++ for_seeding ^= getpid(); + #ifdef USE_RAND48 + srand48(for_seeding); + #else diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/debian/patches/series /tmp/sFHmVEdqkv/deal-3.1.4/debian/patches/series --- deal-3.0.8/debian/patches/series 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/debian/patches/series 2008-08-04 15:31:44.000000000 +0530 @@ -0,0 +1,4 @@ +libdds-dev +absolute-paths +seed-getpid +unsigned-random diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/debian/patches/unsigned-random /tmp/sFHmVEdqkv/deal-3.1.4/debian/patches/unsigned-random --- deal-3.0.8/debian/patches/unsigned-random 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/debian/patches/unsigned-random 2008-08-04 15:31:44.000000000 +0530 @@ -0,0 +1,18 @@ +deal (3.0.8-4) unstable; urgency=low + + * Fix segfault on amd64, (int)random() sometimes returned negative numbers + (Closes: #383625). + + -- Christoph Berg Wed, 30 Aug 2006 01:37:28 +0200 + +--- deal-3.1.4.orig/deal.c ++++ deal-3.1.4/deal.c +@@ -190,7 +190,7 @@ + #if USE_RAND48 + return dealt+(int) (drand48() *(double)(52-dealt)); + #else +- return dealt+(int) (fast_mod(random() , (52-dealt))); ++ return dealt+(int) (fast_mod((unsigned) random() , (52-dealt))); + #endif + } + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/debian/README.source /tmp/sFHmVEdqkv/deal-3.1.4/debian/README.source --- deal-3.0.8/debian/README.source 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/debian/README.source 2008-08-04 15:31:44.000000000 +0530 @@ -0,0 +1,57 @@ +This package uses quilt to manage all modifications to the upstream +source. Changes are stored in the source package as diffs in +debian/patches and applied during the build. + +To configure quilt to use debian/patches instead of patches, you want +either to export QUILT_PATCHES=debian/patches in your environment +or use this snippet in your ~/.quiltrc: + + for where in ./ ../ ../../ ../../../ ../../../../ ../../../../../; do + if [ -e ${where}debian/rules -a -d ${where}debian/patches ]; then + export QUILT_PATCHES=debian/patches + fi + done + +To get the fully patched source after unpacking the source package, cd to +the root level of the source package and run: + + quilt push -a + +The last patch listed in debian/patches/series will become the current +patch. + +To add a new set of changes, first run quilt push -a, and then run: + + quilt new + +where is a descriptive name for the patch, used as the filename in +debian/patches. Then, for every file that will be modified by this patch, +run: + + quilt add + +before editing those files. You must tell quilt with quilt add what files +will be part of the patch before making changes or quilt will not work +properly. After editing the files, run: + + quilt refresh + +to save the results as a patch. + +Alternately, if you already have an external patch and you just want to +add it to the build system, run quilt push -a and then: + + quilt import -P /path/to/patch + quilt push -a + +(add -p 0 to quilt import if needed). as above is the filename to +use in debian/patches. The last quilt push -a will apply the patch to +make sure it works properly. + +To remove an existing patch from the list of patches that will be applied, +run: + + quilt delete + +You may need to run quilt pop -a to unapply patches first before running +this command. diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/debian/rules /tmp/sFHmVEdqkv/deal-3.1.4/debian/rules --- deal-3.0.8/debian/rules 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/debian/rules 2008-08-04 15:31:44.000000000 +0530 @@ -1,35 +1,24 @@ #!/usr/bin/make -f -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 +include /usr/share/quilt/quilt.make D = $(CURDIR)/debian/deal -ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) - CFLAGS += -O0 -else - CFLAGS += -O2 -endif - configure: configure-stamp configure-stamp: dh_testdir - # prevent counttable.c from being remade - touch counttable.c touch configure-stamp build: build-stamp -build-stamp: configure-stamp +build-stamp: configure-stamp $(QUILT_STAMPFN) dh_testdir CFLAGS="$(CFLAGS)" $(MAKE) touch build-stamp -clean: +clean: unpatch dh_testdir - dh_testroot - rm -f build-stamp configure-stamp - -$(MAKE) clean - dh_clean + $(MAKE) clean + dh_clean makecounttable counttable.c build-stamp configure-stamp install: build dh_testdir @@ -41,21 +30,14 @@ install -m 644 input/* $D/usr/share/deal/input install -m 644 format/* $D/usr/share/deal/format install -m 644 lib/* $D/usr/share/deal/lib + + install -m 644 html/*.* $D/usr/share/doc/deal/html + install -m 644 html/graphics/* $D/usr/share/doc/deal/html/graphics + install -m 644 html/ex/* $D/usr/share/doc/deal/html/ex - install -m 644 docs/html/*.* $D/usr/share/doc/deal/html - rm $D/usr/share/doc/deal/html/CHANGES.txt - rm $D/usr/share/doc/deal/html/favicon.ico - install -m 644 docs/graphics/* $D/usr/share/doc/deal/graphics - install -m 644 docs/html/ex/* $D/usr/share/doc/deal/html/ex - -# Build architecture-independent files here. -binary-indep: build install -# We have nothing to do by default. +binary-indep: -# Build architecture-dependent files here. binary-arch: build install - dh_testdir - dh_testroot dh_installchangelogs CHANGES dh_installdocs dh_installman debian/deal.6 diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/debian/watch /tmp/sFHmVEdqkv/deal-3.1.4/debian/watch --- deal-3.0.8/debian/watch 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/debian/watch 2008-08-04 15:31:44.000000000 +0530 @@ -1,2 +1,3 @@ -version=2 -http://thomaso.best.vwh.net/bridge/deal/downloading.html deal(.*)src.zip 308 +version=3 +opts="uversionmangle=s/(.)(.)(.)/$1.$2.$3/" \ +http://bridge.thomasoandrews.com/deal/downloading.html deal([\d.-]*)(?:src)?.zip diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/dist.c /tmp/sFHmVEdqkv/deal-3.1.4/dist.c --- deal-3.0.8/dist.c 2001-02-19 22:41:53.000000000 +0530 +++ deal-3.1.4/dist.c 2008-05-15 05:49:24.000000000 +0530 @@ -26,9 +26,6 @@ #include "dist.h" #include "dealtypes.h" -#ifndef lint -static char rcsid [] = "$Header: /home/thomaso/deal30/RCS/dist.c,v 1.3 1999/07/09 00:32:32 thomaso Exp $"; -#endif #include HandDist dist_table[DIST_COUNT]; @@ -553,7 +550,6 @@ clubs=13-spades-hearts-diamonds; array[4]=lengthObjs[clubs]; result=Tcl_EvalObjv(interp,5,array,TCL_EVAL_GLOBAL); - if (result==TCL_ERROR) { deleteDistFunc(func); Tcl_AppendResult(interp,"\nCould not compile function ",nameStr,"\n", @@ -734,7 +730,7 @@ int tcl_shapeclass_define_binary ( TCL_PARAMS ) TCL_DECL { DistSet set; - char *s; + CONST84 char *s; int i; if (argc!=3) { return TCL_ERROR; } Binary files /tmp/SqcgMuwVDH/deal-3.0.8/docs/graphics/falling_small.jpg and /tmp/sFHmVEdqkv/deal-3.1.4/docs/graphics/falling_small.jpg differ Binary files /tmp/SqcgMuwVDH/deal-3.0.8/docs/graphics/idealbg.jpg and /tmp/sFHmVEdqkv/deal-3.1.4/docs/graphics/idealbg.jpg differ Binary files /tmp/SqcgMuwVDH/deal-3.0.8/docs/graphics/new01.gif and /tmp/sFHmVEdqkv/deal-3.1.4/docs/graphics/new01.gif differ Binary files /tmp/SqcgMuwVDH/deal-3.0.8/docs/graphics/StampSm.gif and /tmp/sFHmVEdqkv/deal-3.1.4/docs/graphics/StampSm.gif differ Binary files /tmp/SqcgMuwVDH/deal-3.0.8/docs/graphics/warning.gif and /tmp/sFHmVEdqkv/deal-3.1.4/docs/graphics/warning.gif differ diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/advanced.html /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/advanced.html --- deal-3.0.8/docs/html/advanced.html 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/advanced.html 1970-01-01 05:30:00.000000000 +0530 @@ -1,476 +0,0 @@ - - - - - - - - - - Deal - An Advanced User Guide - - - - - - - - - - - - - - -
Plane Dealing image -

Deal 3.0

-

An Advanced User Guide

-
-Covering:
    -
  • Vector additive functions -
  • Shape functions -
  • Customizable output formats -
  • Statistical analysis -
  • Hints for fast scripts -
-

- -
-

Prologue

-First things first, you will need to download -Deal and build it. The rest of this guide assumes you have -already done this. -

-This guide also assumes you know everything in the -Introductory Tutorial. Some sections -in this guide will require more knowledge -of Tcl than others. -

-**Warning** It takes careful -eyes, at least on the version of Netscape I am using, to distinguish -between normal parentheses, (), and curly -parentheses, {}. Almost all of the paretheses in the script -listings below are curly parentheses. -


-

Contents

- -

Vector additive functions

- -In the Introductory Tutorial, we mentioned -three functions which we called "additive functions." They were -hcp, controls, and losers. We called them additive -because we could compute them for a single suit holding in a hand or -across the entire hand by summing over all the suits. -

-In this section, we will show how a user can create a large class -of fast additive functions, and show how they can be used. -

-The most common additive function is hcp. How is it -computed? Given a suit holding, we count 4 for the ace, 3 for -the king, 2 for the queen, and 1 for the jack. Here is how -we would define this with a "vector": -

-defvector Hcp 4 3 2 1
-
- -That's pretty simply. Similarly, we can define a Controls vector: -
-defvector Controls 2 1
-
-

-Once these vectors are defined, we can use them as functions anywhere -we used hcp and controls. -

- -Now, considering the following case: Your partner, north, opens a weak -two spades, and you have the agreement that partner always has a 6-card -suit with at least two of the top three honors. You can define a vector: -

-defvector Top3 1 1 1
-
-Now, to test the quality of the spade suit, you could say: -
-if {[Top3 north spades]>=2} { ... }
-
-Pretty simple. -

-So you decide to write a "weak2" procedure: -

-defvector Top3 1 1 1
-
-proc weak2 {hand suit} {
-  if {[$suit $hand]==6 && [Top3 $hand $suit]>=2} { return 1 }
-  return 0
-}
-
-You can call this by saying: -
-#... 
-main {
-	if {[weak2 north spades]} { accept }
-}
-
-This will deal out hands where north has exactly six -spades and two of the top three spades. -

-This works okay (although you have forgotten to restrict the other -suit lengths, so you could end up with voids and side 5-card or -6-card suits.) -

-Two weeks later, you and your partner decide that you will also -consider a suit worth a weak 2 if it contains three of the top -five cards, which, specifically, really means you've now allowed -suits led by QJT, KJT, and AJT. This is -not an uncommon agreement. -

-We could, of course, write a routine called "Top5" and check -both Top3 and Top5, but a little cleverness allows us to roll -this all up into one vector. -

-defvector weak2quality 2 2 2 1 1
-
- -You will see, if you think about it, that this vector evaluates -to 4 or more precisely when the suit has the right quality for -a weak two. You then rewrite the weak2 function: -

-

-defvector weak2quality 2 2 2 1 1
-
-proc weak2 {hand suit} {
-  if {[$suit $hand]==6 && [weak2quality $hand $suit]>=4} { return 1 }
-  return 0
-}
-
- -The advantage of the vector functions is that they can be computed -quickly, using table lookups. -

-However, vectors don't compute many additive functions, like "losers" -and "quick tricks," or even high card points with distribution adjustments. -For this, you will need to use the Deal 3.0 feature, -holding functions. It pretty much -covers *all* such procedures, but still allows for a fast lookup. - -

Shape functions and classes

- -In the Introductory Tutorial, we mentioned -the two functions, balanced, and semi_balance, and -called them "shape functions" because they take a hand name as an -argument, the return value depends only on the "shape" of the hand - -that is, on how many cards are in each suit. -

-In fact, balanced and semi_balanced are a special -sort of shape function, which we will call a "shape class." A "shape -class" is a shape function which returns only the values 0 and 1, -and therefore defines a class of shapes, namely those shapes which -evaluate as 1. -

-Deal allows for extremely fast shape class and -shape function computations. -

-

A basic shape class

-For example, lets say that we want to write a shapeclass which -returns 1 if our hand is right shape for a one spade opening. We would -do so with the following definition: -
-shapeclass spadeshape {
-    if {$s>=5 && $s>=$h && $s>=$d && $s>=$c} { return 1}
-    return 0
-}
-
-This defines a routine, spadeshape, which returns true -precisely when the hand has 5 or more spades and at least as -many spades as any other suit. -

-Notice, the variables $s, $h, $d, and -$c. Consider it this way - when you pass a hand name to -a shape function, it sets these variables to the suit lengths, -and then evaluates the code. [ That is not how it works in -reality, because that would be too slow. ] -

-The idiom, if {expr} {return 1} return 0 - is so common in shape classes, Deal has -a shorthand, shapecond, and we could have defined spadeshape -as: -

-shapecond spadeshape {$s>=5 && $s>=$h && $s>=$d && $s>=$c}
-
-

A sample shape function

- -Shape functions can return any string. They can be extremely -powerful. -

-For example, we can define a function, opening_suit: -

-shapefunc opening_suit {
-	if {$c>$s && $c>$h && $c>$d} { return clubs }
-	if {$d>$s && $d>$h && $d>$c} { return diamonds }
-	if {$s>=5 && $s>=$h} { return spades }
-	if {$h>=5} { return hearts }
-	if {$d>=5 && $d>=$c} { return diamonds }
-	if {$d>$c} { return diamonds }
-	return clubs
-}
-
-This function returns the name of the suit in which you should open -open the hand (at least according to some people) in Standard American -bidding. - -

-Recently, a number of people have mentioned to me Bergen's "rule of -20" for determining whether a hand is worth an opening bid. -According to the rule, add your high card points to -the sum of the lengths of your longest two suits. If that adds up to -20, open the hand. We can write this as follows: -

-shapefunc bergen::shapeval {
-    set p [lsort -integer -decreasing "$s $h $d $c"]
-    set first [lindex "$p" 0]
-    set second [lindex "$p" 1]
-    expr $first+$second
-}
-
-proc bergen::opening {hand} {
-    expr { [hcp $hand] + [bergen::shapeval $hand] >= 20}
-}
-
-We can now use Bergen's rule in our simulations. -

-

Calling shape functions explicitly

- -A shape function (or shape class) can be called with 4 numeric arguments: -
-set open3343 [openingsuit eval 3 3 4 3]
-
-This is most useful in defining shape classes and functions from -other shape classes and functions. Assume you have shape classes -spadeshape and heartshape and you want to define -a new shape class, majorshape. You can do so as follows: -
-shapecond majorshape \
-	{[spadeshape eval $s $h $d $c] || [heartshape eval $s $h $d $c]}
-
- - -

Customizable output formats

- -With verson 2.0 of Deal, it is finally possible to write -your own customizable format routines. -

-It is really fairly simple. When Deal accepts a hand, -it calls the procedure named write_deal. When it is finished -dealing the number of hands requested, it calls a procedure named -flush_deal. -

-To change the output format, we simply redefine these procedures. -Tcl does not mind such redefinitions. -

-For example, the formatter, format/none, is just the code: -

-proc write_deal {} {
-	# empty function
-}
-
-By default, the flush_deal procedure is already empty, so -we do not have to redefine it here. -

-Why might we need flush_deal at all? Some formatters -only write to output periodically. For example, format/practice -writes files out.north, out.east, out.south, -and out.west. The output in out.north looks like: -

-                              north hands
-============================================================================
-     *1*                 *2*                 *3*                 *4*
-  S 84                S T7                S QT3               S AJ9654
-  H J8642             H Q65               H Q983              H K8
-  D Q843              D KJ42              D 865               D J
-  C 73                C T842              C AJ9               C K532
-
-=============================================================================
-
-Clearly, therefore, write_deal is buffering output -internally and only printing every fourth hand. What happens when -the user requests 10 deals? write_deal will be called -on the tenth deal, but because the deal number is not a multiple -of four, write_deal will not know to print the output. -The last two hands will be lost. -

-The solution is to make Deal call flush_deal -on completion of dealing. -

A most basic formatter - printing one hand

- -Here is a new formatter, which we will place in a file call NorthFmt. -
-proc write_deal {} {
-	puts "S: [north -void --- spades]"
-	puts "H: [north -void --- hearts]"
-	puts "D: [north -void --- diamonds]"
-	puts "C: [north -void --- clubs]"
-	puts "============================="
-}
-
-Okay, what does this expression, -[north -void --- spades], do? -The expression [north spades] returns the spade holding -of the north hand in a simple string form. If the suit is void, -it returns the empty string. The "-void ---" in the -example above tells the formatter to use the string "---" for -voids. -

-We could do this a little more easily: - -

-proc write_deal {} {
-    foreach char {S H D C} suit {spades hearts diamonds clubs} {
-	puts "$char: [north -void --- $suit]"
-    }
-    puts "============================="
-}
-
-This uses the interesting feature of the Tcl foreach -which lets two variables move through two lists. -

- -The north routine, without arguments, returns all four suits, in -a Tcl list format. Here is a simple formatter for the north and south -hands: -

-proc write_deal {} {
-    puts "{[north]} {[south]}"
-}
-
-Yielding ugly output like: -
-{{J9654} {KQT832} {} {42}} {{7} {A74} {T763} {J9865}}
-{{KT852} {Q} {KT83} {A83}} {{96} {AK7543} {Q96} {52}}
-
-Not pretty, but useful if piping to another Tcl program, because -Tcl programs will find this fairly easy to parse. -

-

String boxes

-For more complicated formats, I have added to Tcl an invention -of my own for string "drawings." Tcl does not have any -decent formatting routines, other than the format -command, which is based on the printf class of functions -in C. I've always found printf a pain, even back in Fortran. -

-So I invented "string boxes." A string box is a like a drawable -canvas, but for characters rather than pixels. For example, here -is a slightly simpler version of the file format/okb: -

-stringbox okbox 14 70
-okbox write 4 15 "West"
-okbox write 4 50 "East"
-okbox write 0 30 "North"
-okbox write 10 30 "South"
-	...
-
-This code creates a string box named okbox with 14 rows of -70 columns of text (initially all blank), and then writes -the words "West", "East", "North", and "South" in different locations -in that box. -

-Next we define the sub-boxes, one for each hand: -

-	...
-okbox subbox okbox.north 0 36 4 15
-okbox subbox okbox.south 10 36 4 15
-okbox subbox okbox.east 5 50 4 15
-okbox subbox okbox.west 5 15 4 15
-	...
-
- -A "subbox" is created from a parent box, and has both a row and column -location, and a row and column width. In the above instance, all of -our sub-boxes are 4 rows and 15 columns, and placed in the location -where the hands will eventually be printed. -

-Our write_deal procedure would look like: -

-proc write_deal {} {
-  foreach hand {west south north east} {
-    okputhand $hand
-  }
-
-  puts "[okbox]"
-  puts "                       -----------------------------"
-}
-
-proc okputhand {hand} {
-
-  okbox.$hand clear
-
-  set rowhand 0
-  foreach char {S H D C} suit {spades hearts diamonds clubs} {
-    okbox.$hand write $rowhand 0 "$char [$hand -void --- $suit]"
-    incr rowhand
-  }
-}
-
- -write_deal just calls the routine okputhand for each -hand, then writes out the contents of the entire string box, okbox, -followed by the seperator string of hyphens. Note that we convert -a string box to a normal string just by using its name alone, without -arguments, as in [okbox]. We can also convert a string with trailing -whitespace removed from lines, by saying [okbox compact]. -In fact, we probably should have used the compact modifier, -since there is so much trailing white space in this format. -

-The okputhand procedure first clears the sub-box associated -that hand, then writes out the contents of the hand one suit at a time -to that same sub-box. -

-The output looks like: -

-                              North S KT6                             
-                                    H J97                             
-                                    D T8543                           
-                                    C T5                              
-               West                               East                
-               S J75                              S Q983              
-               H T86                              H A52               
-               D AKJ7                             D Q9                
-               C AQ8                              C KJ64              
-                                                                      
-                              South S A42                             
-                                    H KQ43                            
-                                    D 62                              
-                                    C 9732                            
------------------------------
-
- -I have yet to put together complete documentation for string boxes, -but I intend to do so. They have some remarkable features, and perhaps -some surprises for the unwary. -

Statistical analysis

- -Go here. - -

Hints for fast scripts

- -Documentation not yet written. -
-
-Silhouette - Thomas Andrews -(thomaso@best.com) - Copyright 1996-2002. Deal is covered by the -GNU General Public License. -

-Plane Dealing graphic -above created using -POV-Ray. -

- diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/balanswer.html /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/balanswer.html --- deal-3.0.8/docs/html/balanswer.html 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/balanswer.html 1970-01-01 05:30:00.000000000 +0530 @@ -1,159 +0,0 @@ - - - - - - - - -The Sum of the Squares of the Suit Lengths - - - - - -
-

The Sum of the Squares of the Suit Lengths

-

A Measure of the "Sickness" of a Hand Pattern

- -In any hand, the average of the suit lengths is 3.25 = 13/4, obviously, -but what is the standard deviation of the suit lengths? -

-The standard deviation, it turns out, is related to -the sum of the squares of the suit lengths. In particular, the higher -the sum of the squares, the higher the standard deviation. -

-So it should come as no surprise that the more balanced hands should -have lower standard deviations, and hence lower sums of squares. In -particular, when the sum of the squares of the suit lengths is less -than or equal to 47, the hand is "balanced" in the traditional sense: -No singleton or void, and at most one doubleton. -

-Since the smallest value is 43, and all values are odd, we can "normalize" -this metric by subtracting 43 and dividing by 2. -

-We get the following table: - -

-Normalized | Squares sum | Std Dev  | Shapes
-============================================
-         0 |          43 |  0.5000  | 4-3-3-3	 
-         1 |          45 |  0.9574  | 4-4-3-2	
-         2 |          47 |  1.2583  | 5-3-3-2       
-         3 |          49 |  1.5000  | 4-4-4-1, 5-4-2-2 
-         4 |          51 |  1.7078  | 5-4-3-1         
-         5 |          53 |  1.8930  | 6-3-2-2        
-         6 |          55 |  2.0616  | 5-5-2-1,6-3-3-1  
-         7 |          57 |  2.2166  | 5-4-4-0,6-4-2-1 
-         8 |          59 |  2.3629  | 5-5-3-0        
-         9 |          61 |  2.5000  | 7-2-2-2,6-4-3-0  
-        10 |          63 |  2.6300  | 7-3-2-1,6-5-1-1
-        11 |          65 |  2.7538  | 6-5-2-0       
-        12 |          67 |  2.8723  | 7-3-3-0, 7-4-1-1
-        13 |          69 |  2.9860  | 7-4-2-0        
-        15 |          73 |  3.2016  | 6-6-1-0, 8-2-2-1
-        16 |          75 |  3.3040  | 7-5-1-0, 8-3-1-1
-	17 |          77 |  3.4034  | 8-3-2-0        
-        19 |          81 |  3.5940  | 8-4-1-0       
-        21 |          85 |  3.7749  | 7-6-0-0      
-        22 |          87 |  3.8622  | 9-2-1-1     
-        23 |          89 |  3.9476  | 8-5-0-0, 9-2-2-0   
-        24 |          91 |  4.0311  | 9-3-1-0           
-        27 |          97 |  4.2720  | 9-4-0-0          
-        30 |         103 |  4.5000  | 10-1-1-1        
-        31 |         105 |  4.5735  | 10-2-1-0       
-        33 |         109 |  4.7170  | 10-3-0-0      
-        40 |         123 |  5.1881  | 11-1-1-0     
-        41 |         125 |  5.2519  | 11-2-0-0    
-        51 |         145 |  5.8524  | 12-1-0-0   
-        63 |         169 |  6.5000  | 13-0-0-0  
-
-
- -In addition, one can get the wildness of a deal by adding up the sum of the -squares of all 16 suit lengths, or add up the normalized values. Again, -this is correlated to the standard deviation of the suit lengths. -

-We can also measure the wildness of a "fit" by summing the squares of the fits -in each suit. So if I'm 5-3-3-2 and partner is 4-3-2-4, our "fit" is -9-6-5-6. One thing interesting about this is that our opponent's fit -wildness is the same as our fit pattern wildness. That's because if our -pattern is: s-h-d-c, their pattern is (13-s)-(13-h)-(13-d)-(13-c), and the -sum of the squares of these values is: -

-(13-s)^s+(13-h)^s+(13-d)^2+(13-c)^2=
-       s^2 + h^2 + d^2 + c^2 - 26*(s+h+d+c) + 4*13^2
-
-But (s+h+d+c) is 26, so the last two terms cancel, and we are left with the -original value. -

-Of course, if you think in terms of standard deviation, this makes more sense -than the pure calculation - the opponents' pattern has the same relative -distribution, just inverted, so the deviation should be the same. -

-This table can also be normalized, by subtracting 170 and dividing by 2. -There are 103 fit patterns, or 65 if we consider our fit pattern and opponent's -as the same (e.g., that 8-6-6-6 is the same as 7-7-7-5. If the sum of the longest fit and the shortest fit is 13, then the pattern is self-dual, for example, if our fit pattern is 9-7-6-4, then so is the opponent's.) -

-Normalized |  Squares sum | Patterns
-============================================
-         0 |          170 | 7-7-6-6
-         1 |          172 | 8-6-6-6,7-7-7-5
-         2 |          174 | 8-7-6-5
-         4 |          178 | 9-6-6-5,8-8-5-5,8-7-7-4
-         5 |          180 | 9-7-5-5,8-8-6-4
-         6 |          182 | 9-7-6-4
-         8 |          186 | 10-6-5-5,9-8-5-4,8-8-7-3
-         9 |          188 | 10-6-6-4,9-7-7-3
-        10 |          190 | 10-7-5-4,9-8-6-3
-        12 |          194 | 10-7-6-3,9-9-4-4
-        13 |          196 | 11-5-5-5,10-8-4-4,9-9-5-3,8-8-8-2
-        14 |          198 | 11-6-5-4,10-8-5-3,9-8-7-2
-        16 |          202 | 11-7-4-4,11-6-6-3,10-7-7-2,9-9-6-2
-        17 |          204 | 11-7-5-3,10-8-6-2
-        18 |          206 | 10-9-4-3
-        20 |          210 | 12-5-5-4,11-8-4-3,11-7-6-2,10-9-5-2,9-8-8-1
-        21 |          212 | 12-6-4-4,9-9-7-1
-        22 |          214 | 12-6-5-3,11-8-5-2,10-8-7-1
-        24 |          218 | 12-7-4-3,10-10-3-3,10-9-6-1
-        25 |          220 | 12-6-6-2,11-9-3-3,11-7-7-1,10-10-4-2
-        26 |          222 | 12-7-5-2,11-9-4-2,11-8-6-1
-        28 |          226 | 13-5-4-4,12-8-3-3,10-10-5-1,9-9-8-0
-        29 |          228 | 13-5-5-3,12-8-4-2,11-9-5-1,10-8-8-0
-        30 |          230 | 13-6-4-3,12-7-6-1,10-9-7-0
-        32 |          234 | 13-6-5-2,12-8-5-1,11-10-3-2,11-8-7-0
-        33 |          236 | 13-7-3-3,10-10-6-0
-        34 |          238 | 13-7-4-2,12-9-3-2,11-10-4-1,11-9-6-0
-        36 |          242 | 13-6-6-1,12-9-4-1,12-7-7-0
-        37 |          244 | 13-7-5-1,12-8-6-0
-        38 |          246 | 13-8-3-2,11-10-5-0
-        40 |          250 | 13-8-4-1,12-9-5-0,11-11-2-2
-        41 |          252 | 12-10-2-2,11-11-3-1
-        42 |          254 | 13-7-6-0,12-10-3-1
-        44 |          258 | 13-9-2-2,13-8-5-0,11-11-4-0
-        45 |          260 | 13-9-3-1,12-10-4-0
-        48 |          266 | 13-9-4-0
-        50 |          270 | 12-11-2-1
-        52 |          274 | 13-10-2-1,12-11-3-0
-        54 |          278 | 13-10-3-0
-        60 |          290 | 12-12-1-1
-        61 |          292 | 13-11-1-1,12-12-2-0
-        62 |          294 | 13-11-2-0
-        72 |          314 | 13-12-1-0
-        84 |          338 | 13-13-0-0
-
-
-
-Silhouette - Thomas Andrews -(thomaso@best.com) - Copyright 1996-2002. Deal is covered by the -GNU General Public License. -

-Plane Dealing graphic -above created using -POV-Ray. -

- -
diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/CHANGES.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/CHANGES.txt --- deal-3.0.8/docs/html/CHANGES.txt 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/CHANGES.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,123 +0,0 @@ -Changes in Deal 3.0.5 - - * Fixed a bug - Deal 3.0.4 failed to recognize "-" as void - in -S, -E, -N, -W options, as well as in "north is " commands. - - ----- - -Changes in Deal 3.0.4 - - * Update doc examples to match ex/ subdirectory. - - * Deleted util.c and util.h from distribution. - - ----- - -Changes in Deal 3.0.3 - - * Added GNU General Public License copyright to most files, and full - GPL text to release. - - * Altered deal.c to improve performance of reset_deal() routine. - Improved overall performance of 10%. - - * Re-implemented in Tcl the broken undocumented old procedures, - intersectclass, negateclass, and joinclass. This lets you create - new shape classes from old shape classes using standard boolean - functions. Old code removed from dist.c, new code added to deal.tcl . - - * Deleted some unused code in deal.tcl which was left from early - efforts at the smart stacking routines. - - * Updated the documentation - - ----- -Changes in Deal 3.0.2 - - * Fixed a bug in the smartstack methods. - - * Altered zip builds to put files in deal302 directory (rather than - deal3.0.2) - - * Polished the HTML docs (in docs/html directory.) - - * Many, many improved error messages when commands are misused - - * Cleaned up some code - - * Made dist.c use more Tcl_Obj pointers rather than strings - makes for - faster compiles of shape classes. (I can't believe I left those - sprintf calls for so long. :-) - - * Fixed some of the examples which called deal::stack_hand, a non-existant - procedure. - - ----- - -Changes in Deal 3.0.1 - -The changes for Deal 3.0.1 (from Deal 3.0 beta 11) were made essentially -for two reasons: - - (1) To finish the Deal 3.0 release - e.g., added documentation. - (2) To add features needed for the "smartstack" routines. - - * Include HTML docs in docs/html directory. - - * Most library files in release moved to the lib directory - - * Added "smartstack" input class for fast building of hands which fit - specific patterns - - * Added "stacked" procedure to find out the current state of the - deck-stacking. Returns the list of cards stacked to the named hand. - - * Altered stacking methods. Added procedures "deck_stack_cards," - "deck_stack_hand", "stack_cards," and "stack_hand." By default, - "stack_hand" and "stack_cards" just call the "deck_" procedures, - but the idea is that "stack_cards" and "stack_hands" can be - overridden. Now when you call "south is AJ4 KJ54 9643 72" it in - turn calls "stack_hand south AJ4 KJ54 9643 72." Similarly, - "south gets ..." calls "stack_cards," although there the transformation - is somewhat different. - - * Added "list" subcommand to shape classes. e.g., - - shapeclass hasVoid { expr {$s*$h*$d*$c==0} } - - foreach shape [hasVoid list] { - ... - } - - * Added "shape" subcommand to the shape classes and functions, e.g., - - shapefunc foo { ... } - - foo shape {4 2 4 3} - - So: - - foo north - - Is the same as: - - foo shape [north shape] - - * Added the "holding" utility procedure, with subcommands length, - disjoint, ... - - holding length AKxxx => 5 - holding disjoint AKJ4 QT94 => 0 [ false ] - -New to Deal 3.0: - - * Fast holding procedures definable with holdingProc. - - * GIB interfaces (gib::directory, gib::tricks, parscore) - - * Bridge utility routines - lho, rho, partner, score - - * Input format extensibility - - * Uses features of faster versions of Tcl (Tcl 8.x) - diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/commands.html /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/commands.html --- deal-3.0.8/docs/html/commands.html 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/commands.html 1970-01-01 05:30:00.000000000 +0530 @@ -1,1691 +0,0 @@ - -Deal Commands - -

Introduction

-
-This is meant to be a comprehensive list of commands in Deal which -are not native to Tcl. If you want to learn Tcl, I will be providing -a set of pointers later. - -
-Text in blue is meant for Tcl afficianado -- reading this text without knowledge of Tcl might confuse more than -enlighten.
-
-
-
-Text in green is meant for programmers -interested in finding code definitions. -
-
- - - - -

Hand commands: north, east, south, west, hand

- -
-

Usage

-
-east [ -void string] [ suitname ... ]
-hand {hand string} [ -void string] [ suitname ... ]
-
-south subcommand [ ... args ... ]
-hand {hand string} subcommand [ ... args ... ]
-
-These are very strange commands - they really have too much stuffed -into them. That's a historical anomoly which I'm reluctant to abandon. -

-With no subcommands, the routine is used for formatting the hand as -a string. For example, if south is: -

-S: AJ5432
-H: KT94
-D: void
-C: K93
-
-Then the results of various commands are: -
-south                    =>    {AJ5432 KT94 {} K93}
-south spades             =>    AJ5432
-south hearts clubs       =>    {KT94 K93}
-south -void -            =>    {AJ5432 KT94 - K93}
-south -void --- diamonds =>    ---
-
-set h {AK4 {} A95432 JT98}
-hand $h                  =>    {AK4 {} A95432 JT98}
-hand $h spades           =>    AK4
-hand $h hearts clubs     =>    {{} JT98}
-hand $h -void -          =>    {AK4 - A95432 JT98}
-
-The -void switch exists precisely for formatting the output. -

-The various subcommands will be treated in seperate sections. - -The hand version of this command only works with some subcommands. -

- -
For Programmers

-

Implementation:
-
C code -
Location:
-
tcl_deal.c, function tcl_hand_cmd -
-
-
-

Subcommand: shape

-

Usage

-
-north shape
-hand {AJTxx Axx JTxx x} shape
-
-

Summary

-Returns a list of suit lengths, in standard order. -

-For example, the second command above would return the list: -

-5 3 4 1
-
-

Subcommand: pattern

-

Usage

-
-north pattern
-hand {AJ32 A5 JTxx xxx} pattern
-
-

Summary

-Returns a sorted list of the suit lengths, starting with the longest. -For example, the second command above would return the list: -
-4 4 3 2
-
-

Subcommand: is

-

Usage

-
-south is {handstring}
-
-

Summary

-This command pre-places a specific 13 cards. For voids, you can use -the "-" character: -
-south is {AJ32 KT932 - Q876}
-
-Calls to this subcommand must occur before dealing begins, outside the -"main" command. -

-This subcommand calls the stack_hand command. -Inside the main code, the deal is already dealt. -

Subcommand: gets

-

Usage

-
-handname gets card [card ...]
-
-

Summary

-Puts a specific list of cards in the hand named. As with the -"is" subcommand, this must be called before dealing -starts, outside the "main" command. -The card is specified in two characters, a rank character and a suit -character: -
-AS KH JH 9D
-
-This routine dispatches its data to the stack_cards command. - -

Subcommand: has

-

Usage

-
-handname has card [card ...]
-hand {string} has card [...]
-
-

Summary

-This returns a count of the cards listed that occur in the hand named. -
-% south
-AJ54 JT54 43 654
-% south has SA HK HJ HT
-3
-
-
 
-
-

Control commands

- -

Commands: accept and reject

-
-

Usage

-
-accept [ [ if | unless ] expr expr ...]
-reject [ [ if | unless ] expr expr ...]
-
-

Summary

-Without arguments, accept and reject are the -same as return 1 and return -0, respectively. -

-With arguments it's a little more obscure. -

-accept if {$h>4}
-
-This returns 1 if the expression matches. It is equivalent to: -
-if {$h>4} { return 1 }
-
-The code: -
-accept if {$h>4} {$s>4}
-
-Is logically equivalent to: -
-if {$h>4 || $s>4} { return 1}
-
-That is, the values are accepted if either of the expressions -evaluates as true. -

-The unless option does the opposite: -

-accept unless {$h>4} {$s>4}
-
-This is equivalent to: -
-if {!($h>4) || !($s>4)} { return 1 }
-
-

-The means we return with a true value unless one of the expressions -is true. If one of the values is true, we simply go on to the next line. -

-

Examples

-Virtually all of the examples included in the release contain an -instance of "accept" or "reject." - -
- - -
-
-For Programmers:

-

Implementation:
-
C code
-
Location:
-
tcl_deal.c, procedure tcl_deal_control.
-
-This construct is borrowed from the Perl programming language. -Originally, I added it to Deal 2.0 for performance reasons. Those -reasons are obsolote with Tcl 8.x, but I like the mnemonic enough -to keep it, and removing it might confuse old users. -

- - -
-For Tcl Experts:

-There actually is one subtle and occasionally useful distinction -between accept/reject and the stated "if {...} { return ... }" -version. In reality: -

-accept if {$h>4} {$s>4}
-
-is equivalent to: -
-if {$h>4||$s>4} { 
-    return 1
-}
-expr 0
-
-This only matters when the command is the last -command in a procedure. The two procedures: -
-proc A {h s} {
-    if {$h>4||$s>4} {
-        return 1
-    }	
-}
-
-proc B {h s} {
-     accept if {$h>4} {$s>4}
-}
-
-are slightly different. -A call of A 3 3 returns an empty string, while a call -of B 3 3 returns 0. That can be useful, as you can see -here.
-
- -
- -

Command: main

- -
-

Usage

-
-main {
-   block of code
-}
-
- -

Summary

-This defines the primary block of code evaluated after each -deal is generated. If the code returns true, -Deal will treat the deal as a "match" and call -write_deal. It will also increment its count of deals -found and exit if the limit is reached. -
- - -
For Programmers

-

Implementation:
C code
-
Location:
tcl_deal.c, procedure tcl_deal_control. -
-
-
-
- - -

Command: whogets

- -
-

Usage

-
-whogets cardname
-
-This returns the name of the person holding the card cardname. -
- - - -
For Programmers

-

Implementation:
C code
-
Location:
tcl_deal.c, procedure tcl_deal_to_whom. -
-
-
- - -

Command: deal_finished

- -
-

Usage

-
-deal_finished {
-   block of code
-}
-
-This defines the code called at the completion of generating all deals. -This is code you would use to dump statistics, for example. -
- - -
For Programmers

-

Implementation:
C code
-
Location:
tcl_deal.c, procedure tcl_after_set. -
-
- - -
-

Bridge Evaluators

-

Common interfaces

-There are some standard interfaces to bridge evaluation functions. - - -

Hand Procedures

-Any procedure defined entirely based on the values in one hand is considered -a hand procedure. These procedures can be called in one of two -ways: -
-Weak2Bid handname
-
-Weak2Bid hand {AKQxxx xxx xxx x}
-
-The handname parameter can be one of -north, south, east, west. -Shape procedures and holding -procedures fit the hand procedure calling method, along with other -options. -
- -

Shape procedures

-Any procedure defined on the shape of a hand can be called with one of -the following methods: -
-balanced handname
-
-balanced hand {AJ43 AKxx xxx K5}
-
-balanced eval 4 3 4 2
-
-balanced shape {4 3 4 2}
-
-This follows the hand procedure outline with the -addition of the eval option. -

-


- -

Holding procedures

-A holding procedure is a hand procedure -which is evaluated on a bridge hand by evaluating each suit holding -one at a time, and then accumulate the results. There are two -common ways of defining holding procedures, -defvector and -holdingProc. -

This is an -abstraction of a very common bridge evaluation technique. The most -commonly used holding functions are high card points, -losing trick count, controls. For example, when -counting the losers in the hand AKxx Axx KQJxxx x, we -find 1 loser in spades, 2 losers in hearts, 1 loser in diamonds, -and one loser in clubs. We define the total losers to be the sum -across all suits, and get 5 losers, total.

The interface lets -you evaluate the entire hand, or only selected suits in a hand, or -a specific list of holdings. - -

-hcp handname [ suitname ...  ]
-
-hcp hand {AKJxxx K xxx xxx} [ suitname ...  ]
-
-hcp holding AK43 [ ... ]
-
-In the first two cases, if no suits are named, all suits are evaluated, and -the results are accumulated. In the case of the holding call, -the specific holdings passed in are evaluated. -

-Note, I've been saying "accumulated" rather than added. In some cases, -you might have an accumulation method different from addition. For example, -you might return the standard opening leads from a holding: -

-    openingLead holding KQJ7    =>   K
-    openingLead south           => {K} {7 2} {4} {J}
-
-Each suit would create a list of proposed leads, and the result would be -a list of lists of all standard leads from all holdings. Here, the -accumulation is to simply make a list. -
- - - -

Command: balanced and semibalanced

- -
-

Usage

-
-balanced handname
-
-balanced hand {text hand}
-
-balanced eval s h d c
-
-

Summary

-These are both shape procedures. -

-balanced returns true if the hand is some 4333, 4432, or 5332 -without a 5-card major. -

-semibalanced returns true if the hand has no singletons - or voids, not six-card majors, and no seven-card minors. -

- -
For Programmers

-

Implementation:
-
Tcl with shapecond -
Location:
-
deal.tcl -
-These use to be hard-coded in the C code, but it made more sense -to add them to the library code - the user can change the definitions -as he likes. -
-
-
-
- - - - - -

Commands: clubs, diamonds, hearts, spades

- -
-

Usage

-
-     spades handname
-     spades hand {AKxx Axx AJxx Kx}
-
-These implement the hand procedure interface, and -return the suit lengths for the appropriate suit. -
- -
For Programmers

-

Implementation:
-
-
Location:
-
tcl_deal.c, function tcl_suit_count -
-These could be shape procedures but for speed reasons, I've -left them this way. -
-
-
- -
- -

Holding Evaluators

- -

Command: hcp

- -
-

Usage

-
-hcp handname
-hcp handname suitname [suitname ...]
-hcp hand {s h d c}
-hcp hand {s h d c} suitname [suitname ...]
-
-This procedure computes standard high card points - ace is 4, king -is 3, queen is 2, jack is 1. The procedure implements the -holding procedure interface. -
- -
For Programmers

-

-
Implementation: -
C code -
Location: -
Built with additive.c, tcl_create_additive - and deal.c, count_hcp -
-
-
-
- -
- -

Command: losers

- -
-

Usage

-
-losers handname
-losers handname suitname [suitname ...]
-losers hand {s h d c}
-losers hand {s h d c} suitname [suitname ...]
-
-This implements a holding procedure which -computes the number of half losers. This is for historical reasons - -the only holding functions allowed in past releases returned integer -values, but I wanted to have some refinements over raw losing trick count. -
- -
For Programmers

-

Implementation:
-
C code -
Location:
-
Built with additive.c, tcl_create_additive - and deal.c, count_hcp -
-It is probably better to reimplement in Tcl using -holdingProc. -
-
-
- -
- -

Bridge Logic and Utilities

- - - -

Commands: lho, partner, rho

- -
-

Usage

-
-lho handname
-rho handname
-partner handname
-
-

Summary

-These routines accept one hand name and return another. For example, -"lho north" returns "east," and -"partner east" -returns "west." -
- -
For Programmers

-

Implementation:
-
C code -
Location:
-
tcl_deal.c, function tcl_other_hand -
-
-
-
- -
- - -

Commands: holding

- -
-

Usage

-
-holding length AJxx           =>     4
-
-holding contains AJ64 A6      =>     1 (true)
-holding contains AJ64 A65     =>     0 (false)
-
-holding encode AJ4            =>     4612  (binary: 1001000000100 )
-
-holding decode 4612           =>     AJ4
-
-holding matches AKxx  AK42    =>     1 (true)
-
-holding disjoint AJ65 KT82    =>     1 (true)
-holding disjoint A65  A32     =>     0 (false)
-
-holding index AKJ4 0          =>     A
-holding index AKJ4 1          =>     K
-holding index AKJ4 3          =>     4
-holding index AKJ4 -2         =>     J
-holding index AKJ4 10         =>     ""
-
-

Summary

-
- -
For Programmers

-

Implementation:
-
C code -
Location:
-
holdings.c, function IDeal_HoldingCmd -
-
-
-
- -
- - -

Command: score

- -
-

Usage

-
-source lib/score.tcl
-   ...
-score contract vulnerability tricks
-
-

Summary

-This routine computes the standard duplicate bridge score for a contract -from the point of view of declarer, if declaring side takes the given number -of tricks. -

-The contract is passed as a list: -

-2 spades
-
-2 spades undoubled 
-
-4 clubs doubled
-
-6 notrump redoubled
-
-The vulnerablity is one of the words vul or -nonvul. -

-The tricks is the number of tricks taken by declarer. -

Examples

-
-
-score {2 spades} nonvul 8           =>  110
-score {2 spades doubled} nonvul 8   =>  470
-score {2 spades redoubled} nonvul 8 =>  640
-score {2 spades doubled} vul 8      =>  670
-score {2 spades} nonvul 7           =>  -50
-score {2 spades doubled} nonvul 7   =>  -100
-score {2 spades doubled} vul 7      =>  -200
-
-
- -
- -
For Programmers

-

Implementation:
-
Tcl -
Location:
-
score.tcl -
-
-
-
- -
-

- -

GIB-related routines

-These next routines use calls to the GIB double-dummy engine. You must have -a licensed version of GIB -installed on your computer for these routines to work. Also, these -routines only work on Windows at the moment. -

- -

Command: gib::directory

- -
-

Usage

-
-source lib/gib.tcl
-   ...
-gib::directory path
-
-

Summary

-This tells the GIB-related routines where GIB is installed. -

-If this routine is not called, it defaults to GIB's default install -directory, C:/Program Files/GIB. -

-Note: your path should include forward slashes '/', -even on Windows. -

- -
For Programmers

-

Implementation:
-
Tcl
-
Location:
-
gib.tcl -
-
-
-
- -
- - -

Command: gib::tricks

- -
-

Usage

-
-source lib/gib.tcl
-   ...
-gib::tricks declarer denomination
-
-

Summary

-Denomination can be a suit name or "notrump." -Declarer can be any hand name. -

-This routine returns the double-dummy number of tricks available -in this deal, in the given denomination by the given declarer. -

-If GIB is installed anywhere unusual, you will need to call -gib::directory before -gib::tricks is called. -

- -
For Programmers

-

Implementation:
-
Tcl
-
Location:
-
gib.tcl -
-
-
-
- -
- - -

Command: parscore

- -
-

Usage

-
-source lib/parscore.tcl
-   ...
-set result [parscore dealer vul]
-
-set contract [lindex $result 0]
-set declarer [lindex $result 1]
-set score [lindex $result 2]
-set tricks [lindex $result 3]
-set auction [lindex $result 4]
-
-

Summary

-This computes the double-dummy par result for the hand. -

-The parscore routine returns a list of five values - the contract (in -the same form that is used by the score -routine above), the declarer, the score for north/south, the number of -tricks taken, and a "stupid" auction to the contract suitable for putting -into a PBN file. -

-Dealer is relevant on a few occasions. If both south and west can make -1NT, for example, and no 2-level contracts make, then "par" is 1NT by -whomever gets a chance to bid it first. -

-If GIB is installed anywhere unusual, you will need to call -gib::directory before -gib::tricks is called. -

- -
For Programmers

-

Implementation:
-
Tcl -
Location:
-
parscore.tcl -
-
-
-
- -
- - -

Bridge Command Builders

- -A number of common types of bridge functions can easily be implemented to -run quickly via lookup tables, including -holding and shape procedures. -Deal lets the user take advantage of these two sorts of lookup procedures -relatively easily. - - -

Command: defvector

- -
-

Usage

-
-defvector vec aceVal [ kingVal ... ]
-
-vec handname
-
-vec hand {text hand}
-
-vec handname suitname [ suitname ... ]
-
-vec handname suitname [ suitname ... ]
-
-vec hand {text hand} suitname ...
-
-

Summary

-This defines a holding procedure which assigns -integer values to the various cards in the hand. For example -
-defvector hcp6421 6 4 2 1
-
-Defines a holding procedure which counts the ace as worth 6 points, the -king as worth 4, the queen as 2, and the jack as 1. -

-Vectors are limited to being integer-valued. For more complicated -holding procedures, use holdingProc. - -

- - -
For Programmers

-Implementation: C
-Location: vector.c -Vectors are slighly faster than their equivalent -holdingProc. They are an -old optimization which remain mostly for backwards compatibility. -
-

-
- -
- - -

Command: holdingProc

- -
-

Usage

-
-
-

-Temporarily, see the seperate documentation. -

- -
For Programmers
-Implementation: C
-Location: holdings.c, function IDeal_DefHoldingProc -
-
-
- -
- - - - -

Commands: shapeclass, shapecond, and shapefunc

- -
-

Usage

-
-shapeclass name {... code ...}
-
-shapecond name {expr}
-
-shapefunc name {... code ...}
-
-name [ north | south | east | west ]
-
-name eval s h d c
-
-name shape {s h d c}
-
-
-A shape class (or equivalently, a shape condition) also has the list -subcommand: -
-name list
-
-

Summary

-These commands create new procedures which fit the shape -function interface. -

-shapeclass and shapecond define procedures which returns boolean -values. shapefunc can return any type of data. -shapecond is actually an alias: -

-shapecond name {expr}
-
-is the equivalent of: -
-shapeclass name {
-  if {expr} {
-    return 1
-  } else {
-    return 0
-}
-
-The code or expr is allowed to use the variables -s, h, d, or c. -

-More details can be found in the -Advanced Guide. -

-The list subcommand for shape classes returns a list of -shapes that are in the class. -

-Why are there two subcommands, "eval" and "shape" which do the -roughly the same things? -

-Let's say you have a class named "SemiBalanced" already defined, -which includes 5-card majors. You want to define a "Balanced" -class which excludes the 5-card majors. You can do this with -the call: -

-shapecond Balanced {[SemiBalanced eval $s $h $d $c] && $s<5 && $h<5}
-
- -On the other hand, if you have a shape - output by the, say, a -call to [north shape] you can evaluate it as: - -
-    SemiBalanced shape [north shape]
-
- -In fact, this is exactly equivalent to calling - -
-    SemiBalanced north
-
- -only slightly slower. - -
- - -
For Programmers
-Implementation: C
-Location: dist.c, functions tcl_shapeclass_define, -tcl_shapecond_define, and tcl_shapefunc_define -
-
- -
- - -

Statistics

- -

Command: sdev

- -
-

Usage

-
-sdev name
-
-name add data [ data ... ]
-
-name count
-
-name average
-
-name sdev
-
-name rms
-
-

Summary

- -The "sdev" command defines a new Tcl procedure with the given name, which behaves as a -data collection object. You can add data points to it, or you can retrieve -the current number of data points, the average of the data points, the -standard deviation of the data points, or the "root mean square" of the -data points. -

- -

- -
For Programmers
-
Implementation:
C code
-
Location:
stat.c, function tcl_sdev_define. -
-This was implemented in C for efficiency reasons - most real number -computations really need to be done in C if they are going to be done -frequently, and here, the "add" command is called quite often in normal -usage. -
-
-
- -

Command: correlation

- -
-

Usage

-
-     correlation name
-
-     name add xval yval [ xval yval ... ]
-
-     name count
-
-     name correlate
-
-     name average [ x | y ]
-
-     name sdev [ x | y ]
-
-     name rms [ x | y ]
-
-

Summary

-The correlation declaration defines a routine much like -the sdev command, but each datapoint is a pair of values, -and it computes the linear correlation between the x and y -values. -

-You can also get individual data for the x and y -values. -

-If there is no data, it returns an error on average, -correlate, sdev and rms. -

-If there is only one pair entered, it will throw an error on -sdev. -

-

- -
For Programmers
-
Implementation:
C code
-
Location:
stat.c, function tcl_correlation_define. -
-This was implemented in C for efficiency reasons - most real number -computations really need to be done in C if they are going to be done -frequently, and here, the "add" command is called quite often in normal -usage. -
-
- -

Utility Procedures

- - - -

Command: deal_deck

- -
-

Usage

-
-deal_deck
-
-

Summary

-deal_deck is called at every new deal, -even when all 52 cards are specified (stacked) precisely. -Imagine stacking cards as stacking them in an undealt deck, -but that the cards are only distributed to the hands when -deal_deck is called. -

-Most of the time, you won't need to call deal_deck directly, but it is -useful to understand its behavior if you are going to write advanced -procedures like input formats. -

-Stacked cards are permanently stacked until the deck is reset. In this code: -

-    stack_hand south {AKQ32 AJ53 K54 2}
-    deal_deck
-    deal_deck
-    puts [south spades]
-
-The output is "AKQ32". Use reset_deck -to undo card stackings. -

-The deal_deck procedure does one thing rather complicated -when it is called, the first thing it does is execute all -code registered with the -deal_reset_cmds. -This allows the script writer to do one of several things before -the deal is generated: -

    -
  • Delete metadata related to the deal. For example, the first time -the user calls gib::tricks south spades it calls the -GIB double-dummy processor. Each time after that, it uses a stored -value for this function call up until the next call to -deal_deck. -
  • The reset command might, instead, read the next deal from a file, -stack the deck, and then re-register itself. Then when deal_deck is -is called, it just deals that hand from the file. This is a crude -way of allowing Deal to transparently read deals from a file (or generate -deals in other ways, such as smart stacking. -
- -
  • - -
  • - -
    For Programmers

    -

    Implementation:
    -
    C -
    Location:
    -
    tcl_deal.c, function tcl_deal_deck -
    -
    -
    -
    - -
    - - -

    Command: reset_deck

    - -
    -

    Usage

    -
    -reset_deck
    -
    -

    Summary

    -This forgets about all stacked cards. The deck, from Deal's -point of view, plus a list of cards which must go to specific hands. -The cards which are assigned to specific hands are "stacked." The cards -which are not stacked can go anywhere at the next call to -deal_deck. -
    - -
    For Programmers

    -

    Implementation:
    -
    C -
    Location:
    -
    tcl_deal.c, function tcl_reset_deck -
    -
    -
    -
    - -
    - - - -

    Commands: stack_hand and stack_cards

    - -
    -

    Usage

    -
    -stack_hand handname hand
    -stack_cards handname suitname holding [...]
    -
    -

    Summary

    -By default, these two routines just call -deck_stack_hand and deck_stack_cards, -respectively - that is, they forcibly place cards in the deck. -

    -But these routines are meant to be overridden. For example, when using -one of the input formats which reads deals from a file, -the format will redefine these two procedures to give errors. -

    -% deal -I "line foo.txt" -e "stack_cards south spades AJ"
    -Tcl stack dump of error info:
    -No card stacking with input format ::line
    -...
    -
    -A more complicated re-definition occurs in the -smartstack input format, which alters its hand -generation depending on what cards are stacked where. - -
    - -
    For Programmers

    -

    -
    Location:
    -
    hand.c, function tcl_stack_hand and -tcl_stack_cards -
    -
    -
    -
    - -
    - - - -

    Commands: deck_stack_hand and deck_stack_cards

    - -
    -

    Usage

    -
    -deck_stack_hand handname hand
    -deck_stack_cards handname suitname holding [...]
    -
    -

    Summary

    -These routines are the "underlying" deck-stacking routines. Any cards -stacked with these routines remain stacked until the next call to -reset_deck -
    - -
    For Programmers

    -

    -
    Location:
    -
    hand.c, function tcl_stack_hand and -tcl_stack_cards -
    -
    -
    -
    - -
    - - -

    Command: stacked

    - -
    -

    Usage

    -
    -stacked handname
    -
    -

    Summary

    -Determines what cards are stacked to this hand, returning them as -a list of holdings: -
    -south gets AS KH 3H QD JD TC 9C 8C
    -puts [stacked south]
    -
    -writes out the list: -
    -A K3 QJ T98
    -
    -This is useful for the smartstacker, because -we don't want to force the user to stack cards *after* specifying conditions. -
    -stack_hand north {AJT KT3 KJ 75432}
    -deal::input smartstack south balanced hcp 20 21
    -
    -The call to stack_hand occurs before smartstack -is loaded, so stack_hand has not been redefined. So what -smartstack does is read the cards already stacked, and -use that for its initial conditions. -

    -

    - -
    For Programmers

    -

    Implementation:
    -
    -
    Location:
    -
    tcl_deal.c, function tcl_stacked_cards -
    -
    -
    -
    - -
    - - -

    Command: deal::nostacking

    - -
    -

    Usage

    -
    -::deal::nostacking
    -
    -

    Summary

    -This procedure redefines the stack_hand and -stack_cards procedures to generate error messages, and -generates an error if any cards are currently stacked. -

    -This is used in all of the input formats which read complete deals from -files, and thus are incompatible with stacking. -

    - -
    For Programmers

    -

    Implementation:
    -
    -
    Location:
    -
    deal.tcl, function deal::nostacking -
    -
    -
    -
    - -
    - - - -

    Command: deal_reset_cmds

    - -
    -

    Usage

    -
    -deal_reset_cmds {...code...} [ ... ]
    -
    -

    Summary

    -This adds a set of commands that are to be called before the next -deal. The code is executed at the next call to the -deal_deck procedure, which, unless -you are doing something complicated, means it is called at the beginning -of each time through the evaluation loop. -

    -deal_reset_cmds can be used so that metadata about the previous deal, -such as cached values and the like, are unset. See -deal::metadata. -

    -It is also used for defining input formats, -so that deals can be read from files. For example, the "line" input format -has the following routine declared: -

    -namespace eval line {
    -    #....
    -    proc next {} {
    -	variable handle
    -	set length -1
    -	catch { set length [gets $handle line] }
    -
    -        # ... process the line, or handle oef stuff ...
    -        # ...
    -	deal_reset_cmds {::line::next}
    -    }
    -}
    -
    -

    -The key is that when line::next is done, it re-registers itself, making -sure that it is called next time through as well. -

    -The code passed in to deal_reset_cmds is -called only once, at the next request for a deal - think of it as -registering a one-time trigger. Multiple triggers can be registered - -they are called in the reverse order that they are added, which can seem -counter-intuitive until you think of the process as an "undo" process. -

    - -
    For Programmers

    -

    Implementation:
    -
    -
    Location:
    -
    tcl_deal.c, function add_reset_cmds -
    -This callback idea is fairly powerful, and will probably be clarified -and elaborated in later releases. Unfortunately, initial efforts to use -it to alter the deal source (by say reading deals from a file) have -been mixed - Windows/DOS seems to choke occasionally on it. -
    -
    -
    - -
    - - -

    Command: deal::metadata

    - -
    -

    Usage

    -
    -deal::metadata name {...code...}
    -
    -

    Summary

    -Currently, this is just a peculiar way of caching slow evaluation routines. -At the moment, the only place it is used is in -gib::tricks. -

    -When you call deal::metadata, it will check to see if -there is a value associated with the name requested -already. If there is, the value is returned. If it does not, it evaluates the -specified code and associates the result with the name. The key -is, when the next deal is being analyzed, all the cached values are pitched. -

    -This isn't really necessary or efficient in most cases, but with -evaluations which take some time, e.g. GIB calls, it -improves things. -

    - -
    For Programmers

    -

    Implementation:
    -
    Tcl -
    Location:
    -
    deal.tcl -
    -In later releases, metadata read from input streams (say, the fields -from a PBN file) will also be stored here. -

    -This procedure uses -deal_reset_cmds. -The metadata is cleared each time the deal_deck -command is called. - -

    -
    - -
    -

    Input formats

    - -

    Command: deal::input

    - - -
    -

    Usage

    -
    -deal::input formatName args
    -
    -

    Summary

    -The deal::input command is used to define an input source -for deals. It works as follows: -
      -
    1. The file input/<formatName>.tcl is loaded. This -Tcl file should define a new Tcl 'namespace' with the name formatName, -with member procedures named set_input and next. -
    2. Deal then calls -<formatName>::set_input args, which should -initialize the format reading. Usually, the argument(s) are one argument -representing the source file. -
    3. The next deal, <formatName>::next is called. -
    - -
    - - -
    -
    -For Programmers:

    -

    Implementation:
    -
    Tcl code
    -
    Location:
    -
    deal.tcl
    -
    -
    -
    - -

    Input Format: giblib

    - -
    -

    Usage

    -
    -deal::input giblib [filename]
    -
    -or on the command line: -
    -% deal -I giblib
    -
    -or -
    -% deal -I "giblib filename"
    -
    -

    Summary

    -Specifies that deals are read from the specified file in the format -of Matt Ginsberg's library.dat file. This includes double-dummy tricks -data, so that later calls to gib::tricks -will not entail calls to the GIB binaries. -

    -If no filename is given, the library tries to read from a file called -"library.dat" in the current directory. -

    -The -I command-line flag is a quick alias for -deal::input, passing the next argument as -Tcl arguments to the deal::input command. -

    - -
    -
    -For Programmers:

    -

    Implementation:
    -
    Tcl code
    -
    Location:
    -
    input/giblib.tcl
    -This procedure uses deal_reset_cmds. -
    -
    -
    -
    - -

    Input Format: line

    - -
    -

    Usage

    -
    -deal::input line [filename]
    -
    -

    Summary

    -Specifies that deals are read from the specified file in the format -written by Deal's "-l" option. -

    -If no filename is given, the library reads from standard -input. This way, you can create a single data file and then -run several different queries against it: -

    -% deal -l 100000 > sample
    -% deal -e "deal::input line sample" -i query1 
    -% deal -e "deal::input line sample" -i query2
    -
    -[ The -e option just evaluates the code in the next -argument as Tcl code. Alternative, you can use the -I -option, which is shorthand for input formats: -
    -% deal -I "line sample" -i query1 
    -
    -The -I args option is exactly the same as -e "deal::input args" - -
    - -
    -
    -For Programmers:

    -

    Implementation:
    -
    Tcl code
    -
    Location:
    -
    input/line.tcl
    -
    -
    -
    - -

    Input: smartstack

    - -
    -

    Usage

    -
    -deal::input smartstack hand shapeclass [holdproc min max]
    -
    -or on the command line: -
    -% deal -I "smartstack shapeclass ..."
    -
    -

    Summary

    -This is the most complicated Deal input method in the current release. -It does not read deals from a file - it is, instead, a different path to -generation of deals. The purpose of this format is to allow fast generations -of deals where one hand fits a very specific description. For example, -if you want to find hands where south has a balanced 27-count, you -could write: -
    -deal::input smartstack south balanced hcp 27 27
    -
    -On my computer, that returns the first deal in 14 seconds, and every deal after -that takes a tiny fraction of a second. That's because smartstack -first builds a large "factory" in memory, but once it is built, the -factory spits out hands matching this condition very quickly. -

    -By contrast, a standard "deal" script to find balanced 27-counts -takes about 2.8 seconds to find each deal. That means that if you only -want to find about five deals of this sort, the old style program -is faster, but if you want a lot more, use smartstack. -For example, if you wanted 1000 examples, smartstack -takes about 15 seconds, while the old deal will take about 45 minutes. -

    -One interesting feature of smartstack is that it is often -faster if the hand type is less frequent. For example, it takes about 6 -seconds to find ten deals with 9-card spade suits, and about 5 seconds to -find ten deals with 10-card spade suits. Similarly, it is faster at -finding hands with exactly 9 controls than it is at finding hands -with 9-12 controls. -

    -The smartstack routine only works on one hand - after it -places cards in that hand, it generates the rest using the usual -algorithm. -

    - -
    -
    -For Programmers:

    -

    Implementation:
    -
    Tcl code
    -
    Location:
    -
    input/smartstack.tcl, lib/handFactory.tcl
    -
    Notes
    -
    See the two articles from the bridge developers mailing list -describing the algorithm: -My first stab at describing it and -some corrections. - -
    -
    -
    -
    -

    Formatting

    - -

    Command: write_deal

    - -
    -

    Usage

    -
    -write_deal
    -
    -

    Summary

    -This is the the name of a procedure which is called when deals are accepted. -By default, it writes the result in the format: -
    -          S: 98632
    -          H: A4
    -          D: AJ754
    -          C: J
    - S: K              S: AJT7
    - H: J3             H: QT95
    - D: T98            D: Q2
    - C: AKT7532        C: 984
    -          S: Q54
    -          H: K8762
    -          D: K63
    -          C: Q6
    ---------------------------
    -
    -New output formats are defined by redefining this routine. -
    - -
    For Programmers

    -

    Implementation:
    -
    Tcl -
    Location:
    -
    format/default -
    -
    -
    -
    - -
    - -

    Command: flush_deal

    - -
    -

    Usage

    -
    -flush_deal
    -
    -

    Summary

    -This routine is called at the very end of a run for deal. It does nothing, -by default, but some output formats may require it if data is cached. -
    - -
    For Programmers

    -

    Implementation:
    -
    -
    Location:
    -
    YYYYY, function ZZZZ -
    -
    -
    -
    - -
    - - diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/commindex.html /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/commindex.html --- deal-3.0.8/docs/html/commindex.html 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/commindex.html 1970-01-01 05:30:00.000000000 +0530 @@ -1,68 +0,0 @@ - -Back to Deal top page -

    Index

    - -
  • accept -
  • balanced -
  • clubs -
  • correlation -
  • deal::input -
  • deal::metadata -
  • deal::nostacking -
  • deal_deck -
  • deal_finished -
  • deal_reset_cmds -
  • deck_stack_cards -
  • deck_stack_hand - -
  • defvector -
  • diamonds -
  • east -
  • flush_deal -
  • gets subcommand -
  • giblib input -
  • GIB-related routines -
  • gib::directory -
  • gib::tricks -
  • hand -
  • hand procedures -
  • has subcommand -
  • hcp -
  • hearts -
  • holding procedures -
  • holding -
  • holdingProc - -
  • input files -
  • is subcommand -
  • lho -
  • library.dat input -
  • line input -
  • losers -
  • main -
  • north -
  • parscore -
  • partner -
  • pattern subcommand -
  • reject -
  • reset_deck -
  • rho -
  • shape subcommand -
  • score -
  • sdev -
  • semibalanced -
  • shapeclass -
  • shapecond -
  • shapefunc -
  • shape procedures -
  • smartstack -
  • south -
  • spades -
  • stack_cards -
  • stack_hand -
  • stacked -
  • statistics -
  • west -
  • whogets -
  • write_deal - diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/commtop.html /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/commtop.html --- deal-3.0.8/docs/html/commtop.html 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/commtop.html 1970-01-01 05:30:00.000000000 +0530 @@ -1,16 +0,0 @@ - - - - - -Index of Deal Commands - - - - - - - - - - diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/dist.html /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/dist.html --- deal-3.0.8/docs/html/dist.html 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/dist.html 1970-01-01 05:30:00.000000000 +0530 @@ -1,728 +0,0 @@ - - - - - - - - - Hand Distribution Table - - - - - - -
    -

    Hand Distribution Table

    -

    -I am including this information in my web pages because I think it is -neat and that it is a method I think other writers of hand generators -might want to use. -

    -It is also the only time I can think of when I have -used anything I learned in graduate school. - -

    Creation of the table

    -

    -My program, 'Deal', needed a fast way to determine whether a hand -was in a particular class. The goal was to stay out of the TCL interpreter -as much as possible. The answer was to implement a lookup table with an easy -indexing algorithm. -

    -There are 560 hand shapes, where by "shape", I mean the ordered listing -of suit lengths: spades-hearts-diamonds-clubs. -

    -The hand shapes are in easy 1-1 correspondence with the 3-subsets -of {0,...,15}. -In particular, the hand shape with s spades, h hearts, -d diamonds, and c clubs corresponds -to the 3-set {s, s+h+1, -s+h+d+2}. -

    -There is an linear order on n-subsets, for fixed n, called the squashed -order [see Combinatorics on Finite Sets, Anderson, pp 112-119.] -The nice thing about this order is that it is easy to find the index of -an n-set in the order. -In the case of n=3, take a subset {x,y,z}, with 0<=x<y<z<=15. -The index of this set in the squashed order is -

    (z choose 3) + (y choose 2) + (x choose 1)
    -For the hand shape s-h-d-c, then, the corresponding index in the squashed -order is -
    (s+h+d+2 choose 3) + (s+h+1 choose 2) + (s choose 1)
    -

    -For added speed, I pre-computed -(n+2 choose 3) and (n+1 choose 2) for n=0,...13, placing the values -in static arrays. The resulting C code looks like: -

    -
    -static int distTableIndex(s,h,d)
    -int s,h,d;
    -{
    -  static choose2tab[]={0, 1, 3,  6, 10, 15, 21, 28,  36,  45,  55,  66,  78,  91};
    -  static choose3tab[]={0, 1, 4, 10, 20, 35, 56, 84, 120, 165, 220, 286, 364, 455};
    -  return choose3tab[s+h+d]+choose2tab[s+h]+s;
    -}
    -
    -
    - -It is precisely because I can quickly compute this index that I have -chosen the squashed order. Perhaps other orders also happen to allow -for quick indexing, but this is the one I found in my personal math library. - -

    Usage of the table

    - -The table is useful for fast lookups. For example, lets say you were -looking for hands which were five-five or better in any two suits. You could, -of course, simply check each suit length, but the problem with this is -that in an interpreted language, like Tcl, that might be too slow. If, -however, you built a 560 element binary array, and do the computation -560 times up front, then when we start analyzing actual deals, we -can quickly determine whether a particular shape was in that class. -

    -In reality, the table is not computed until the first request -is made of a shapeclass, which allows users to create large libraries -to be included but not instantiated until used. -

    -For example: -

    -
    -shapecond Balanced {$s*$s+$h*$h+$d*$d+$c*$c<=47}
    -
    -
    -When this shapeclass is first used, a table of 560 entries is created, -and then the interpreter evaluates this expression only 560 times. -For rare hand classes, this is a significant improvement. -

    -When Deal is confronted with a specific query about membership -in this class, all it has to do is use distTableIndex find the -index, then look it up in the table. This is significantly -faster than reinterpreting the Tcl code every time. -

    -The concept of "shape class" led to the concept of "shape function". -These are functions which use the shape of the hand to determine the -value. For instance, I have a function which determines the opening -suit for a hand: -

    -
    -shapefunc opensuit {
    -
    -	if {$s>=5 && $s>=$h && $s>=$d && $s>=$c} {return spades}
    -
    -	if {$h>=5 && $h>=$d && $h>=$c} { return hearts }
    -
    -	if {$d>=4 && $d>=$c} {return diamonds}
    -
    -	if {$c<3} {return diamonds}
    -
    -	return clubs
    -}
    -
    -
    -[ The current implementation of shapefunc is a bit of a memory hog, -unfortunately, since it allocates strings for every element of the -table, even if the strings are duplicates. For instance, the function -above has only 4 return values, "spades", "hearts", "diamonds", and "clubs". -Still, shapefunc instantiates 560 strings. Smarter implementations -are certainly possible, and Tcl 8.0 alleviates the problem considerably -(because it allows deals with reference-counted strings.) ] -

    -[ We could also instantiate the table an entry at a time, leaving null pointers -in the table until a value has been requested. This has the advantage that -we will often compute considerably fewer values from the table. The -disadvantage is that every time we need a value from the table, we will have -to do a check to see if a pointer value is null. It -is not clear to me this would be an improvement or not, but it would -add a complexity to the code that I am not willing to maintain. It might -seem that you would need to check a pointer anyway, to determine if the -shapeclass has been instantiated or not, but the implementation avoids -such a check.] - -

    Note

    -The above definition of Balanced is an interesting oddity, -which I leave it up to the reader to try to understand. -Think about it for a moment before you look here. - -

    Table

    - -Here is the raw data of the table. Not very interesting, but it does -help to make it clear how the squashed ordering works, and why the index -values are computed as they are. - - -Index| S H D C -================== - 0 | 0 0 0 13 - 1 | 0 0 1 12 - 2 | 0 1 0 12 - 3 | 1 0 0 12 - 4 | 0 0 2 11 - 5 | 0 1 1 11 - 6 | 1 0 1 11 - 7 | 0 2 0 11 - 8 | 1 1 0 11 - 9 | 2 0 0 11 - 10 | 0 0 3 10 - 11 | 0 1 2 10 - 12 | 1 0 2 10 - 13 | 0 2 1 10 - 14 | 1 1 1 10 - 15 | 2 0 1 10 - 16 | 0 3 0 10 - 17 | 1 2 0 10 - 18 | 2 1 0 10 - 19 | 3 0 0 10 - 20 | 0 0 4 9 - 21 | 0 1 3 9 - 22 | 1 0 3 9 - 23 | 0 2 2 9 - 24 | 1 1 2 9 - 25 | 2 0 2 9 - 26 | 0 3 1 9 - 27 | 1 2 1 9 - 28 | 2 1 1 9 - 29 | 3 0 1 9 - 30 | 0 4 0 9 - 31 | 1 3 0 9 - 32 | 2 2 0 9 - 33 | 3 1 0 9 - 34 | 4 0 0 9 - 35 | 0 0 5 8 - 36 | 0 1 4 8 - 37 | 1 0 4 8 - 38 | 0 2 3 8 - 39 | 1 1 3 8 - 40 | 2 0 3 8 - 41 | 0 3 2 8 - 42 | 1 2 2 8 - 43 | 2 1 2 8 - 44 | 3 0 2 8 - 45 | 0 4 1 8 - 46 | 1 3 1 8 - 47 | 2 2 1 8 - 48 | 3 1 1 8 - 49 | 4 0 1 8 - 50 | 0 5 0 8 - 51 | 1 4 0 8 - 52 | 2 3 0 8 - 53 | 3 2 0 8 - 54 | 4 1 0 8 - 55 | 5 0 0 8 - 56 | 0 0 6 7 - 57 | 0 1 5 7 - 58 | 1 0 5 7 - 59 | 0 2 4 7 - 60 | 1 1 4 7 - 61 | 2 0 4 7 - 62 | 0 3 3 7 - 63 | 1 2 3 7 - 64 | 2 1 3 7 - 65 | 3 0 3 7 - 66 | 0 4 2 7 - 67 | 1 3 2 7 - 68 | 2 2 2 7 - 69 | 3 1 2 7 - 70 | 4 0 2 7 - 71 | 0 5 1 7 - 72 | 1 4 1 7 - 73 | 2 3 1 7 - 74 | 3 2 1 7 - 75 | 4 1 1 7 - 76 | 5 0 1 7 - 77 | 0 6 0 7 - 78 | 1 5 0 7 - 79 | 2 4 0 7 - 80 | 3 3 0 7 - 81 | 4 2 0 7 - 82 | 5 1 0 7 - 83 | 6 0 0 7 - 84 | 0 0 7 6 - 85 | 0 1 6 6 - 86 | 1 0 6 6 - 87 | 0 2 5 6 - 88 | 1 1 5 6 - 89 | 2 0 5 6 - 90 | 0 3 4 6 - 91 | 1 2 4 6 - 92 | 2 1 4 6 - 93 | 3 0 4 6 - 94 | 0 4 3 6 - 95 | 1 3 3 6 - 96 | 2 2 3 6 - 97 | 3 1 3 6 - 98 | 4 0 3 6 - 99 | 0 5 2 6 -100 | 1 4 2 6 -101 | 2 3 2 6 -102 | 3 2 2 6 -103 | 4 1 2 6 -104 | 5 0 2 6 -105 | 0 6 1 6 -106 | 1 5 1 6 -107 | 2 4 1 6 -108 | 3 3 1 6 -109 | 4 2 1 6 -110 | 5 1 1 6 -111 | 6 0 1 6 -112 | 0 7 0 6 -113 | 1 6 0 6 -114 | 2 5 0 6 -115 | 3 4 0 6 -116 | 4 3 0 6 -117 | 5 2 0 6 -118 | 6 1 0 6 -119 | 7 0 0 6 -120 | 0 0 8 5 -121 | 0 1 7 5 -122 | 1 0 7 5 -123 | 0 2 6 5 -124 | 1 1 6 5 -125 | 2 0 6 5 -126 | 0 3 5 5 -127 | 1 2 5 5 -128 | 2 1 5 5 -129 | 3 0 5 5 -130 | 0 4 4 5 -131 | 1 3 4 5 -132 | 2 2 4 5 -133 | 3 1 4 5 -134 | 4 0 4 5 -135 | 0 5 3 5 -136 | 1 4 3 5 -137 | 2 3 3 5 -138 | 3 2 3 5 -139 | 4 1 3 5 -140 | 5 0 3 5 -141 | 0 6 2 5 -142 | 1 5 2 5 -143 | 2 4 2 5 -144 | 3 3 2 5 -145 | 4 2 2 5 -146 | 5 1 2 5 -147 | 6 0 2 5 -148 | 0 7 1 5 -149 | 1 6 1 5 -150 | 2 5 1 5 -151 | 3 4 1 5 -152 | 4 3 1 5 -153 | 5 2 1 5 -154 | 6 1 1 5 -155 | 7 0 1 5 -156 | 0 8 0 5 -157 | 1 7 0 5 -158 | 2 6 0 5 -159 | 3 5 0 5 -160 | 4 4 0 5 -161 | 5 3 0 5 -162 | 6 2 0 5 -163 | 7 1 0 5 -164 | 8 0 0 5 -165 | 0 0 9 4 -166 | 0 1 8 4 -167 | 1 0 8 4 -168 | 0 2 7 4 -169 | 1 1 7 4 -170 | 2 0 7 4 -171 | 0 3 6 4 -172 | 1 2 6 4 -173 | 2 1 6 4 -174 | 3 0 6 4 -175 | 0 4 5 4 -176 | 1 3 5 4 -177 | 2 2 5 4 -178 | 3 1 5 4 -179 | 4 0 5 4 -180 | 0 5 4 4 -181 | 1 4 4 4 -182 | 2 3 4 4 -183 | 3 2 4 4 -184 | 4 1 4 4 -185 | 5 0 4 4 -186 | 0 6 3 4 -187 | 1 5 3 4 -188 | 2 4 3 4 -189 | 3 3 3 4 -190 | 4 2 3 4 -191 | 5 1 3 4 -192 | 6 0 3 4 -193 | 0 7 2 4 -194 | 1 6 2 4 -195 | 2 5 2 4 -196 | 3 4 2 4 -197 | 4 3 2 4 -198 | 5 2 2 4 -199 | 6 1 2 4 -200 | 7 0 2 4 -201 | 0 8 1 4 -202 | 1 7 1 4 -203 | 2 6 1 4 -204 | 3 5 1 4 -205 | 4 4 1 4 -206 | 5 3 1 4 -207 | 6 2 1 4 -208 | 7 1 1 4 -209 | 8 0 1 4 -210 | 0 9 0 4 -211 | 1 8 0 4 -212 | 2 7 0 4 -213 | 3 6 0 4 -214 | 4 5 0 4 -215 | 5 4 0 4 -216 | 6 3 0 4 -217 | 7 2 0 4 -218 | 8 1 0 4 -219 | 9 0 0 4 -220 | 0 0 10 3 -221 | 0 1 9 3 -222 | 1 0 9 3 -223 | 0 2 8 3 -224 | 1 1 8 3 -225 | 2 0 8 3 -226 | 0 3 7 3 -227 | 1 2 7 3 -228 | 2 1 7 3 -229 | 3 0 7 3 -230 | 0 4 6 3 -231 | 1 3 6 3 -232 | 2 2 6 3 -233 | 3 1 6 3 -234 | 4 0 6 3 -235 | 0 5 5 3 -236 | 1 4 5 3 -237 | 2 3 5 3 -238 | 3 2 5 3 -239 | 4 1 5 3 -240 | 5 0 5 3 -241 | 0 6 4 3 -242 | 1 5 4 3 -243 | 2 4 4 3 -244 | 3 3 4 3 -245 | 4 2 4 3 -246 | 5 1 4 3 -247 | 6 0 4 3 -248 | 0 7 3 3 -249 | 1 6 3 3 -250 | 2 5 3 3 -251 | 3 4 3 3 -252 | 4 3 3 3 -253 | 5 2 3 3 -254 | 6 1 3 3 -255 | 7 0 3 3 -256 | 0 8 2 3 -257 | 1 7 2 3 -258 | 2 6 2 3 -259 | 3 5 2 3 -260 | 4 4 2 3 -261 | 5 3 2 3 -262 | 6 2 2 3 -263 | 7 1 2 3 -264 | 8 0 2 3 -265 | 0 9 1 3 -266 | 1 8 1 3 -267 | 2 7 1 3 -268 | 3 6 1 3 -269 | 4 5 1 3 -270 | 5 4 1 3 -271 | 6 3 1 3 -272 | 7 2 1 3 -273 | 8 1 1 3 -274 | 9 0 1 3 -275 | 0 10 0 3 -276 | 1 9 0 3 -277 | 2 8 0 3 -278 | 3 7 0 3 -279 | 4 6 0 3 -280 | 5 5 0 3 -281 | 6 4 0 3 -282 | 7 3 0 3 -283 | 8 2 0 3 -284 | 9 1 0 3 -285 |10 0 0 3 -286 | 0 0 11 2 -287 | 0 1 10 2 -288 | 1 0 10 2 -289 | 0 2 9 2 -290 | 1 1 9 2 -291 | 2 0 9 2 -292 | 0 3 8 2 -293 | 1 2 8 2 -294 | 2 1 8 2 -295 | 3 0 8 2 -296 | 0 4 7 2 -297 | 1 3 7 2 -298 | 2 2 7 2 -299 | 3 1 7 2 -300 | 4 0 7 2 -301 | 0 5 6 2 -302 | 1 4 6 2 -303 | 2 3 6 2 -304 | 3 2 6 2 -305 | 4 1 6 2 -306 | 5 0 6 2 -307 | 0 6 5 2 -308 | 1 5 5 2 -309 | 2 4 5 2 -310 | 3 3 5 2 -311 | 4 2 5 2 -312 | 5 1 5 2 -313 | 6 0 5 2 -314 | 0 7 4 2 -315 | 1 6 4 2 -316 | 2 5 4 2 -317 | 3 4 4 2 -318 | 4 3 4 2 -319 | 5 2 4 2 -320 | 6 1 4 2 -321 | 7 0 4 2 -322 | 0 8 3 2 -323 | 1 7 3 2 -324 | 2 6 3 2 -325 | 3 5 3 2 -326 | 4 4 3 2 -327 | 5 3 3 2 -328 | 6 2 3 2 -329 | 7 1 3 2 -330 | 8 0 3 2 -331 | 0 9 2 2 -332 | 1 8 2 2 -333 | 2 7 2 2 -334 | 3 6 2 2 -335 | 4 5 2 2 -336 | 5 4 2 2 -337 | 6 3 2 2 -338 | 7 2 2 2 -339 | 8 1 2 2 -340 | 9 0 2 2 -341 | 0 10 1 2 -342 | 1 9 1 2 -343 | 2 8 1 2 -344 | 3 7 1 2 -345 | 4 6 1 2 -346 | 5 5 1 2 -347 | 6 4 1 2 -348 | 7 3 1 2 -349 | 8 2 1 2 -350 | 9 1 1 2 -351 |10 0 1 2 -352 | 0 11 0 2 -353 | 1 10 0 2 -354 | 2 9 0 2 -355 | 3 8 0 2 -356 | 4 7 0 2 -357 | 5 6 0 2 -358 | 6 5 0 2 -359 | 7 4 0 2 -360 | 8 3 0 2 -361 | 9 2 0 2 -362 |10 1 0 2 -363 |11 0 0 2 -364 | 0 0 12 1 -365 | 0 1 11 1 -366 | 1 0 11 1 -367 | 0 2 10 1 -368 | 1 1 10 1 -369 | 2 0 10 1 -370 | 0 3 9 1 -371 | 1 2 9 1 -372 | 2 1 9 1 -373 | 3 0 9 1 -374 | 0 4 8 1 -375 | 1 3 8 1 -376 | 2 2 8 1 -377 | 3 1 8 1 -378 | 4 0 8 1 -379 | 0 5 7 1 -380 | 1 4 7 1 -381 | 2 3 7 1 -382 | 3 2 7 1 -383 | 4 1 7 1 -384 | 5 0 7 1 -385 | 0 6 6 1 -386 | 1 5 6 1 -387 | 2 4 6 1 -388 | 3 3 6 1 -389 | 4 2 6 1 -390 | 5 1 6 1 -391 | 6 0 6 1 -392 | 0 7 5 1 -393 | 1 6 5 1 -394 | 2 5 5 1 -395 | 3 4 5 1 -396 | 4 3 5 1 -397 | 5 2 5 1 -398 | 6 1 5 1 -399 | 7 0 5 1 -400 | 0 8 4 1 -401 | 1 7 4 1 -402 | 2 6 4 1 -403 | 3 5 4 1 -404 | 4 4 4 1 -405 | 5 3 4 1 -406 | 6 2 4 1 -407 | 7 1 4 1 -408 | 8 0 4 1 -409 | 0 9 3 1 -410 | 1 8 3 1 -411 | 2 7 3 1 -412 | 3 6 3 1 -413 | 4 5 3 1 -414 | 5 4 3 1 -415 | 6 3 3 1 -416 | 7 2 3 1 -417 | 8 1 3 1 -418 | 9 0 3 1 -419 | 0 10 2 1 -420 | 1 9 2 1 -421 | 2 8 2 1 -422 | 3 7 2 1 -423 | 4 6 2 1 -424 | 5 5 2 1 -425 | 6 4 2 1 -426 | 7 3 2 1 -427 | 8 2 2 1 -428 | 9 1 2 1 -429 |10 0 2 1 -430 | 0 11 1 1 -431 | 1 10 1 1 -432 | 2 9 1 1 -433 | 3 8 1 1 -434 | 4 7 1 1 -435 | 5 6 1 1 -436 | 6 5 1 1 -437 | 7 4 1 1 -438 | 8 3 1 1 -439 | 9 2 1 1 -440 |10 1 1 1 -441 |11 0 1 1 -442 | 0 12 0 1 -443 | 1 11 0 1 -444 | 2 10 0 1 -445 | 3 9 0 1 -446 | 4 8 0 1 -447 | 5 7 0 1 -448 | 6 6 0 1 -449 | 7 5 0 1 -450 | 8 4 0 1 -451 | 9 3 0 1 -452 |10 2 0 1 -453 |11 1 0 1 -454 |12 0 0 1 -455 | 0 0 13 0 -456 | 0 1 12 0 -457 | 1 0 12 0 -458 | 0 2 11 0 -459 | 1 1 11 0 -460 | 2 0 11 0 -461 | 0 3 10 0 -462 | 1 2 10 0 -463 | 2 1 10 0 -464 | 3 0 10 0 -465 | 0 4 9 0 -466 | 1 3 9 0 -467 | 2 2 9 0 -468 | 3 1 9 0 -469 | 4 0 9 0 -470 | 0 5 8 0 -471 | 1 4 8 0 -472 | 2 3 8 0 -473 | 3 2 8 0 -474 | 4 1 8 0 -475 | 5 0 8 0 -476 | 0 6 7 0 -477 | 1 5 7 0 -478 | 2 4 7 0 -479 | 3 3 7 0 -480 | 4 2 7 0 -481 | 5 1 7 0 -482 | 6 0 7 0 -483 | 0 7 6 0 -484 | 1 6 6 0 -485 | 2 5 6 0 -486 | 3 4 6 0 -487 | 4 3 6 0 -488 | 5 2 6 0 -489 | 6 1 6 0 -490 | 7 0 6 0 -491 | 0 8 5 0 -492 | 1 7 5 0 -493 | 2 6 5 0 -494 | 3 5 5 0 -495 | 4 4 5 0 -496 | 5 3 5 0 -497 | 6 2 5 0 -498 | 7 1 5 0 -499 | 8 0 5 0 -500 | 0 9 4 0 -501 | 1 8 4 0 -502 | 2 7 4 0 -503 | 3 6 4 0 -504 | 4 5 4 0 -505 | 5 4 4 0 -506 | 6 3 4 0 -507 | 7 2 4 0 -508 | 8 1 4 0 -509 | 9 0 4 0 -510 | 0 10 3 0 -511 | 1 9 3 0 -512 | 2 8 3 0 -513 | 3 7 3 0 -514 | 4 6 3 0 -515 | 5 5 3 0 -516 | 6 4 3 0 -517 | 7 3 3 0 -518 | 8 2 3 0 -519 | 9 1 3 0 -520 |10 0 3 0 -521 | 0 11 2 0 -522 | 1 10 2 0 -523 | 2 9 2 0 -524 | 3 8 2 0 -525 | 4 7 2 0 -526 | 5 6 2 0 -527 | 6 5 2 0 -528 | 7 4 2 0 -529 | 8 3 2 0 -530 | 9 2 2 0 -531 |10 1 2 0 -532 |11 0 2 0 -533 | 0 12 1 0 -534 | 1 11 1 0 -535 | 2 10 1 0 -536 | 3 9 1 0 -537 | 4 8 1 0 -538 | 5 7 1 0 -539 | 6 6 1 0 -540 | 7 5 1 0 -541 | 8 4 1 0 -542 | 9 3 1 0 -543 |10 2 1 0 -544 |11 1 1 0 -545 |12 0 1 0 -546 | 0 13 0 0 -547 | 1 12 0 0 -548 | 2 11 0 0 -549 | 3 10 0 0 -550 | 4 9 0 0 -551 | 5 8 0 0 -552 | 6 7 0 0 -553 | 7 6 0 0 -554 | 8 5 0 0 -555 | 9 4 0 0 -556 |10 3 0 0 -557 |11 2 0 0 -558 |12 1 0 0 -559 |13 0 0 0 - -
    -
    -Silhouette -Thomas Andrews -(thomaso@best.com) -Copyright 1996-2002. Deal is covered by the -GNU General Public License. -
    - -
    - - diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/downloading.html /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/downloading.html --- deal-3.0.8/docs/html/downloading.html 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/downloading.html 1970-01-01 05:30:00.000000000 +0530 @@ -1,245 +0,0 @@ - - - - - - - - - Deal 3.0 - Downloading - - - - - - - - - -
    Deal 3.0 -

    Downloading Deal

    -
    - -
    -
    - -

    Downloading Deal 3.0.7

    -
      -
    • DOS/Windows release of Deal 3.0.7, [460K]. -Tested on Windows 98, but past versions have worked on Windows 95, Windows NT, -and Windows ME. I'm not sure if it works on Windows XP. -

      This is a standalone release, just unzip it and you are ready to -run. It will create a directory called "deal307." -

      -Note: This is not a Windows program - it is a DOS program. If, after -unzipping, you double click on the Deal application, it will open a DOS -window, deal 10 deals, then close, which is hardly useful. See the -Windows/DOS tutorial for operation instructions. -

      -

    • The Deal 3.0.7 source code (.zip file), -[280K]. This source release is intended for use with "make," and hence -more of a Unix source release. Unzip this file - it should create -a source directory called deal307. Then go to Building Deal for hints on how to build Deal on -your platform. -
    -

    Recent Changes

    -
    -Changes in Deal 3.0.7
    -
    -[ No binary changes - all changes in the Tcl files. ]
    -
    -   * Changed "score" to be a table lookup.
    -   * Fixed a bug in "parscore" which wrong-sided the
    -     contract sometimes.
    -   * Fixed documentation file "commands.html".
    -
    -Changes in Deal 3.0.6
    -
    -[ No binary changes this release - all changes in the Tcl files. ]
    -
    -   * Made changes to gib.tcl to work with the latest version of GIB.
    -
    -   * Fixed a few bugs with various formatting procedures.
    -
    -Changes in Deal 3.0.5
    -
    -   * Fixed a bug - Deal 3.0.4 failed to recognize "-" as void
    -   in -S, -E, -N, -W options, as well as in "north is " commands.
    -
    -     -----
    -
    -Changes in Deal 3.0.4
    -
    -   * Update doc examples to match ex/ subdirectory.
    -
    -   * Deleted util.c and util.h from distribution.
    -
    -     -----
    -
    -Changes in Deal 3.0.3
    -
    -  * Added GNU General Public License copyright to most files, and full
    -  GPL text to release.
    -
    -  * Altered deal.c to improve performance of reset_deal() routine.
    -  Improved overall performance of 10%.
    -
    -  * Re-implemented in Tcl the broken undocumented old procedures,
    -   intersectclass, negateclass, and joinclass.  This lets you create
    -   new shape classes from old shape classes using standard boolean
    -   functions.  Old code removed from dist.c, new code added to deal.tcl .
    -
    -  * Deleted some unused code in deal.tcl which was left from early
    -   efforts at the smart stacking routines.
    -
    -  * Updated the documentation
    -
    -     -----
    -Changes in Deal 3.0.2
    -
    -  * Fixed a bug in the smartstack methods.
    -
    -  * Altered zip builds to put files in deal302 directory (rather than
    -   deal3.0.2)
    -
    -  * Polished the HTML docs (in docs/html directory.)
    -
    -  * Many, many improved error messages when commands are misused
    -
    -  * Cleaned up some code
    -
    -  * Made dist.c use more Tcl_Obj pointers rather than strings - makes for
    -   faster compiles of shape classes.  (I can't believe I left those
    -   sprintf calls for so long. :-)
    -
    -  * Fixed some of the examples which called deal::stack_hand, a non-existant
    -   procedure.
    -
    -     -----
    -
    -Changes in Deal 3.0.1
    -
    -The changes for Deal 3.0.1 (from Deal 3.0 beta 11) were made essentially
    -for two reasons:
    -
    - (1) To finish the Deal 3.0 release - e.g., added documentation.
    - (2) To add features needed for the "smartstack" routines.
    -
    -  * Include HTML docs in docs/html directory.
    -
    -  * Most library files in release moved to the lib directory
    -
    -  * Added "smartstack" input class for fast building of hands which fit
    -  specific patterns
    -  
    -  * Added "stacked" procedure to find out the current state of the
    -  deck-stacking. Returns the list of cards stacked to the named hand.
    -
    -  * Altered stacking methods.  Added procedures "deck_stack_cards," 
    -  "deck_stack_hand", "stack_cards," and "stack_hand."  By default,
    -  "stack_hand" and "stack_cards" just call the "deck_" procedures,
    -  but the idea is that "stack_cards" and "stack_hands" can be
    -  overridden. Now when you call "south is AJ4 KJ54 9643 72" it in
    -  turn calls "stack_hand south AJ4 KJ54 9643 72." Similarly,
    -  "south gets ..." calls "stack_cards," although there the transformation
    -  is somewhat different.
    -  
    -  * Added "list" subcommand to shape classes.  e.g.,
    -
    -	  shapeclass hasVoid { expr {$s*$h*$d*$c==0} }
    -
    -	  foreach shape [hasVoid list] {
    -		...
    -	  }
    -
    -  * Added "shape" subcommand to the shape classes and functions, e.g.,
    -
    -	  shapefunc foo { ... }
    -
    -	  foo shape {4 2 4 3}
    -
    -    So:
    -
    -	  foo north
    -
    -    Is the same as:
    -
    -	  foo shape [north shape]
    -
    -  * Added the "holding" utility procedure, with subcommands length,
    -    disjoint, ...
    -
    -	  holding length AKxxx   =>    5
    -	  holding disjoint AKJ4 QT94  => 0    [ false ]
    -  
    -New to Deal 3.0:
    -
    -  * Fast holding procedures definable with holdingProc.
    -
    -  * GIB interfaces (gib::directory, gib::tricks, parscore)
    -
    -  * Bridge utility routines - lho, rho, partner, score
    -
    -  * Input format extensibility
    -
    -  * Uses features of faster versions of Tcl (Tcl 8.x)
    -
    -
    - -

    Building Deal

    -

    Selecting Tcl

    -Many Unix and Linux computers already have Tcl installed. If your -computer does not, you will need to select a version and install it. -

    -On Unix, I'd recommend Tcl 8.3.x (or later,) but on Windows, I'd recommend Tcl -8.0.5, because I've had problems with Tcl hanging with later versions. -

    -All versions of Tcl can be downloaded from the -Scriptics web site. -

    -

    The Makefile

    -After downloading the Deal source code, -you should get a zip file. When you unzip it, you should get a directory, -deal307. -

    -On Unix machines, you will need to edit the Makefile to point to -your installation of Tcl. You may have to -change the following variables in the Makefile: -

    -
    TCL_LIB -
    The directory where the Tcl library is installed. - default value is /usr/local/lib. -
    TCL_INCL -
    The directory where tcl.h is installed. The default - value is /usr/local/include. -
    LDFLAGS -
    Really a list of liabraries needed at link time. By default, - "-L($TCL_LIB) -ltcl8.3 -lm", which works - at least on SunOS 4, HP, and SGI. On Solaris 2, you need to - add "-ldl -lsocket -lnsl". -
    EXTRA_CFLAGS -
    Whatever else you need... -
    -
    -
    -Silhouette - Thomas Andrews -(thomaso@best.com) - Copyright 1996-2002. Deal is covered by the -GNU General Public License. -

    -Plane Dealing graphic -above created using -POV-Ray. -

    -
    - - diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/1-shapeclass.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/1-shapeclass.txt --- deal-3.0.8/docs/html/ex/1-shapeclass.txt 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/ex/1-shapeclass.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,36 +0,0 @@ -############################################## -# Look for hand where north has 44 in the majors, a short minor, -# and 11-15 HCP. -# -# To execute: -# deal -i ex/1-shapeclass.tcl [num] -############################################## - -shapeclass roman_short_minor {expr {$h==4 && $s==4 && ($c<=1 || $d<=1)}} - -main { - reject unless {[roman_short_minor north]} - set hcp_n [hcp north] - accept if {$hcp_n>=11 && $hcp_n<=15} -} -############################################## - - - -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/1-stack.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/1-stack.txt --- deal-3.0.8/docs/html/ex/1-stack.txt 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/ex/1-stack.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,52 +0,0 @@ -############################################## -# Look for hand where north has 44 in the majors, a short minor, -# and 11-15 HCP. -# -# To execute: -# deal -i ex/1-stack.tcl [num] -# -# This example uses the smart stacking algorithm to generate the -# same sorts of hands as example1 and example1-shapeclass. -# The very first deal is slow - when the deal is requested a -# large "factory" object is built in memory - but every other -# deal generated after that first one is generated extremely quickly. -# -# In this example, you'd have to want about 1500 matches to the condition -# for the investment to break even. But after 1500, the advantage of -# the smart stacking is huge. -# -# The payoff is even greater for rarer hand conditions. -############################################## - -shapeclass roman_short_minor {expr $h==4 && $s==4 && ($c<=1 || $d<=1)} - -deal::input smartstack north roman_short_minor HCP 11 15 - - -set start [clock seconds] -set count 0 -defvector HCP 4 3 2 1 - -proc flush_deal {} { - global start - global count - set time [expr {[clock seconds]-$start}] -} - -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/1.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/1.txt --- deal-3.0.8/docs/html/ex/1.txt 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/ex/1.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,51 +0,0 @@ -############################################## -# Look for hand where north has 44 in the majors, a short minor, -# and 11-15 HCP. -# -# Parts of this could be done more efficiently with a "shapeclass" -# command. -# -# To execute: -# deal -i ex/1.tcl [num] -############################################## -main { - # Pitch deals - # where north does - # not have four spades - reject if {[spades north]!=4} - - # Pitch deals - # where north does - # not have four hearts - reject if {[hearts north]!=4} - - # Pitch deals - # where north has - # 2 or 3 diamonds - set d [diamonds north] - reject if {$d==2} {$d==3} - - # Accept deals - # where north has - # 11-15 HCP. - set hcp_n [hcp north] - accept if {$hcp_n>=11 && $hcp_n<=15} -} -############################################## -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/2.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/2.txt --- deal-3.0.8/docs/html/ex/2.txt 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/ex/2.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,29 +0,0 @@ - -# I held the south hand given below, and east opened 2C. -# I overcalled 2S red-on-red. This procedure deals hands -# where east will open 2C in front of the south hand. - -south is "Q86432 T2 932 83" - -main { - set h [hcp east] - reject if {$h<18} - accept if {$h>22} {[losers east]<4} -} -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/3nt-common.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/3nt-common.txt --- deal-3.0.8/docs/html/ex/3nt-common.txt 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/ex/3nt-common.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,36 +0,0 @@ -shapecond gam3NT.shape {$s<=3&&$h<=3&&(($d>=7&&$c<=4)||($c>=7&&$d<=4))} - -# return '1' if not compatible with a gambling notrump hand, -# '0' otherwise -holdingProc gam3NT.suit {A K Q J len} { - - if {$len>=7} { - if {$len<=9&&$A&&$K&&$Q} { return 0} - return 1 - } - - if {$len<=4} { - if {$A||$K} { return 1 } - return 0 - } - - return 1 - -} -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/3nt-nostack.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/3nt-nostack.txt --- deal-3.0.8/docs/html/ex/3nt-nostack.txt 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/docs/html/ex/3nt-nostack.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,54 +0,0 @@ -# -# -# To run: -# -# deal -i ex/3nt-nostack.tcl -# -# Find deals where south is "AK K52 98765 962" and north has a gambling -# 3nt hand. -# -# This uses the definition: Solid 7-9 card minor suit, no 4-card major or -# 5+ card in the other minor, no controls outside the solid suit. -# -# This is slower than the smart-stacking version by an order of magnitude -# when requesting 1000 deals. -# -source /usr/share/deal/format/none - -south is "AK K52 98765 962" - -source 3nt-common.txt - -set diamonds 0 -set clubs 0 - -main { - reject unless {[gam3NT.shape north]} - reject unless {0==[gam3NT.suit north]} - if {[diamonds north]>=7} { incr diamonds } { incr clubs } - puts "-- [north shape]" - accept -} - -deal_finished { - #puts "Solid diamonds: $diamonds" - #puts "Solid clubs : $clubs" -} - -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/3nt-stack.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/3nt-stack.txt --- deal-3.0.8/docs/html/ex/3nt-stack.txt 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/docs/html/ex/3nt-stack.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,65 +0,0 @@ -# -# Find deals where south is "AK K52 98765 962" and north has a gambling -# 3nt hand. -# -# This was one of the first examples I gave of how "smart stacking" could -# be used. -# -# Compare output from this with output from ex/3nt-nostack.tcl to make -# sure that the relative odds are being obeyed, eg: -# -# deal -i ex/3nt-stack.tcl 1000 | sort | uniq -c | sort -nr > stack.txt -# deal -i ex/3nt-nostack.tcl 1000 | sort | uniq -c | sort -nr > nostack.txt -# -# Obviously, they shouldn't be exactly the same, but they should be similar. - -source /usr/share/deal/format/none - -shapecond gam3NT.shape {$s<=3&&$h<=3&&(($d>=7&&$c<=4)||($c>=7&&$d<=4))} - -# return '1' if not compatible with a gambling notrump hand, -# '0' otherwise -holdingProc gam3NT.suit {A K Q J len} { - - if {$len>=7} { - if {$len<=9&&$A&&$K&&$Q} { return 0} - return 1 - } - - if {$len<=4} { - if {$A||$K} { return 1 } - return 0 - } - - return 1 - -} - -deal::input smartstack north gam3NT.shape gam3NT.suit 0 0 - -south is "AK K52 98765 962" - -# Dump the data table from the smart stacking routine - -main { - puts "-- [north shape]" - accept -} - -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/3-shapeclass.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/3-shapeclass.txt --- deal-3.0.8/docs/html/ex/3-shapeclass.txt 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/ex/3-shapeclass.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,42 +0,0 @@ -# You hold the south hand: 764 J4 J753 AQJ2 -# and the auction has gone: 1S(W)-1NT-2NT-3NT by the opponents, -# who are playing 2/1. -# Choose a lead. - -# In this example, I've assumed west has no side 4-card suit, -# and that he holds exactly 5 spades and 16-19 HCP. - -# I've also assumed that East had some way to show a 5-card heart -# suit over 2NT, and hence, that he doesn't hold one, and also that -# east does not have spade support. - -south is 764 J4 J753 AQJ2 - -shapecond balanced5S {$s==5&&($h*$d*$c==18)} - -main { - reject unless {[balanced5S west]} - set w [hcp west] - reject if {$w<16} {$w>19} - reject if {[hearts east]>4} {[spades east]>2} - set e [hcp east] - reject if {$e<6} {$e>11} {[losers east]<6} - accept -} -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/3.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/3.txt --- deal-3.0.8/docs/html/ex/3.txt 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/ex/3.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,40 +0,0 @@ -# You hold the south hand: 764 J4 J753 AQJ2 -# and the auction has gone: 1S(W)-1NT-2NT-3NT by the opponents, -# who are playing 2/1. -# Choose a lead. - -# In this example, I've assumed west has no side 4-card suit, -# and that he holds exactly 5 spades and 16-19 HCP. - -# I've also assumed that East had some way to show a 5-card heart -# suit over 2NT, and hence, that he doesn't hold one, and also that -# east does not have spade support. - -south is 764 J4 J753 AQJ2 - -main { - reject unless {[spades west]==5} - set w [hcp west] - reject if {$w<16} {$w>19} {[hearts west]>3} {[diamonds west]>3} {[clubs west]>3} - reject if {[hearts east]>4} {[spades east]>2} - set e [hcp east] - reject if {$e<6} {$e>11} {[losers east]<6} - accept -} -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/4-holding.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/4-holding.txt --- deal-3.0.8/docs/html/ex/4-holding.txt 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/ex/4-holding.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,32 +0,0 @@ -# -# By agreement, you open a weak 2 with exactly 6 cards in your major, -# fewer than 4 cards in the other major, 5-10 HCP and either 2 of the -# top 3 or three of the top 5 in your suit. -# - -holdingProc -boolean Weak2Quality {length A K Q J T} { - expr {$length==6 && (($A+$K+$Q)>=2 || ($A+$K+$Q+$J+$T)>=3)} -} - -main { - set sh [hcp south] - reject if {$sh>10} {$sh<5} {[hearts south]>3} {[clubs south]>3} {[diamonds south]>3} - accept if {[Weak2Quality south spades]} -} -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/4-stack.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/4-stack.txt --- deal-3.0.8/docs/html/ex/4-stack.txt 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/ex/4-stack.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,36 +0,0 @@ -# -# By agreement, you open a weak 2 with exactly 6 cards in your major, -# fewer than 4 cards in the other major, 5-10 HCP and either 2 of the -# top 3 or three of the top 5 in your suit. -# - -holdingProc -boolean Weak2Quality {length A K Q J T} { - accept if {$length<3} - reject unless {$length==6} - accept if {(($A+$K+$Q)>=2 || ($A+$K+$Q+$J+$T)>=3)} -} - -shapecond Weak2Shape {$d<=3&&$c<=3&&(($h<=3&&$s==6)||($h==6&&$s<=3))} - -deal::input smartstack south Weak2Shape hcp 5 10 - -smartstack::restrictHolding spades Weak2Quality 1 1 -smartstack::restrictHolding hearts Weak2Quality 1 1 - -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/4.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/4.txt --- deal-3.0.8/docs/html/ex/4.txt 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/ex/4.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,37 +0,0 @@ -# -# By agreement, you open a weak 2 with exactly 6 cards in your major, -# fewer than 4 cards in the other major, 5-10 HCP and either 2 of the -# top 3 or three of the top 5 in your suit. -# - -defvector W2Q 2 2 2 1 1 -main { - set sh [hcp south] - reject if {$sh>10} {$sh<5} {[clubs south]>3} {[diamonds south]>3} - set s [spades south] - if {$s == 6} { - reject if {[hearts south]>3} {[W2Q south spades]<=3} - accept - } - reject if {$s>3} - set h [hearts south] - reject if {$h!=6} {[W2Q south hearts]<=3} - accept -} -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/5.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/5.txt --- deal-3.0.8/docs/html/ex/5.txt 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/ex/5.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,41 +0,0 @@ -############################# -# When I first wrote this I was somewhat surprised. -# -# This deals hands where south opens a strong blue club and -# north has a 3+ controls (that is, he has a strong positive -# response.) -# -# I was surprised to find that slam was making 1/2 the time on these -# hands. In other words, for Blue-clubbers, if the auction starts: -# -# 1C 1S/1NT/2C/2D -# -# there is a 50% chance that a slam should be bid... -############################# - -main { - reject unless {[controls north]>=3} - set w [hcp south] - reject unless {$w >=17} - if {[balanced south]} { - reject if {$w==17} {$w>=22 && $w<=24} - } - accept -} -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/6a.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/6a.txt --- deal-3.0.8/docs/html/ex/6a.txt 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/ex/6a.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,56 +0,0 @@ -# -# File: ex/6a.tcl -# -# This is a test which shows why you'd want to use a "shape class" -# or "shape function", which are fast lookup tables... -# -# This is the slow version, which doesn't use the shape function -# -# It seeks hands where north and south have voids in the same -# suit. (Alternatively, it finds hands where east and west have -# a 13-card fit.) -# -# See ex/6b.tcl and ex/6c.tcl for faster versions of the same search -# - -main { - accept unless {[spades south]!=0} {[spades north]!=0} - accept unless {[hearts south]!=0} {[hearts north]!=0} - accept unless {[diamonds south]!=0} {[diamonds north]!=0} - accept unless {[clubs south]!=0} {[clubs north]!=0} -} - -# It should be noted that this script is written so that -# the north hand is never even dealt unless the south hand -# has a void. That's because, internally, 'deal' doesn't deal -# a hand unless information is requested about that hand. -# -# If the lines were: -# -# accept if {[spades south]==0 && [spades north]==0} -# -# 'deal' would request information for *both* hands, and that would -# double the amount of work. Hence the use of the slightly less clear -# 'accept unless' idiom. -# -# How much of an optimization is it to not deal the north hand? -# Profiling has shown me that a vast amount of time is spent in -# the randomnization routines, so cutting down on these calls -# is a significant time savings. -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/6b.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/6b.txt --- deal-3.0.8/docs/html/ex/6b.txt 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/ex/6b.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,48 +0,0 @@ -# -# File: ex/6b.tcl -# -# This implements the same search as ex/6a.tcl, using a simple -# shape class. -# -# Basically, we use a shapeclass to immediately reject deals where -# south doesn't have a void. This keeps us from doing unnecessary -# work, and practically doubles the speed of the search. -# -# The shape class "hasvoid" returns one (True) if there is a void -# somewhere in the hand and zero (False) otherwise. It would -# seem like this is doing *more* work than example A, but the -# lookup in a shapeclass is much better optimized, and we break -# out of the loop if south doesn't have void, and move on to -# the next. -# -# example6c is about the same speed but uses an idiom worth -# seeing for other sorts of problems. -# - -shapecond hasvoid {$s==0 || $h==0 || $d==0 || $c==0} - -main { - reject unless [hasvoid south] - accept if {[spades south]==0 && [spades north]==0} - accept if {[hearts south]==0 && [hearts north]==0} - accept if {[diamonds south]==0 && [diamonds north]==0} - accept if {[clubs south]==0 && [clubs north]==0} - reject -} -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/6c.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/6c.txt --- deal-3.0.8/docs/html/ex/6c.txt 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/ex/6c.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,62 +0,0 @@ -# -# File: ex/6c.tcl -# -# This file uses a "shape function" to optimize a search for hands -# where north and south have voids in the same suit. -# -# The shape function "voids" returns a list of the suits in which -# the hand given has a void. So if south is: -# -# S --- S AK5 S KJ8 -# H 5432 H A982 H Q932 -# D --- D 543 D AT9863 -# C AQT986543 C T92 C ---- -# -# [voids south] will return: -# -# "spades diamonds" "" "clubs" -# -# We then run through this list and check if north has any void in -# common. -# -# This doesn't seem like it would be faster, but it is, because -# the shape function is computed up front as a table, and each call -# after the first is a quick lookup. In fact, this is twice -# as fast as the script in ex/6a.tcl . -# -# It is only slightly faster than ex/6b.tcl, though. The main -# reason I include it is to show a technique that can be used elsewhere. -# Another example which uses this is example7, a rather complicated routine... -# - -shapefunc voids { - set res "" - if {$s==0} { lappend res spades } - if {$h==0} { lappend res hearts } - if {$d==0} { lappend res diamonds } - if {$c==0} { lappend res clubs } - return $res -} - -main { - foreach suit [voids south] { - accept if {[$suit north]==0} - } -} -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/6d.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/6d.txt --- deal-3.0.8/docs/html/ex/6d.txt 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/ex/6d.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,53 +0,0 @@ -# -# File: ex/6d.tcl -# -# This file uses a "holding function" to optimize a search for hands -# where north and south have voids in the same suit. -# -# The holding function "isVoid" returns a list of the suits in which -# the hand given has a void. So if south is: -# -# S --- S AK5 S KJ8 -# H 5432 H A982 H Q932 -# D --- D 543 D AT9863 -# C AQT986543 C T92 C ---- -# -# [voids south] will return: -# -# "spades diamonds" "" "clubs" -# -# This is the same output as in the "voids" procedure for ex/6c.tcl, -# but it is implemented as a holding procedure rather than a shape -# procedure. -# -# We then run through this list and check if north has any void in -# common. -# -# This is considerably slower the 6b.tcl and 6c.tcl, though. - -holdingProc -boolean voids {len} { - expr {$len==0} -} - -main { - foreach suit [voids south] { - accept if {[$suit north]==0} - } -} -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/7.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/7.txt --- deal-3.0.8/docs/html/ex/7.txt 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/docs/html/ex/7.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,99 +0,0 @@ -# -# A Certain poster to rec.games.bridge has been posting -# a computer generated bidding system that, to most bridge -# players eyes, looks somewhat deranged. -# - -# bid.lib is a library of tcl routines which allow you -# to define opening bids and later check to see if a hand -# fits the conditions - -source /usr/share/deal/lib/bid.tcl - -defvector AKQ 4 3 2 -defvector Top4 1 1 1 1 -defvector Aces 1 -defvector None 0 -proc top4spades {hand} { - return [Top4 $hand spades] -} - -# Usage: -# describebid -# -# Don Quixote's system: -# -describebid 5D {$d>=8} AKQ 0 3 -describebid 5C {$c>=8} controls 0 1 -describebid 4S {$s==8} controls 0 3 -describebid 4H {$h>=7} controls 0 1 -describebid 4D {$d>=8} AKQ 5 7 -describebid 4C {$h==8 && $d*$c*$s==3} Aces 1 1 -describebid 3NT {$s==9 && ($h==2 || $d==2 || $c==2)} top4spades 2 4 -describebid 3S {$s==7 && $d*$c*$h==6} AKQ 0 7 -describebid 3H {$h==7} losers 16 17 -describebid 3D {$d==7 && ($h==3 || $c==3 || $d==3)} hcp 3 3 -describebid 3C {$c==7 && $d*$h*$s==4} AKQ 0 3 -describebid 2NT {$s==7 && $c*$h*$d==8} hcp 4 5 -describebid 2S {$s==7 && $c*$d*$h==4} hcp 3 5 -describebid 2H {$h==7} Aces 0 0 -describebid 2D {$d==7 && $h*$s*$c==6} hcp 2 5 -describebid 2C {$c>=3 && $d>=3 && $h>=3 && $s>=3} hcp 22 23 - -####################################### -# -# This uses the proceducre "getbidlist", which is really -# a "shapefunc" defined in bid.lib . It returns a list -# of all the possible described bids which can be made, given -# only the shape of the hand. This turns out to be a very -# good optimization - rather than looping through all the -# bids, we only have to loop through a small subset. -# -# "checkcondition" then actually checks whether the hand -# is fits the other condition (which does a computation -# using the function provided and checks whether the hand is -# in the correct range.) -# -# This search looks for (south) hands which would open -# 2C under the above system. What kind of system -# opens at the 2 level only 1/100 times, anyway? -# Bizarre. -# -####################################### - -foreach bid $bidlist { - set count($bid) 0 -} -set accepted 0 -set tried 0 - -main { - incr tried - foreach bid [getbidlist south] { - if {[checkcondition $bid south]} { - puts "$bid with [south]" - incr count($bid) - incr accepted - accept - } - } - reject -} - -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ex/holdingProc.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ex/holdingProc.txt --- deal-3.0.8/docs/html/ex/holdingProc.txt 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/ex/holdingProc.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,54 +0,0 @@ -# -# A simple 'holding procedure' to determine high card points -# -holdingProc HCP {A K Q J} { - expr {$A*4+$K*3+$Q*2+$J} -} - -# -# The 'smartPoints' procedure incorporates two adjustments to -# the standard high card points. -# -# 1) A point is added for every card over 4 in a single suit -# 2) Honors in short suits are somewhat discounted -# -holdingProc smartPoints {length A K Q J} { - if {$length>=5} { - return [expr {$A*4+$K*3+$Q*2+$J+$length-4}] - } - if {$length==0} { return 0 } - if {$length==1} { - return [expr {$A*4+$K*2}] - } - if {$length==2} { - return [expr {$A*4+$K*3+$Q}] - } - expr {$A*4+$K*3+$Q*2+$J} -} - -# -# Find deals where north has less than 13 HCP but are compensated over -# 13 points by shape -# -main { - reject if {[HCP north]>12} - accept if {[smartPoints north]>12} -} - -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/examples.html /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/examples.html --- deal-3.0.8/docs/html/examples.html 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/examples.html 1970-01-01 05:30:00.000000000 +0530 @@ -1,80 +0,0 @@ - - - - - - - - - Deal - Example Scripts - - - - - - - - - - - - - - -
    Plane Dealing image

    Deal 3.0

    -

    Examples

    -
    -
    -
    - -
      -
    • Example 1: North is 44 in majors and short in -a minor, with 11 to 15 points. -
    • Example 2: South holds a specific hand and -east opens two clubs. -
    • Example 3: Holding a specific hand, south -on lead after opponents bid: 1S(W)-1NT-2NT-3NT. -
    • Example 4: South opens a weak two in spades -or hearts -
    • Example 5: Playing Blue Club, responder -to 1C opening has three or more controls -
    • Shape class variants of above examples: - -
    • Example 6: Find deals where north and south are void in the same suit, -using several different methods. - -
    • Smart stacking examples: - -
    -
    -
    -Silhouette - Thomas Andrews -(thomaso@best.com) - Copyright 1996-2002. Deal is covered by the -GNU General Public License. -

    -Plane Dealing graphic -above created using -POV-Ray. -

    - diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/ext-ref.html /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/ext-ref.html --- deal-3.0.8/docs/html/ext-ref.html 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/ext-ref.html 1970-01-01 05:30:00.000000000 +0530 @@ -1,61 +0,0 @@ - - - - - Deal - Other References and Resources - - - - - - - -Back to Deal Top Page. - - - - - - -
    Jack of Hearts

    Deal 3.0

    -

    Other References and Resources

    -
    -
      -
    • Tcl Resources -
    • Other Dealers -
    -
    -
    - -

    Tcl Resources

    -John Ousterhout wrote Tcl originally as a research project, and -then Sun hired him, forming the Scriptics group around Ousterhout -and Tcl. The Scriptics group was spun off into a separate company. -The Scriptics website is -the best place to go for the latest information about Tcl, online -documentation, etc. - - -

    Other Dealers

    - -
      -
    • Aside from Deal, the most often cited dealer on rec.games.bridge is -Dealer, -originally written by Hans van Staveren. -
    • There are quite a few more dealers listed at the -Great Bridge Links -Software Page. -
    - -
    -
    -Silhouette -Thomas Andrews -(thomaso@best.com) -Copyright 1996-2002. Deal is covered by the -GNU General Public License. -

    -Plane Dealing graphic -above created using -POV-Ray. -

    Binary files /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/favicon.ico and /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/favicon.ico differ diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/GIBstuff.html /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/GIBstuff.html --- deal-3.0.8/docs/html/GIBstuff.html 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/GIBstuff.html 1970-01-01 05:30:00.000000000 +0530 @@ -1,190 +0,0 @@ - - - - - - - - -Deal 3.0 - GIB interfaces - - -
    -

    Deal 3.0 - GIB interfaces

    - -The file lib/gib.tcl defines a simple interface for accessing -the GIB double-dummy solver. -

    -This code only works on Windows. - -

    gib::directory

    -This command tells Deal where GIB is installed. If GIB is installed -in the standard Windows directory, -C:\Program Files\GIB, -then you don't need to call this. But if it is installed elsewhere, -you need to call this procedure: -
    -source lib/gib.tcl
    -
    -gib::directory "c:/Games/GIB"
    -
    -Note that Tcl uses forward-slash characters, / to seperate directory patchs. -

    -You can also just edit gib.tcl to permanently change the default. -

    -Another thing you might want to change is where the gib library -places temporary files. Currently, gib.tcl has the directory -C:\temp hard-coded for the temporary files. If you -don't have such a directory, and don't want to create one, then you'll -need to edit gib.tcl . - -

    gib::tricks

    - -The procedure gib::tricks returns the number of tricks -a hand can make in a specific denomination (suit or notrump.) -For example: -
    -source lib/gib.tcl
    -
    -main {
    -
    -  accept if {[gib::tricks south notrump]>=12}
    -
    -}
    -
    - -finds deals where south can make 12 or more tricks in notrump, -double-dummy. -

    -This is going to be slow - each call to gib::tricks can take -over a second - so you might try to put some additional -conditions: -

    -source lib/gib.tcl
    -
    -main {
    -
    -  reject if {[hcp north]+[hcp south]<26}
    -
    -  accept if {[gib::tricks south notrump]>=12}
    -
    -}
    -
    -That might miss the occasional freakish slam, but it will be considerably -faster. - -

    -The gib::tricks procedure caches values, -so that multiple calls with the same parameters on the same deal -result in quick turn-around. -

    -This is useful if we are using the parscore -in our query, or if we use the output format, gibpar, -discussed later. - - -

    parscore

    - -This routine determines the double-dummy par score for a deal. Because -it calls gib::tricks 20 times - once for each declarer and denomination - it -can take 20 seconds or more per deal. Not good for huge batches. -

    -Parscore takes as input the declarer and vulnerability: -

    -set result [parscore north NS]
    -set contract [lindex $result 0]
    -set declarer [lindex $result 1]
    -set score    [lindex $result 2]
    -set tricks   [lindex $result 3]
    -set auction  [lindex $result 4]
    -
    -Vulnerability can be one of None, NS, EW, -or All. -

    -The result returned is fairly complex - it consists of a list of elements. -

      -
    • The first element is a contract, in the form "2 spades doubled" or "2 spades." [ Double-dummy par scores are, of course, never redoubled. ] -
    • The second element is the declarer. -
    • The third element is the score -
    • The fourth element is the number of tricks declarer can take. -
    • The fifth is a stupid auction to get to the contract. If north is dealer -and east is declarer in the double-dummy par contract of 4 clubs doubled, -the auction will be "Pass 4C X Pass Pass Pass". Not very inspired, but -needed for the gibpar application, below. -
    - -[Why do we need to know who is dealer? Suppose north and east are -the only ones who can make 1NT, and that no higher contracts make. Then -double-dummy par is 1NT by east if east is dealer, while it is 1NT by north -if anybody else is dealer.] - -

    The gibpar format

    - -As soon as I got GIB, I wanted to use Deal to generate PBN files for -GIB to use in play. It was trickier than I thought - GIB apparently -wants a *score* in the PBN file. This was why I created the -parscore command above - so that I could write out a PBN -file with a score which was objective, rather than random. -

    -This format is used like any other format: -

    -C:\Deal30> deal -i format/gibpar 36 > myfile.pbn
    -
    - -As with any other Deal format, format/gibpar can be used with filters: - -
    -C:\Deal30> deal -i format/gibpar -i ex/1.tcl > myfile.pbn
    -
    - -Once you've generated this PBN file, you can load it into GIB via the -"Load Saved Deal" command. -

    -Competing against double-dummy par is grueling work - it's essentially -playing a team game where everybody at the other table is an -infallible psychic - both your "opponents" and your teammates. -That means that any swings are due to errors at your table -and/or luck. They will always bid that making 15% grand at the -other table, for example. -


    -
    -Silhouette - Thomas Andrews -(thomaso@best.com) - Copyright 1996-2002. Deal is covered by the -GNU General Public License. -

    -Plane Dealing graphic -above created using -POV-Ray. -

    -
    diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/history.html /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/history.html --- deal-3.0.8/docs/html/history.html 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/history.html 1970-01-01 05:30:00.000000000 +0530 @@ -1,116 +0,0 @@ - - - - - - - - - - Deal - A Brief History - - - - - - - - - - - - - - - - -
    Plane Dealing image

    Deal 3.0

    -

    A brief history

    -
    -
    -
    D
    eal -was originally conceived in 1988 for -bidding practice. I was a math graduate student just learning -bridge and another grad student, Robin Pemantle, suggested a way to practice bidding. -His idea was to have the computer deal out twenty or so hands, and -then offer each hand up to you, randomly, for bidding. This way, -you could bid all four hands in each of twenty deals, and, if you -tried hard, you could avoid remembering which hand was which. -

    -I mentioned that idea to my partner at the time, Nathan Glasser, -and he wrote a program called bid, which is still - -available from the bridge archives. -

    -The problem with bid was that it could not -be used for practicing specific auctions. John Oswalt solved -this in a rather crude fashion. His modification forced you to re-link -your application each time you wrote a new query (in C). - -

    -After using this modified version for a while, I got frustrated and -wrote a very crude interpreter. It was a "stack-based" language -so I wouldn't have to write a parser. It was very much like the Unix "dc" -calculator, only without all the features. (That's a joke, but I guess -you wouldn't get it if you didn't know dc.) -

    -I could have used a fully interpreted language, like Perl, but for -the types of simulations I was doing, I need very fast execution -of the computation routines, and so implementing the core in an -interpreted language was going to slow down the program too much. -

    -In about 1992 I first stumble across the Tcl language. Immediately, -I saw that I could use it in my dealer. Tcl was an interpreted -language which had excellent support for extensibility via fast -C routines. It turned out that Nathan's -code did not easily fit into my new scheme, so I rewrote the dealer -from scratch. I had my first version done quickly, and released the -first public version (v0.5 I called it, in retrospect) in 1993. -

    -The next version (v1.0) was released about two years later, and basically -cleaned up the query interface. In the haze of my memory, I can not -recall what features were added, certainly "vectors" and "shape classes." -

    -Version 2.0 uses new optimization methods, some of which -were suggested to me by the very same Nathan Glasser. There are some -other new features, including shape functions, customizable -output formatting, and more built-in formats. -

    -Version 3.0, is the next major release. Major changes are: -

      -
    • GNU GPL license - making it free for all use -
    • Much faster execution using Tcl 8.x features. -
    • Addition of 'holding functions' - like 'vectors' but more suitable -for complex evaluations like "losers" and "CCCC." -
    • "Smart stacking" for finding rare hands. -
    -

    -The next version of Deal I've called "iDeal." -It's a much changed beast, and could almost be called a general bridge -programming environment. Currently, my progress here has stalled, but -I'm planning on a GUI interface to the Deal. -

    -While Deal is a labor of love for me, it makes it easier -to love the project if I get feedback which shows people are using -Deal. Even if you tried Deal and did not like -it, please let me know. -


    -
    -Silhouette -Thomas Andrews -(thomaso@best.com) -Copyright 1996-2002. Deal is covered by the -GNU General Public License. -

    -Plane Dealing graphic -above created using -POV-Ray. -

    -
    - - diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/holding.html /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/holding.html --- deal-3.0.8/docs/html/holding.html 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/holding.html 1970-01-01 05:30:00.000000000 +0530 @@ -1,155 +0,0 @@ - -Holding Procedures - - -

    Holding Procedures in Deal 3.0 and iDeal

    - -

    Introduction

    -One of the main new bridge evaluation features in Deal 3.0 and iDeal -is the ability to define fast procedures for evaluating a single holding. -

    -In Deal 2.0, we were able to define -Vector functions, which assigned -integer values to each card. This covered a lot of standard evaluation -techniques, but not the more complicated forms. Evaluators like -"quick tricks" and "losers," while still computed suit by suit and totaled, -cannot be defined by assigning values to cards alone. -

    -The solution is to allow the creation of general procedures for evaluating -a holding, while still taking advantage of fast lookup tables. Thus, -the introduction of the holdingProc command. - -

    The holdingProc Command

    - -holdingProc looks like a normal Tcl definition of a procedure. For example, -we might write: -
    -
    -holdingProc HCP {A K Q J} {
    -    expr {$A*4+$K*3+$Q*2+$J}
    -}
    -
    -
    -to define a function called HCP. This function behaves exactly -the same as the builtin hcp routine - the user can ask for -the total points in a hand or for a specific suit in the hand: -
    -
    -set n [HCP north]
    -set hs [HCP north spades]
    -
    -
    -When evaluated, the parameter A is set to one if the holding has the ace, -and zero otherwise. -

    -That's a simple example, but let's say we want to do some smart reevaluation. -For example, we might want to add a point for each card in a suit beyond -the fourth. We also might want to evaluate a stiff king as two points, rather -than three, a stiff queen as zero, and a doubleton queen as one. -

    -We can do this by adding a "length" parameter to the parameters list: -

    -
    -holdingProc SmartHCP {A K Q J length} {
    -
    -    if {$length>=4} {
    -        # Normal evaluation, +1 for each card longer than the fourth
    -	return [expr {$A*4+$K*3+$Q*2+$J+($len-4)}]
    -    }
    -
    -    if {$length==3} {
    -        # Normal evaluation for 3-card suits
    -	return [expr {$A*4+$K*3+$Q*2+$J}]
    -    }
    -
    -    if {$length==2} {
    -        # Jacks in doubletons are worth zero, queens one
    -	return [expr {$A*4+$K*3+$Q}]
    -    }
    -
    -    if {$length==1} {
    -        # Queens and jacks in singletons are worth zero, kings two
    -	return [expr {$A*4+$K*2}]
    -    }
    -
    -    return 0
    -}
    -
    -
    - -Even though this code is slow, it is only evaluated at most 160 times, after -which values are reused, yielding remarkably fast evaluations. One deal, -you might get a holding of KQ75 which this routine evaluates -as if it were evaluating KQxx. The next hand, it sees the -holding KQ82 and, seeing this also as KQxx, remembers -the previous value. -

    Types of Holding Procedures

    - -By default, the holding procedure assumes that the values returned are integers, -so that when it tries to add up the values of all four suits, it applies -an integer sum. -

    -If you want the return value interpreted as a double, you can specify it -in the declaration. For example, we can define a quick tricks procedure: -

    -
    -holdingProc -double QuickTricks {A K Q J T length} {
    -    if {$A&&$K} { return 2 }
    -    if {$A} { return 1 }
    -    if {$K && ($Q || ($J && $T))} {
    -         return 1
    -    }
    -    if {$K && $length>1} {
    -            return 0.5
    -    }
    -    return 0
    -}
    -
    -
    -

    -You can define the type to be any of the following: -

    -
    -integer -
    The default, adds integer values when evaluated across multiple suits. -
    -double -
    Adds resulting values as doubles when evaluated across multiple suits. -
    -boolean -
    When evaluated on a hand, lists the suits, by name, which evaluate as true. -For example, if you defined 'biddableSuit' it would return the list -"spades hearts" for the hand KT954 AJ32 94 92. -
    -string -
    Returns a list of values when evaluated on multiple suits. -
    -

    Arguments Allowed

    -The arguments are interpreted based on the first character of their name, -or, in the case of spots, via the idiom 'x.' For example, we could -have defined SmartHCP as: -
    -
    -holdingProc SmartHCP {ace King QuizShow j len} {
    -      ...
    -}
    -
    -
    -They can occur in any order. -

    -For spot cards, you can use arguments named "x2", "x3", "x4", .., and "x9." -The ten can be passed as "x10" or "T." -

    -One last possible parameter is anything beginning with an "s" or "S", which means -that the holding is passed as a string. This is useful when you already have -a hash table somewhere for stored data. For example, the 'ddeval' code which -comes with iDeal and Deal 3.0 uses a table of raw data created in -advance. -


    -
    -Silhouette -Thomas Andrews -(thomaso@best.com) -Copyright 1996-2002. Deal is covered by the -GNU General Public License. -

    -Plane Dealing graphic -above created using -POV-Ray. -

    diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/index.html /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/index.html --- deal-3.0.8/docs/html/index.html 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/index.html 1970-01-01 05:30:00.000000000 +0530 @@ -1,91 +0,0 @@ - - - - Deal Top Page - - - - - - - - - - - - - -
    -

    Deal 3.0

    -

    A bridge hand generator

    by Thomas Andrews

    -Features: -
    -
  • Easy to use for quick, simple dealing -
  • Customizable output formats -
  • Infinitely extensible via TCL -
  • Easily portable to most platforms -
  • Free (for non-commercial use) -
  • Deal 3.0
    -
    - -

    Information found on these pages:

    - - -

    Things you can do with Deal:

    -
      -
    • Dealing: Generate random deals for your club. -
    • Bidding practice: Practice general bidding, - or specific situations -
    • Settle arguments: Was bidding game wise over - that limit raise? Was that the spade nine really the best lead? -
    • Statistical experiments: How often does a bid - occur? How often does this slam make? -
    • "Problem solver" contests: Solve magazine - problems, and learn where even the experts go wrong -
    • Interface with other programs: Deal 3.0 comes - with the ability to call the GIB double dummy solver. -
    - -

    What is Tcl?

    - -Tcl, pronounced "tickle," stands for "Tool command language." -If you are a Windows user, think of it as the Unix equivalent to -Visual Basic. But, unlike Visual Basic, Tcl works on almost all -operating systems, not just those made by Bill Gates. -

    -Tcl is used in a variety of different software, from testing tools -to web software (AOL Server, Vignette) and, of most interest to bridge -players, Floater, the free online bridge program. -

    -The people in charge of Tcl are -Scriptics. But don't let their web site fool you - the basic software is free. - -

    -


    -
    - -
    Thomas Andrews -(thomaso@best.com) - Copyright 1996-2001. Deal is copyrighted under the -GNU General Public License. -
    -

    -Plane Dealing graphic -above created using -POV-Ray. -

    diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/look.css /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/look.css --- deal-3.0.8/docs/html/look.css 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/look.css 1970-01-01 05:30:00.000000000 +0530 @@ -1,69 +0,0 @@ -body { - background-image: url(../graphics/idealbg.jpg) -} - -A:link { - color: #663300; -} - -A:visited { - color: #990000 ; -} - -A:hover { - color: white ; - background: #336699 -} - -A:active { - color: #000099 -} - -A.image:hover { - background: transparent ; -} - -div.header { - text-align: center -} - -span.alert { - color: red ; - background: transparent -} - -span.code { - font-family: Courier, monospace ; - white-space: nowrap ; -} - -div.codesample, pre.codesample { - width: 0 ; - font-family: Courier, monospace; - font-size: small ; - white-space: pre ; - margin-left: 10% ; - padding-bottom: 1em; - padding-top: 1em; - margin-top: 0.25in ; - margin-bottom: 0.25in ; - border-top: thin groove ; - line-height: 120%; - border-bottom: thin groove -} - -div.back { - margin-left: 5% ; - margin-right: 5% ; - text-align: right -} - -div.toplevel,table.toplevel { - width:90% ; - margin-left: 5%; - margin-right: 5%; -} - -span.reference { - font-style: italic ; -} diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/newfeatures.html /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/newfeatures.html --- deal-3.0.8/docs/html/newfeatures.html 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/newfeatures.html 1970-01-01 05:30:00.000000000 +0530 @@ -1,227 +0,0 @@ - - - - Deal 3.0 - New Features - - - - - - - -Back to Deal Top Page. - - - -
    -

    Deal 3.0 - New Features

    -
      -
    • General performance improvements using Tcl 8.x features -
    • Fast holding procedures -
    • Interface to the GIB double dummy solver -
    • More input formats, and extensible input formats -
    • Smart hand stacking -
    - -
    - - -

    Performance Improvements

    -There are a number of performance improvements in Deal 3.0. - -

    Tcl 8.x Improvements

    -In early releases of Tcl (7.x and earlier) the interpreter treated -everything as a string. That meant that Tcl data and procedures were -regularly parsed and reparsed, which made it a fairly slow language. -Tcl 8.x changed that - it uses -internal objects which have optional string representations. -

    -This means that the first time you pass the string "AK4" to a -Deal procedure, it will parse it into an -internal represention, and then never parses it again. The -internals of Deal now take advantage of this -in quite a lot of places. - -

    Fast and general holding procedures

    -Many bridge evaluators can be seen as evaluating the holdings -in each suit, and then adding up the values. For example, -in the hand: -
    -  Spades: AKx
    -  Hearts: KQJ
    -Diamonds: xxxx
    -   Clubs: Axx
    -
    -We compute the high card points as 7, 6, 0, and 4, in spades, hearts, -diamonds, and clubs, for a total of 17 points. We compute losers -in the suits as 1, 1, 3, and 2, for a total of 7 losers. -

    -In Deal 2.0, you could define a very limited set of procedures of this -sort - the so-called vector procedures. -You could, for example, define "high card points" or "controls," but -not "losers." -

    -In Deal 3.0, virtually any such procedure can be written. -

    -See seperate document for more details. - -

    Other Features

    -

    GIB interfaces

    - -Deal 3.0 now has a a set of tools for people who own -GIB. Specifically, -it provides a procedure for determing the number of tricks -available on a deal, double dummy. -

    -See separate document for details. -

    Input formats

    -Deal 3.0 now lets you read deals from a file easily. It is -also easy to write extensions which change the way Deal 3.0 -reads from files or generates deals. -

    -To access an input format, you can either add the line: -

    -deal::input formatName [args...]
    -
    -or, from the command line, use the -I switch: -
    -deal -I "FormatName[ args...]" ...
    -
    -Deal 3.0 includes the following input formats: -
    -
    line -
    This reads in deals in the format written by deal with the -l -flag. For example, you can generate a file of 1000 deals then run two -seperate queries on the file with: -
    -deal -l 1000 > sample.txt
    -deal -I "line sample.txt" -i query1.tcl > out1.txt
    -deal -I "line sample.txt" -i query2.tcl > out2.txt
    -
    -If no file is given, the lines are read from standard input. -

    -

    giblib -
    Matt Ginsberg has made available a large file of 700,000+ deals -with double dummy data. This input format lets read this data -file sequentially. Calls to the GIB procedure gib::tricks -take the data from this file, rather than calling the double-dummy -solver. -
    -deal::input giblib [filename]
    -
    - -If no file is given, Deal looks in the -current directory for a file named library.dat. -

    -The data file is not included in this release - it's really huge. -See the -GIB research project page for more details. -

    smartstack -
    The deal of the smartstack is to find certain rare -types of deals very quickly, not using the standard dealing techniques, -but using a more complicated and data-heavy approach. -Smart stacking is documented -seperately below. -
    -To add a new input format named Foo, you write a file named -input/Foo.tcl which contains a Tcl package named Foo -with procedures called set_input and next. -See the input formats included with Deal for examples. -The next procedure should return an error when it has -reached the end of input. -

    -An input format does not have to read from a file. For example, -the smartstack code is a factory which builds deals -on the fly with one hand fitting a certain condition. - -

    Smart Stacking

    -Deal, by default, just keeps dealing hands until it finds one that -fits a pattern. This can be too slow sometimes when looking for -specific hands. -

    -Suppose we want north to have a balanced hand with 22 or 23 high card -points. We can force this -by using the smartstack input format: -

    -deal::input smartstack north balanced hcp 22 23
    -
    -The arguments tell the stacker to randomly build north hands that -are balanced with high card points in the range of 22 and 23. -

    -Any shape class can be used in the place of balanced, -and any holding procedure can be used in place of hcp -in the above example. If an evaluator is not passed in, there -is no range requirement. If you wish no shape restrictions, -use the shapeclass AnyShape. -

    -Specific cards can still be placed in specific hands: -

    -        deal::input smartstack north balanced hcp {20 21}
    -	south is K52 KJ3 98542 AK
    -        north gets AS QS QH
    -
    -Smart stacking can also put restrictions on specific suits: - -
    -deal::input smartstack north balanced hcp 20 21
    -smartstack::holding diamonds controls 2 3
    -
    -This requires north to have 2-3 controls in diamonds. -

    -The tighter the restrictions, the faster Deal -will be able to build hands which satisfy them. -

    -Any additional conditions you want to place on any of the hands can -still be placed in main, as usual. -

    Performance issues

    -Smart stacking costs a lot of initial overhead. For example, on -my Linux computer, ex/1-shapeclass.tcl in the release -has no startup -time, and takes about 0.014 seconds per match found. The equivalent -script using smartstack, ex/1-stack.tcl, -takes almost 13 seconds at startup -time, but then takes onlu 0.002 seconds per match found. So -if I'm generating 10,000 with these deals, it takes about -36 with smart stacking, and about 140 seconds without. But if -I'm generating 1,000, they take about the same time, and if I'm generating -only 10, using smart stacking is costly. -

    -Is smart stacking ever useful when dealing with small sample requests? -Definitely - if the hand is *very* specific and/or rare. For example, -the two above scripts use a point range of 11-15, but if they are -changed to seek 21-22 hcp hands of the same shape, they both take about 10 -seconds to find 10 deals, but the smart stacker takes only 14 seconds -to find 1,000, while the standard algorithm takes 1,000 second! -

    -Originally, I was going to call the "smart stacker" by the name, -"deal factory." Like a real world factory, there is a large startup -cost, but after it is built, it builds deals to specification far -faster. The more specific your needs and/or the larger supply you -need, the more useful that initial investment is. -

    -If I use smartstack to generate balanced hands with 20 points, it has -a startup time of about 20 seconds. If I request balanced 25-counts, -17 seconds, balanced 29-counts 12 seconds. After startup, the amount -of time to find examples is almost nil. Without smartstack, it takes -about five minutes to generate ten examples of balanced 29-counts. -With smartstack, only 13 seconds. -

    -For the evaluator, don't use one that has too many possible values, -or the size of the stacker's table balloons horribly. -For example, in each suit, the values possible for hcp are -0-10. But if you were to use something really complex with floating -point values, you might screw the pooch. No smart checking is applied -when building the table, either, so Deal might just appear to churn. -


    -
    -Silhouette -Thomas Andrews -(thomaso@best.com) -Copyright 1996-2002. Deal is covered by the -GNU General Public License. -

    -Plane Dealing graphic -above created using -POV-Ray. -

    diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/quickdos.html /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/quickdos.html --- deal-3.0.8/docs/html/quickdos.html 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/quickdos.html 1970-01-01 05:30:00.000000000 +0530 @@ -1,641 +0,0 @@ - - - - - - - - - - Deal - An Introductory Tutorial for Windows - - - - - - - - - -
    Plane Dealing image

    Deal 3.0

    -

    An Introductory Tutorial for Windows

    -Covering:
      -
    • Dealing hands -
    • Stacking hands -
    • Output formats -
    • Basic scripting with Tcl -
    -
    -
    -
    -

    Prologue

    -First things first, you will need to download -Deal and install it. The rest of this tutorial assumes you have -already done this. -

    -**Warning** It takes careful eyes, at least on the version of Netscape I am -using, to distinguish between normal parentheses, (), and curly -parentheses, {}. Almost all of the paretheses in the script -listings below are curly parentheses. -

    Basic Dealing - The Command Line

    - -

    Basic Dealing - Scripting

    - - -

    Basic Dealing

    - -

    Dealing hands

    -

    -Start a DOS window (or Command Prompt window on NT) and change your directory -to the location where Deal was installed. -

    -C:\> cd "C:\deal30"
    -
    -C:\deal30> 
    -
    - -The most basic version of deal runs with no conditions set on the deal, -and generates 10 deals: -
    -C:\deal30> deal
    -
    - -The output probably scrolled off the screen, so you might want to do -
    -C:\deal30> deal | more
    -
    - -to allow scrolling, or: -
    -C:\deal30> deal > out.txt
    -
    - -which saves the output from deal to the file, out.txt. - -

    -If you give "deal" a number on the command line, it generates that many -deals: -

    -C:\deal30> deal 2
    -          S : T6542
    -          H : A4
    -          D : A93
    -          C : KT2
    - S : Q83            S : K97
    - H : 9873           H : K52
    - D : JT7            D : Q64
    - C : Q74            C : J863
    -          S: AJ
    -          H: QJT6
    -          D: K852
    -          C: A95
    ----------------------------
    -          S : ---
    -          H : 975
    -          D : AT986
    -          C : T9753
    - S : J7             S : AKT6         
    - H : T32            H : KJ864        
    - D : K32            D : J74          
    - C : AJ842          C : 6            
    -          S: Q985432
    -          H: AQ
    -          D: Q5
    -          C: KQ
    ----------------------------
    -C:\deal30> 
    -
    -In this example, Deal dealt two hands, as requested. -

    -

    Stacking a hand

    -Okay, let's take another example. Suppose you opened 3H on the following -hand in a team game: -
    -S: ---
    -H: KQJT62
    -D: T9876
    -C: 84
    -
    -You stumble into a six heart contract, when in fact, six diamonds has better -play opposite partner's hand. Partner swears that opening 3H with this -hand loses more often than it wins. You disagree. How do you resolve -this? -

    -Deal can help. Just run it as: - -

    -C:\deal30> deal -S "- KQJT62 T9876 84" 25
    -          S : KJ2
    -          H : 954
    -          D : A5
    -          C : AKT65
    - S : T9764          S : AQ853        
    - H : A              H : 873          
    - D : J2             D : KQ43         
    - C : QJ973          C : 2            
    -          S: ---
    -          H: KQJT62
    -          D: T9876
    -          C: 84
    ----------------------------
    -          S : KJT64
    -          H : 5
    -          D : K42
    -          C : AQ65
    - S : 9875           S : AQ32         
    - H : A93            H : 874          
    - D : AJ5            D : Q3           
    - C : KJ9            C : T732         
    -          S: ---
    -          H: KQJT62
    -          D: T9876
    -          C: 84
    ----------------------------
    -	.... (rest of 25 hands ellided) ...
    -
    - -You inspect the 25 hands dealt, guessing how the auction would -proceed. Sometimes, your answers will be inconclusive, but more -often one or both partners learns something from the simulation. -

    -There are, of course, also -N, -E, and -W options -for the other three seats. -

    Formatting output

    -Perhaps you'd like the hands to be written in some other format. -This can be arranged fairly easily. -

    -For example, suppose you wish to deal 8 hands for practice bidding -with partner. In that case, you would use the "practice" format: - -

    -C:\deal30> deal -i format/practice 8 > out.all
    -C:\deal30> more out.east
    -                              east hands
    -============================================================================
    -     *1*                 *2*                 *3*                 *4*
    -  S 84                S T7                S QT3               S AJ9654
    -  H J8642             H Q65               H Q983              H K8
    -  D Q843              D KJ42              D 865               D J
    -  C 73                C T842              C AJ9               C K532
    -
    -=============================================================================
    -     *5*                 *6*                 *7*                 *8*
    -  S J7                S 85                S AQT764            S 3
    -  H Q9864             H AK4               H K5                H JT4
    -  D 874               D A764              D 9                 D QJT86
    -  C J85               C Q862              C T976              C AK82
    -
    -=============================================================================
    -
    - - -The -i flag tells Deal to include the named file, -in this case, the file named format/practice. This file redefines -the output format. At the end of this run, you should get five files: -out.north, out.east, out.south, -out.west, and out.all. -

    -Now you can print out these files, pass them out amongst four people, -and practice your bidding, using out.all at the end to make -a double dummy assessment of the auction results. -

    -What if you only have two people, and you want to practice uninterrupted -auctions? You could print out the north and south hands, and practice -with those, but that would be an artificial -test, because you obviously can't assume an uncontested auction for -arbitrary deals. -

    -When we learn about writing scripts for Deal, we will solve with this problem by filtering out hands we think would lead to competitive -bidding. -

    -What are the formats that come with the kit? Well, you can simply list -the format sub-directory to find out. Here are the ones there -as of this writing: -

    -
    none -
    This script set the formatting routine to a null routine. - Not useful, so far, but useful, for example, when doing - statistical analysis. -
    numeric -
    This formatter writes the deal as a line which looks something - like: -
    -3031333123220300123320212213021202022103101101003113
    -
    - It's a line of 52 numbers, where 0, 1, 2, and 3 mean - north, east, south, and west, respectively. - The first digit tells where the ace of spades goes, the - second digit tells where the king of spades goes, etc. -
    okb -
    This formatter writes the output with the same spacing as the old -OKbridge screen. -
    practice -
    We've just seen this one - for seperating out hands for -practice bidding. -
    -There is one last output format, which, for historical reasons, -has its own command line switch, -l. - -
    -C:\deal30> deal -l 3
    -AJ9 976532 K92 A|86 A AT87 987653|Q732 JT8 543 T42|KT54 KQ4 QJ6 KQJ
    -K94 J93 QJ3 7653|A8 A8765 97 KQ98|JT2 Q AKT8654 T4|Q7653 KT42 2 AJ2
    -KJ753 T A4 KQ932|AQ94 AJ92 QT87 J|86 Q764 K9653 74|T2 K853 J2 AT865
    -C:\deal30>
    -
    - -In the past, this was the only way to get alternate formats. The -user would pipe this output to another program, usually a Perl script, -which would parse each line and format the output. -

    -With the addition, in v2.0 of Deal, of user-configurable formatting, -this usage becomes obselete, but I'm leaving the feature because -it has one other use, which will be mentioned later. - -

    Basic Dealing - Scripting

    -

    Our First Script

    -Let's say we want a selection of deals in which north holds a one spade -opener. For now, we will use a crude definition for an opening 1S call - -we will require north to have 5 or more spades and 12 or more points. -

    -Here is the script we write (to a file we'll call onespade): - -

    -main {
    -  if {[spades north]>=5 && [hcp north]>=12} { accept }
    -  reject
    -}
    -
    - - -

    Running the script

    -We run this code by saying: - -
    -C:\deal30> deal -i onespade 2
    -          S : AKQT5
    -          H : A7
    -          D : 8542
    -          C : AT
    - S : 64             S : J98          
    - H : K943           H : 862          
    - D : J              D : AK963        
    - C : KQ8732         C : 54           
    -          S: 732
    -          H: QJT5
    -          D: QT7
    -          C: J96
    ----------------------------
    -          S : AQT73
    -          H : A
    -          D : AJ987
    -          C : 73
    - S : K5             S : J42          
    - H : JT8632         H : KQ95         
    - D : Q63            D : KT4          
    - C : 85             C : K92          
    -          S: 986
    -          H: 74
    -          D: 52
    -          C: AQJT64
    ----------------------------
    -
    - -

    How the script works

    -By default, Deal accepts all hands. With the main code in -onespade, we tell Deal to override that behavior. -

    -This is similar to the way we used scripts to override Deal's -default formatting. Note, we even use the same flag, -i, -to load our formatters and onespade. -

    -What does this main code do? It is run after every deal -is complete, and used to evaluate the hand. In this case, we have only -two lines of code: - -

    -if {[spades north]>=5 && [hcp north]>=12} { accept }
    -reject
    -
    - -The expression [spades north] returns the number of spades -in the north hand. The expression [hcp north] returns -the number of HCP (high card points) in the north hand. The "&&" -is called a logical "and" operator, which returns true if the conditionals -on both sides of it are true. -

    -If the entire expression: -

    -[spades north]>=5 && [hcp north]>=12
    -
    -evaluates as true, the "accept" function is called. This causes -Deal to exit the "main" code and format the hand. -

    -If the expression evalutes as false, Deal goes to the next line -of code, which calls the "reject" function. This tells Deal to -discard the hand, and exit the "main" code. -

    -Deal keeps trying until the requested number of deals is accepted. -

    -What happens if a deal is not explicitly accepted or rejected? -If neither accept nor reject is called, the deal -is rejected. That means that in our first script, the reject -call was redundant, and we could have simply written the script as: - -

    -main {
    -  if {[spades north]>=5 && [hcp north]>=12} { accept }
    -}
    -
    - -

    Monitoring Deal

    -You might want to try running this script with the -v switch: -
    -C:\deal30> deal -v -i onespade
    -
    -The -v flag tells Deal to give a progress report, which looks -like: - -
    -...
    -Deal 1 found after 2 tries
    -...
    -Deal 2 found after 21 tries
    -...
    -Deal 3 found after 31 tries
    -
    - -This will give you some idea of how rare your condition is, and -also gives a good progress report when Deal is -writing to a file or running with a "silent" format, like -format/none. These status messages are written to "stderr", -which means that the output from Deal can be -redirected to a file without obscuring these messages.

    - -

    Using formats with your script

    - -If we wanted to use another output format with this script, we could do so -on the command line, as follows: -
    -C:\deal30> deal -i format/practice -i onespade
    -
    -Or, alternately, we could add an explicit "source" command to our -script: - -
    -source format/practice
    -
    -main {
    -        if {[spades north]>=5 && [hcp north]>=12} { accept }
    -}
    -
    - - -In fact, this second format unveils the secret of the -i flag - -it is simply a request to "source" a file. In fact, if you were to -write your own formatter, you would not have to put the file in -the "format" directory. -If you put it in the current directory, you could then say: -
    -C:\deal30> deal -i myformatter 100
    -
    -and it would work fine. The "format" subdirectory is just a convenience. -You will often want to re-use a format, and placing them in one place -lets you find out which formats are available. - -

    Stacking hands with a script

    - -Let's say you were dealt the hand: -
    -S: ---
    -H: 98532
    -D: A864
    -C: T962
    -
    -the previous day at a Swiss Teams event. -

    -Your partner opened 1S, and, playing 2/1 Game Force, you chose to -pass. This turns out well for you on this deal, because at the other -table, the opponents played in three spades, down 1. Afterwards, -you wonder if you really made the right decision. Your intuition -tells you that it was the right choice, but you realize there are -risks in both passing and bidding, and you know that intuition is -very bad at assessing levels of risk. -

    -Deal can help. Using our script, onespade, -we can run the following simulation: -

    -C:\deal30> deal -S "- 96532 A864 T962" -i onespade
    -
    -The -S flag stacks the south hand with the hand you held, -and the script runs exactly the same thereafter. You can now peruse -the output to see whether it was a good idea or a bad idea to pass. -

    -As with the formatting, we can also do our deck-stacking in our script. - -

    -south is - 98532 A864 T962
    -
    -main {
    -  if {[spades north]>=5 && [hcp north]>=12} { accept }
    -}
    -
    - - -Notice, we do our deck-stacking outside of the evaluation loop. -Remember, the main expression is responsible for evaluating the deals -after Deal finishes dealing the hands. -We obviously want the stacking instruction to occur before -dealing occurs, so the stacking command must be outside the main -evaluation. -

    -

    A partial list of routines

    -For evaluation routines, we have seen the hcp and spades -routines, as well as the "accept" and "reject" directives. -Obviously, there are also routines called hearts, - diamonds, and clubs which count their respective -suits. The following functions are also built-ins: -
    -
    controls
    This function computes the number of -controls held by a hand. -
    losers
    This function does a crude computation of -the losing trick count for a hand (it actually compute's half-losers, -so when [losers south] returns 14, that really means 7 losers.) -
    balanced
    This function returns true (1) if the -hand name passed is balanced in the usual sense - no shortness, at most -one doubleton, and no five-card major. It returns false (0) otherwise. -
    semibalanced
    Returns true (1) if the hand passed -has no shortness and no six-card major or seven-card minor, and false -(0) otherwise. -
    -The three functions, controls, hcp, and losers, -all have the property that we can compute them one suit at a time, and -sum the result for the entire hand. The implementation takes advantage -of this and allows the user to request these values for specific suits: - -
    -main {
    -  if {[hcp south hearts spades]>10} {accept}
    -}
    -
    - -This script accepts a deal if south has ten or more points in hearts -and spades. controls and losers can be used similarly. -Any function of this sort we will call "additive." We will see later that -we can define a wide class of interesting -additive functions. -

    -The functions balanced and semi_balanced are entirely -dependent on the shape of the hand, and not on which cards the hand holds. We -will call these "shape functions." We will find out later how to -define incredibly fast shape functions. - -

    A Second Script - defining Tcl procedures

    - -Let's say we want to write a script which accepts a deal if north -has a strong notrump (15 to 17 range) and south has about invitational -values and a 5-card major. - -

    -Our script , which we will call jacobytest might look something like: - - -

    -# In deal 2.0, you don't need this next line, but deal 3.0 does - 
    -# without this line, the "balanced" routine is not defined.
    -
    -main {
    -	if {![balanced north]} {reject}
    -
    -	set hn [hcp north]
    -	if {$hn>17 || $hn<15} {reject}
    -
    -	set hs [hcp south]
    -	if {$hs<8 || $hs>9} {reject}
    -
    -	if {[spades south]==5 || [hearts south]==5} { accept }
    -}
    -
    - - -We have used one of our new functions here, balanced, as -well as a new Tcl feature, variables. We could, of course, not used -variables, but then we would have had to write the lines: -
    -if {[hcp north]>17 || [hcp north]<15} {reject}
    -
    -That is going to be slower, with one more function call. Not appreciable -today, with a simple query, but when you might be processing a million or -more hands at a time, you learn to be frugal. -

    -Suddenly, you realize you want to test this situation with a 12-14 notrump, -instead. Or you realize you often want to reuse this concept. You -can do so by defining Tcl procedures. -

    - -

    -proc notrump {hand min max} {
    -  if {![balanced $hand]} {return 0}
    -
    -  set hc [hcp $hand]
    -  if {$hc < $min || $hc>$max} { return 0}
    -
    -  return 1
    -}
    -
    -proc jacobyinvite {hand ntmin ntmax} {
    -
    -  if {[spades $hand]!=5 && [hearts $hand]!=5} {return 0}
    -
    -  set hc [hcp $hand]
    -  if {$hc+$ntmin <= 25 && $hc+$ntmax>=24} { return 1 }
    -
    -  return 0
    -
    -}
    -
    -set NTmin 12
    -set NTmax 14
    -
    -main {
    -  if {![notrump north $NTmin $NTmax]} { reject }
    -  if {[jacobyinvite south $NTmin $NTmax]} { accept }
    -}
    -
    - -You are unlikely to need the jacobyinvite function -beyond this script, but the notrump function will be something -you will want -to use again and again. You might even put it in a library of routines, called -mylibrary and source that library every time you need one or more -of the routines for a script: -
    -source mylibrary
    -
    -rather than rewriting the routine every time. -

    -In fact, the Deal kit comes with a file called library -, which is just such a library of routines the author of Deal - found himself re-using. - -

    Revisiting accept and reject

    -The directives, accept and reject, can be used -in more complicated ways that are sometimes more efficient and -sometimes more readable. -

    -Here is the main script from the notrump example -using some odd constructs: -

    -main {
    -  reject unless {[notrump north $NTmin $NTmax]}
    -  accept if {[jacobyinvite south $NTmin $NTmax]}
    -}
    -
    -Some people might find this more readable. The first line says -we are going to reject the deal unless the condition -is true. The second conditional says we are going to accept -the deal if the expression evaluates as true. -

    -Multiple arguments are allowed. The following command: -

    -reject unless {expr1} {expr2} ... {exprn}
    -
    -runs through all of the expressions until it finds one which evaluates -as "true". If it does not find a true value, it rejects the hand. -Otherwise, deal goes on to the next line in evaluating main. -

    -For reject if the deal is rejected if any one of the expressions -is true. Similarly, accept if accepts a deal if one of the -expressions is true. For accept unless, the deal is accepted -unless the one of the expressions is true. - -


    -This concludes the Introductory Tutorial. I hope -it inspires you to check out the Deal - Advanced -Guide and to learn more about Tcl. -Or check out the index of all deal commands. -
    -
    -Silhouette -Thomas Andrews -(thomaso@best.com) -Copyright 1996-2002. Deal is covered by the -GNU General Public License. -

    -Plane Dealing graphic -above created using -POV-Ray. -

    -
    diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/quickstart.html /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/quickstart.html --- deal-3.0.8/docs/html/quickstart.html 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/quickstart.html 1970-01-01 05:30:00.000000000 +0530 @@ -1,598 +0,0 @@ - - - - - - - - - - Deal - An Introductory Tutorial - - - - - - - - - - - - -
    Plane Dealing image -
    -

    Deal 3.0

    -

    An Introductory Tutorial

    -
    -Covering:
      -
    • Dealing hands -
    • Stacking hands -
    • Output formats -
    • Basic scripting with Tcl -
    -
    - -
    -
    -

    Prologue

    -First things first, you will need to download -Deal and build it. The rest of this tutorial assumes you have -already done this. -

    -**Warning** It takes careful eyes, at least on the version of Netscape I am -using, to distinguish between normal parentheses, (), and curly -parentheses, {}. Almost all of the paretheses in the script -listings below are curly parentheses. -

    Basic Dealing - The Command Line

    - -

    Basic Dealing - Scripting

    - - -

    Basic Dealing

    - -

    Dealing hands

    -At your command or DOS prompt, you say, deal. By default, this deals ten hands. -If you give deal a numeric argument, it will deal that number -of hands you specify. -
    -$ deal 2
    -          S : T6542
    -          H : A4
    -          D : A93
    -          C : KT2
    - S : Q83            S : K97          
    - H : 9873           H : K52          
    - D : JT7            D : Q64          
    - C : Q74            C : J863         
    -          S: AJ
    -          H: QJT6
    -          D: K852
    -          C: A95
    ----------------------------
    -          S : ---
    -          H : 975
    -          D : AT986
    -          C : T9753
    - S : J7             S : AKT6         
    - H : T32            H : KJ864        
    - D : K32            D : J74          
    - C : AJ842          C : 6            
    -          S: Q985432
    -          H: AQ
    -          D: Q5
    -          C: KQ
    ----------------------------
    -$
    -
    - -Deal dealt two hands, as requested. -

    -

    Stacking a hand

    -Okay, let's take another example. Say you opened 3H on the following -hand in a team game: -
    -S: ---
    -H: KQJT62
    -D: T9876
    -C: 84
    -
    -You stumble into a six heart contract, when in fact, six diamonds has better -play opposite partner's hand. Partner swears that opening 3H with this -hand loses more often than it wins. You disagree. How do you resolve -this? -

    -Deal can help. Just run it as: -

    -$ deal -S "- KQJT62 T9876 84" 25
    -          S : KJ2
    -          H : 954
    -          D : A5
    -          C : AKT65
    - S : T9764          S : AQ853        
    - H : A              H : 873          
    - D : J2             D : KQ43         
    - C : QJ973          C : 2            
    -          S: ---
    -          H: KQJT62
    -          D: T9876
    -          C: 84
    ----------------------------
    -          S : KJT64
    -          H : 5
    -          D : K42
    -          C : AQ65
    - S : 9875           S : AQ32         
    - H : A93            H : 874          
    - D : AJ5            D : Q3           
    - C : KJ9            C : T732         
    -          S: ---
    -          H: KQJT62
    -          D: T9876
    -          C: 84
    ----------------------------
    -	.... (rest of 25 hands ellided) ...
    -
    -You inspect the 25 hands dealt, guessing how the auction would -proceed. Sometimes, your answers will be inconclusive, but more -often one or both partners learns something from the simulation. -

    -There are, of course, also -N, -E, and -W options -for the other three seats. -

    Formatting output

    -Perhaps you'd like the hands to be written in some other format. -This can be arranged fairly easily. -

    -For example, suppose you wish to deal 8 hands for practice bidding -with partner. In that case, you would use the "practice" format: -

    -$ deal -i format/practice 8 > out.all
    -$ cat out.east
    -                              east hands
    -============================================================================
    -     *1*                 *2*                 *3*                 *4*
    -  S 84                S T7                S QT3               S AJ9654
    -  H J8642             H Q65               H Q983              H K8
    -  D Q843              D KJ42              D 865               D J
    -  C 73                C T842              C AJ9               C K532
    -
    -=============================================================================
    -     *5*                 *6*                 *7*                 *8*
    -  S J7                S 85                S AQT764            S 3
    -  H Q9864             H AK4               H K5                H JT4
    -  D 874               D A764              D 9                 D QJT86
    -  C J85               C Q862              C T976              C AK82
    -
    -=============================================================================
    -
    - -The -i flag tells Deal to include the named file, -in this case, the file named format/practice. This file redefines -the output format. At the end of this run, you should get five files: -out.north, out.east, out.south, -out.west, and out.all. -

    -Now you can print out these files, pass them out amongst four people, -and practice your bidding, using out.all at the end to make -a double dummy assessment of the auction results. -

    -What if you only have two people, and you want to practice uninterrupted -auctions? You could print out the north and south hands, and practice -with those, but that would be an artificial -test, because you obviously can't assume an uncontested auction for -arbitrary deals. -

    -When we learn about writing scripts for Deal, we will solve with this problem by filtering out hands we think would lead to competitive -bidding. -

    -What are the formats that come with the kit? Well, you can simply list -the format sub-directory to find out. Here are the ones there -as of this writing: -

    -
    none -
    This script set the formatting routine to a null routine. - Not useful, so far, but useful, for example, when doing - statistical analysis. -
    numeric -
    This formatter writes the deal as a line which looks something - like: -
    -3031333123220300123320212213021202022103101101003113
    -
    - It's a line of 52 numbers, where 0, 1, 2, and 3 mean - north, east, south, and west, respectively. - The first digit tells where the ace of spades goes, the - second digit tells where the king of spades goes, etc. -
    okb -
    This formatter writes the output with the same spacing as the old -OKbridge screen. -
    practice -
    We've just seen this one - for seperating out hands for -practice bidding. -
    -There is one last output format, which, for historical reasons, -has its own command line switch, -l. -
    -$ deal -l 3
    -AJ9 976532 K92 A|86 A AT87 987653|Q732 JT8 543 T42|KT54 KQ4 QJ6 KQJ
    -K94 J93 QJ3 7653|A8 A8765 97 KQ98|JT2 Q AKT8654 T4|Q7653 KT42 2 AJ2
    -KJ753 T A4 KQ932|AQ94 AJ92 QT87 J|86 Q764 K9653 74|T2 K853 J2 AT865
    -$
    -
    -In the past, this was the only way to get alternate formats. The -user would pipe this output to another program, usually a Perl script, -which would parse each line and format the output. -

    -With the addition, in v2.0 of Deal, of user-configurable formatting, -this usage becomes obselete, but I'm leaving the feature because -it has one other use, which will be mentioned later. - -

    Basic Dealing - Scripting

    -

    Our First Script

    -Let's say we want a selection of deals in which north holds a one spade -opener. For now, we will use a crude definition for an opening 1S call - -we will require north to have 5 or more spades and 12 or more points. -

    -Here is the script we write (to a file we'll call onespade): -

    -main {
    -  if {[spades north]>=5 && [hcp north]>=12} { accept }
    -  reject
    -}
    -
    - -

    Running the script

    -We run this code by saying: -
    -$ deal -i onespade 2
    -          S : AKQT5
    -          H : A7
    -          D : 8542
    -          C : AT
    - S : 64             S : J98          
    - H : K943           H : 862          
    - D : J              D : AK963        
    - C : KQ8732         C : 54           
    -          S: 732
    -          H: QJT5
    -          D: QT7
    -          C: J96
    ----------------------------
    -          S : AQT73
    -          H : A
    -          D : AJ987
    -          C : 73
    - S : K5             S : J42          
    - H : JT8632         H : KQ95         
    - D : Q63            D : KT4          
    - C : 85             C : K92          
    -          S: 986
    -          H: 74
    -          D: 52
    -          C: AQJT64
    ----------------------------
    -
    -

    How the script works

    -By default, Deal accepts all hands. With the main code in -onespade, we tell Deal to override that behavior. -

    -This is similar to the way we used scripts to override Deal's -default formatting. Note, we even use the same flag, -i, -to load our formatters and onespade. -

    -What does this main code do? It is run after every deal -is complete, and used to evaluate the hand. In this case, we have only -two lines of code: -

    -if {[spades north]>=5 && [hcp north]>=12} { accept }
    -reject
    -
    -The expression [spades north] returns the number of spades -in the north hand. The expression [hcp north] returns -the number of HCP (high card points) in the north hand. The "&&" -is called a logical "and" operator, which returns true if the conditionals -on both sides of it are true. -

    -If the entire expression: -

    -[spades north]>=5 && [hcp north]>=12
    -
    -evaluates as true, the "accept" function is called. This causes -Deal to exit the "main" code and format the hand. -

    -If the expression evalutes as false, Deal goes to the next line -of code, which calls the "reject" function. This tells Deal to -discard the hand, and exit the "main" code. -

    -Deal keeps trying until the requested number of deals is accepted. -

    -What happens if a deal is not explicitly accepted or rejected? -If neither accept nor reject is called, the deal -is rejected. That means that in our first script, the reject -call was redundant, and we could have simply written the script as: -

    -main {
    -  if {[spades north]>=5 && [hcp north]>=12} { accept }
    -}
    -
    -

    Monitoring Deal

    -You might want to try running this script with the -v switch: -
    -$ deal -v -i onespade
    -
    -The -v flag tells Deal to give a progress report, which looks -like: - -
    -...
    -Deal 1 found after 2 tries
    -...
    -Deal 2 found after 21 tries
    -...
    -Deal 3 found after 31 tries
    -
    -This will give you some idea of how rare your condition is, and -also gives a good progress report when Deal is -writing to a file or running with a "silent" format, like -format/none. These status messages are written to "stderr", -which means that the output from Deal can be -redirected to a file without obscuring these messages.

    - -

    Using formats with your script

    - -If we wanted to use another output format with this script, we could do so -on the command line, as follows: -
    -$ deal -i format/practice -i onespade
    -
    -Or, alternately, we could add an explicit "source" command to our -script: -
    -source format/practice
    -
    -main {
    -        if {[spades north]>=5 && [hcp north]>=12} { accept }
    -}
    -
    - -In fact, this second format unveils the secret of the -i flag - -it is simply a request to "source" a file. In fact, if you were to -write your own formatter, you would not have to put the file in -the "format" directory. -If you put it in the current directory, you could then say: -
    -$ deal -i myformatter 100
    -
    -and it would work fine. The "format" subdirectory is just a convenience. -You will often want to re-use a format, and placing them in one place -lets you find out which formats are available. - -

    Stacking hands with a script

    - -Let's say you were dealt the hand: -
    -S: ---
    -H: 98532
    -D: A864
    -C: T962
    -
    -the previous day at a Swiss Teams event. -

    -Your partner opened 1S, and, playing 2/1 Game Force, you chose to -pass. This turns out well for you on this deal, because at the other -table, the opponents played in three spades, down 1. Afterwards, -you wonder if you really made the right decision. Your intuition -tells you that it was the right choice, but you realize there are -risks in both passing and bidding, and you know that intuition is -very bad at assessing levels of risk. -

    -Deal can help. Using our script, onespade, -we can run the following simulation: -

    -$ deal -S "- 96532 A864 T962" -i onespade
    -
    -The -S flag stacks the south hand with the hand you held, -and the script runs exactly the same thereafter. You can now peruse -the output to see whether it was a good idea or a bad idea to pass. -

    -As with the formatting, we can also do our deck-stacking in our script. -

    -south is "- 98532 A864 T962"
    -
    -main {
    -  if {[spades north]>=5 && [hcp north]>=12} { accept }
    -}
    -
    - -Notice, we do our deck-stacking outside of the evaluation loop. -Remember, the main expression is responsible for evaluating the deals -after Deal finishes dealing the hands. -We obviously want the stacking instruction to occur before -dealing occurs, so the stacking command must be outside the main -evaluation. -

    -

    A partial list of routines

    -For evaluation routines, we have seen the hcp and spades -routines, as well as the "accept" and "reject" directives. -Obviously, there are also routines called hearts, - diamonds, and clubs which count their respective -suits. The following functions are also built-ins: -
    -
    controls
    This function computes the number of -controls held by a hand. -
    losers
    This function does a crude computation of -the losing trick count for a hand (it actually compute's half-losers, -so when [losers south] returns 14, that really means 7 losers.) -
    balanced
    This function returns true (1) if the -hand name passed is balanced in the usual sense - no shortness, at most -one doubleton, and no five-card major. It returns false (0) otherwise. -
    semibalanced
    Returns true (1) if the hand passed -has no shortness and no six-card or longer suit, and false (0) otherwise. -
    -The three functions, controls, hcp, and losers, -all have the property that we can compute them one suit at a time, and -sum the result for the entire hand. The implementation takes advantage -of this and allows the user to request these values for specific suits: -
    -main {
    -  if {[hcp south hearts spades]>10} {accept}
    -}
    -
    -This script accepts a deal if south has ten or more points in hearts -and spades. controls and losers can be used similarly. -Any function of this sort we will call "additive." We will see later that -we can define a wide class of interesting -additive functions. -

    -The functions balanced and semi_balanced are entirely -dependent on the shape of the hand, and not on which cards the hand holds. We -will call these "shape functions." We will find out later how to -define incredibly fast shape functions. - -

    A Second Script - defining Tcl procedures

    - -Let's say we want to write a script which accepts a deal if north -has a strong notrump (15 to 17 range) and south has about invitational -values and a 5-card major. - -

    -Our script , which we will call jacobytest might look something like: - -

    -# In deal 3.0, you don't need this next line, but deal 3.0 does - 
    -# without this line, the "balanced" routine is not defined.
    -
    -main {
    -	if {![balanced north]} {reject}
    -
    -	set hn [hcp north]
    -	if {$hn>17 || $hn<15} {reject}
    -
    -	set hs [hcp south]
    -	if {$hs<8 || $hs>9} {reject}
    -
    -	if {[spades south]==5 || [hearts south]==5} { accept }
    -}
    -
    - -We have used one of our new functions here, balanced, as -well as a new Tcl feature, variables. We could, of course, not used -variables, but then we would have had to write the lines: -
    -if {[hcp north]>17 || [hcp north]<15} {reject}
    -
    -That is going to be slower, with one more function call. Not appreciable -today, with a simple query, but when you might be processing a million or -more hands at a time, you learn to be frugal. -

    -Suddenly, you realize you want to test this situation with a 12-14 notrump, -instead. Or you realize you often want to reuse this concept. You -can do so by defining Tcl procedures. -

    -

    -proc notrump {hand min max} {
    -
    -  if {![balanced $hand]} {return 0}
    -
    -  set hc [hcp $hand]
    -  if {$hc < $min || $hc>$max} { return 0}
    -
    -  return 1
    -}
    -
    -proc jacobyinvite {hand ntmin ntmax} {
    -  if {[spades $hand]!=5 && [hearts $hand]!=5} {return 0}
    -
    -  set hc [hcp $hand]
    -  if {$hc+$ntmin <= 25 && $hc+$ntmax>=24} { return 1 }
    -
    -  return 0
    -}
    -
    -set NTmin 12
    -set NTmax 14
    -
    -main {
    -  if {![notrump north $NTmin $NTmax]} { reject }
    -  if {[jacobyinvite south $NTmin $NTmax]} { accept }
    -}
    -
    -You are unlikely to need the jacobyinvite function -beyond this script, but the notrump function will be something -you will want -to use again and again. You might even put it in a library of routines, called -mylibrary and source that library every time you need one or more -of the routines for a script: -
    -source mylibrary
    -
    -rather than rewriting the routine every time. -

    -In fact, the Deal kit comes with a file called library -, which is just such a library of routines the author of Deal - found himself re-using. -


    -

    Revisiting accept and reject

    -The directives, accept and reject, can be used -in more complicated ways that are sometimes more efficient and -sometimes more readable. -

    -Here is the main script from the notrump example -using some odd constructs: -

    -main {
    -  reject unless {[notrump north $NTmin $NTmax]}
    -  accept if {[jacobyinvite south $NTmin $NTmax]}
    -}
    -
    -Some people might find this more readable. The first line says -we are going to reject the deal unless the condition -is true. The second conditional says we are going to accept -the deal if the expression evaluates as true. -

    -Multiple arguments are allowed. The following command: -

    -reject unless {expr1} {expr2} ... {exprn}
    -
    -runs through all of the expressions until it finds one which evaluates -as "true". If it does not find a true value, it rejects the hand. -Otherwise, deal goes on to the next line in evaluating main. -

    -For reject if the deal is rejected if any one of the expressions -is true. Similarly, accept if accepts a deal if one of the -expressions is true. For accept unless, the deal is accepted -unless the one of the expressions is true. - -

    -


    -This concludes the Introductory Tutorial. I hope -it inspires you to check out the Deal - Advanced -Guide and to learn more about Tcl. -Or check out the index of all deal commands. - -
    -
    -Silhouette - Thomas Andrews -(thomaso@best.com) - Copyright 1996-2002. Deal is covered by the -GNU General Public License. -

    -Plane Dealing graphic -above created using -POV-Ray. -

    -
    - diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/docs/html/tkdeal.txt /tmp/sFHmVEdqkv/deal-3.1.4/docs/html/tkdeal.txt --- deal-3.0.8/docs/html/tkdeal.txt 2002-12-19 20:51:07.000000000 +0530 +++ deal-3.1.4/docs/html/tkdeal.txt 1970-01-01 05:30:00.000000000 +0530 @@ -1,144 +0,0 @@ -global hf - -set hf(debug) 0 - -set hf(lwidgets) "ssymbol hsymbol dsymbol csymbol" -set hf(rwidgets) "spades hearts diamonds clubs" -set hf(allwidgets) "$hf(lwidgets) $hf(rwidgets)" - -set deal_count 0 -set current_deal -1 - -proc handframe {name args} { - - frame $name -class hand -borderwidth 2 -relief raised - - rename $name ${name}_frame - - frame $name.left -height 100 - frame $name.right -height 100 - - label $name.ssymbol -width 10 -anchor e -text "Spades:" - label $name.hsymbol -width 10 -anchor e -text "Hearts:" - label $name.dsymbol -width 10 -anchor e -text "Diamonds:" - label $name.csymbol -width 10 -anchor e -text "Clubs:" - - pack $name.ssymbol $name.hsymbol $name.dsymbol $name.csymbol \ - -side top -in $name.left -fill both - - label $name.spades -width 13 -anchor w - label $name.hearts -width 13 -anchor w - label $name.diamonds -width 13 -anchor w - label $name.clubs -width 13 -anchor w - - pack $name.spades $name.hearts $name.diamonds $name.clubs \ - -side top -in $name.right -fill both - - pack $name.left $name.right -side left -in $name -fill both - - proc $name {args} "eval \"handframe_process $name \$args\"" -} - -proc handframe_process {name args} { - set cnt [llength $args] - - switch [lindex $args 0] { - configure { - eval "handframe_configure $name [lrange $args 1 end]" - } hand { - if {$cnt != 5} { error "Wrong number of arguments"} - $name.spades configure -text [lindex $args 1] - $name.hearts configure -text [lindex $args 2] - $name.diamonds configure -text [lindex $args 3] - $name.clubs configure -text [lindex $args 4] - } destroy { - destroy $name.ssymbol $name.hsymbol $name.dsymbol $name.csymbol - destroy $name.left $name.right - pack $name.spades $name.hearts $name.diamonds $name.clubs - } default { - error "Unknown args $args" - } -} -} - -proc handframe_configure {name args} { - global hf - - foreach window $hf(allwidgets) { - eval "$name.$window configure $args" - } -} - -wm maxsize . 2000 2000 - -frame .buttons -pack .buttons -side top -fill x - -button .prev -command { get_prev_deal } -text "Prev Deal" - pack .prev -side left -in .buttons -padx 3p -button .next -command { get_next_deal } -text "Next Deal" - pack .next -side left -in .buttons -padx 3p - -button .quit -command { destroy .} -text "Quit" - pack .quit -side right -in .buttons -padx 3p -set deal_count 0 -set current_deal -1 - -handframe .north -pack .north -side top -pady 10p -frame .ew - - pack .ew -side top -after .north -pady 10p - handframe .west - handframe .east - pack .west -side left -in .ew -padx 10p - pack .east -side right -in .ew -padx 10p - -handframe .south -pack .south -side top -after .ew -pady 10p - -proc post_deal {deal} { - set list [split $deal " |"] - set length [llength $list] - while {0<=[set ind [lsearch -exact $list ""]]} { - set list [lreplace $list $ind $ind ---] - } - eval ".north hand [lrange $list 0 3]" - eval ".south hand [lrange $list 8 11]" - eval ".west hand [lrange $list 12 15]" - eval ".east hand [lrange $list 4 7]" -} - -proc activate_deal {dealno} { - global deal_count - global deal current_deal - post_deal $deal($dealno) - set current_deal $dealno - .next configure -state normal - .prev configure -state normal - if {$dealno==0} { .prev configure -state disabled } - if {$dealno+1==$deal_count} { .next configure -state disabled} -} - -proc get_next_deal {} { - global current_deal deal_count - - if {$current_deal+1>=$deal_count} {beep; return} - activate_deal [expr $current_deal+1] -} - -proc get_prev_deal {} { - global current_deal deal_count - if {$current_deal<=0} {beep; return} - activate_deal [expr $current_deal-1] -} - -set deal_count 0 -while {0<=[gets stdin deal($deal_count)]} { - incr deal_count -} - -activate_deal 0 - -bind . n get_next_deal -bind . p get_prev_deal diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/format/article /tmp/sFHmVEdqkv/deal-3.1.4/format/article --- deal-3.0.8/format/article 2001-10-09 20:48:33.000000000 +0530 +++ deal-3.1.4/format/article 2008-05-22 06:25:15.000000000 +0530 @@ -1,6 +1,7 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: article,v 1.2 2008/05/22 00:55:15 thomaso Exp $ # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/format/count /tmp/sFHmVEdqkv/deal-3.1.4/format/count --- deal-3.0.8/format/count 2001-10-09 20:48:33.000000000 +0530 +++ deal-3.1.4/format/count 2008-05-22 06:25:15.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: count,v 1.2 2008/05/22 00:55:15 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/format/ddline /tmp/sFHmVEdqkv/deal-3.1.4/format/ddline --- deal-3.0.8/format/ddline 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/format/ddline 2008-05-22 06:25:15.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: ddline,v 1.5 2008/05/22 00:55:15 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -15,7 +17,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -source /usr/share/deal/lib/gib.tcl set ddline(counter) 0 @@ -23,12 +24,17 @@ global ddline set line [list] set dd [list] + foreach suit {spades hearts diamonds clubs notrump} { + puts -nonewline stderr "." + foreach hand {north east south west} { + set dummy [deal::tricks $hand $suit] + } + } foreach hand {north east south west} { - puts -nonewline stderr "." lappend line [join [$hand] "."] set handdd [list] foreach suit {spades hearts diamonds clubs notrump} { - lappend handdd [gib::tricks $hand $suit] + lappend handdd [deal::tricks $hand $suit] } lappend dd $handdd } diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/format/default /tmp/sFHmVEdqkv/deal-3.1.4/format/default --- deal-3.0.8/format/default 2001-10-09 20:48:33.000000000 +0530 +++ deal-3.1.4/format/default 2008-06-04 09:37:01.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: default,v 1.5 2008/06/04 04:07:01 thomasoa Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -16,8 +18,6 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # -# This is set up to make output look like an okbridge screen. -# namespace eval formatter { variable loc set loc(row:east) 4 @@ -28,6 +28,9 @@ set loc(col:west) 1 set loc(row:south) 8 set loc(col:south) 10 + variable suitletters [list S: H: D: C:] + variable suitsunicode [list "\u2660" "\u2665" "\u2666" "\u2663"] + variable suitsymbols $suitletters stringbox ::formatter::writer 12 60 @@ -36,11 +39,12 @@ } proc puthand {hand} { + variable suitsymbols writer.$hand clear set row 0 - foreach suit {spades hearts diamonds clubs} letter {S H D C} { + foreach suit {spades hearts diamonds clubs} symbol $suitsymbols { -writer.$hand write $row 0 "$letter: [$hand -void --- $suit]" +writer.$hand write $row 0 "$symbol [$hand -void --- $suit]" incr row } } @@ -53,6 +57,10 @@ } } +if {$deal::unicode && [info exists env(LANG)] && [string first "UTF-8" [string toupper $env(LANG)]]>=0} { + set ::formatter::suitsymbols $::formatter::suitsunicode +} + proc write_deal {} { formatter::write_deal puts stdout "--------------------------" diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/format/gibpar /tmp/sFHmVEdqkv/deal-3.1.4/format/gibpar --- deal-3.0.8/format/gibpar 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/format/gibpar 2008-05-17 23:44:47.000000000 +0530 @@ -1,150 +1 @@ -# -# Copyright (C) 1996-2001, Thomas Andrews -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -source /usr/share/deal/lib/parscore.tcl - -namespace eval gibpar { - - variable gibpar - - set gibpar(num) 1 - set gibpar(incr) 1 - set gibpar(dealer) [list north east south west] - set gibpar(vul) [list None NS EW All NS EW All None EW All None NS All None NS EW] - - set gibpar(Date) [clock format [clock seconds] -format "%Y.%m.%d"] - - foreach seat {North East South West} { - set gibpar($seat) "$seat" - } - - set gibpar(letter:north) N - set gibpar(letter:east) E - set gibpar(letter:west) W - set gibpar(word:doubled) X - set gibpar(word:redoubled) XX - set gibpar(word:) "" - set gibpar(lho:south) W - set gibpar(lho:west) N - set gibpar(lho:north) E - set gibpar(lho:east) S - - proc pbn_write_line {key value} { - puts "\[$key \"$value\"\]" - } - - proc getVul {} { - variable gibpar - set vullist $gibpar(vul) - set num $gibpar(num) - set index [expr {($num-1)%[llength $vullist]}] - lindex $vullist $index - } - - proc dealerOrder {args} { - variable gibpar - set gibpar(dealer) $args - } - - proc vulOrder {args} { - variable gibpar - set gibpar(vul) $args - } - - proc getDealer {} { - variable gibpar - set dlrlist $gibpar(dealer) - set num $gibpar(num) - set index [expr {($num-1)%[llength $dlrlist]}] - lindex $dlrlist $index - } - - proc pbn_contract {contract} { - variable gibpar - set level [lindex $contract 0] - set denom [lindex $contract 1] - set dbl [lindex $contract 2] - - append level [par_first_upper $denom] $gibpar(word:$dbl) - } - - proc write_deal {} { - - variable gibpar - set num $gibpar(num) - set dealer [getDealer] - set vul [getVul] - incr gibpar(num) $gibpar(incr) - puts stderr "Computing par for deal $num $dealer $vul" - set par [parscore $dealer $vul] - set contract [lindex $par 0] - set declarer [lindex $par 1] - set score [lindex $par 2] - set tricks [lindex $par 3] - set auction [lindex $par 4] - pbn_write_line Date $gibpar(Date) - pbn_write_line Board $num - - foreach seat {West North East South} { - pbn_write_line $seat $gibpar($seat) - } - - pbn_write_line Dealer [par_first_upper $dealer] - pbn_write_line Vulnerable $vul - - foreach hand {north east south west} { - set fmt($hand) "[$hand spades].[$hand hearts].[$hand diamonds].[$hand clubs]" - } - pbn_write_line Deal "N:$fmt(north) $fmt(east) $fmt(south) $fmt(west)" - - pbn_write_line Contract [pbn_contract $contract] - pbn_write_line Declarer [par_first_upper $declarer] - pbn_write_line Result $tricks - pbn_write_line Score "NS $score" - puts "{" - ::formatter::write_deal - puts "}" - - pbn_write_line Auction [par_first_upper $dealer] - - set count 0 - foreach bid $auction { - if {$count==4} { - puts "" - set count 0 - } - - if {$count>0} { - puts -nonewline " " - } - - puts -nonewline $bid - incr count - } - - - puts "" - - pbn_write_line Play $gibpar(lho:$declarer) - puts "*" - puts "" - } -} - -proc write_deal {} { - ::gibpar::write_deal -} +source format/par diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/format/none /tmp/sFHmVEdqkv/deal-3.1.4/format/none --- deal-3.0.8/format/none 2001-10-09 20:48:33.000000000 +0530 +++ deal-3.1.4/format/none 2008-05-22 06:25:15.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: none,v 1.2 2008/05/22 00:55:15 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/format/numeric /tmp/sFHmVEdqkv/deal-3.1.4/format/numeric --- deal-3.0.8/format/numeric 2001-10-09 20:48:33.000000000 +0530 +++ deal-3.1.4/format/numeric 2008-05-22 06:25:15.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: numeric,v 1.2 2008/05/22 00:55:15 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/format/okb /tmp/sFHmVEdqkv/deal-3.1.4/format/okb --- deal-3.0.8/format/okb 2001-10-09 20:48:33.000000000 +0530 +++ deal-3.1.4/format/okb 2008-05-22 06:25:15.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: okb,v 1.2 2008/05/22 00:55:15 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/format/onehand /tmp/sFHmVEdqkv/deal-3.1.4/format/onehand --- deal-3.0.8/format/onehand 2001-10-09 20:48:33.000000000 +0530 +++ deal-3.1.4/format/onehand 2008-05-22 06:25:15.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: onehand,v 1.2 2008/05/22 00:55:15 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/format/par /tmp/sFHmVEdqkv/deal-3.1.4/format/par --- deal-3.0.8/format/par 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/format/par 2008-06-11 02:18:43.000000000 +0530 @@ -0,0 +1,163 @@ +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# $Id: par,v 1.5 2008/06/10 20:48:43 thomaso Exp $ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +source lib/parscore.tcl + +namespace eval par { + + variable par + + set par(num) 1 + set par(incr) 1 + set par(dealer) [list north east south west] + set par(vul) [list None NS EW All NS EW All None EW All None NS All None NS EW] + + if {[info commands clock]=="clock"} { + set par(Date) [clock format [clock seconds] -format "%Y.%m.%d"] + } else { + set par(Date) "1965.01.01" + } + + foreach seat {North East South West} { + set par($seat) "$seat" + } + + set par(letter:north) N + set par(letter:east) E + set par(letter:west) W + set par(word:doubled) X + set par(word:redoubled) XX + set par(word:) "" + set par(lho:south) W + set par(lho:west) N + set par(lho:north) E + set par(lho:east) S + + proc pbn_write_line {key value} { + puts "\[$key \"$value\"\]" + } + + proc getVul {} { + variable par + set vullist $par(vul) + set num $par(num) + set index [expr {($num-1)%[llength $vullist]}] + lindex $vullist $index + } + + proc dealerOrder {args} { + variable par + set par(dealer) $args + } + + proc vulOrder {args} { + variable par + set par(vul) $args + } + + proc getDealer {} { + variable par + set dlrlist $par(dealer) + set num $par(num) + set index [expr {($num-1)%[llength $dlrlist]}] + lindex $dlrlist $index + } + + proc pbn_contract {contract} { + variable par + set level [lindex $contract 0] + set denom [lindex $contract 1] + set dbl [lindex $contract 2] + + append level [par_first_upper $denom] $par(word:$dbl) + } + + proc write_deal {} { + + variable par + set num $par(num) + set dealer [getDealer] + set vul [getVul] + incr par(num) $par(incr) + puts stderr "Computing par for deal $num $dealer $vul" + set mypar [parscore $dealer $vul] + set contract [lindex $mypar 0] + set declarer [lindex $mypar 1] + set score [lindex $mypar 2] + set tricks [lindex $mypar 3] + set auction [lindex $mypar 4] + pbn_write_line Date $par(Date) + pbn_write_line Board $num + + foreach seat {West North East South} { + pbn_write_line $seat $par($seat) + } + + pbn_write_line Dealer [par_first_upper $dealer] + pbn_write_line Vulnerable $vul + + foreach hand {north east south west} { + set fmt($hand) "[$hand spades].[$hand hearts].[$hand diamonds].[$hand clubs]" + } + pbn_write_line Deal "N:$fmt(north) $fmt(east) $fmt(south) $fmt(west)" + + pbn_write_line Contract [pbn_contract $contract] + pbn_write_line Declarer [par_first_upper $declarer] + pbn_write_line Result $tricks + pbn_write_line Score "NS $score" + puts "{" + ::formatter::write_deal + foreach hand {north east south west} { + foreach denom {clubs diamonds hearts spades notrump} { + puts "$hand makes [::deal::tricks $hand $denom] tricks in $denom" + } + } + puts "}" + + pbn_write_line Auction [par_first_upper $dealer] + + set count 0 + foreach bid $auction { + if {$count==4} { + puts "" + set count 0 + } + + if {$count>0} { + puts -nonewline " " + } + + puts -nonewline $bid + incr count + } + + + puts "" + + if {$declarer != ""} { + pbn_write_line Play $par(lho:$declarer) + puts "*" + puts "" + } + } +} + +proc write_deal {} { + ::par::write_deal +} diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/format/parArticle /tmp/sFHmVEdqkv/deal-3.1.4/format/parArticle --- deal-3.0.8/format/parArticle 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/format/parArticle 2008-05-22 06:25:15.000000000 +0530 @@ -4,6 +4,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: parArticle,v 1.2 2008/05/22 00:55:15 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -18,7 +20,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -source /usr/share/deal/lib/parscore.tcl +source lib/parscore.tcl set particle(num) 0 set particle(dealer) [list north east south west] diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/format/pbn /tmp/sFHmVEdqkv/deal-3.1.4/format/pbn --- deal-3.0.8/format/pbn 2001-10-09 20:48:33.000000000 +0530 +++ deal-3.1.4/format/pbn 2008-05-22 06:25:15.000000000 +0530 @@ -2,6 +2,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: pbn,v 1.2 2008/05/22 00:55:15 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/format/practice /tmp/sFHmVEdqkv/deal-3.1.4/format/practice --- deal-3.0.8/format/practice 2001-10-09 20:48:33.000000000 +0530 +++ deal-3.1.4/format/practice 2008-05-22 06:25:15.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: practice,v 1.2 2008/05/22 00:55:15 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/format/simpleokb /tmp/sFHmVEdqkv/deal-3.1.4/format/simpleokb --- deal-3.0.8/format/simpleokb 2001-10-09 20:48:33.000000000 +0530 +++ deal-3.1.4/format/simpleokb 2008-05-22 06:25:15.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: simpleokb,v 1.2 2008/05/22 00:55:15 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/hand.c /tmp/sFHmVEdqkv/deal-3.1.4/hand.c --- deal-3.0.8/hand.c 2001-10-09 20:57:29.000000000 +0530 +++ deal-3.1.4/hand.c 2008-05-15 05:49:24.000000000 +0530 @@ -29,10 +29,6 @@ * * */ -#ifndef lint -static char rcsid [] = "$Header: /home/thomaso/deal30/RCS/tcl_deal.c,v 1.3 1999/07/09 00:31:40 thomaso Exp thomaso $"; -#endif - #include #include diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/Holding.h /tmp/sFHmVEdqkv/deal-3.1.4/Holding.h --- deal-3.0.8/Holding.h 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/Holding.h 2008-06-11 01:27:40.000000000 +0530 @@ -0,0 +1,32 @@ +#ifndef __DDS_HOLDING_H__ +#define __DDS_HOLDING_H__ +#include "ddsInterface.h" + +/* + * This is just a utility class so you can say: + * cout << Holding(h) << endl; + * when h is of type holding_t. + */ +struct Holding { + holding_t _h; + inline Holding(holding_t h) : _h(h) { } +}; + + +inline ostream& operator <<(ostream &out,const Holding &holding) { + static const char *cards="AKQJT98765432"; + int index=0; + holding_t h = holding._h; + + if (h) { + for (holding_t card=1<<12; card; card >>= 1, index++) { + if (h & card) { + out << cards[index]; + } + } + } else { + out << "(void)"; + } + return out; +} +#endif diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/holdings.c /tmp/sFHmVEdqkv/deal-3.1.4/holdings.c --- deal-3.0.8/holdings.c 2001-02-19 22:42:45.000000000 +0530 +++ deal-3.1.4/holdings.c 2008-05-29 19:30:10.000000000 +0530 @@ -924,9 +924,7 @@ subsetCmd, matchesCmd, lengthFlag, - spotFlag, - initKeywords=1; int cmd; diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/advanced.html /tmp/sFHmVEdqkv/deal-3.1.4/html/advanced.html --- deal-3.0.8/html/advanced.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/advanced.html 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,477 @@ + + + + + + + + + + + Deal - An Advanced User Guide + + + + + + + + + + + + + + +
    Plane Dealing image +

    Deal 3.1

    +

    An Advanced User Guide

    +
    +Covering:
      +
    • Vector additive functions +
    • Shape functions +
    • Customizable output formats +
    • Statistical analysis +
    • Hints for fast scripts +
    +

    + +
    +

    Prologue

    +First things first, you will need to download +Deal and build it. The rest of this guide assumes you have +already done this. +

    +This guide also assumes you know everything in the +Introductory Tutorial. Some sections +in this guide will require more knowledge +of Tcl than others. +

    +**Warning** It takes careful +eyes, at least on the version of Netscape I am using, to distinguish +between normal parentheses, (), and curly +parentheses, {}. Almost all of the paretheses in the script +listings below are curly parentheses. +


    +

    Contents

    + +

    Vector additive functions

    + +In the Introductory Tutorial, we mentioned +three functions which we called "additive functions." They were +hcp, controls, and losers. We called them additive +because we could compute them for a single suit holding in a hand or +across the entire hand by summing over all the suits. +

    +In this section, we will show how a user can create a large class +of fast additive functions, and show how they can be used. +

    +The most common additive function is hcp. How is it +computed? Given a suit holding, we count 4 for the ace, 3 for +the king, 2 for the queen, and 1 for the jack. Here is how +we would define this with a "vector": +

    +defvector Hcp 4 3 2 1
    +
    + +That's pretty simply. Similarly, we can define a Controls vector: +
    +defvector Controls 2 1
    +
    +

    +Once these vectors are defined, we can use them as functions anywhere +we used hcp and controls. +

    + +Now, considering the following case: Your partner, north, opens a weak +two spades, and you have the agreement that partner always has a 6-card +suit with at least two of the top three honors. You can define a vector: +

    +defvector Top3 1 1 1
    +
    +Now, to test the quality of the spade suit, you could say: +
    +if {[Top3 north spades]>=2} { ... }
    +
    +Pretty simple. +

    +So you decide to write a "weak2" procedure: +

    +defvector Top3 1 1 1
    +
    +proc weak2 {hand suit} {
    +  if {[$suit $hand]==6 && [Top3 $hand $suit]>=2} { return 1 }
    +  return 0
    +}
    +
    +You can call this by saying: +
    +#... 
    +main {
    +	if {[weak2 north spades]} { accept }
    +}
    +
    +This will deal out hands where north has exactly six +spades and two of the top three spades. +

    +This works okay (although you have forgotten to restrict the other +suit lengths, so you could end up with voids and side 5-card or +6-card suits.) +

    +Two weeks later, you and your partner decide that you will also +consider a suit worth a weak 2 if it contains three of the top +five cards, which, specifically, really means you've now allowed +suits led by QJT, KJT, and AJT. This is +not an uncommon agreement. +

    +We could, of course, write a routine called "Top5" and check +both Top3 and Top5, but a little cleverness allows us to roll +this all up into one vector. +

    +defvector weak2quality 2 2 2 1 1
    +
    + +You will see, if you think about it, that this vector evaluates +to 4 or more precisely when the suit has the right quality for +a weak two. You then rewrite the weak2 function: +

    +

    +defvector weak2quality 2 2 2 1 1
    +
    +proc weak2 {hand suit} {
    +  if {[$suit $hand]==6 && [weak2quality $hand $suit]>=4} { return 1 }
    +  return 0
    +}
    +
    + +The advantage of the vector functions is that they can be computed +quickly, using table lookups. +

    +However, vectors don't compute many additive functions, like "losers" +and "quick tricks," or even high card points with distribution adjustments. +For this, you will need to use the Deal 3.1 feature, +holding functions. It pretty much +covers *all* such procedures, but still allows for a fast lookup. + +

    Shape functions and classes

    + +In the Introductory Tutorial, we mentioned +the two functions, balanced, and semi_balance, and +called them "shape functions" because they take a hand name as an +argument, the return value depends only on the "shape" of the hand - +that is, on how many cards are in each suit. +

    +In fact, balanced and semi_balanced are a special +sort of shape function, which we will call a "shape class." A "shape +class" is a shape function which returns only the values 0 and 1, +and therefore defines a class of shapes, namely those shapes which +evaluate as 1. +

    +Deal allows for extremely fast shape class and +shape function computations. +

    +

    A basic shape class

    +For example, lets say that we want to write a shapeclass which +returns 1 if our hand is right shape for a one spade opening. We would +do so with the following definition: +
    +shapeclass spadeshape {
    +    if {$s>=5 && $s>=$h && $s>=$d && $s>=$c} { return 1}
    +    return 0
    +}
    +
    +This defines a routine, spadeshape, which returns true +precisely when the hand has 5 or more spades and at least as +many spades as any other suit. +

    +Notice, the variables $s, $h, $d, and +$c. Consider it this way - when you pass a hand name to +a shape function, it sets these variables to the suit lengths, +and then evaluates the code. [ That is not how it works in +reality, because that would be too slow. ] +

    +The idiom, if {expr} {return 1} return 0 + is so common in shape classes, Deal has +a shorthand, shapecond, and we could have defined spadeshape +as: +

    +shapecond spadeshape {$s>=5 && $s>=$h && $s>=$d && $s>=$c}
    +
    +

    A sample shape function

    + +Shape functions can return any string. They can be extremely +powerful. +

    +For example, we can define a function, opening_suit: +

    +shapefunc opening_suit {
    +	if {$c>$s && $c>$h && $c>$d} { return clubs }
    +	if {$d>$s && $d>$h && $d>$c} { return diamonds }
    +	if {$s>=5 && $s>=$h} { return spades }
    +	if {$h>=5} { return hearts }
    +	if {$d>=5 && $d>=$c} { return diamonds }
    +	if {$d>$c} { return diamonds }
    +	return clubs
    +}
    +
    +This function returns the name of the suit in which you should open +open the hand (at least according to some people) in Standard American +bidding. + +

    +Recently, a number of people have mentioned to me Bergen's "rule of +20" for determining whether a hand is worth an opening bid. +According to the rule, add your high card points to +the sum of the lengths of your longest two suits. If that adds up to +20, open the hand. We can write this as follows: +

    +shapefunc bergen::shapeval {
    +    set p [lsort -integer -decreasing "$s $h $d $c"]
    +    set first [lindex "$p" 0]
    +    set second [lindex "$p" 1]
    +    expr $first+$second
    +}
    +
    +proc bergen::opening {hand} {
    +    expr { [hcp $hand] + [bergen::shapeval $hand] >= 20}
    +}
    +
    +We can now use Bergen's rule in our simulations. +

    +

    Calling shape functions explicitly

    + +A shape function (or shape class) can be called with 4 numeric arguments: +
    +set open3343 [openingsuit eval 3 3 4 3]
    +
    +This is most useful in defining shape classes and functions from +other shape classes and functions. Assume you have shape classes +spadeshape and heartshape and you want to define +a new shape class, majorshape. You can do so as follows: +
    +shapecond majorshape \
    +	{[spadeshape eval $s $h $d $c] || [heartshape eval $s $h $d $c]}
    +
    + + +

    Customizable output formats

    + +With verson 2.0 of Deal, it is finally possible to write +your own customizable format routines. +

    +It is really fairly simple. When Deal accepts a hand, +it calls the procedure named write_deal. When it is finished +dealing the number of hands requested, it calls a procedure named +flush_deal. +

    +To change the output format, we simply redefine these procedures. +Tcl does not mind such redefinitions. +

    +For example, the formatter, format/none, is just the code: +

    +proc write_deal {} {
    +	# empty function
    +}
    +
    +By default, the flush_deal procedure is already empty, so +we do not have to redefine it here. +

    +Why might we need flush_deal at all? Some formatters +only write to output periodically. For example, format/practice +writes files out.north, out.east, out.south, +and out.west. The output in out.north looks like: +

    +                              north hands
    +============================================================================
    +     *1*                 *2*                 *3*                 *4*
    +  S 84                S T7                S QT3               S AJ9654
    +  H J8642             H Q65               H Q983              H K8
    +  D Q843              D KJ42              D 865               D J
    +  C 73                C T842              C AJ9               C K532
    +
    +=============================================================================
    +
    +Clearly, therefore, write_deal is buffering output +internally and only printing every fourth hand. What happens when +the user requests 10 deals? write_deal will be called +on the tenth deal, but because the deal number is not a multiple +of four, write_deal will not know to print the output. +The last two hands will be lost. +

    +The solution is to make Deal call flush_deal +on completion of dealing. +

    A most basic formatter - printing one hand

    + +Here is a new formatter, which we will place in a file call NorthFmt. +
    +proc write_deal {} {
    +	puts "S: [north -void --- spades]"
    +	puts "H: [north -void --- hearts]"
    +	puts "D: [north -void --- diamonds]"
    +	puts "C: [north -void --- clubs]"
    +	puts "============================="
    +}
    +
    +Okay, what does this expression, +[north -void --- spades], do? +The expression [north spades] returns the spade holding +of the north hand in a simple string form. If the suit is void, +it returns the empty string. The "-void ---" in the +example above tells the formatter to use the string "---" for +voids. +

    +We could do this a little more easily: + +

    +proc write_deal {} {
    +    foreach char {S H D C} suit {spades hearts diamonds clubs} {
    +	puts "$char: [north -void --- $suit]"
    +    }
    +    puts "============================="
    +}
    +
    +This uses the interesting feature of the Tcl foreach +which lets two variables move through two lists. +

    + +The north routine, without arguments, returns all four suits, in +a Tcl list format. Here is a simple formatter for the north and south +hands: +

    +proc write_deal {} {
    +    puts "{[north]} {[south]}"
    +}
    +
    +Yielding ugly output like: +
    +{{J9654} {KQT832} {} {42}} {{7} {A74} {T763} {J9865}}
    +{{KT852} {Q} {KT83} {A83}} {{96} {AK7543} {Q96} {52}}
    +
    +Not pretty, but useful if piping to another Tcl program, because +Tcl programs will find this fairly easy to parse. +

    +

    String boxes

    +For more complicated formats, I have added to Tcl an invention +of my own for string "drawings." Tcl does not have any +decent formatting routines, other than the format +command, which is based on the printf class of functions +in C. I've always found printf a pain, even back in Fortran. +

    +So I invented "string boxes." A string box is a like a drawable +canvas, but for characters rather than pixels. For example, here +is a slightly simpler version of the file format/okb: +

    +stringbox okbox 14 70
    +okbox write 4 15 "West"
    +okbox write 4 50 "East"
    +okbox write 0 30 "North"
    +okbox write 10 30 "South"
    +	...
    +
    +This code creates a string box named okbox with 14 rows of +70 columns of text (initially all blank), and then writes +the words "West", "East", "North", and "South" in different locations +in that box. +

    +Next we define the sub-boxes, one for each hand: +

    +	...
    +okbox subbox okbox.north 0 36 4 15
    +okbox subbox okbox.south 10 36 4 15
    +okbox subbox okbox.east 5 50 4 15
    +okbox subbox okbox.west 5 15 4 15
    +	...
    +
    + +A "subbox" is created from a parent box, and has both a row and column +location, and a row and column width. In the above instance, all of +our sub-boxes are 4 rows and 15 columns, and placed in the location +where the hands will eventually be printed. +

    +Our write_deal procedure would look like: +

    +proc write_deal {} {
    +  foreach hand {west south north east} {
    +    okputhand $hand
    +  }
    +
    +  puts "[okbox]"
    +  puts "                       -----------------------------"
    +}
    +
    +proc okputhand {hand} {
    +
    +  okbox.$hand clear
    +
    +  set rowhand 0
    +  foreach char {S H D C} suit {spades hearts diamonds clubs} {
    +    okbox.$hand write $rowhand 0 "$char [$hand -void --- $suit]"
    +    incr rowhand
    +  }
    +}
    +
    + +write_deal just calls the routine okputhand for each +hand, then writes out the contents of the entire string box, okbox, +followed by the seperator string of hyphens. Note that we convert +a string box to a normal string just by using its name alone, without +arguments, as in [okbox]. We can also convert a string with trailing +whitespace removed from lines, by saying [okbox compact]. +In fact, we probably should have used the compact modifier, +since there is so much trailing white space in this format. +

    +The okputhand procedure first clears the sub-box associated +that hand, then writes out the contents of the hand one suit at a time +to that same sub-box. +

    +The output looks like: +

    +                              North S KT6                             
    +                                    H J97                             
    +                                    D T8543                           
    +                                    C T5                              
    +               West                               East                
    +               S J75                              S Q983              
    +               H T86                              H A52               
    +               D AKJ7                             D Q9                
    +               C AQ8                              C KJ64              
    +                                                                      
    +                              South S A42                             
    +                                    H KQ43                            
    +                                    D 62                              
    +                                    C 9732                            
    +-----------------------------
    +
    + +I have yet to put together complete documentation for string boxes, +but I intend to do so. They have some remarkable features, and perhaps +some surprises for the unwary. +

    Statistical analysis

    + +Go here. + +

    Hints for fast scripts

    + +Documentation not yet written. +
    +
    +Silhouette +Thomas Andrews +(deal@thomasoandrews.com) +Copyright 1996-2008. Deal is covered by the +GNU General Public License. +

    +Plane Dealing graphic +above created using +POV-Ray. +

    +
    diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/balanswer.html /tmp/sFHmVEdqkv/deal-3.1.4/html/balanswer.html --- deal-3.0.8/html/balanswer.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/balanswer.html 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,159 @@ + + + + + + + + + +The Sum of the Squares of the Suit Lengths + + + + + +
    +

    The Sum of the Squares of the Suit Lengths

    +

    A Measure of the "Sickness" of a Hand Pattern

    + +In any hand, the average of the suit lengths is 3.25 = 13/4, obviously, +but what is the standard deviation of the suit lengths? +

    +The standard deviation, it turns out, is related to +the sum of the squares of the suit lengths. In particular, the higher +the sum of the squares, the higher the standard deviation. +

    +So it should come as no surprise that the more balanced hands should +have lower standard deviations, and hence lower sums of squares. In +particular, when the sum of the squares of the suit lengths is less +than or equal to 47, the hand is "balanced" in the traditional sense: +No singleton or void, and at most one doubleton. +

    +Since the smallest value is 43, and all values are odd, we can "normalize" +this metric by subtracting 43 and dividing by 2. +

    +We get the following table: + +

    +Normalized | Squares sum | Std Dev  | Shapes
    +============================================
    +         0 |          43 |  0.5000  | 4-3-3-3	 
    +         1 |          45 |  0.9574  | 4-4-3-2	
    +         2 |          47 |  1.2583  | 5-3-3-2       
    +         3 |          49 |  1.5000  | 4-4-4-1, 5-4-2-2 
    +         4 |          51 |  1.7078  | 5-4-3-1         
    +         5 |          53 |  1.8930  | 6-3-2-2        
    +         6 |          55 |  2.0616  | 5-5-2-1,6-3-3-1  
    +         7 |          57 |  2.2166  | 5-4-4-0,6-4-2-1 
    +         8 |          59 |  2.3629  | 5-5-3-0        
    +         9 |          61 |  2.5000  | 7-2-2-2,6-4-3-0  
    +        10 |          63 |  2.6300  | 7-3-2-1,6-5-1-1
    +        11 |          65 |  2.7538  | 6-5-2-0       
    +        12 |          67 |  2.8723  | 7-3-3-0, 7-4-1-1
    +        13 |          69 |  2.9860  | 7-4-2-0        
    +        15 |          73 |  3.2016  | 6-6-1-0, 8-2-2-1
    +        16 |          75 |  3.3040  | 7-5-1-0, 8-3-1-1
    +	17 |          77 |  3.4034  | 8-3-2-0        
    +        19 |          81 |  3.5940  | 8-4-1-0       
    +        21 |          85 |  3.7749  | 7-6-0-0      
    +        22 |          87 |  3.8622  | 9-2-1-1     
    +        23 |          89 |  3.9476  | 8-5-0-0, 9-2-2-0   
    +        24 |          91 |  4.0311  | 9-3-1-0           
    +        27 |          97 |  4.2720  | 9-4-0-0          
    +        30 |         103 |  4.5000  | 10-1-1-1        
    +        31 |         105 |  4.5735  | 10-2-1-0       
    +        33 |         109 |  4.7170  | 10-3-0-0      
    +        40 |         123 |  5.1881  | 11-1-1-0     
    +        41 |         125 |  5.2519  | 11-2-0-0    
    +        51 |         145 |  5.8524  | 12-1-0-0   
    +        63 |         169 |  6.5000  | 13-0-0-0  
    +
    +
    + +In addition, one can get the wildness of a deal by adding up the sum of the +squares of all 16 suit lengths, or add up the normalized values. Again, +this is correlated to the standard deviation of the suit lengths. +

    +We can also measure the wildness of a "fit" by summing the squares of the fits +in each suit. So if I'm 5-3-3-2 and partner is 4-3-2-4, our "fit" is +9-6-5-6. One thing interesting about this is that our opponent's fit +wildness is the same as our fit pattern wildness. That's because if our +pattern is: s-h-d-c, their pattern is (13-s)-(13-h)-(13-d)-(13-c), and the +sum of the squares of these values is: +

    +(13-s)^s+(13-h)^s+(13-d)^2+(13-c)^2=
    +       s^2 + h^2 + d^2 + c^2 - 26*(s+h+d+c) + 4*13^2
    +
    +But (s+h+d+c) is 26, so the last two terms cancel, and we are left with the +original value. +

    +Of course, if you think in terms of standard deviation, this makes more sense +than the pure calculation - the opponents' pattern has the same relative +distribution, just inverted, so the deviation should be the same. +

    +This table can also be normalized, by subtracting 170 and dividing by 2. +There are 103 fit patterns, or 65 if we consider our fit pattern and opponent's +as the same (e.g., that 8-6-6-6 is the same as 7-7-7-5. If the sum of the longest fit and the shortest fit is 13, then the pattern is self-dual, for example, if our fit pattern is 9-7-6-4, then so is the opponent's.) +

    +Normalized |  Squares sum | Patterns
    +============================================
    +         0 |          170 | 7-7-6-6
    +         1 |          172 | 8-6-6-6,7-7-7-5
    +         2 |          174 | 8-7-6-5
    +         4 |          178 | 9-6-6-5,8-8-5-5,8-7-7-4
    +         5 |          180 | 9-7-5-5,8-8-6-4
    +         6 |          182 | 9-7-6-4
    +         8 |          186 | 10-6-5-5,9-8-5-4,8-8-7-3
    +         9 |          188 | 10-6-6-4,9-7-7-3
    +        10 |          190 | 10-7-5-4,9-8-6-3
    +        12 |          194 | 10-7-6-3,9-9-4-4
    +        13 |          196 | 11-5-5-5,10-8-4-4,9-9-5-3,8-8-8-2
    +        14 |          198 | 11-6-5-4,10-8-5-3,9-8-7-2
    +        16 |          202 | 11-7-4-4,11-6-6-3,10-7-7-2,9-9-6-2
    +        17 |          204 | 11-7-5-3,10-8-6-2
    +        18 |          206 | 10-9-4-3
    +        20 |          210 | 12-5-5-4,11-8-4-3,11-7-6-2,10-9-5-2,9-8-8-1
    +        21 |          212 | 12-6-4-4,9-9-7-1
    +        22 |          214 | 12-6-5-3,11-8-5-2,10-8-7-1
    +        24 |          218 | 12-7-4-3,10-10-3-3,10-9-6-1
    +        25 |          220 | 12-6-6-2,11-9-3-3,11-7-7-1,10-10-4-2
    +        26 |          222 | 12-7-5-2,11-9-4-2,11-8-6-1
    +        28 |          226 | 13-5-4-4,12-8-3-3,10-10-5-1,9-9-8-0
    +        29 |          228 | 13-5-5-3,12-8-4-2,11-9-5-1,10-8-8-0
    +        30 |          230 | 13-6-4-3,12-7-6-1,10-9-7-0
    +        32 |          234 | 13-6-5-2,12-8-5-1,11-10-3-2,11-8-7-0
    +        33 |          236 | 13-7-3-3,10-10-6-0
    +        34 |          238 | 13-7-4-2,12-9-3-2,11-10-4-1,11-9-6-0
    +        36 |          242 | 13-6-6-1,12-9-4-1,12-7-7-0
    +        37 |          244 | 13-7-5-1,12-8-6-0
    +        38 |          246 | 13-8-3-2,11-10-5-0
    +        40 |          250 | 13-8-4-1,12-9-5-0,11-11-2-2
    +        41 |          252 | 12-10-2-2,11-11-3-1
    +        42 |          254 | 13-7-6-0,12-10-3-1
    +        44 |          258 | 13-9-2-2,13-8-5-0,11-11-4-0
    +        45 |          260 | 13-9-3-1,12-10-4-0
    +        48 |          266 | 13-9-4-0
    +        50 |          270 | 12-11-2-1
    +        52 |          274 | 13-10-2-1,12-11-3-0
    +        54 |          278 | 13-10-3-0
    +        60 |          290 | 12-12-1-1
    +        61 |          292 | 13-11-1-1,12-12-2-0
    +        62 |          294 | 13-11-2-0
    +        72 |          314 | 13-12-1-0
    +        84 |          338 | 13-13-0-0
    +
    +
    +
    +Silhouette +Thomas Andrews +(deal@thomasoandrews.com) +Copyright 1996-2008. Deal is covered by the +GNU General Public License. +

    +Plane Dealing graphic +above created using +POV-Ray. +

    +
    diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/commands2.html /tmp/sFHmVEdqkv/deal-3.1.4/html/commands2.html --- deal-3.0.8/html/commands2.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/commands2.html 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,1730 @@ + + +Deal Commands + +

    Introduction

    +
    +This is meant to be a comprehensive list of commands in Deal which +are not native to Tcl. If you want to learn Tcl, I will be providing +a set of pointers later. + +
    +Text in blue is meant for Tcl afficianado +- reading this text without knowledge of Tcl might confuse more than +enlighten.
    +
    +
    +
    +Text in green is meant for programmers +interested in finding code definitions. +
    +
    + + + + +

    Hand commands: north, east, south, west, hand

    + +
    +

    Usage

    +
    +east [ -void string] [ suitname ... ]
    +hand {hand string} [ -void string] [ suitname ... ]
    +
    +south subcommand [ ... args ... ]
    +hand {hand string} subcommand [ ... args ... ]
    +
    +These are very strange commands - they really have too much stuffed +into them. That's a historical anomoly which I'm reluctant to abandon. +

    +With no subcommands, the routine is used for formatting the hand as +a string. For example, if south is: +

    +S: AJ5432
    +H: KT94
    +D: void
    +C: K93
    +
    +Then the results of various commands are: +
    +south                    =>    {AJ5432 KT94 {} K93}
    +south spades             =>    AJ5432
    +south hearts clubs       =>    {KT94 K93}
    +south -void -            =>    {AJ5432 KT94 - K93}
    +south -void --- diamonds =>    ---
    +
    +set h {AK4 {} A95432 JT98}
    +hand $h                  =>    {AK4 {} A95432 JT98}
    +hand $h spades           =>    AK4
    +hand $h hearts clubs     =>    {{} JT98}
    +hand $h -void -          =>    {AK4 - A95432 JT98}
    +
    +The -void switch exists precisely for formatting the output. +

    +The various subcommands will be treated in seperate sections. + +The hand version of this command only works with some subcommands. +

    + +
    For Programmers

    +

    Implementation:
    +
    C code +
    Location:
    +
    tcl_deal.c, function tcl_hand_cmd +
    +
    +
    +

    Subcommand: shape

    +

    Usage

    +
    +north shape
    +hand {AJTxx Axx JTxx x} shape
    +
    +

    Summary

    +Returns a list of suit lengths, in standard order. +

    +For example, the second command above would return the list: +

    +5 3 4 1
    +
    +

    Subcommand: pattern

    +

    Usage

    +
    +north pattern
    +hand {AJ32 A5 JTxx xxx} pattern
    +
    +

    Summary

    +Returns a sorted list of the suit lengths, starting with the longest. +For example, the second command above would return the list: +
    +4 4 3 2
    +
    +

    Subcommand: is

    +

    Usage

    +
    +south is {handstring}
    +
    +

    Summary

    +This command pre-places a specific 13 cards. For voids, you can use +the "-" character: +
    +south is {AJ32 KT932 - Q876}
    +
    +Calls to this subcommand must occur before dealing begins, outside the +"main" command. +

    +This subcommand calls the stack_hand command. +Inside the main code, the deal is already dealt. +

    Subcommand: gets

    +

    Usage

    +
    +handname gets card [card ...]
    +
    +

    Summary

    +Puts a specific list of cards in the hand named. As with the +"is" subcommand, this must be called before dealing +starts, outside the "main" command. +The card is specified in two characters, a rank character and a suit +character: +
    +AS KH JH 9D
    +
    +This routine dispatches its data to the stack_cards command. + +

    Subcommand: has

    +

    Usage

    +
    +handname has card [card ...]
    +hand {string} has card [...]
    +
    +

    Summary

    +This returns a count of the cards listed that occur in the hand named. +
    +% south
    +AJ54 JT54 43 654
    +% south has SA HK HJ HT
    +3
    +
    +
     
    +
    +

    Control commands

    + +

    Commands: accept and reject

    +
    +

    Usage

    +
    +accept [ [ if | unless ] expr expr ...]
    +reject [ [ if | unless ] expr expr ...]
    +
    +

    Summary

    +Without arguments, accept and reject are the +same as return 1 and return +0, respectively. +

    +With arguments it's a little more obscure. +

    +accept if {$h>4}
    +
    +This returns 1 if the expression matches. It is equivalent to: +
    +if {$h>4} { return 1 }
    +
    +The code: +
    +accept if {$h>4} {$s>4}
    +
    +Is logically equivalent to: +
    +if {$h>4 || $s>4} { return 1}
    +
    +That is, the values are accepted if either of the expressions +evaluates as true. +

    +The unless option does the opposite: +

    +accept unless {$h>4} {$s>4}
    +
    +This is equivalent to: +
    +if {!($h>4) || !($s>4)} { return 1 }
    +
    +

    +The means we return with a true value unless one of the expressions +is true. If one of the values is true, we simply go on to the next line. +

    +

    Examples

    +Virtually all of the examples included in the release contain an +instance of "accept" or "reject." + +
    + + +
    +
    +For Programmers:

    +

    Implementation:
    +
    C code
    +
    Location:
    +
    tcl_deal.c, procedure tcl_deal_control.
    +
    +This construct is borrowed from the Perl programming language. +Originally, I added it to Deal 2.0 for performance reasons. Those +reasons are obsolote with Tcl 8.x, but I like the mnemonic enough +to keep it, and removing it might confuse old users. +

    + + +
    +For Tcl Experts:

    +There actually is one subtle and occasionally useful distinction +between accept/reject and the stated "if {...} { return ... }" +version. In reality: +

    +accept if {$h>4} {$s>4}
    +
    +is equivalent to: +
    +if {$h>4||$s>4} { 
    +    return 1
    +}
    +expr 0
    +
    +This only matters when the command is the last +command in a procedure. The two procedures: +
    +proc A {h s} {
    +    if {$h>4||$s>4} {
    +        return 1
    +    }	
    +}
    +
    +proc B {h s} {
    +     accept if {$h>4} {$s>4}
    +}
    +
    +are slightly different. +A call of A 3 3 returns an empty string, while a call +of B 3 3 returns 0. That can be useful, as you can see +here.
    +
    + +
    + +

    Command: main

    + +
    +

    Usage

    +
    +main {
    +   block of code
    +}
    +
    + +

    Summary

    +This defines the primary block of code evaluated after each +deal is generated. If the code returns true, +Deal will treat the deal as a "match" and call +write_deal. It will also increment its count of deals +found and exit if the limit is reached. +
    + + +
    For Programmers

    +

    Implementation:
    C code
    +
    Location:
    tcl_deal.c, procedure tcl_deal_control. +
    +
    +
    +
    + + +

    Command: whogets

    + +
    +

    Usage

    +
    +whogets cardname
    +
    +This returns the name of the person holding the card cardname. +
    + + + +
    For Programmers

    +

    Implementation:
    C code
    +
    Location:
    tcl_deal.c, procedure tcl_deal_to_whom. +
    +
    +
    + + +

    Command: deal_finished

    + +
    +

    Usage

    +
    +deal_finished {
    +   block of code
    +}
    +
    +This defines the code called at the completion of generating all deals. +This is code you would use to dump statistics, for example. +
    + + +
    For Programmers

    +

    Implementation:
    C code
    +
    Location:
    tcl_deal.c, procedure tcl_after_set. +
    +
    + + +
    +

    Bridge Evaluators

    +

    Common interfaces

    +There are some standard interfaces to bridge evaluation functions. + + +

    Hand Procedures

    +Any procedure defined entirely based on the values in one hand is considered +a hand procedure. These procedures can be called in one of two +ways: +
    +Weak2Bid handname
    +
    +Weak2Bid hand {AKQxxx xxx xxx x}
    +
    +The handname parameter can be one of +north, south, east, west. +Shape procedures and holding +procedures fit the hand procedure calling method, along with other +options. +
    + +

    Shape procedures

    +Any procedure defined on the shape of a hand can be called with one of +the following methods: +
    +balanced handname
    +
    +balanced hand {AJ43 AKxx xxx K5}
    +
    +balanced eval 4 3 4 2
    +
    +balanced shape {4 3 4 2}
    +
    +This follows the hand procedure outline with the +addition of the eval option. +

    +


    + +

    Holding procedures

    +A holding procedure is a hand procedure +which is evaluated on a bridge hand by evaluating each suit holding +one at a time, and then accumulate the results. There are two +common ways of defining holding procedures, +defvector and +holdingProc. +

    This is an +abstraction of a very common bridge evaluation technique. The most +commonly used holding functions are high card points, +losing trick count, controls. For example, when +counting the losers in the hand AKxx Axx KQJxxx x, we +find 1 loser in spades, 2 losers in hearts, 1 loser in diamonds, +and one loser in clubs. We define the total losers to be the sum +across all suits, and get 5 losers, total.

    The interface lets +you evaluate the entire hand, or only selected suits in a hand, or +a specific list of holdings. + +

    +hcp handname [ suitname ...  ]
    +
    +hcp hand {AKJxxx K xxx xxx} [ suitname ...  ]
    +
    +hcp holding AK43 [ ... ]
    +
    +In the first two cases, if no suits are named, all suits are evaluated, and +the results are accumulated. In the case of the holding call, +the specific holdings passed in are evaluated. +

    +Note, I've been saying "accumulated" rather than added. In some cases, +you might have an accumulation method different from addition. For example, +you might return the standard opening leads from a holding: +

    +    openingLead holding KQJ7    =>   K
    +    openingLead south           => {K} {7 2} {4} {J}
    +
    +Each suit would create a list of proposed leads, and the result would be +a list of lists of all standard leads from all holdings. Here, the +accumulation is to simply make a list. +
    + + + +

    Command: balanced and semibalanced

    + +
    +

    Usage

    +
    +balanced handname
    +
    +balanced hand {text hand}
    +
    +balanced eval s h d c
    +
    +

    Summary

    +These are both shape procedures. +

    +balanced returns true if the hand is some 4333, 4432, or 5332 +without a 5-card major. +

    +semibalanced returns true if the hand has no singletons + or voids, not six-card majors, and no seven-card minors. +

    + +
    For Programmers

    +

    Implementation:
    +
    Tcl with shapecond +
    Location:
    +
    deal.tcl +
    +These use to be hard-coded in the C code, but it made more sense +to add them to the library code - the user can change the definitions +as he likes. +
    +
    +
    +
    + + + + + +

    Commands: clubs, diamonds, hearts, spades

    + +
    +

    Usage

    +
    +     spades handname
    +     spades hand {AKxx Axx AJxx Kx}
    +
    +These implement the hand procedure interface, and +return the suit lengths for the appropriate suit. +
    + +
    For Programmers

    +

    Implementation:
    +
    +
    Location:
    +
    tcl_deal.c, function tcl_suit_count +
    +These could be shape procedures but for speed reasons, I've +left them this way. +
    +
    +
    +
    + +

    Holding Evaluators

    + +

    Command: hcp

    + +
    +

    Usage

    +
    +hcp handname
    +hcp handname suitname [suitname ...]
    +hcp hand {s h d c}
    +hcp hand {s h d c} suitname [suitname ...]
    +
    +This procedure computes standard high card points - ace is 4, king +is 3, queen is 2, jack is 1. The procedure implements the +holding procedure interface. +
    + +
    For Programmers

    +

    +
    Implementation: +
    C code +
    Location: +
    Built with additive.c, tcl_create_additive + and deal.c, count_hcp +
    +
    +
    +
    +
    + +

    Command: losers

    + +
    +

    Usage

    +
    +losers handname
    +losers handname suitname [suitname ...]
    +losers hand {s h d c}
    +losers hand {s h d c} suitname [suitname ...]
    +
    +This implements a holding procedure which +computes the number of half losers. This is for historical reasons - +the only holding functions allowed in past releases returned integer +values, but I wanted to have some refinements over raw losing trick count. +
    + +
    For Programmers

    +

    Implementation:
    +
    C code +
    Location:
    +
    Built with additive.c, tcl_create_additive + and deal.c, count_hcp +
    +It is probably better to reimplement in Tcl using +holdingProc. +
    +
    +
    +
    + +

    Bridge Logic and Utilities

    + + + +

    Commands: lho, partner, rho

    + +
    +

    Usage

    +
    +lho handname
    +rho handname
    +partner handname
    +
    +

    Summary

    +These routines accept one hand name and return another. For example, +"lho north" returns "east," and +"partner east" +returns "west." +
    + +
    For Programmers

    +

    Implementation:
    +
    C code +
    Location:
    +
    tcl_deal.c, function tcl_other_hand +
    +
    +
    +
    +
    + + +

    Commands: holding

    + +
    +

    Usage

    +
    +holding length AJxx           =>     4
    +
    +holding contains AJ64 A6      =>     1 (true)
    +holding contains AJ64 A65     =>     0 (false)
    +
    +holding encode AJ4            =>     4612  (binary: 1001000000100 )
    +
    +holding decode 4612           =>     AJ4
    +
    +holding matches AKxx  AK42    =>     1 (true)
    +
    +holding disjoint AJ65 KT82    =>     1 (true)
    +holding disjoint A65  A32     =>     0 (false)
    +
    +holding index AKJ4 0          =>     A
    +holding index AKJ4 1          =>     K
    +holding index AKJ4 3          =>     4
    +holding index AKJ4 -2         =>     J
    +holding index AKJ4 10         =>     ""
    +
    +

    Summary

    +
    + +
    For Programmers

    +

    Implementation:
    +
    C code +
    Location:
    +
    holdings.c, function IDeal_HoldingCmd +
    +
    +
    +
    +
    + + +

    Command: score

    + +
    +

    Usage

    +
    +source lib/score.tcl
    +   ...
    +score contract vulnerability tricks
    +
    +

    Summary

    +This routine computes the standard duplicate bridge score for a contract +from the point of view of declarer, if declaring side takes the given number +of tricks. +

    +The contract is passed as a list: +

    +2 spades
    +
    +2 spades undoubled 
    +
    +4 clubs doubled
    +
    +6 notrump redoubled
    +
    +The vulnerablity is one of the words vul or +nonvul. +

    +The tricks is the number of tricks taken by declarer. +

    Examples

    +
    +
    +score {2 spades} nonvul 8           =>  110
    +score {2 spades doubled} nonvul 8   =>  470
    +score {2 spades redoubled} nonvul 8 =>  640
    +score {2 spades doubled} vul 8      =>  670
    +score {2 spades} nonvul 7           =>  -50
    +score {2 spades doubled} nonvul 7   =>  -100
    +score {2 spades doubled} vul 7      =>  -200
    +
    +
    + +
    + +
    For Programmers

    +

    Implementation:
    +
    Tcl +
    Location:
    +
    score.tcl +
    +
    +
    +
    +
    +

    + +

    GIB-related routines

    +These next routines use calls to the GIB double-dummy engine. You must have +a licensed version of GIB +installed on your computer for these routines to work. Also, these +routines only work on Windows at the moment. +

    + +

    Command: gib::directory

    + +
    +

    Usage

    +
    +source lib/gib.tcl
    +   ...
    +gib::directory path
    +
    +

    Summary

    +This tells the GIB-related routines where GIB is installed. +

    +If this routine is not called, it defaults to GIB's default install +directory, C:/Program Files/GIB. +

    +Note: your path should include forward slashes '/', +even on Windows. +

    + +
    For Programmers

    +

    Implementation:
    +
    Tcl
    +
    Location:
    +
    gib.tcl +
    +
    +
    +
    +
    + + +

    Command: gib::tricks

    + +
    +

    Usage

    +
    +source lib/gib.tcl
    +   ...
    +gib::tricks declarer denomination
    +
    +

    Summary

    +Denomination can be a suit name or "notrump." +Declarer can be any hand name. +

    +This routine returns the double-dummy number of tricks available +in this deal, in the given denomination by the given declarer. +

    +If GIB is installed anywhere unusual, you will need to call +gib::directory before +gib::tricks is called. +

    + +
    For Programmers

    +

    Implementation:
    +
    Tcl
    +
    Location:
    +
    gib.tcl +
    +
    +
    +
    +
    + + +

    Command: parscore

    + +
    +

    Usage

    +
    +source lib/parscore.tcl
    +   ...
    +set result [parscore dealer vul]
    +
    +set contract [lindex $result 0]
    +set declarer [lindex $result 1]
    +set score [lindex $result 2]
    +set tricks [lindex $result 3]
    +set auction [lindex $result 4]
    +
    +

    Summary

    +This computes the double-dummy par result for the hand. +

    +The parscore routine returns a list of five values - the contract (in +the same form that is used by the score +routine above), the declarer, the score for north/south, the number of +tricks taken, and a "stupid" auction to the contract suitable for putting +into a PBN file. +

    +Dealer is relevant on a few occasions. If both south and west can make +1NT, for example, and no 2-level contracts make, then "par" is 1NT by +whomever gets a chance to bid it first. +

    +If GIB is installed anywhere unusual, you will need to call +gib::directory before +gib::tricks is called. +

    + +
    For Programmers

    +

    Implementation:
    +
    Tcl +
    Location:
    +
    parscore.tcl +
    +
    +
    +
    +
    + + +

    Bridge Command Builders

    + +A number of common types of bridge functions can easily be implemented to +run quickly via lookup tables, including +holding and shape procedures. +Deal lets the user take advantage of these two sorts of lookup procedures +relatively easily. + + +

    Command: defvector

    + +
    +

    Usage

    +
    +defvector vec aceVal [ kingVal ... ]
    +
    +vec handname
    +
    +vec hand {text hand}
    +
    +vec handname suitname [ suitname ... ]
    +
    +vec handname suitname [ suitname ... ]
    +
    +vec hand {text hand} suitname ...
    +
    +

    Summary

    +This defines a holding procedure which assigns +integer values to the various cards in the hand. For example +
    +defvector hcp6421 6 4 2 1
    +
    +Defines a holding procedure which counts the ace as worth 6 points, the +king as worth 4, the queen as 2, and the jack as 1. +

    +Vectors are limited to being integer-valued. For more complicated +holding procedures, use holdingProc. + +

    + + +
    For Programmers

    +Implementation: C
    +Location: vector.c +Vectors are slighly faster than their equivalent +holdingProc. They are an +old optimization which remain mostly for backwards compatibility. +
    +

    +
    +
    + + +

    Command: holdingProc

    + +
    +

    Usage

    +
    +
    +

    +Temporarily, see the seperate documentation. +

    + +
    For Programmers
    +Implementation: C
    +Location: holdings.c, function IDeal_DefHoldingProc +
    +
    +
    +
    + + + + +

    Commands: shapeclass, shapecond, and shapefunc

    + +
    +

    Usage

    +
    +shapeclass name {... code ...}
    +
    +shapecond name {expr}
    +
    +shapefunc name {... code ...}
    +
    +name [ north | south | east | west ]
    +
    +name eval s h d c
    +
    +name shape {s h d c}
    +
    +
    +A shape class (or equivalently, a shape condition) also has the list +subcommand: +
    +name list
    +
    +

    Summary

    +These commands create new procedures which fit the shape +function interface. +

    +shapeclass and shapecond define procedures which returns boolean +values. shapefunc can return any type of data. +shapecond is actually an alias: +

    +shapecond name {expr}
    +
    +is the equivalent of: +
    +shapeclass name {
    +  if {expr} {
    +    return 1
    +  } else {
    +    return 0
    +}
    +
    +The code or expr is allowed to use the variables +s, h, d, or c. +

    +More details can be found in the +Advanced Guide. +

    +The list subcommand for shape classes returns a list of +shapes that are in the class. +

    +Why are there two subcommands, "eval" and "shape" which do the +roughly the same things? +

    +Let's say you have a class named "SemiBalanced" already defined, +which includes 5-card majors. You want to define a "Balanced" +class which excludes the 5-card majors. You can do this with +the call: +

    +shapecond Balanced {[SemiBalanced eval $s $h $d $c] && $s<5 && $h<5}
    +
    + +On the other hand, if you have a shape - output by the, say, a +call to [north shape] you can evaluate it as: + +
    +    SemiBalanced shape [north shape]
    +
    + +In fact, this is exactly equivalent to calling + +
    +    SemiBalanced north
    +
    + +only slightly slower. + +
    + + +
    For Programmers
    +Implementation: C
    +Location: dist.c, functions tcl_shapeclass_define, +tcl_shapecond_define, and tcl_shapefunc_define +
    +
    +
    + + +

    Statistics

    + +

    Command: sdev

    + +
    +

    Usage

    +
    +sdev name
    +
    +name add data [ data ... ]
    +
    +name count
    +
    +name average
    +
    +name sdev
    +
    +name rms
    +
    +

    Summary

    + +The "sdev" command defines a new Tcl procedure with the given name, which behaves as a +data collection object. You can add data points to it, or you can retrieve +the current number of data points, the average of the data points, the +standard deviation of the data points, or the "root mean square" of the +data points. +

    + +

    + +
    For Programmers
    +
    Implementation:
    C code
    +
    Location:
    stat.c, function tcl_sdev_define. +
    +This was implemented in C for efficiency reasons - most real number +computations really need to be done in C if they are going to be done +frequently, and here, the "add" command is called quite often in normal +usage. +
    +
    +
    + +

    Command: correlation

    + +
    +

    Usage

    +
    +     correlation name
    +
    +     name add xval yval [ xval yval ... ]
    +
    +     name count
    +
    +     name correlate
    +
    +     name average [ x | y ]
    +
    +     name sdev [ x | y ]
    +
    +     name rms [ x | y ]
    +
    +

    Summary

    +The correlation declaration defines a routine much like +the sdev command, but each datapoint is a pair of values, +and it computes the linear correlation between the x and y +values. +

    +You can also get individual data for the x and y +values. +

    +If there is no data, it returns an error on average, +correlate, sdev and rms. +

    +If there is only one pair entered, it will throw an error on +sdev. +

    +

    + +
    For Programmers
    +
    Implementation:
    C code
    +
    Location:
    stat.c, function tcl_correlation_define. +
    +This was implemented in C for efficiency reasons - most real number +computations really need to be done in C if they are going to be done +frequently, and here, the "add" command is called quite often in normal +usage. +
    +
    + +

    Utility Procedures

    + + + +

    Command: deal_deck

    + +
    +

    Usage

    +
    +deal_deck
    +
    +

    Summary

    +deal_deck is called at every new deal, +even when all 52 cards are specified (stacked) precisely. +Imagine stacking cards as stacking them in an undealt deck, +but that the cards are only distributed to the hands when +deal_deck is called. +

    +Most of the time, you won't need to call deal_deck directly, but it is +useful to understand its behavior if you are going to write advanced +procedures like input formats. +

    +Stacked cards are permanently stacked until the deck is reset. In this code: +

    +    stack_hand south {AKQ32 AJ53 K54 2}
    +    deal_deck
    +    deal_deck
    +    puts [south spades]
    +
    +The output is "AKQ32". Use reset_deck +to undo card stackings. +

    +The deal_deck procedure does one thing rather complicated +when it is called, the first thing it does is execute all +code registered with the +deal_reset_cmds. +This allows the script writer to do one of several things before +the deal is generated: +

      +
    • Delete metadata related to the deal. For example, the first time +the user calls gib::tricks south spades it calls the +GIB double-dummy processor. Each time after that, it uses a stored +value for this function call up until the next call to +deal_deck. +
    • The reset command might, instead, read the next deal from a file, +stack the deck, and then re-register itself. Then when deal_deck is +is called, it just deals that hand from the file. This is a crude +way of allowing Deal to transparently read deals from a file (or generate +deals in other ways, such as smart stacking. +
    + +
  • + +
  • + +
    For Programmers

    +

    Implementation:
    +
    C +
    Location:
    +
    tcl_deal.c, function tcl_deal_deck +
    +
    +
    +
    +
    + + +

    Command: reset_deck

    + +
    +

    Usage

    +
    +reset_deck
    +
    +

    Summary

    +This forgets about all stacked cards. The deck, from Deal's +point of view, plus a list of cards which must go to specific hands. +The cards which are assigned to specific hands are "stacked." The cards +which are not stacked can go anywhere at the next call to +deal_deck. +
    + +
    For Programmers

    +

    Implementation:
    +
    C +
    Location:
    +
    tcl_deal.c, function tcl_reset_deck +
    +
    +
    +
    +
    + + + +

    Commands: stack_hand and stack_cards

    + +
    +

    Usage

    +
    +stack_hand handname hand
    +stack_cards handname suitname holding [...]
    +
    +

    Summary

    +By default, these two routines just call +deck_stack_hand and deck_stack_cards, +respectively - that is, they forcibly place cards in the deck. +

    +But these routines are meant to be overridden. For example, when using +one of the input formats which reads deals from a file, +the format will redefine these two procedures to give errors. +

    +% deal -I "line foo.txt" -e "stack_cards south spades AJ"
    +Tcl stack dump of error info:
    +No card stacking with input format ::line
    +...
    +
    +A more complicated re-definition occurs in the +smartstack input format, which alters its hand +generation depending on what cards are stacked where. + +
    + +
    For Programmers

    +

    +
    Location:
    +
    hand.c, function tcl_stack_hand and +tcl_stack_cards +
    +
    +
    +
    +
    + + + +

    Commands: deck_stack_hand and deck_stack_cards

    + +
    +

    Usage

    +
    +deck_stack_hand handname hand
    +deck_stack_cards handname suitname holding [...]
    +
    +

    Summary

    +These routines are the "underlying" deck-stacking routines. Any cards +stacked with these routines remain stacked until the next call to +reset_deck +
    + +
    For Programmers

    +

    +
    Location:
    +
    hand.c, function tcl_stack_hand and +tcl_stack_cards +
    +
    +
    +
    +
    + + +

    Command: stacked

    + +
    +

    Usage

    +
    +stacked handname
    +
    +

    Summary

    +Determines what cards are stacked to this hand, returning them as +a list of holdings: +
    +south gets AS KH 3H QD JD TC 9C 8C
    +puts [stacked south]
    +
    +writes out the list: +
    +A K3 QJ T98
    +
    +This is useful for the smartstacker, because +we don't want to force the user to stack cards *after* specifying conditions. +
    +stack_hand north {AJT KT3 KJ 75432}
    +deal::input smartstack south balanced hcp 20 21
    +
    +The call to stack_hand occurs before smartstack +is loaded, so stack_hand has not been redefined. So what +smartstack does is read the cards already stacked, and +use that for its initial conditions. +

    +

    + +
    For Programmers

    +

    Implementation:
    +
    +
    Location:
    +
    tcl_deal.c, function tcl_stacked_cards +
    +
    +
    +
    +
    + + +

    Command: deal::nostacking

    + +
    +

    Usage

    +
    +::deal::nostacking
    +
    +

    Summary

    +This procedure redefines the stack_hand and +stack_cards procedures to generate error messages, and +generates an error if any cards are currently stacked. +

    +This is used in all of the input formats which read complete deals from +files, and thus are incompatible with stacking. +

    + +
    For Programmers

    +

    Implementation:
    +
    +
    Location:
    +
    deal.tcl, function deal::nostacking +
    +
    +
    +
    +
    + + + +

    Command: deal_reset_cmds

    + +
    +

    Usage

    +
    +deal_reset_cmds {...code...} [ ... ]
    +
    +

    Summary

    +This adds a set of commands that are to be called before the next +deal. The code is executed at the next call to the +deal_deck procedure, which, unless +you are doing something complicated, means it is called at the beginning +of each time through the evaluation loop. +

    +deal_reset_cmds can be used so that metadata about the previous deal, +such as cached values and the like, are unset. See +deal::metadata. +

    +It is also used for defining input formats, +so that deals can be read from files. For example, the "line" input format +has the following routine declared: +

    +namespace eval line {
    +    #....
    +    proc next {} {
    +	variable handle
    +	set length -1
    +	catch { set length [gets $handle line] }
    +
    +        # ... process the line, or handle oef stuff ...
    +        # ...
    +	deal_reset_cmds {::line::next}
    +    }
    +}
    +
    +

    +The key is that when line::next is done, it re-registers itself, making +sure that it is called next time through as well. +

    +The code passed in to deal_reset_cmds is +called only once, at the next request for a deal - think of it as +registering a one-time trigger. Multiple triggers can be registered - +they are called in the reverse order that they are added, which can seem +counter-intuitive until you think of the process as an "undo" process. +

    + +
    For Programmers

    +

    Implementation:
    +
    +
    Location:
    +
    tcl_deal.c, function add_reset_cmds +
    +This callback idea is fairly powerful, and will probably be clarified +and elaborated in later releases. Unfortunately, initial efforts to use +it to alter the deal source (by say reading deals from a file) have +been mixed - Windows/DOS seems to choke occasionally on it. +
    +
    +
    +
    + + +

    Command: deal::metadata

    + +
    +

    Usage

    +
    +deal::metadata name {...code...}
    +
    +

    Summary

    +Currently, this is just a peculiar way of caching slow evaluation routines. +At the moment, the only place it is used is in +gib::tricks. +

    +When you call deal::metadata, it will check to see if +there is a value associated with the name requested +already. If there is, the value is returned. If it does not, it evaluates the +specified code and associates the result with the name. The key +is, when the next deal is being analyzed, all the cached values are pitched. +

    +This isn't really necessary or efficient in most cases, but with +evaluations which take some time, e.g. GIB calls, it +improves things. +

    + +
    For Programmers

    +

    Implementation:
    +
    Tcl +
    Location:
    +
    deal.tcl +
    +In later releases, metadata read from input streams (say, the fields +from a PBN file) will also be stored here. +

    +This procedure uses +deal_reset_cmds. +The metadata is cleared each time the deal_deck +command is called. + +

    +
    +
    +

    Input formats

    + +

    Command: deal::input

    + + +
    +

    Usage

    +
    +deal::input formatName args
    +
    +

    Summary

    +The deal::input command is used to define an input source +for deals. It works as follows: +
      +
    1. The file input/<formatName>.tcl is loaded. This +Tcl file should define a new Tcl 'namespace' with the name formatName, +with member procedures named set_input and next. +
    2. Deal then calls +<formatName>::set_input args, which should +initialize the format reading. Usually, the argument(s) are one argument +representing the source file. +
    3. The next deal, <formatName>::next is called. +
    + +
    + + +
    +
    +For Programmers:

    +

    Implementation:
    +
    Tcl code
    +
    Location:
    +
    deal.tcl
    +
    +
    +
    + +

    Input Format: giblib

    + +
    +

    Usage

    +
    +deal::input giblib [filename]
    +
    +or on the command line: +
    +% deal -I giblib
    +
    +or +
    +% deal -I "giblib filename"
    +
    +

    Summary

    +Specifies that deals are read from the specified file in the format +of Matt Ginsberg's library.dat file. This includes double-dummy tricks +data, so that later calls to gib::tricks +will not entail calls to the GIB binaries. +

    +If no filename is given, the library tries to read from a file called +"library.dat" in the current directory. +

    +The -I command-line flag is a quick alias for +deal::input, passing the next argument as +Tcl arguments to the deal::input command. +

    + +
    +
    +For Programmers:

    +

    Implementation:
    +
    Tcl code
    +
    Location:
    +
    input/giblib.tcl
    +This procedure uses deal_reset_cmds. +
    +
    +
    +
    + +

    Input Format: line

    + +
    +

    Usage

    +
    +deal::input line [filename]
    +
    +

    Summary

    +Specifies that deals are read from the specified file in the format +written by Deal's "-l" option. +

    +If no filename is given, the library reads from standard +input. This way, you can create a single data file and then +run several different queries against it: +

    +% deal -l 100000 > sample
    +% deal -e "deal::input line sample" -i query1 
    +% deal -e "deal::input line sample" -i query2
    +
    +[ The -e option just evaluates the code in the next +argument as Tcl code. Alternative, you can use the -I +option, which is shorthand for input formats: +
    +% deal -I "line sample" -i query1 
    +
    +The -I args option is exactly the same as -e "deal::input args" + +
    + +
    +
    +For Programmers:

    +

    Implementation:
    +
    Tcl code
    +
    Location:
    +
    input/line.tcl
    +
    +
    +
    + +

    Input: smartstack

    + +
    +

    Usage

    +
    +deal::input smartstack hand shapeclass [holdproc min max]
    +
    +or on the command line: +
    +% deal -I "smartstack shapeclass ..."
    +
    +

    Summary

    +This is the most complicated Deal input method in the current release. +It does not read deals from a file - it is, instead, a different path to +generation of deals. The purpose of this format is to allow fast generations +of deals where one hand fits a very specific description. For example, +if you want to find hands where south has a balanced 27-count, you +could write: +
    +deal::input smartstack south balanced hcp 27 27
    +
    +On my computer, that returns the first deal in 14 seconds, and every deal after +that takes a tiny fraction of a second. That's because smartstack +first builds a large "factory" in memory, but once it is built, the +factory spits out hands matching this condition very quickly. +

    +By contrast, a standard "deal" script to find balanced 27-counts +takes about 2.8 seconds to find each deal. That means that if you only +want to find about five deals of this sort, the old style program +is faster, but if you want a lot more, use smartstack. +For example, if you wanted 1000 examples, smartstack +takes about 15 seconds, while the old deal will take about 45 minutes. +

    +One interesting feature of smartstack is that it is often +faster if the hand type is less frequent. For example, it takes about 6 +seconds to find ten deals with 9-card spade suits, and about 5 seconds to +find ten deals with 10-card spade suits. Similarly, it is faster at +finding hands with exactly 9 controls than it is at finding hands +with 9-12 controls. +

    +The smartstack routine only works on one hand - after it +places cards in that hand, it generates the rest using the usual +algorithm. +

    + +
    +
    +For Programmers:

    +

    Implementation:
    +
    Tcl code
    +
    Location:
    +
    input/smartstack.tcl, lib/handFactory.tcl
    +
    Notes
    +
    See the two articles from the bridge developers mailing list +describing the algorithm: +My first stab at describing it and +some corrections. + +
    +
    +
    +
    +

    Formatting

    + +

    Command: write_deal

    + +
    +

    Usage

    +
    +write_deal
    +
    +

    Summary

    +This is the the name of a procedure which is called when deals are accepted. +By default, it writes the result in the format: +
    +          S: 98632
    +          H: A4
    +          D: AJ754
    +          C: J
    + S: K              S: AJT7
    + H: J3             H: QT95
    + D: T98            D: Q2
    + C: AKT7532        C: 984
    +          S: Q54
    +          H: K8762
    +          D: K63
    +          C: Q6
    +--------------------------
    +
    +New output formats are defined by redefining this routine. +
    + +
    For Programmers

    +

    Implementation:
    +
    Tcl +
    Location:
    +
    format/default +
    +
    +
    +
    +
    + +

    Command: flush_deal

    + +
    +

    Usage

    +
    +flush_deal
    +
    +

    Summary

    +This routine is called at the very end of a run for deal. It does nothing, +by default, but some output formats may require it if data is cached. +
    + +
    For Programmers

    +

    Implementation:
    +
    +
    Location:
    +
    YYYYY, function ZZZZ +
    +
    +
    +
    +
    + + + +

    Output Formats

    +There are a number of built-in output formats which can be used by +Deal. All of these formats come in the formats/ directory. +

    Format: default

    +This is the formatter that is used by default. + +

    Format: none

    +This formatter writes nothing. Useful when all you want is +statistics. + +

    Format: ddline

    +

    If your input routine contains complete double-dummy tricks data, or +if you have GIB installed on your machine, this writes out a deal and +double-dummy data in a single line, like: +

    +
    +952.T7.K9.AKT874|K.986.QT87643.J3|A4.5432.A52.Q965|QJT8763.AKQJ.J.2|3 5 5 10 9|9 7 8 3 4|3 5 5 10 9|9 7 8 3 4
    +
    +

    The hands are in order of NESW. The data after the hands indicates +the number of tricks each hand can take when declared by that hand, +again in order NESW again. The five numbers per hand indicates the +number of tricks that declarer can take in spades, hearts, diamonds, +clubs, and notrump, respectively.

    +

    While the basic way to generate DD data is with GIB, input formats +might also have double-dummy data. For example, once you've generated +a file with a call: +

    +deal -i format/ddline > out.dd
    +
    +you can later use that file as input: +
    +deal -I "ddline out.dd" -i format/ddline
    +
    +This uses the ddline input format to read +out.dd. + +

    Format: gibpar

    +

    Usage

    +
    +deal -i format/gibpar ....   > out.pbn
    +
    +Uses GIB's double-dummy solver to generate a PBN file to allow GIB +owners to play against theoretical par. + +

    Format: pbn

    +
    +deal -i format/pbn ....   > out.pbn
    +
    +Generates a PBN file of the deals. When loaded into GIB, this file +will let you play the generated deals in Chicago scoring. + +

    Format: practice

    +
    +deal -i format/practice > out.all
    +
    +This generates five files, out.north, out.east, out.south, out.west +and out.all. The first four files contain the individual hands for +each seat, while the out.all contains the complete deals. You then +pass out hand files to each person for bidding practice. +
    + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/commands.html /tmp/sFHmVEdqkv/deal-3.1.4/html/commands.html --- deal-3.0.8/html/commands.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/commands.html 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,1994 @@ + + +Deal Commands + +

    Introduction

    +
    +This is meant to be a comprehensive list of commands in Deal which +are not native to Tcl. If you want to learn Tcl, I will be providing +a set of pointers later. + +
    +Text in blue is meant for Tcl afficianado +- reading this text without knowledge of Tcl might confuse more than +enlighten.
    +
    +
    +
    +Text in green is meant for programmers +interested in finding code definitions. +
    +
    + + + + +

    Hand commands: north, east, south, west, hand

    + +
    +

    Usage

    +
    +east [ -void string] [ suitname ... ]
    +hand {hand string} [ -void string] [ suitname ... ]
    +
    +south subcommand [ ... args ... ]
    +hand {hand string} subcommand [ ... args ... ]
    +
    +These are very strange commands - they really have too much stuffed +into them. That's a historical anomoly which I'm reluctant to abandon. +

    +With no subcommands, the routine is used for formatting the hand as +a string. For example, if south is: +

    +S: AJ5432
    +H: KT94
    +D: void
    +C: K93
    +
    +Then the results of various commands are: +
    +south                    =>    {AJ5432 KT94 {} K93}
    +south spades             =>    AJ5432
    +south hearts clubs       =>    {KT94 K93}
    +south -void -            =>    {AJ5432 KT94 - K93}
    +south -void --- diamonds =>    ---
    +
    +set h {AK4 {} A95432 JT98}
    +hand $h                  =>    {AK4 {} A95432 JT98}
    +hand $h spades           =>    AK4
    +hand $h hearts clubs     =>    {{} JT98}
    +hand $h -void -          =>    {AK4 - A95432 JT98}
    +
    +The -void switch exists precisely for formatting the output. +

    +The various subcommands will be treated in seperate sections. + +The hand version of this command only works with some subcommands. +

    + +
    For Programmers

    +

    Implementation:
    +
    C code +
    Location:
    +
    tcl_deal.c, function tcl_hand_cmd +
    +
    +
    +

    Subcommand: shape

    +

    Usage

    +
    +north shape
    +hand {AJTxx Axx JTxx x} shape
    +
    +

    Summary

    +Returns a list of suit lengths, in standard order. +

    +For example, the second command above would return the list: +

    +5 3 4 1
    +
    +

    Subcommand: pattern

    +

    Usage

    +
    +north pattern
    +hand {AJ32 A5 JTxx xxx} pattern
    +
    +

    Summary

    +Returns a sorted list of the suit lengths, starting with the longest. +For example, the second command above would return the list: +
    +4 4 3 2
    +
    +

    Subcommand: is

    +

    Usage

    +
    +south is {handstring}
    +
    +

    Summary

    +This command pre-places a specific 13 cards. For voids, you can use +the "-" character: +
    +south is {AJ32 KT932 - Q876}
    +
    +Calls to this subcommand must occur before dealing begins, outside the +"main" command. +

    +This subcommand calls the stack_hand command. +Inside the main code, the deal is already dealt. +

    Subcommand: gets

    +

    Usage

    +
    +handname gets card [card ...]
    +
    +

    Summary

    +Puts a specific list of cards in the hand named. As with the +"is" subcommand, this must be called before dealing +starts, outside the "main" command. +The card is specified in two characters, a rank character and a suit +character: +
    +AS KH JH 9D
    +
    +This routine dispatches its data to the stack_cards command. + +

    Subcommand: has

    +

    Usage

    +
    +handname has card [card ...]
    +hand {string} has card [...]
    +
    +

    Summary

    +This returns a count of the cards listed that occur in the hand named. +
    +% south
    +AJ54 JT54 43 654
    +% south has SA HK HJ HT
    +3
    +
    +
     
    +
    +

    Control commands

    + +

    Commands: accept and reject

    +
    +

    Usage

    +
    +accept [ [ if | unless ] expr expr ...]
    +reject [ [ if | unless ] expr expr ...]
    +
    +

    Summary

    +Without arguments, accept and reject are the +same as return 1 and return +0, respectively. +

    +With arguments it's a little more obscure. +

    +accept if {$h>4}
    +
    +This returns 1 if the expression matches. It is equivalent to: +
    +if {$h>4} { return 1 }
    +
    +The code: +
    +accept if {$h>4} {$s>4}
    +
    +Is logically equivalent to: +
    +if {$h>4 || $s>4} { return 1}
    +
    +That is, the values are accepted if either of the expressions +evaluates as true. +

    +The unless option does the opposite: +

    +accept unless {$h>4} {$s>4}
    +
    +This is equivalent to: +
    +if {!($h>4) || !($s>4)} { return 1 }
    +
    +

    +The means we return with a true value unless one of the expressions +is true. If one of the values is true, we simply go on to the next line. +

    +

    Examples

    +Virtually all of the examples included in the release contain an +instance of "accept" or "reject." + +
    + + +
    +
    +For Programmers:

    +

    Implementation:
    +
    C code
    +
    Location:
    +
    tcl_deal.c, procedure tcl_deal_control.
    +
    +This construct is borrowed from the Perl programming language. +Originally, I added it to Deal 2.0 for performance reasons. Those +reasons are obsolote with Tcl 8.x, but I like the mnemonic enough +to keep it, and removing it might confuse old users. +

    + + +
    +For Tcl Experts:

    +There actually is one subtle and occasionally useful distinction +between accept/reject and the stated "if {...} { return ... }" +version. In reality: +

    +accept if {$h>4} {$s>4}
    +
    +is equivalent to: +
    +if {$h>4||$s>4} { 
    +    return 1
    +}
    +expr 0
    +
    +This only matters when the command is the last +command in a procedure. The two procedures: +
    +proc A {h s} {
    +    if {$h>4||$s>4} {
    +        return 1
    +    }	
    +}
    +
    +proc B {h s} {
    +     accept if {$h>4} {$s>4}
    +}
    +
    +are slightly different. +A call of A 3 3 returns an empty string, while a call +of B 3 3 returns 0. That can be useful, as you can see +here.
    +
    + +
    + +

    Command: main

    + +
    +

    Usage

    +
    +main {
    +   block of code
    +}
    +
    + +

    Summary

    +This defines the primary block of code evaluated after each +deal is generated. If the code returns true, +Deal will treat the deal as a "match" and call +write_deal. It will also increment its count of deals +found and exit if the limit is reached. +
    + + +
    For Programmers

    +

    Implementation:
    C code
    +
    Location:
    tcl_deal.c, procedure tcl_deal_control. +
    +
    +
    +
    + + +

    Command: whogets

    + +
    +

    Usage

    +
    +whogets cardname
    +
    +This returns the name of the person holding the card cardname. +
    + + + +
    For Programmers

    +

    Implementation:
    C code
    +
    Location:
    tcl_deal.c, procedure tcl_deal_to_whom. +
    +
    +
    + + +

    Command: deal_finished

    + +
    +

    Usage

    +
    +deal_finished {
    +   block of code
    +}
    +
    +This defines the code called at the completion of generating all deals. +This is code you would use to dump statistics, for example. +
    + + +
    For Programmers

    +

    Implementation:
    C code
    +
    Location:
    tcl_deal.c, procedure tcl_after_set. +
    +
    + + +
    +

    Bridge Evaluators

    +

    Common interfaces

    +There are some standard interfaces to bridge evaluation functions. + + +

    Hand Procedures

    +Any procedure defined entirely based on the values in one hand is considered +a hand procedure. These procedures can be called in one of two +ways: +
    +Weak2Bid handname
    +
    +Weak2Bid hand {AKQxxx xxx xxx x}
    +
    +The handname parameter can be one of +north, south, east, west. +Shape procedures and holding +procedures fit the hand procedure calling method, along with other +options. +
    + +

    Shape procedures

    +Any procedure defined on the shape of a hand can be called with one of +the following methods: +
    +balanced handname
    +
    +balanced hand {AJ43 AKxx xxx K5}
    +
    +balanced eval 4 3 4 2
    +
    +balanced shape {4 3 4 2}
    +
    +This follows the hand procedure outline with the +addition of the eval option. +

    +


    + +

    Holding procedures

    +A holding procedure is a hand procedure +which is evaluated on a bridge hand by evaluating each suit holding +one at a time, and then accumulate the results. There are two +common ways of defining holding procedures, +defvector and +holdingProc. +

    This is an +abstraction of a very common bridge evaluation technique. The most +commonly used holding functions are high card points, +losing trick count, controls. For example, when +counting the losers in the hand AKxx Axx KQJxxx x, we +find 1 loser in spades, 2 losers in hearts, 1 loser in diamonds, +and one loser in clubs. We define the total losers to be the sum +across all suits, and get 5 losers, total.

    The interface lets +you evaluate the entire hand, or only selected suits in a hand, or +a specific list of holdings. + +

    +hcp handname [ suitname ...  ]
    +
    +hcp hand {AKJxxx K xxx xxx} [ suitname ...  ]
    +
    +hcp holding AK43 [ ... ]
    +
    +In the first two cases, if no suits are named, all suits are evaluated, and +the results are accumulated. In the case of the holding call, +the specific holdings passed in are evaluated. +

    +Note, I've been saying "accumulated" rather than added. In some cases, +you might have an accumulation method different from addition. For example, +you might return the standard opening leads from a holding: +

    +    openingLead holding KQJ7    =>   K
    +    openingLead south           => {K} {7 2} {4} {J}
    +
    +Each suit would create a list of proposed leads, and the result would be +a list of lists of all standard leads from all holdings. Here, the +accumulation is to simply make a list. +
    + + + +

    Command: balanced and semibalanced

    + +
    +

    Usage

    +
    +balanced handname
    +
    +balanced hand {text hand}
    +
    +balanced eval s h d c
    +
    +

    Summary

    +These are both shape procedures. +

    +balanced returns true if the hand is some 4333, 4432, or 5332 +without a 5-card major. +

    +semibalanced returns true if the hand has no singletons + or voids, not six-card majors, and no seven-card minors. +

    + +
    For Programmers

    +

    Implementation:
    +
    Tcl with shapecond +
    Location:
    +
    deal.tcl +
    +These use to be hard-coded in the C code, but it made more sense +to add them to the library code - the user can change the definitions +as he likes. +
    +
    +
    +
    + + + + + +

    Commands: clubs, diamonds, hearts, spades

    + +
    +

    Usage

    +
    +     spades handname
    +     spades hand {AKxx Axx AJxx Kx}
    +
    +These implement the hand procedure interface, and +return the suit lengths for the appropriate suit. +
    + +
    For Programmers

    +

    Implementation:
    +
    +
    Location:
    +
    tcl_deal.c, function tcl_suit_count +
    +These could be shape procedures but for speed reasons, I've +left them this way. +
    +
    +
    + +
    + +

    Holding Evaluators

    + +

    Command: hcp

    + +
    +

    Usage

    +
    +hcp handname
    +hcp handname suitname [suitname ...]
    +hcp hand {s h d c}
    +hcp hand {s h d c} suitname [suitname ...]
    +
    +This procedure computes standard high card points - ace is 4, king +is 3, queen is 2, jack is 1. The procedure implements the +holding procedure interface. +
    + +
    For Programmers

    +

    +
    Implementation: +
    C code +
    Location: +
    Built with additive.c, tcl_create_additive + and deal.c, count_hcp +
    +
    +
    +
    + +
    + +

    Command: losers

    + +
    +

    Usage

    +
    +losers handname
    +losers handname suitname [suitname ...]
    +losers hand {s h d c}
    +losers hand {s h d c} suitname [suitname ...]
    +
    +This implements a holding procedure which +computes the number of half losers. This is for historical reasons - +the only holding functions allowed in past releases returned integer +values, but I wanted to have some refinements over raw losing trick count. +
    + +
    For Programmers

    +

    Implementation:
    +
    C code +
    Location:
    +
    Built with additive.c, tcl_create_additive + and deal.c, count_hcp +
    +It is probably better to reimplement in Tcl using +holdingProc. +
    +
    +
    + +
    + +

    Bridge Logic and Utilities

    + + + +

    Commands: lho, partner, rho

    + +
    +

    Usage

    +
    +lho handname
    +rho handname
    +partner handname
    +
    +

    Summary

    +These routines accept one hand name and return another. For example, +"lho north" returns "east," and +"partner east" +returns "west." +
    + +
    For Programmers

    +

    Implementation:
    +
    C code +
    Location:
    +
    tcl_deal.c, function tcl_other_hand +
    +
    +
    +
    + +
    + + +

    Commands: holding

    + +
    +

    Usage

    +
    +holding length AJxx           =>     4
    +
    +holding contains AJ64 A6      =>     1 (true)
    +holding contains AJ64 A65     =>     0 (false)
    +
    +holding encode AJ4            =>     4612  (binary: 1001000000100 )
    +
    +holding decode 4612           =>     AJ4
    +
    +holding matches AKxx  AK42    =>     1 (true)
    +
    +holding disjoint AJ65 KT82    =>     1 (true)
    +holding disjoint A65  A32     =>     0 (false)
    +
    +holding index AKJ4 0          =>     A
    +holding index AKJ4 1          =>     K
    +holding index AKJ4 3          =>     4
    +holding index AKJ4 -2         =>     J
    +holding index AKJ4 10         =>     ""
    +
    +

    Summary

    +
    + +
    For Programmers

    +

    Implementation:
    +
    C code +
    Location:
    +
    holdings.c, function IDeal_HoldingCmd +
    +
    +
    +
    + +
    + + +

    Command: score

    + +
    +

    Usage

    +
    +source lib/score.tcl
    +   ...
    +score contract vulnerability tricks
    +
    +

    Summary

    +This routine computes the standard duplicate bridge score for a contract +from the point of view of declarer, if declaring side takes the given number +of tricks. +

    +The contract is passed as a list: +

    +2 spades
    +
    +2 spades undoubled 
    +
    +4 clubs doubled
    +
    +6 notrump redoubled
    +
    +The vulnerablity is one of the words vul or +nonvul. +

    +The tricks is the number of tricks taken by declarer. +

    Examples

    +
    +
    +score {2 spades} nonvul 8           =>  110
    +score {2 spades doubled} nonvul 8   =>  470
    +score {2 spades redoubled} nonvul 8 =>  640
    +score {2 spades doubled} vul 8      =>  670
    +score {2 spades} nonvul 7           =>  -50
    +score {2 spades doubled} nonvul 7   =>  -100
    +score {2 spades doubled} vul 7      =>  -200
    +
    +
    + +
    + +
    For Programmers

    +

    Implementation:
    +
    Tcl +
    Location:
    +
    score.tcl +
    +
    +
    +
    + +
    + +

    Double Dummy Solver

    +

    Starting with Deal 3.1, I've included simple access to Bo Haglund's double-dummy solver library.

    + +

    Command: deal::tricks

    + +
    +

    Usage

    +
    +deal::tricks declarer denomination
    +
    + +

    Summary

    +

    deal::tricks returns the maximum number of tricks makable by declarer in the given denomination. +

    declarer must be one of "north", "east", "south", or "west." By default, it is "south."

    +

    denomination must be a suit name or "notrump." The default value is "notrump."

    +

    By default, deal::tricks uses the tricks function, which calls Bo Haglund's double-dummy solver.

    +

    However, if you include "lib/gib.tcl", deal::tricks will call the GIB double dummy solver.

    +

    deal::tricks caches values, so multiple calls for the same deal with the same declarer and denomination will not result in multiple calls to the +double-dummy solver.

    +

    Bo Haglund's solver has a feature which makes it faster if the next double dummy solver call is in the same denomination as the previous call. That means that +if you need all double-dummy values, you would want to write your code as:

    +
    +
    +   foreach denom {clubs diamonds hearts spades notrump} {
    +     foreach hand {north east south west} {
    +       set tricks [deal::tricks $hand $denom]
    +       ...
    +     }
    +   }
    +
    + + + +
    + +
    For Programmers

    +

    Implementation:
    +
    Tcl
    +
    Location:
    +
    deal.tcl +
    +
    +
    +
    + +
    + + + + +

    Command: tricks

    + +
    +

    Usage

    +
    +tricks [ declarer [ denomination [ goal ] ] ]
    +
    + +

    Summary

    +

    Unless you are using the goal parameter, you will probably want to use the deal::tricks command, since it has the +advantage of caching values.

    +

    When no goal is passed, "tricks" returns the maximum number of tricks makable by declarer in the given denomination. +

    If a (positive) goal number of tricks is set, "tricks" returns 1 if declarer can make that many tricks, and 0 if the defense can always hold declarer to fewer tricks. +

    declarer must be one of "north", "east", "south", or "west." By default, it is "south."

    +

    denomination must be a suit name or "notrump." The default value is "notrump." +

    goal must be an integer value, either -1 for "best play" or a value from 1 to 13 equal to the goal number of tricks for declarer. Default is -1.

    + +
    + +
    For Programmers

    +

    Implementation:
    +
    C, C++
    +
    Location:
    +
    dds.cpp, tcl_dds.c +
    +
    +
    +
    + +
    + + +

    Command: dds

    + + +
    +

    Usage

    +
    +dds [-reuse | -noreuse] [-diagram diagram] [-goal goal]  [-leader leader] [ declarer [ denomination ] ]
    +
    + +

    Summary

    +

    The dds command gives even more refined access to Bo Haglund's double dummy engine, including the ability to solve problems with fewer than 52 cards. + +

    The -reuse flag tells the double-dummy solver to reuse the data it generated from the last call. For example, if the hand is identical to the previous call and played in the same denomination, you'll want to reuse the data. +

    The -noreuse flag tells the double-dummy solver not to reuse the data. This is the default. +

    The -diagram flag tells the double-dummy solver to solve a specific diagram, rather than the current deal. A diagram is of the form of a Tcl list in the order north, east, south, west. +

    The -leader flag tells the double-dummy solver who is on lead. +

    For example, to solve George Coffin's "Avoidance" end position from his Great 88, you would write: +

    +set diagram {
    +           {A987 - A} 
    +           {Q5 987 -} 
    +           {64 K2 2} 
    +           {K2 AQ3 -} 
    +}
    +set tricks [dds -leader south -diagram $diagram south notrump]
    +...
    +
    +

    There are example tests of all the Great 88 in the file tests/great88 that is included in this release. +

    + +
    For Programmers

    +

    Implementation:
    +
    C, C++
    +
    Location:
    +
    dds.cpp, tcl_dds.c +
    +
    +
    +
    + +
    + + +

    Command: parscore

    + +
    +

    Usage

    +
    +source lib/parscore.tcl
    +   ...
    +set result [parscore dealer vul]
    +
    +set contract [lindex $result 0]
    +set declarer [lindex $result 1]
    +set score [lindex $result 2]
    +set tricks [lindex $result 3]
    +set auction [lindex $result 4]
    +
    +

    Summary

    +This computes the double-dummy par result for the current deal. +

    +The parscore routine returns a list of five values - the contract (in +the same form that is used by the score +routine above), the declarer, the score for north/south, the number of +tricks taken, and a "stupid" auction to the contract suitable for putting +into a PBN file. +

    +Dealer is relevant on a few occasions. If both south and west can make +1NT, for example, and no 2-level contracts make, then "par" is 1NT by +whomever gets a chance to bid it first. +

    + +
    For Programmers

    +

    Implementation:
    +
    Tcl +
    Location:
    +
    parscore.tcl +
    +
    +
    +
    + +
    + + + + + +

    GIB-related routines

    +These next routines use calls to the GIB double-dummy engine. You must have +a licensed version of GIB +installed on your computer for these routines to work. Also, these +routines only work on Windows at the moment. +

    + +

    Command: gib::directory

    + +
    +

    Usage

    +
    +source lib/gib.tcl
    +   ...
    +gib::directory path
    +
    +

    Summary

    +This tells the GIB-related routines where GIB is installed. +

    +If this routine is not called, it defaults to GIB's default install +directory, C:/Program Files/GIB. +

    +Note: your path should include forward slashes '/', +even on Windows. +

    + +
    For Programmers

    +

    Implementation:
    +
    Tcl
    +
    Location:
    +
    gib.tcl +
    +
    +
    +
    + +
    + + +

    Command: gib::tricks

    + +
    +

    Usage

    +
    +source lib/gib.tcl
    +   ...
    +gib::tricks declarer denomination
    +
    +

    Summary

    +

    You probably want to use the deal::tricks command, even when using GIB's double dummy solver. +

    Denomination can be a suit name or "notrump." +Declarer can be any hand name. +

    +This routine returns the double-dummy number of tricks available +in this deal, in the given denomination by the given declarer. +

    +If GIB is installed anywhere unusual, you will need to call +gib::directory before +deal::tricks is called. +

    + +
    For Programmers

    +

    Implementation:
    +
    Tcl
    +
    Location:
    +
    gib.tcl +
    +
    +
    +
    + +
    + +

    Bridge Command Builders

    + +A number of common types of bridge functions can easily be implemented to +run quickly via lookup tables, including +holding and shape procedures. +Deal lets the user take advantage of these two sorts of lookup procedures +relatively easily. + + +

    Command: defvector

    + +
    +

    Usage

    +
    +defvector vec aceVal [ kingVal ... ]
    +
    +vec handname
    +
    +vec hand {text hand}
    +
    +vec handname suitname [ suitname ... ]
    +
    +vec handname suitname [ suitname ... ]
    +
    +vec hand {text hand} suitname ...
    +
    +

    Summary

    +This defines a holding procedure which assigns +integer values to the various cards in the hand. For example +
    +defvector hcp6421 6 4 2 1
    +
    +Defines a holding procedure which counts the ace as worth 6 points, the +king as worth 4, the queen as 2, and the jack as 1. +

    +Vectors are limited to being integer-valued. For more complicated +holding procedures, use holdingProc. + +

    + + +
    For Programmers

    +Implementation: C
    +Location: vector.c +Vectors are slighly faster than their equivalent +holdingProc. They are an +old optimization which remain mostly for backwards compatibility. +
    +

    +
    + +
    + + +

    Command: holdingProc

    + +
    +

    Usage

    +
    +
    +

    +Temporarily, see the seperate documentation. +

    + +
    For Programmers
    +Implementation: C
    +Location: holdings.c, function IDeal_DefHoldingProc +
    +
    +
    + +
    + + + + +

    Commands: shapeclass, shapecond, and shapefunc

    + +
    +

    Usage

    +
    +shapeclass name {... code ...}
    +
    +shapecond name {expr}
    +
    +shapefunc name {... code ...}
    +
    +name [ north | south | east | west ]
    +
    +name eval s h d c
    +
    +name shape {s h d c}
    +
    +
    +A shape class (or equivalently, a shape condition) also has the list +subcommand: +
    +name list
    +
    +

    Summary

    +These commands create new procedures which fit the shape +function interface. +

    +shapeclass and shapecond define procedures which returns boolean +values. shapefunc can return any type of data. +shapecond is actually an alias: +

    +shapecond name {expr}
    +
    +is the equivalent of: +
    +shapeclass name {
    +  if {expr} {
    +    return 1
    +  } else {
    +    return 0
    +}
    +
    +The code or expr is allowed to use the variables +s, h, d, or c. +

    +More details can be found in the +Advanced Guide. +

    +The list subcommand for shape classes returns a list of +shapes that are in the class. +

    +Why are there two subcommands, "eval" and "shape" which do the +roughly the same things? +

    +Let's say you have a class named "SemiBalanced" already defined, +which includes 5-card majors. You want to define a "Balanced" +class which excludes the 5-card majors. You can do this with +the call: +

    +shapecond Balanced {[SemiBalanced eval $s $h $d $c] && $s<5 && $h<5}
    +
    + +On the other hand, if you have a shape - output by the, say, a +call to [north shape] you can evaluate it as: + +
    +    SemiBalanced shape [north shape]
    +
    + +In fact, this is exactly equivalent to calling + +
    +    SemiBalanced north
    +
    + +only slightly slower. + +
    + + +
    For Programmers
    +Implementation: C
    +Location: dist.c, functions tcl_shapeclass_define, +tcl_shapecond_define, and tcl_shapefunc_define +
    +
    + +
    + + +

    Statistics

    + +

    Command: sdev

    + +
    +

    Usage

    +
    +sdev name
    +
    +name add data [ data ... ]
    +
    +name count
    +
    +name average
    +
    +name sdev
    +
    +name rms
    +
    +

    Summary

    + +The "sdev" command defines a new Tcl procedure with the given name, which behaves as a +data collection object. You can add data points to it, or you can retrieve +the current number of data points, the average of the data points, the +standard deviation of the data points, or the "root mean square" of the +data points. +

    + +

    + +
    For Programmers
    +
    Implementation:
    C code
    +
    Location:
    stat.c, function tcl_sdev_define. +
    +This was implemented in C for efficiency reasons - most real number +computations really need to be done in C if they are going to be done +frequently, and here, the "add" command is called quite often in normal +usage. +
    +
    +
    + +

    Command: correlation

    + +
    +

    Usage

    +
    +     correlation name
    +
    +     name add xval yval [ xval yval ... ]
    +
    +     name count
    +
    +     name correlate
    +
    +     name average [ x | y ]
    +
    +     name sdev [ x | y ]
    +
    +     name rms [ x | y ]
    +
    +

    Summary

    +The correlation declaration defines a routine much like +the sdev command, but each datapoint is a pair of values, +and it computes the linear correlation between the x and y +values. +

    +You can also get individual data for the x and y +values. +

    +If there is no data, it returns an error on average, +correlate, sdev and rms. +

    +If there is only one pair entered, it will throw an error on +sdev. +

    +

    + +
    For Programmers
    +
    Implementation:
    C code
    +
    Location:
    stat.c, function tcl_correlation_define. +
    +This was implemented in C for efficiency reasons - most real number +computations really need to be done in C if they are going to be done +frequently, and here, the "add" command is called quite often in normal +usage. +
    +
    + +

    Utility Procedures

    + + +

    Command Line: -x flag

    + + + +
    +

    Usage

    +
    +   deal -x filename
    +
    +

    The '-x' flag tells deal to source the file and then exit.

    +

    This is useful if you want to skip the entire deal loop, and process stuff on your own. For example, the code in tests/great88 does not generate any deals, it just solves 88 5-card double-dummy problems. Before the -x flag, you had to +explicitly call 'exit' from such scripts.

    +
    + + +

    Command: full_deal

    + + + +
    +

    Usage

    +
    +   set deal [full_deal]
    +
    +

    This simple utility command returns the deal as a list of hands in the order of north, east, south, and west. Suitable for psassing into dds with the -diagram flag, or remembering a deal after the end of the loop. +

    + + +

    Command: seed_deal

    + +
    +

    Usage

    +
    +seed_deal number
    +
    +

    Command Line: -s

    +
    +$ deal -s number ...
    +
    +

    Summary

    +

    seed_deal is used to seed the random number generator, to make sure that Deal generates the same sequence of +random numbers. +

    Care has to be taken if you want to make sure that you are generating the same sequence of deals. For one thing, if you have a main inner loop, you should add the command "finish_deal" to the main section. +

    +main {
    +   finish_deal
    +   ...
    +}
    +
    +

    That bypasses some optimizations and forces an entire deal to be generated each time through main. + + +

    Command: deal_deck

    + +
    +

    Usage

    +
    +deal_deck
    +
    +

    Summary

    +deal_deck is called at every new deal, +even when all 52 cards are specified (stacked) precisely. +Imagine stacking cards as stacking them in an undealt deck, +but that the cards are only distributed to the hands when +deal_deck is called. +

    +Most of the time, you won't need to call deal_deck directly, but it is +useful to understand its behavior if you are going to write advanced +procedures like input formats. +

    +Stacked cards are permanently stacked until the deck is reset. In this code: +

    +    stack_hand south {AKQ32 AJ53 K54 2}
    +    deal_deck
    +    deal_deck
    +    puts [south spades]
    +
    +The output is "AKQ32". Use reset_deck +to undo card stackings. +

    +The deal_deck procedure does one thing rather complicated +when it is called, the first thing it does is execute all +code registered with the +deal_reset_cmds. +This allows the script writer to do one of several things before +the deal is generated: +

      +
    • Delete metadata related to the deal. For example, the first time +the user calls deal::tricks south spades it calls the +double-dummy processor. Each time after that, it uses a stored +value for this function call up until the next call to +deal_deck. +
    • The reset command might, instead, read the next deal from a file, +stack the deck, and then re-register itself. Then when deal_deck is +is called, it just deals that hand from the file. This is a crude +way of allowing Deal to transparently read deals from a file (or generate +deals in other ways, such as smart stacking. +
    +
    + +
    For Programmers

    +

    Implementation:
    +
    C +
    Location:
    +
    tcl_deal.c, function tcl_deal_deck +
    +
    +
    +
    + +
    + + +

    Command: reset_deck

    + +
    +

    Usage

    +
    +reset_deck
    +
    +

    Summary

    +This forgets about all stacked cards. The deck, from Deal's +point of view, plus a list of cards which must go to specific hands. +The cards which are assigned to specific hands are "stacked." The cards +which are not stacked can go anywhere at the next call to +deal_deck. +
    + +
    For Programmers

    +

    Implementation:
    +
    C +
    Location:
    +
    tcl_deal.c, function tcl_reset_deck +
    +
    +
    +
    + +
    + + + +

    Commands: stack_hand and stack_cards

    + +
    +

    Usage

    +
    +stack_hand handname hand
    +stack_cards handname suitname holding [...]
    +
    +

    Summary

    +By default, these two routines just call +deck_stack_hand and deck_stack_cards, +respectively - that is, they forcibly place cards in the deck. +

    +But these routines are meant to be overridden. For example, when using +one of the input formats which reads deals from a file, +the format will redefine these two procedures to give errors. +

    +% deal -I "line foo.txt" -e "stack_cards south spades AJ"
    +Tcl stack dump of error info:
    +No card stacking with input format ::line
    +...
    +
    +A more complicated re-definition occurs in the +smartstack input format, which alters its hand +generation depending on what cards are stacked where. + +
    + +
    For Programmers

    +

    +
    Location:
    +
    hand.c, function tcl_stack_hand and +tcl_stack_cards +
    +
    +
    +
    + +
    + + + +

    Commands: deck_stack_hand and deck_stack_cards

    + +
    +

    Usage

    +
    +deck_stack_hand handname hand
    +deck_stack_cards handname suitname holding [...]
    +
    +

    Summary

    +These routines are the "underlying" deck-stacking routines. Any cards +stacked with these routines remain stacked until the next call to +reset_deck +
    + +
    For Programmers

    +

    +
    Location:
    +
    hand.c, function tcl_stack_hand and +tcl_stack_cards +
    +
    +
    +
    + +
    + + +

    Command: stacked

    + +
    +

    Usage

    +
    +stacked handname
    +
    +

    Summary

    +Determines what cards are stacked to this hand, returning them as +a list of holdings: +
    +south gets AS KH 3H QD JD TC 9C 8C
    +puts [stacked south]
    +
    +writes out the list: +
    +A K3 QJ T98
    +
    +This is useful for the smartstacker, because +we don't want to force the user to stack cards *after* specifying conditions. +
    +stack_hand north {AJT KT3 KJ 75432}
    +deal::input smartstack south balanced hcp 20 21
    +
    +The call to stack_hand occurs before smartstack +is loaded, so stack_hand has not been redefined. So what +smartstack does is read the cards already stacked, and +use that for its initial conditions. +

    +

    + +
    For Programmers

    +

    Implementation:
    +
    +
    Location:
    +
    tcl_deal.c, function tcl_stacked_cards +
    +
    +
    +
    + +
    + + +

    Command: deal::nostacking

    + +
    +

    Usage

    +
    +::deal::nostacking
    +
    +

    Summary

    +This procedure redefines the stack_hand and +stack_cards procedures to generate error messages, and +generates an error if any cards are currently stacked. +

    +This is used in all of the input formats which read complete deals from +files, and thus are incompatible with stacking. +

    + +
    For Programmers

    +

    Implementation:
    +
    +
    Location:
    +
    deal.tcl, function deal::nostacking +
    +
    +
    +
    + +
    + + + +

    Command: deal_reset_cmds

    + +
    +

    Usage

    +
    +deal_reset_cmds {...code...} [ ... ]
    +
    +

    Summary

    +This adds a set of commands that are to be called before the next +deal. The code is executed at the next call to the +deal_deck procedure, which, unless +you are doing something complicated, means it is called at the beginning +of each time through the evaluation loop. +

    +deal_reset_cmds can be used so that metadata about the previous deal, +such as cached values and the like, are unset. See +deal::metadata. +

    +It is also used for defining input formats, +so that deals can be read from files. For example, the "line" input format +has the following routine declared: +

    +namespace eval line {
    +    #....
    +    proc next {} {
    +	variable handle
    +	set length -1
    +	catch { set length [gets $handle line] }
    +
    +        # ... process the line, or handle oef stuff ...
    +        # ...
    +	deal_reset_cmds {::line::next}
    +    }
    +}
    +
    +

    +The key is that when line::next is done, it re-registers itself, making +sure that it is called next time through as well. +

    +The code passed in to deal_reset_cmds is +called only once, at the next request for a deal - think of it as +registering a one-time trigger. Multiple triggers can be registered - +they are called in the reverse order that they are added, which can seem +counter-intuitive until you think of the process as an "undo" process. +

    + +
    For Programmers

    +

    Implementation:
    +
    +
    Location:
    +
    tcl_deal.c, function add_reset_cmds +
    +
    +
    +
    + +
    + + +

    Command: deal::metadata

    + +
    +

    Usage

    +
    +deal::metadata name {...code...}
    +
    +

    Summary

    +Currently, this is just a peculiar way of caching slow evaluation routines. +At the moment, the only place it is used is in +deal::tricks. +

    +When you call deal::metadata, it will check to see if +there is a value associated with the name requested +already. If there is, the value is returned. If it does not, it evaluates the +specified code and associates the result with the name. The key +is, when the next deal is being analyzed, all the cached values are pitched. +

    +This isn't really necessary or efficient in most cases, but with +evaluations which take some time, e.g. GIB calls, it +improves things. +

    + +
    For Programmers

    +

    Implementation:
    +
    Tcl +
    Location:
    +
    deal.tcl +
    +In later releases, metadata read from input streams (say, the fields +from a PBN file) will also be stored here. +

    +This procedure uses +deal_reset_cmds. +The metadata is cleared each time the deal_deck +command is called. + +

    +
    + +
    +

    Input formats

    + +

    Command: deal::input

    + + +
    +

    Usage

    +
    +deal::input formatName args
    +
    +

    Summary

    +The deal::input command is used to define an input source +for deals. It works as follows: +
      +
    1. The file input/<formatName>.tcl is loaded. This +Tcl file should define a new Tcl 'namespace' with the name formatName, +with member procedures named set_input and next. +
    2. Deal then calls +<formatName>::set_input args, which should +initialize the format reading. Usually, the argument(s) are one argument +representing the source file. +
    3. The next deal, <formatName>::next is called. +
    + +
    + + +
    +
    +For Programmers:

    +

    Implementation:
    +
    Tcl code
    +
    Location:
    +
    deal.tcl
    +
    +
    +
    + +

    Input Format: giblib

    + +
    +

    Usage

    +
    +deal::input giblib [filename]
    +
    +or on the command line: +
    +% deal -I giblib
    +
    +or +
    +% deal -I "giblib filename"
    +
    +

    Summary

    +Specifies that deals are read from the specified file in the format +of Matt Ginsberg's library.dat file. This includes double-dummy tricks +data, so that later calls to deal::tricks +will not entail calls to the GIB binaries. +

    +If no filename is given, the library tries to read from a file called +"library.dat" in the current directory. +

    +The -I command-line flag is a quick alias for +deal::input, passing the next argument as +Tcl arguments to the deal::input command. +

    + +
    +
    +For Programmers:

    +

    Implementation:
    +
    Tcl code
    +
    Location:
    +
    input/giblib.tcl
    +This procedure uses deal_reset_cmds. +
    +
    +
    +
    + +

    Input Format: line

    + +
    +

    Usage

    +
    +deal::input line [filename]
    +
    +

    Summary

    +Specifies that deals are read from the specified file in the format +written by Deal's "-l" option. +

    +If no filename is given, the library reads from standard +input. This way, you can create a single data file and then +run several different queries against it: +

    +% deal -l 100000 > sample
    +% deal -e "deal::input line sample" -i query1
    +% deal -e "deal::input line sample" -i query2
    +
    +[ The -e option just evaluates the code in the next +argument as Tcl code. Alternative, you can use the -I +option, which is shorthand for input formats: +
    +% deal -I "line sample" -i query1
    +
    +The -I args option is exactly the same as -e "deal::input args" + +
    + +
    +
    +For Programmers:

    +

    Implementation:
    +
    Tcl code
    +
    Location:
    +
    input/line.tcl
    +
    +
    +
    + +

    Input Format: ddline

    + +
    +

    Usage

    +
    +deal::input line [filename]
    +
    +

    Summary

    +

    Specifies that deals are read from the specified file in the format +written by Deal's ddline format. +

    The ddline format include doubled-dummy tricks data, so when using ddline for input, calls to deal::tricks return the data read from the file. +

    + +
    +
    +For Programmers:

    +

    Implementation:
    +
    Tcl code
    +
    Location:
    +
    input/line.tcl
    +
    +
    +
    + +

    Input: smartstack

    + +
    +

    Usage

    +
    +deal::input smartstack hand shapeclass [holdproc min max]
    +
    +or on the command line: +
    +% deal -I "smartstack shapeclass ..."
    +
    +

    Summary

    +This is the most complicated Deal input method in the current release. +It does not read deals from a file - it is, instead, a different path to +generation of deals. The purpose of this format is to allow fast generations +of deals where one hand fits a very specific description. For example, +if you want to find hands where south has a balanced 27-count, you +could write: +
    +deal::input smartstack south balanced hcp 27 27
    +
    +On my computer, that returns the first deal in 14 seconds, and every deal after +that takes a tiny fraction of a second. That's because smartstack +first builds a large "factory" in memory, but once it is built, the +factory spits out hands matching this condition very quickly. +

    +By contrast, a standard "deal" script to find balanced 27-counts +takes about 2.8 seconds to find each deal. That means that if you only +want to find about five deals of this sort, the old style program +is faster, but if you want a lot more, use smartstack. +For example, if you wanted 1000 examples, smartstack +takes about 15 seconds, while the old deal will take about 45 minutes. +

    +One interesting feature of smartstack is that it is often +faster if the hand type is less frequent. For example, it takes about 6 +seconds to find ten deals with 9-card spade suits, and about 5 seconds to +find ten deals with 10-card spade suits. Similarly, it is faster at +finding hands with exactly 9 controls than it is at finding hands +with 9-12 controls. +

    +The smartstack routine only works on one hand - after it +places cards in that hand, it generates the rest using the usual +algorithm. +

    + +
    +
    +For Programmers:

    +

    Implementation:
    +
    Tcl code
    +
    Location:
    +
    input/smartstack.tcl, lib/handFactory.tcl
    +
    Notes
    +
    See the two articles from the bridge developers mailing list +describing the algorithm: +My first stab at describing it and +some corrections. + +
    +
    +
    +
    +

    Formatting

    + +

    Command: write_deal

    + +
    +

    Usage

    +
    +write_deal
    +
    +

    Summary

    +This is the the name of a procedure which is called when deals are accepted. +By default, it writes the result in the format: +
    +          S: 98632
    +          H: A4
    +          D: AJ754
    +          C: J
    + S: K              S: AJT7
    + H: J3             H: QT95
    + D: T98            D: Q2
    + C: AKT7532        C: 984
    +          S: Q54
    +          H: K8762
    +          D: K63
    +          C: Q6
    +--------------------------
    +
    +New output formats are defined by redefining this routine. +
    + +
    For Programmers

    +

    Implementation:
    +
    Tcl +
    Location:
    +
    format/default +
    +
    +
    +
    + +
    + +

    Command: flush_deal

    + +
    +

    Usage

    +
    +flush_deal
    +
    +

    Summary

    +This routine is called at the very end of a run for deal. It does nothing, +by default, but some output formats may require it if data is cached. +
    + +
    For Programmers

    +

    Implementation:
    +
    +
    Location:
    +
    YYYYY, function ZZZZ +
    +
    +
    +
    + +
    + + +

    Output Format: format/par

    + +
    +

    Usage

    +
    +source format/par
    +
    +

    Summary

    +

    By including this file, you are setting the output format to write the results in PBN format, with results set to the double dummy theoretical par. +

    +$ deal -i format/par 1
    +[Date "2008.05.19"]
    +[Board "1"]
    +[West "West"]
    +[North "North"]
    +[East "East"]
    +[South "South"]
    +[Dealer "N"]
    +[Vulnerable "None"]
    +[Deal "N:K.A7.QJT9865.AK7 T94.K98532.2.943 A872.QT4.AK4.862 QJ653.J6.73.QJT5"]
    +[Contract "6N"]
    +[Declarer "S"]
    +[Result "12"]
    +[Score "NS 990"]
    +{
    +          S: K
    +          H: A7
    +          D: QJT9865
    +          C: AK7
    + S: QJ653          S: T94
    + H: J6             H: K98532
    + D: 73             D: 2
    + C: QJT5           C: 943
    +          S: A872
    +          H: QT4
    +          D: AK4
    +          C: 862
    +north makes 9 tricks in clubs
    +north makes 12 tricks in diamonds
    +north makes 8 tricks in hearts
    +north makes 7 tricks in spades
    +north makes 12 tricks in notrump
    +east makes 3 tricks in clubs
    +east makes 1 tricks in diamonds
    +east makes 5 tricks in hearts
    +east makes 4 tricks in spades
    +east makes 1 tricks in notrump
    +south makes 8 tricks in clubs
    +south makes 12 tricks in diamonds
    +south makes 8 tricks in hearts
    +south makes 7 tricks in spades
    +south makes 12 tricks in notrump
    +west makes 3 tricks in clubs
    +west makes 1 tricks in diamonds
    +west makes 5 tricks in hearts
    +west makes 4 tricks in spades
    +west makes 1 tricks in notrump
    +}
    +[Auction "N"]
    +Pass   Pass   6N
    +[Play "W"]
    +*
    +
    +
    + +
    For Programmers

    +

    Implementation:
    +
    TclLocation: +
    format/par
    +
    +
    +
    +
    + +
    + + +

    Output Format: format/ddline

    + +
    +

    Usage

    +
    +source format/ddline
    +
    +

    Summary

    +

    By including this file, you are redefining the output format to the form "ddline", which writes out the deal on a single line, as with the '-l' flag, but then adds complete double-dummy data to the deal as well. If you write the output to a file: +

    +$ deal -i format/ddline 100 > doubledummy.txt
    +
    +

    then you can use the ddline input format to read the file back in: +

    +$ deal -I "ddline doubledummy.txt" -i query.tcl 100
    +
    +

    And any call to deal::tricks in query.tcl will use the value stored doubledummy.txt. +

    + +
    For Programmers

    +

    Implementation:
    +
    TclLocation: +
    format/ddline
    +
    +
    +
    +
    + +
    + + + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/commindex.html /tmp/sFHmVEdqkv/deal-3.1.4/html/commindex.html --- deal-3.0.8/html/commindex.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/commindex.html 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,83 @@ + + + +Index of Deal Commands + + +Back to Deal top page +

    Index

    + +
  • accept +
  • balanced +
  • clubs +
  • correlation +
  • deal::input +
  • deal::metadata +
  • deal::nostacking +
  • deal_deck +
  • deal_finished +
  • deal_reset_cmds +
  • deck_stack_cards +
  • deck_stack_hand + +
  • defvector +
  • diamonds +
  • ddline input format
  • +
  • ddline output format
  • +
  • Double Dummy Solver, Bo Haglund's +
  • dds +
  • east +
  • flush_deal +
  • full_deal +
  • gets subcommand +
  • giblib input +
  • GIB-related routines +
  • gib::directory +
  • gib::tricks +
  • hand +
  • hand procedures +
  • has subcommand +
  • hcp +
  • hearts +
  • holding procedures +
  • holding +
  • holdingProc + +
  • input files +
  • deal::tricks +
  • is subcommand +
  • lho +
  • library.dat input +
  • line input +
  • losers +
  • main +
  • north +
  • par output format
  • +
  • parscore +
  • partner +
  • pattern subcommand +
  • reject +
  • reset_deck +
  • rho +
  • seed_deal +
  • shape subcommand +
  • score +
  • sdev +
  • semibalanced +
  • shapeclass +
  • shapecond +
  • shapefunc +
  • shape procedures +
  • smartstack +
  • south +
  • spades +
  • stack_cards +
  • stack_hand +
  • stacked +
  • statistics +
  • tricks +
  • west +
  • whogets +
  • write_deal +
  • -x flag + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/commtop.html /tmp/sFHmVEdqkv/deal-3.1.4/html/commtop.html --- deal-3.0.8/html/commtop.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/commtop.html 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,17 @@ + + + + + + +Index of Deal Commands + + + + + + + + + + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/cright.html /tmp/sFHmVEdqkv/deal-3.1.4/html/cright.html --- deal-3.0.8/html/cright.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/cright.html 2008-06-11 02:20:28.000000000 +0530 @@ -0,0 +1,11 @@ +
    +
    + +
    Thomas Andrews +(deal@thomasoandrews.com) + Copyright 1996-2005. +
    +

    +Plane Dealing graphic above created using +POV-Ray. +

    diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/dds.html /tmp/sFHmVEdqkv/deal-3.1.4/html/dds.html --- deal-3.0.8/html/dds.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/dds.html 2008-06-11 02:20:28.000000000 +0530 @@ -0,0 +1,54 @@ + + + + + + + + + +Double Dummy Solver + + + + +
    +

    Double Dummy Solver

    +

    Deal now has a built-in double dummy solver, as provided by Bo Haglund. +

    The command for accessing the double dummy solver is documented here. +

    Deal currently contains the code for DDS 1.1.8. +

    While DDS is fairly fast most of the time, on some deals, it can take a long time. In particular, when there are lots +of voids, can take several minutes to analyze the board. +

    For example, in this deal: +

    +          S: ---
    +          H: QT97
    +          D: AJ432
    +          C: K865
    + S: K865           S: QT97
    + H: ---            H: AJ432
    + D: QT97           D: K865
    + C: AJ432          C: ---
    +          S: AJ432
    +          H: K865
    +          D: ---
    +          C: QT97
    +
    +

    DDS takes more than 20 minutes to analyze South declaring Notrump. +


    +
    +Silhouette +Thomas Andrews +(deal@thomasoandrews.com) +Copyright 1996-2008. Deal is covered by the +GNU General Public License. +

    +Plane Dealing graphic +above created using +POV-Ray. +

    +
    + + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/dist.html /tmp/sFHmVEdqkv/deal-3.1.4/html/dist.html --- deal-3.0.8/html/dist.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/dist.html 2008-06-11 02:20:28.000000000 +0530 @@ -0,0 +1,732 @@ + + + + + + + + + + Hand Distribution Table + + + + + + +
    +

    Hand Distribution Table

    +

    +I am including this information in my web pages because I think it is +neat and that it is a method I think other writers of hand generators +might want to use. +

    +It is also the only time I can think of when I have +used anything I learned in graduate school. + +

    Creation of the table

    +

    +My program, 'Deal', needed a fast way to determine whether a hand +was in a particular class. The goal was to stay out of the TCL interpreter +as much as possible. The answer was to implement a lookup table with an easy +indexing algorithm. +

    +There are 560 hand shapes, where by "shape", I mean the ordered listing +of suit lengths: spades-hearts-diamonds-clubs. +

    +The hand shapes are in easy 1-1 correspondence with the 3-subsets +of {0,...,15}. +In particular, the hand shape with s spades, h hearts, +d diamonds, and c clubs corresponds +to the 3-set {s, s+h+1, +s+h+d+2}. +

    +There is a linear order on n-subsets, for fixed n, called the squashed +order [see Combinatorics on Finite Sets, Anderson, pp 112-119.] +The nice thing about this order is that it is easy to find the index of +an n-set in the order. +In the case of n=3, take a subset {x,y,z}, with 0<=x<y<z<=15. +The index of this set in the squashed order is +

    (z choose 3) + (y choose 2) + (x choose 1)
    +For the hand shape s-h-d-c, then, the corresponding index in the squashed +order is +
    (s+h+d+2 choose 3) + (s+h+1 choose 2) + (s choose 1)
    +

    +For added speed, I pre-computed +(n+2 choose 3) and (n+1 choose 2) for n=0,...13, placing the values +in static arrays. The resulting C code looks like: +

    +
    +static int distTableIndex(s,h,d)
    +int s,h,d;
    +{
    +  static choose2tab[]={0, 1, 3,  6, 10, 15, 21, 28,  36,  45,  55,  66,  78,  91};
    +  static choose3tab[]={0, 1, 4, 10, 20, 35, 56, 84, 120, 165, 220, 286, 364, 455};
    +  return choose3tab[s+h+d]+choose2tab[s+h]+s;
    +}
    +
    +
    + +It is precisely because I can quickly compute this index that I have +chosen the squashed order. Perhaps other orders also happen to allow +for quick indexing, but this is the one I found in my personal math library. + +

    Usage of the table

    + +The table is useful for fast lookups. For example, lets say you were +looking for hands which were five-five or better in any two suits. You could, +of course, simply check each suit length, but the problem with this is +that in an interpreted language, like Tcl, that might be too slow. If, +however, you built a 560 element binary array, and do the computation +560 times up front, then when we start analyzing actual deals, we +can quickly determine whether a particular shape was in that class. +

    +In reality, the table is not computed until the first request +is made of a shapeclass, which allows users to create large libraries +to be included but not instantiated until used. +

    +For example: +

    +
    +shapecond Balanced {$s*$s+$h*$h+$d*$d+$c*$c<=47}
    +
    +
    +When this shapeclass is first used, a table of 560 entries is created, +and then the interpreter evaluates this expression only 560 times. +For rare hand classes, this is a significant improvement. +

    +When Deal is confronted with a specific query about membership +in this class, all it has to do is use distTableIndex find the +index, then look it up in the table. This is significantly +faster than reinterpreting the Tcl code every time. +

    +The concept of "shape class" led to the concept of "shape function". +These are functions which use the shape of the hand to determine the +value. For instance, I have a function which determines the opening +suit for a hand: +

    +
    +shapefunc opensuit {
    +
    +	if {$s>=5 && $s>=$h && $s>=$d && $s>=$c} {return spades}
    +
    +	if {$h>=5 && $h>=$d && $h>=$c} { return hearts }
    +
    +	if {$d>=4 && $d>=$c} {return diamonds}
    +
    +	if {$c<3} {return diamonds}
    +
    +	return clubs
    +}
    +
    +
    +[ The current implementation of shapefunc is a bit of a memory hog, +unfortunately, since it allocates strings for every element of the +table, even if the strings are duplicates. For instance, the function +above has only 4 return values, "spades", "hearts", "diamonds", and "clubs". +Still, shapefunc instantiates 560 strings. Smarter implementations +are certainly possible, and Tcl 8.0 alleviates the problem considerably +(because it allows deals with reference-counted strings.) ] +

    +[ We could also instantiate the table an entry at a time, leaving null pointers +in the table until a value has been requested. This has the advantage that +we will often compute considerably fewer values from the table. The +disadvantage is that every time we need a value from the table, we will have +to do a check to see if a pointer value is null. It +is not clear to me this would be an improvement or not, but it would +add a complexity to the code that I am not willing to maintain. It might +seem that you would need to check a pointer anyway, to determine if the +shapeclass has been instantiated or not, but the implementation avoids +such a check.] + +

    Note

    +The above definition of Balanced is an interesting oddity, +which I leave it up to the reader to try to understand. +Think about it for a moment before you look here. + +

    Table

    + +Here is the raw data of the table. Not very interesting, but it does +help to make it clear how the squashed ordering works, and why the index +values are computed as they are. + + +Index| S H D C +================== + 0 | 0 0 0 13 + 1 | 0 0 1 12 + 2 | 0 1 0 12 + 3 | 1 0 0 12 + 4 | 0 0 2 11 + 5 | 0 1 1 11 + 6 | 1 0 1 11 + 7 | 0 2 0 11 + 8 | 1 1 0 11 + 9 | 2 0 0 11 + 10 | 0 0 3 10 + 11 | 0 1 2 10 + 12 | 1 0 2 10 + 13 | 0 2 1 10 + 14 | 1 1 1 10 + 15 | 2 0 1 10 + 16 | 0 3 0 10 + 17 | 1 2 0 10 + 18 | 2 1 0 10 + 19 | 3 0 0 10 + 20 | 0 0 4 9 + 21 | 0 1 3 9 + 22 | 1 0 3 9 + 23 | 0 2 2 9 + 24 | 1 1 2 9 + 25 | 2 0 2 9 + 26 | 0 3 1 9 + 27 | 1 2 1 9 + 28 | 2 1 1 9 + 29 | 3 0 1 9 + 30 | 0 4 0 9 + 31 | 1 3 0 9 + 32 | 2 2 0 9 + 33 | 3 1 0 9 + 34 | 4 0 0 9 + 35 | 0 0 5 8 + 36 | 0 1 4 8 + 37 | 1 0 4 8 + 38 | 0 2 3 8 + 39 | 1 1 3 8 + 40 | 2 0 3 8 + 41 | 0 3 2 8 + 42 | 1 2 2 8 + 43 | 2 1 2 8 + 44 | 3 0 2 8 + 45 | 0 4 1 8 + 46 | 1 3 1 8 + 47 | 2 2 1 8 + 48 | 3 1 1 8 + 49 | 4 0 1 8 + 50 | 0 5 0 8 + 51 | 1 4 0 8 + 52 | 2 3 0 8 + 53 | 3 2 0 8 + 54 | 4 1 0 8 + 55 | 5 0 0 8 + 56 | 0 0 6 7 + 57 | 0 1 5 7 + 58 | 1 0 5 7 + 59 | 0 2 4 7 + 60 | 1 1 4 7 + 61 | 2 0 4 7 + 62 | 0 3 3 7 + 63 | 1 2 3 7 + 64 | 2 1 3 7 + 65 | 3 0 3 7 + 66 | 0 4 2 7 + 67 | 1 3 2 7 + 68 | 2 2 2 7 + 69 | 3 1 2 7 + 70 | 4 0 2 7 + 71 | 0 5 1 7 + 72 | 1 4 1 7 + 73 | 2 3 1 7 + 74 | 3 2 1 7 + 75 | 4 1 1 7 + 76 | 5 0 1 7 + 77 | 0 6 0 7 + 78 | 1 5 0 7 + 79 | 2 4 0 7 + 80 | 3 3 0 7 + 81 | 4 2 0 7 + 82 | 5 1 0 7 + 83 | 6 0 0 7 + 84 | 0 0 7 6 + 85 | 0 1 6 6 + 86 | 1 0 6 6 + 87 | 0 2 5 6 + 88 | 1 1 5 6 + 89 | 2 0 5 6 + 90 | 0 3 4 6 + 91 | 1 2 4 6 + 92 | 2 1 4 6 + 93 | 3 0 4 6 + 94 | 0 4 3 6 + 95 | 1 3 3 6 + 96 | 2 2 3 6 + 97 | 3 1 3 6 + 98 | 4 0 3 6 + 99 | 0 5 2 6 +100 | 1 4 2 6 +101 | 2 3 2 6 +102 | 3 2 2 6 +103 | 4 1 2 6 +104 | 5 0 2 6 +105 | 0 6 1 6 +106 | 1 5 1 6 +107 | 2 4 1 6 +108 | 3 3 1 6 +109 | 4 2 1 6 +110 | 5 1 1 6 +111 | 6 0 1 6 +112 | 0 7 0 6 +113 | 1 6 0 6 +114 | 2 5 0 6 +115 | 3 4 0 6 +116 | 4 3 0 6 +117 | 5 2 0 6 +118 | 6 1 0 6 +119 | 7 0 0 6 +120 | 0 0 8 5 +121 | 0 1 7 5 +122 | 1 0 7 5 +123 | 0 2 6 5 +124 | 1 1 6 5 +125 | 2 0 6 5 +126 | 0 3 5 5 +127 | 1 2 5 5 +128 | 2 1 5 5 +129 | 3 0 5 5 +130 | 0 4 4 5 +131 | 1 3 4 5 +132 | 2 2 4 5 +133 | 3 1 4 5 +134 | 4 0 4 5 +135 | 0 5 3 5 +136 | 1 4 3 5 +137 | 2 3 3 5 +138 | 3 2 3 5 +139 | 4 1 3 5 +140 | 5 0 3 5 +141 | 0 6 2 5 +142 | 1 5 2 5 +143 | 2 4 2 5 +144 | 3 3 2 5 +145 | 4 2 2 5 +146 | 5 1 2 5 +147 | 6 0 2 5 +148 | 0 7 1 5 +149 | 1 6 1 5 +150 | 2 5 1 5 +151 | 3 4 1 5 +152 | 4 3 1 5 +153 | 5 2 1 5 +154 | 6 1 1 5 +155 | 7 0 1 5 +156 | 0 8 0 5 +157 | 1 7 0 5 +158 | 2 6 0 5 +159 | 3 5 0 5 +160 | 4 4 0 5 +161 | 5 3 0 5 +162 | 6 2 0 5 +163 | 7 1 0 5 +164 | 8 0 0 5 +165 | 0 0 9 4 +166 | 0 1 8 4 +167 | 1 0 8 4 +168 | 0 2 7 4 +169 | 1 1 7 4 +170 | 2 0 7 4 +171 | 0 3 6 4 +172 | 1 2 6 4 +173 | 2 1 6 4 +174 | 3 0 6 4 +175 | 0 4 5 4 +176 | 1 3 5 4 +177 | 2 2 5 4 +178 | 3 1 5 4 +179 | 4 0 5 4 +180 | 0 5 4 4 +181 | 1 4 4 4 +182 | 2 3 4 4 +183 | 3 2 4 4 +184 | 4 1 4 4 +185 | 5 0 4 4 +186 | 0 6 3 4 +187 | 1 5 3 4 +188 | 2 4 3 4 +189 | 3 3 3 4 +190 | 4 2 3 4 +191 | 5 1 3 4 +192 | 6 0 3 4 +193 | 0 7 2 4 +194 | 1 6 2 4 +195 | 2 5 2 4 +196 | 3 4 2 4 +197 | 4 3 2 4 +198 | 5 2 2 4 +199 | 6 1 2 4 +200 | 7 0 2 4 +201 | 0 8 1 4 +202 | 1 7 1 4 +203 | 2 6 1 4 +204 | 3 5 1 4 +205 | 4 4 1 4 +206 | 5 3 1 4 +207 | 6 2 1 4 +208 | 7 1 1 4 +209 | 8 0 1 4 +210 | 0 9 0 4 +211 | 1 8 0 4 +212 | 2 7 0 4 +213 | 3 6 0 4 +214 | 4 5 0 4 +215 | 5 4 0 4 +216 | 6 3 0 4 +217 | 7 2 0 4 +218 | 8 1 0 4 +219 | 9 0 0 4 +220 | 0 0 10 3 +221 | 0 1 9 3 +222 | 1 0 9 3 +223 | 0 2 8 3 +224 | 1 1 8 3 +225 | 2 0 8 3 +226 | 0 3 7 3 +227 | 1 2 7 3 +228 | 2 1 7 3 +229 | 3 0 7 3 +230 | 0 4 6 3 +231 | 1 3 6 3 +232 | 2 2 6 3 +233 | 3 1 6 3 +234 | 4 0 6 3 +235 | 0 5 5 3 +236 | 1 4 5 3 +237 | 2 3 5 3 +238 | 3 2 5 3 +239 | 4 1 5 3 +240 | 5 0 5 3 +241 | 0 6 4 3 +242 | 1 5 4 3 +243 | 2 4 4 3 +244 | 3 3 4 3 +245 | 4 2 4 3 +246 | 5 1 4 3 +247 | 6 0 4 3 +248 | 0 7 3 3 +249 | 1 6 3 3 +250 | 2 5 3 3 +251 | 3 4 3 3 +252 | 4 3 3 3 +253 | 5 2 3 3 +254 | 6 1 3 3 +255 | 7 0 3 3 +256 | 0 8 2 3 +257 | 1 7 2 3 +258 | 2 6 2 3 +259 | 3 5 2 3 +260 | 4 4 2 3 +261 | 5 3 2 3 +262 | 6 2 2 3 +263 | 7 1 2 3 +264 | 8 0 2 3 +265 | 0 9 1 3 +266 | 1 8 1 3 +267 | 2 7 1 3 +268 | 3 6 1 3 +269 | 4 5 1 3 +270 | 5 4 1 3 +271 | 6 3 1 3 +272 | 7 2 1 3 +273 | 8 1 1 3 +274 | 9 0 1 3 +275 | 0 10 0 3 +276 | 1 9 0 3 +277 | 2 8 0 3 +278 | 3 7 0 3 +279 | 4 6 0 3 +280 | 5 5 0 3 +281 | 6 4 0 3 +282 | 7 3 0 3 +283 | 8 2 0 3 +284 | 9 1 0 3 +285 |10 0 0 3 +286 | 0 0 11 2 +287 | 0 1 10 2 +288 | 1 0 10 2 +289 | 0 2 9 2 +290 | 1 1 9 2 +291 | 2 0 9 2 +292 | 0 3 8 2 +293 | 1 2 8 2 +294 | 2 1 8 2 +295 | 3 0 8 2 +296 | 0 4 7 2 +297 | 1 3 7 2 +298 | 2 2 7 2 +299 | 3 1 7 2 +300 | 4 0 7 2 +301 | 0 5 6 2 +302 | 1 4 6 2 +303 | 2 3 6 2 +304 | 3 2 6 2 +305 | 4 1 6 2 +306 | 5 0 6 2 +307 | 0 6 5 2 +308 | 1 5 5 2 +309 | 2 4 5 2 +310 | 3 3 5 2 +311 | 4 2 5 2 +312 | 5 1 5 2 +313 | 6 0 5 2 +314 | 0 7 4 2 +315 | 1 6 4 2 +316 | 2 5 4 2 +317 | 3 4 4 2 +318 | 4 3 4 2 +319 | 5 2 4 2 +320 | 6 1 4 2 +321 | 7 0 4 2 +322 | 0 8 3 2 +323 | 1 7 3 2 +324 | 2 6 3 2 +325 | 3 5 3 2 +326 | 4 4 3 2 +327 | 5 3 3 2 +328 | 6 2 3 2 +329 | 7 1 3 2 +330 | 8 0 3 2 +331 | 0 9 2 2 +332 | 1 8 2 2 +333 | 2 7 2 2 +334 | 3 6 2 2 +335 | 4 5 2 2 +336 | 5 4 2 2 +337 | 6 3 2 2 +338 | 7 2 2 2 +339 | 8 1 2 2 +340 | 9 0 2 2 +341 | 0 10 1 2 +342 | 1 9 1 2 +343 | 2 8 1 2 +344 | 3 7 1 2 +345 | 4 6 1 2 +346 | 5 5 1 2 +347 | 6 4 1 2 +348 | 7 3 1 2 +349 | 8 2 1 2 +350 | 9 1 1 2 +351 |10 0 1 2 +352 | 0 11 0 2 +353 | 1 10 0 2 +354 | 2 9 0 2 +355 | 3 8 0 2 +356 | 4 7 0 2 +357 | 5 6 0 2 +358 | 6 5 0 2 +359 | 7 4 0 2 +360 | 8 3 0 2 +361 | 9 2 0 2 +362 |10 1 0 2 +363 |11 0 0 2 +364 | 0 0 12 1 +365 | 0 1 11 1 +366 | 1 0 11 1 +367 | 0 2 10 1 +368 | 1 1 10 1 +369 | 2 0 10 1 +370 | 0 3 9 1 +371 | 1 2 9 1 +372 | 2 1 9 1 +373 | 3 0 9 1 +374 | 0 4 8 1 +375 | 1 3 8 1 +376 | 2 2 8 1 +377 | 3 1 8 1 +378 | 4 0 8 1 +379 | 0 5 7 1 +380 | 1 4 7 1 +381 | 2 3 7 1 +382 | 3 2 7 1 +383 | 4 1 7 1 +384 | 5 0 7 1 +385 | 0 6 6 1 +386 | 1 5 6 1 +387 | 2 4 6 1 +388 | 3 3 6 1 +389 | 4 2 6 1 +390 | 5 1 6 1 +391 | 6 0 6 1 +392 | 0 7 5 1 +393 | 1 6 5 1 +394 | 2 5 5 1 +395 | 3 4 5 1 +396 | 4 3 5 1 +397 | 5 2 5 1 +398 | 6 1 5 1 +399 | 7 0 5 1 +400 | 0 8 4 1 +401 | 1 7 4 1 +402 | 2 6 4 1 +403 | 3 5 4 1 +404 | 4 4 4 1 +405 | 5 3 4 1 +406 | 6 2 4 1 +407 | 7 1 4 1 +408 | 8 0 4 1 +409 | 0 9 3 1 +410 | 1 8 3 1 +411 | 2 7 3 1 +412 | 3 6 3 1 +413 | 4 5 3 1 +414 | 5 4 3 1 +415 | 6 3 3 1 +416 | 7 2 3 1 +417 | 8 1 3 1 +418 | 9 0 3 1 +419 | 0 10 2 1 +420 | 1 9 2 1 +421 | 2 8 2 1 +422 | 3 7 2 1 +423 | 4 6 2 1 +424 | 5 5 2 1 +425 | 6 4 2 1 +426 | 7 3 2 1 +427 | 8 2 2 1 +428 | 9 1 2 1 +429 |10 0 2 1 +430 | 0 11 1 1 +431 | 1 10 1 1 +432 | 2 9 1 1 +433 | 3 8 1 1 +434 | 4 7 1 1 +435 | 5 6 1 1 +436 | 6 5 1 1 +437 | 7 4 1 1 +438 | 8 3 1 1 +439 | 9 2 1 1 +440 |10 1 1 1 +441 |11 0 1 1 +442 | 0 12 0 1 +443 | 1 11 0 1 +444 | 2 10 0 1 +445 | 3 9 0 1 +446 | 4 8 0 1 +447 | 5 7 0 1 +448 | 6 6 0 1 +449 | 7 5 0 1 +450 | 8 4 0 1 +451 | 9 3 0 1 +452 |10 2 0 1 +453 |11 1 0 1 +454 |12 0 0 1 +455 | 0 0 13 0 +456 | 0 1 12 0 +457 | 1 0 12 0 +458 | 0 2 11 0 +459 | 1 1 11 0 +460 | 2 0 11 0 +461 | 0 3 10 0 +462 | 1 2 10 0 +463 | 2 1 10 0 +464 | 3 0 10 0 +465 | 0 4 9 0 +466 | 1 3 9 0 +467 | 2 2 9 0 +468 | 3 1 9 0 +469 | 4 0 9 0 +470 | 0 5 8 0 +471 | 1 4 8 0 +472 | 2 3 8 0 +473 | 3 2 8 0 +474 | 4 1 8 0 +475 | 5 0 8 0 +476 | 0 6 7 0 +477 | 1 5 7 0 +478 | 2 4 7 0 +479 | 3 3 7 0 +480 | 4 2 7 0 +481 | 5 1 7 0 +482 | 6 0 7 0 +483 | 0 7 6 0 +484 | 1 6 6 0 +485 | 2 5 6 0 +486 | 3 4 6 0 +487 | 4 3 6 0 +488 | 5 2 6 0 +489 | 6 1 6 0 +490 | 7 0 6 0 +491 | 0 8 5 0 +492 | 1 7 5 0 +493 | 2 6 5 0 +494 | 3 5 5 0 +495 | 4 4 5 0 +496 | 5 3 5 0 +497 | 6 2 5 0 +498 | 7 1 5 0 +499 | 8 0 5 0 +500 | 0 9 4 0 +501 | 1 8 4 0 +502 | 2 7 4 0 +503 | 3 6 4 0 +504 | 4 5 4 0 +505 | 5 4 4 0 +506 | 6 3 4 0 +507 | 7 2 4 0 +508 | 8 1 4 0 +509 | 9 0 4 0 +510 | 0 10 3 0 +511 | 1 9 3 0 +512 | 2 8 3 0 +513 | 3 7 3 0 +514 | 4 6 3 0 +515 | 5 5 3 0 +516 | 6 4 3 0 +517 | 7 3 3 0 +518 | 8 2 3 0 +519 | 9 1 3 0 +520 |10 0 3 0 +521 | 0 11 2 0 +522 | 1 10 2 0 +523 | 2 9 2 0 +524 | 3 8 2 0 +525 | 4 7 2 0 +526 | 5 6 2 0 +527 | 6 5 2 0 +528 | 7 4 2 0 +529 | 8 3 2 0 +530 | 9 2 2 0 +531 |10 1 2 0 +532 |11 0 2 0 +533 | 0 12 1 0 +534 | 1 11 1 0 +535 | 2 10 1 0 +536 | 3 9 1 0 +537 | 4 8 1 0 +538 | 5 7 1 0 +539 | 6 6 1 0 +540 | 7 5 1 0 +541 | 8 4 1 0 +542 | 9 3 1 0 +543 |10 2 1 0 +544 |11 1 1 0 +545 |12 0 1 0 +546 | 0 13 0 0 +547 | 1 12 0 0 +548 | 2 11 0 0 +549 | 3 10 0 0 +550 | 4 9 0 0 +551 | 5 8 0 0 +552 | 6 7 0 0 +553 | 7 6 0 0 +554 | 8 5 0 0 +555 | 9 4 0 0 +556 |10 3 0 0 +557 |11 2 0 0 +558 |12 1 0 0 +559 |13 0 0 0 + +
    +
    +Silhouette +Thomas Andrews +(deal@thomasoandrews.com) +Copyright 1996-2008. Deal is covered by the +GNU General Public License. +

    +Plane Dealing graphic +above created using +POV-Ray. +

    +
    + + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/downloading.html /tmp/sFHmVEdqkv/deal-3.1.4/html/downloading.html --- deal-3.0.8/html/downloading.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/downloading.html 2008-06-11 02:20:28.000000000 +0530 @@ -0,0 +1,284 @@ + + + + + + + + + + Deal 3.1 - Downloading + + + + + + + + + +
    Deal 3.1 +

    Downloading Deal

    +
    + +
    +
    + +

    Downloading Deal 3.1.4

    +

    Go to the main Deal page to download the latest version. +

    Recent Changes

    +
    +Changes in Deal 3.1.4
    +
    +   * Added -trick flag to dds
    +
    +   * Allowed for inclusion of Tcl release libraries
    +
    +   * Moved most of deal.tcl to lib/features.tcl
    +
    +Changes in Deal 3.1.3
    +
    +   * Fixed performance issue in DDS that I introduced in Deal 3.1.0.
    +
    +   * Added -x command line flag
    +
    +Changes in Deal 3.1.2
    +
    +   * Added dds command for more control over the double dummy solver
    +
    +   * Added 'universal' target to Makefile for building Mac universal binaries
    +
    +   * Added tests for double-dummy solver, including Great 88 file
    +
    +   * Performance tweaks to the double-dummy solver
    +
    +   * Fixed a typo bug in deal.tcl
    +
    +   * Added full_deal command
    +
    +   * Added unicode output option for default format (to put out suit symbols)
    +
    +   * Changed to allow "-" as void in inputs
    +
    +   * Fixed seeding with seed_deal command
    +
    +   * Updated documentation and built a documentation-management system
    +
    +Changes in Deal 3.1.1
    +
    +   * Implemented deal::tricks for caching of double dummy data
    +     and uniform interface to double dummy tricks data
    +
    +   * Changed call to Haglund's solver to re-use data when processing
    +     contracts in the same denomination and different declarers.
    +
    +Changes in Deal 3.1
    +
    +   * Added Bo Haglund's Double Dummy Solver
    +
    +Changes in Deal 3.0.8
    +
    +[ No binary changes ]
    +
    +   * Fixed "line" input format
    +
    +   * Updates documentation
    +
    +Changes in Deal 3.0.7
    +
    +[ No binary changes - all changes in the Tcl files. ]
    +
    +   * Changed "score" to be a table lookup.
    +   * Fixed a bug in "parscore" which wrong-sided the
    +     contract sometimes.
    +   * Fixed documentation file "commands.html".
    +
    +Changes in Deal 3.0.6
    +
    +[ No binary changes this release - all changes in the Tcl files. ]
    +
    +   * Made changes to gib.tcl to work with the latest version of GIB.
    +
    +   * Fixed a few bugs with various formatting procedures.
    +
    +Changes in Deal 3.0.5
    +
    +   * Fixed a bug - Deal 3.0.4 failed to recognize "-" as void
    +   in -S, -E, -N, -W options, as well as in "north is " commands.
    +
    +     -----
    +
    +Changes in Deal 3.0.4
    +
    +   * Update doc examples to match ex/ subdirectory.
    +
    +   * Deleted util.c and util.h from distribution.
    +
    +     -----
    +
    +Changes in Deal 3.0.3
    +
    +  * Added GNU General Public License copyright to most files, and full
    +  GPL text to release.
    +
    +  * Altered deal.c to improve performance of reset_deal() routine.
    +  Improved overall performance of 10%.
    +
    +  * Re-implemented in Tcl the broken undocumented old procedures,
    +   intersectclass, negateclass, and joinclass.  This lets you create
    +   new shape classes from old shape classes using standard boolean
    +   functions.  Old code removed from dist.c, new code added to deal.tcl .
    +
    +  * Deleted some unused code in deal.tcl which was left from early
    +   efforts at the smart stacking routines.
    +
    +  * Updated the documentation
    +
    +     -----
    +Changes in Deal 3.0.2
    +
    +  * Fixed a bug in the smartstack methods.
    +
    +  * Altered zip builds to put files in deal302 directory (rather than
    +   deal3.0.2)
    +
    +  * Polished the HTML docs (in docs/html directory.)
    +
    +  * Many, many improved error messages when commands are misused
    +
    +  * Cleaned up some code
    +
    +  * Made dist.c use more Tcl_Obj pointers rather than strings - makes for
    +   faster compiles of shape classes.  (I can't believe I left those
    +   sprintf calls for so long. :-)
    +
    +  * Fixed some of the examples which called deal::stack_hand, a non-existant
    +   procedure.
    +
    +     -----
    +
    +Changes in Deal 3.0.1
    +
    +The changes for Deal 3.0.1 (from Deal 3.0 beta 11) were made essentially
    +for two reasons:
    +
    + (1) To finish the Deal 3.0 release - e.g., added documentation.
    + (2) To add features needed for the "smartstack" routines.
    +
    +  * Include HTML docs in docs/html directory.
    +
    +  * Most library files in release moved to the lib directory
    +
    +  * Added "smartstack" input class for fast building of hands which fit
    +  specific patterns
    +  
    +  * Added "stacked" procedure to find out the current state of the
    +  deck-stacking. Returns the list of cards stacked to the named hand.
    +
    +  * Altered stacking methods.  Added procedures "deck_stack_cards," 
    +  "deck_stack_hand", "stack_cards," and "stack_hand."  By default,
    +  "stack_hand" and "stack_cards" just call the "deck_" procedures,
    +  but the idea is that "stack_cards" and "stack_hands" can be
    +  overridden. Now when you call "south is AJ4 KJ54 9643 72" it in
    +  turn calls "stack_hand south AJ4 KJ54 9643 72." Similarly,
    +  "south gets ..." calls "stack_cards," although there the transformation
    +  is somewhat different.
    +  
    +  * Added "list" subcommand to shape classes.  e.g.,
    +
    +	  shapeclass hasVoid { expr {$s*$h*$d*$c==0} }
    +
    +	  foreach shape [hasVoid list] {
    +		...
    +	  }
    +
    +  * Added "shape" subcommand to the shape classes and functions, e.g.,
    +
    +	  shapefunc foo { ... }
    +
    +	  foo shape {4 2 4 3}
    +
    +    So:
    +
    +	  foo north
    +
    +    Is the same as:
    +
    +	  foo shape [north shape]
    +
    +  * Added the "holding" utility procedure, with subcommands length,
    +    disjoint, ...
    +
    +	  holding length AKxxx   =>    5
    +	  holding disjoint AKJ4 QT94  => 0    [ false ]
    +  
    +New to Deal 3.0:
    +
    +  * Fast holding procedures definable with holdingProc.
    +
    +  * GIB interfaces (gib::directory, gib::tricks, parscore)
    +
    +  * Bridge utility routines - lho, rho, partner, score
    +
    +  * Input format extensibility
    +
    +  * Uses features of faster versions of Tcl (Tcl 8.x)
    +
    +
    + +

    Building Deal

    +

    Selecting Tcl

    +Many Unix and Linux computers already have Tcl installed, as do Mac's running OS X. If your +computer does not, you will need to select a version and install it. +

    +On Unix, I'd recommend Tcl 8.3.x (or later,) but on Windows, I'd recommend Tcl +8.0.5, because I've had problems with Tcl hanging with later versions. +

    +All versions of Tcl can be downloaded from the +Scriptics web site. +

    +

    The Makefile

    +After downloading the Deal source code, +you should get a zip file. When you unzip it, you should get a directory, +deal314. +

    +On Unix machines, you will need to edit the Makefile to point to +your installation of Tcl. You may have to +change the following variables in the Makefile: +

    +
    TCL_LIB +
    The directory where the Tcl library is installed. + default value is /usr/local/lib. +
    TCL_INCL +
    The directory where tcl.h is installed. The default + value is /usr/local/include. +
    LDFLAGS +
    Really a list of liabraries needed at link time. By default, + "-L($TCL_LIB) -ltcl8.3 -lm", which works + at least on SunOS 4, HP, and SGI. On Solaris 2, you need to + add "-ldl -lsocket -lnsl". +
    EXTRA_CFLAGS +
    Whatever else you need... +
    +
    +
    +Silhouette +Thomas Andrews +(deal@thomasoandrews.com) +Copyright 1996-2008. Deal is covered by the +GNU General Public License. +

    +Plane Dealing graphic +above created using +POV-Ray. +

    +
    + + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/1-shapeclass.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/1-shapeclass.txt --- deal-3.0.8/html/ex/1-shapeclass.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/1-shapeclass.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,36 @@ +############################################## +# Look for hand where north has 44 in the majors, a short minor, +# and 11-15 HCP. +# +# To execute: +# deal -i ex/1-shapeclass.tcl [num] +############################################## + +shapeclass roman_short_minor {expr {$h==4 && $s==4 && ($c<=1 || $d<=1)}} + +main { + reject unless {[roman_short_minor north]} + set hcp_n [hcp north] + accept if {$hcp_n>=11 && $hcp_n<=15} +} +############################################## + + + +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/1-stack.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/1-stack.txt --- deal-3.0.8/html/ex/1-stack.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/1-stack.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,52 @@ +############################################## +# Look for hand where north has 44 in the majors, a short minor, +# and 11-15 HCP. +# +# To execute: +# deal -i ex/1-stack.tcl [num] +# +# This example uses the smart stacking algorithm to generate the +# same sorts of hands as example1 and example1-shapeclass. +# The very first deal is slow - when the deal is requested a +# large "factory" object is built in memory - but every other +# deal generated after that first one is generated extremely quickly. +# +# In this example, you'd have to want about 1500 matches to the condition +# for the investment to break even. But after 1500, the advantage of +# the smart stacking is huge. +# +# The payoff is even greater for rarer hand conditions. +############################################## + +shapeclass roman_short_minor {expr $h==4 && $s==4 && ($c<=1 || $d<=1)} + +deal::input smartstack north roman_short_minor HCP 11 15 + + +set start [clock seconds] +set count 0 +defvector HCP 4 3 2 1 + +proc flush_deal {} { + global start + global count + set time [expr {[clock seconds]-$start}] +} + +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/1.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/1.txt --- deal-3.0.8/html/ex/1.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/1.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,51 @@ +############################################## +# Look for hand where north has 44 in the majors, a short minor, +# and 11-15 HCP. +# +# Parts of this could be done more efficiently with a "shapeclass" +# command. +# +# To execute: +# deal -i ex/1.tcl [num] +############################################## +main { + # Pitch deals + # where north does + # not have four spades + reject if {[spades north]!=4} + + # Pitch deals + # where north does + # not have four hearts + reject if {[hearts north]!=4} + + # Pitch deals + # where north has + # 2 or 3 diamonds + set d [diamonds north] + reject if {$d==2} {$d==3} + + # Accept deals + # where north has + # 11-15 HCP. + set hcp_n [hcp north] + accept if {$hcp_n>=11 && $hcp_n<=15} +} +############################################## +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/2.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/2.txt --- deal-3.0.8/html/ex/2.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/2.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,29 @@ + +# I held the south hand given below, and east opened 2C. +# I overcalled 2S red-on-red. This procedure deals hands +# where east will open 2C in front of the south hand. + +south is "Q86432 T2 932 83" + +main { + set h [hcp east] + reject if {$h<18} + accept if {$h>22} {[losers east]<4} +} +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/3nt-common.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/3nt-common.txt --- deal-3.0.8/html/ex/3nt-common.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/3nt-common.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,36 @@ +shapecond gam3NT.shape {$s<=3&&$h<=3&&(($d>=7&&$c<=4)||($c>=7&&$d<=4))} + +# return '1' if not compatible with a gambling notrump hand, +# '0' otherwise +holdingProc gam3NT.suit {A K Q J len} { + + if {$len>=7} { + if {$len<=9&&$A&&$K&&$Q} { return 0} + return 1 + } + + if {$len<=4} { + if {$A||$K} { return 1 } + return 0 + } + + return 1 + +} +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/3nt-nostack.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/3nt-nostack.txt --- deal-3.0.8/html/ex/3nt-nostack.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/3nt-nostack.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,54 @@ +# +# +# To run: +# +# deal -i ex/3nt-nostack.tcl +# +# Find deals where south is "AK K52 98765 962" and north has a gambling +# 3nt hand. +# +# This uses the definition: Solid 7-9 card minor suit, no 4-card major or +# 5+ card in the other minor, no controls outside the solid suit. +# +# This is slower than the smart-stacking version by an order of magnitude +# when requesting 1000 deals. +# +source format/none + +south is "AK K52 98765 962" + +source ex/3nt-common.tcl + +set diamonds 0 +set clubs 0 + +main { + reject unless {[gam3NT.shape north]} + reject unless {0==[gam3NT.suit north]} + if {[diamonds north]>=7} { incr diamonds } { incr clubs } + puts "-- [north shape]" + accept +} + +deal_finished { + #puts "Solid diamonds: $diamonds" + #puts "Solid clubs : $clubs" +} + +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/3nt-stack.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/3nt-stack.txt --- deal-3.0.8/html/ex/3nt-stack.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/3nt-stack.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,65 @@ +# +# Find deals where south is "AK K52 98765 962" and north has a gambling +# 3nt hand. +# +# This was one of the first examples I gave of how "smart stacking" could +# be used. +# +# Compare output from this with output from ex/3nt-nostack.tcl to make +# sure that the relative odds are being obeyed, eg: +# +# deal -i ex/3nt-stack.tcl 1000 | sort | uniq -c | sort -nr > stack.txt +# deal -i ex/3nt-nostack.tcl 1000 | sort | uniq -c | sort -nr > nostack.txt +# +# Obviously, they shouldn't be exactly the same, but they should be similar. + +source format/none + +shapecond gam3NT.shape {$s<=3&&$h<=3&&(($d>=7&&$c<=4)||($c>=7&&$d<=4))} + +# return '1' if not compatible with a gambling notrump hand, +# '0' otherwise +holdingProc gam3NT.suit {A K Q J len} { + + if {$len>=7} { + if {$len<=9&&$A&&$K&&$Q} { return 0} + return 1 + } + + if {$len<=4} { + if {$A||$K} { return 1 } + return 0 + } + + return 1 + +} + +deal::input smartstack north gam3NT.shape gam3NT.suit 0 0 + +south is "AK K52 98765 962" + +# Dump the data table from the smart stacking routine + +main { + puts "-- [north shape]" + accept +} + +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/3-shapeclass.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/3-shapeclass.txt --- deal-3.0.8/html/ex/3-shapeclass.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/3-shapeclass.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,42 @@ +# You hold the south hand: 764 J4 J753 AQJ2 +# and the auction has gone: 1S(W)-1NT-2NT-3NT by the opponents, +# who are playing 2/1. +# Choose a lead. + +# In this example, I've assumed west has no side 4-card suit, +# and that he holds exactly 5 spades and 16-19 HCP. + +# I've also assumed that East had some way to show a 5-card heart +# suit over 2NT, and hence, that he doesn't hold one, and also that +# east does not have spade support. + +south is 764 J4 J753 AQJ2 + +shapecond balanced5S {$s==5&&($h*$d*$c==18)} + +main { + reject unless {[balanced5S west]} + set w [hcp west] + reject if {$w<16} {$w>19} + reject if {[hearts east]>4} {[spades east]>2} + set e [hcp east] + reject if {$e<6} {$e>11} {[losers east]<6} + accept +} +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/3.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/3.txt --- deal-3.0.8/html/ex/3.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/3.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,40 @@ +# You hold the south hand: 764 J4 J753 AQJ2 +# and the auction has gone: 1S(W)-1NT-2NT-3NT by the opponents, +# who are playing 2/1. +# Choose a lead. + +# In this example, I've assumed west has no side 4-card suit, +# and that he holds exactly 5 spades and 16-19 HCP. + +# I've also assumed that East had some way to show a 5-card heart +# suit over 2NT, and hence, that he doesn't hold one, and also that +# east does not have spade support. + +south is 764 J4 J753 AQJ2 + +main { + reject unless {[spades west]==5} + set w [hcp west] + reject if {$w<16} {$w>19} {[hearts west]>3} {[diamonds west]>3} {[clubs west]>3} + reject if {[hearts east]>4} {[spades east]>2} + set e [hcp east] + reject if {$e<6} {$e>11} {[losers east]<6} + accept +} +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/4-holding.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/4-holding.txt --- deal-3.0.8/html/ex/4-holding.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/4-holding.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,32 @@ +# +# By agreement, you open a weak 2 with exactly 6 cards in your major, +# fewer than 4 cards in the other major, 5-10 HCP and either 2 of the +# top 3 or three of the top 5 in your suit. +# + +holdingProc -boolean Weak2Quality {length A K Q J T} { + expr {$length==6 && (($A+$K+$Q)>=2 || ($A+$K+$Q+$J+$T)>=3)} +} + +main { + set sh [hcp south] + reject if {$sh>10} {$sh<5} {[hearts south]>3} {[clubs south]>3} {[diamonds south]>3} + accept if {[Weak2Quality south spades]} +} +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/4-stack.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/4-stack.txt --- deal-3.0.8/html/ex/4-stack.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/4-stack.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,36 @@ +# +# By agreement, you open a weak 2 with exactly 6 cards in your major, +# fewer than 4 cards in the other major, 5-10 HCP and either 2 of the +# top 3 or three of the top 5 in your suit. +# + +holdingProc -boolean Weak2Quality {length A K Q J T} { + accept if {$length<3} + reject unless {$length==6} + accept if {(($A+$K+$Q)>=2 || ($A+$K+$Q+$J+$T)>=3)} +} + +shapecond Weak2Shape {$d<=3&&$c<=3&&(($h<=3&&$s==6)||($h==6&&$s<=3))} + +deal::input smartstack south Weak2Shape hcp 5 10 + +smartstack::restrictHolding spades Weak2Quality 1 1 +smartstack::restrictHolding hearts Weak2Quality 1 1 + +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/4.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/4.txt --- deal-3.0.8/html/ex/4.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/4.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,37 @@ +# +# By agreement, you open a weak 2 with exactly 6 cards in your major, +# fewer than 4 cards in the other major, 5-10 HCP and either 2 of the +# top 3 or three of the top 5 in your suit. +# + +defvector W2Q 2 2 2 1 1 +main { + set sh [hcp south] + reject if {$sh>10} {$sh<5} {[clubs south]>3} {[diamonds south]>3} + set s [spades south] + if {$s == 6} { + reject if {[hearts south]>3} {[W2Q south spades]<=3} + accept + } + reject if {$s>3} + set h [hearts south] + reject if {$h!=6} {[W2Q south hearts]<=3} + accept +} +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/5.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/5.txt --- deal-3.0.8/html/ex/5.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/5.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,41 @@ +############################# +# When I first wrote this I was somewhat surprised. +# +# This deals hands where south opens a strong blue club and +# north has a 3+ controls (that is, he has a strong positive +# response.) +# +# I was surprised to find that slam was making 1/2 the time on these +# hands. In other words, for Blue-clubbers, if the auction starts: +# +# 1C 1S/1NT/2C/2D +# +# there is a 50% chance that a slam should be bid... +############################# + +main { + reject unless {[controls north]>=3} + set w [hcp south] + reject unless {$w >=17} + if {[balanced south]} { + reject if {$w==17} {$w>=22 && $w<=24} + } + accept +} +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/6a.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/6a.txt --- deal-3.0.8/html/ex/6a.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/6a.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,56 @@ +# +# File: ex/6a.tcl +# +# This is a test which shows why you'd want to use a "shape class" +# or "shape function", which are fast lookup tables... +# +# This is the slow version, which doesn't use the shape function +# +# It seeks hands where north and south have voids in the same +# suit. (Alternatively, it finds hands where east and west have +# a 13-card fit.) +# +# See ex/6b.tcl and ex/6c.tcl for faster versions of the same search +# + +main { + accept unless {[spades south]!=0} {[spades north]!=0} + accept unless {[hearts south]!=0} {[hearts north]!=0} + accept unless {[diamonds south]!=0} {[diamonds north]!=0} + accept unless {[clubs south]!=0} {[clubs north]!=0} +} + +# It should be noted that this script is written so that +# the north hand is never even dealt unless the south hand +# has a void. That's because, internally, 'deal' doesn't deal +# a hand unless information is requested about that hand. +# +# If the lines were: +# +# accept if {[spades south]==0 && [spades north]==0} +# +# 'deal' would request information for *both* hands, and that would +# double the amount of work. Hence the use of the slightly less clear +# 'accept unless' idiom. +# +# How much of an optimization is it to not deal the north hand? +# Profiling has shown me that a vast amount of time is spent in +# the randomnization routines, so cutting down on these calls +# is a significant time savings. +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/6b.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/6b.txt --- deal-3.0.8/html/ex/6b.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/6b.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,48 @@ +# +# File: ex/6b.tcl +# +# This implements the same search as ex/6a.tcl, using a simple +# shape class. +# +# Basically, we use a shapeclass to immediately reject deals where +# south doesn't have a void. This keeps us from doing unnecessary +# work, and practically doubles the speed of the search. +# +# The shape class "hasvoid" returns one (True) if there is a void +# somewhere in the hand and zero (False) otherwise. It would +# seem like this is doing *more* work than example A, but the +# lookup in a shapeclass is much better optimized, and we break +# out of the loop if south doesn't have void, and move on to +# the next. +# +# example6c is about the same speed but uses an idiom worth +# seeing for other sorts of problems. +# + +shapecond hasvoid {$s==0 || $h==0 || $d==0 || $c==0} + +main { + reject unless [hasvoid south] + accept if {[spades south]==0 && [spades north]==0} + accept if {[hearts south]==0 && [hearts north]==0} + accept if {[diamonds south]==0 && [diamonds north]==0} + accept if {[clubs south]==0 && [clubs north]==0} + reject +} +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/6c.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/6c.txt --- deal-3.0.8/html/ex/6c.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/6c.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,62 @@ +# +# File: ex/6c.tcl +# +# This file uses a "shape function" to optimize a search for hands +# where north and south have voids in the same suit. +# +# The shape function "voids" returns a list of the suits in which +# the hand given has a void. So if south is: +# +# S --- S AK5 S KJ8 +# H 5432 H A982 H Q932 +# D --- D 543 D AT9863 +# C AQT986543 C T92 C ---- +# +# [voids south] will return: +# +# "spades diamonds" "" "clubs" +# +# We then run through this list and check if north has any void in +# common. +# +# This doesn't seem like it would be faster, but it is, because +# the shape function is computed up front as a table, and each call +# after the first is a quick lookup. In fact, this is twice +# as fast as the script in ex/6a.tcl . +# +# It is only slightly faster than ex/6b.tcl, though. The main +# reason I include it is to show a technique that can be used elsewhere. +# Another example which uses this is example7, a rather complicated routine... +# + +shapefunc voids { + set res "" + if {$s==0} { lappend res spades } + if {$h==0} { lappend res hearts } + if {$d==0} { lappend res diamonds } + if {$c==0} { lappend res clubs } + return $res +} + +main { + foreach suit [voids south] { + accept if {[$suit north]==0} + } +} +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/6d.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/6d.txt --- deal-3.0.8/html/ex/6d.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/6d.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,53 @@ +# +# File: ex/6d.tcl +# +# This file uses a "holding function" to optimize a search for hands +# where north and south have voids in the same suit. +# +# The holding function "isVoid" returns a list of the suits in which +# the hand given has a void. So if south is: +# +# S --- S AK5 S KJ8 +# H 5432 H A982 H Q932 +# D --- D 543 D AT9863 +# C AQT986543 C T92 C ---- +# +# [voids south] will return: +# +# "spades diamonds" "" "clubs" +# +# This is the same output as in the "voids" procedure for ex/6c.tcl, +# but it is implemented as a holding procedure rather than a shape +# procedure. +# +# We then run through this list and check if north has any void in +# common. +# +# This is considerably slower the 6b.tcl and 6c.tcl, though. + +holdingProc -boolean voids {len} { + expr {$len==0} +} + +main { + foreach suit [voids south] { + accept if {[$suit north]==0} + } +} +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/7.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/7.txt --- deal-3.0.8/html/ex/7.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/7.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,99 @@ +# +# A Certain poster to rec.games.bridge has been posting +# a computer generated bidding system that, to most bridge +# players eyes, looks somewhat deranged. +# + +# bid.lib is a library of tcl routines which allow you +# to define opening bids and later check to see if a hand +# fits the conditions + +source lib/bid.tcl + +defvector AKQ 4 3 2 +defvector Top4 1 1 1 1 +defvector Aces 1 +defvector None 0 +proc top4spades {hand} { + return [Top4 $hand spades] +} + +# Usage: +# describebid +# +# Don Quixote's system: +# +describebid 5D {$d>=8} AKQ 0 3 +describebid 5C {$c>=8} controls 0 1 +describebid 4S {$s==8} controls 0 3 +describebid 4H {$h>=7} controls 0 1 +describebid 4D {$d>=8} AKQ 5 7 +describebid 4C {$h==8 && $d*$c*$s==3} Aces 1 1 +describebid 3NT {$s==9 && ($h==2 || $d==2 || $c==2)} top4spades 2 4 +describebid 3S {$s==7 && $d*$c*$h==6} AKQ 0 7 +describebid 3H {$h==7} losers 16 17 +describebid 3D {$d==7 && ($h==3 || $c==3 || $d==3)} hcp 3 3 +describebid 3C {$c==7 && $d*$h*$s==4} AKQ 0 3 +describebid 2NT {$s==7 && $c*$h*$d==8} hcp 4 5 +describebid 2S {$s==7 && $c*$d*$h==4} hcp 3 5 +describebid 2H {$h==7} Aces 0 0 +describebid 2D {$d==7 && $h*$s*$c==6} hcp 2 5 +describebid 2C {$c>=3 && $d>=3 && $h>=3 && $s>=3} hcp 22 23 + +####################################### +# +# This uses the proceducre "getbidlist", which is really +# a "shapefunc" defined in bid.lib . It returns a list +# of all the possible described bids which can be made, given +# only the shape of the hand. This turns out to be a very +# good optimization - rather than looping through all the +# bids, we only have to loop through a small subset. +# +# "checkcondition" then actually checks whether the hand +# is fits the other condition (which does a computation +# using the function provided and checks whether the hand is +# in the correct range.) +# +# This search looks for (south) hands which would open +# 2C under the above system. What kind of system +# opens at the 2 level only 1/100 times, anyway? +# Bizarre. +# +####################################### + +foreach bid $bidlist { + set count($bid) 0 +} +set accepted 0 +set tried 0 + +main { + incr tried + foreach bid [getbidlist south] { + if {[checkcondition $bid south]} { + puts "$bid with [south]" + incr count($bid) + incr accepted + accept + } + } + reject +} + +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ex/holdingProc.txt /tmp/sFHmVEdqkv/deal-3.1.4/html/ex/holdingProc.txt --- deal-3.0.8/html/ex/holdingProc.txt 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ex/holdingProc.txt 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,54 @@ +# +# A simple 'holding procedure' to determine high card points +# +holdingProc HCP {A K Q J} { + expr {$A*4+$K*3+$Q*2+$J} +} + +# +# The 'smartPoints' procedure incorporates two adjustments to +# the standard high card points. +# +# 1) A point is added for every card over 4 in a single suit +# 2) Honors in short suits are somewhat discounted +# +holdingProc smartPoints {length A K Q J} { + if {$length>=5} { + return [expr {$A*4+$K*3+$Q*2+$J+$length-4}] + } + if {$length==0} { return 0 } + if {$length==1} { + return [expr {$A*4+$K*2}] + } + if {$length==2} { + return [expr {$A*4+$K*3+$Q}] + } + expr {$A*4+$K*3+$Q*2+$J} +} + +# +# Find deals where north has less than 13 HCP but are compensated over +# 13 points by shape +# +main { + reject if {[HCP north]>12} + accept if {[smartPoints north]>12} +} + +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/examples.html /tmp/sFHmVEdqkv/deal-3.1.4/html/examples.html --- deal-3.0.8/html/examples.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/examples.html 2008-06-11 02:20:28.000000000 +0530 @@ -0,0 +1,81 @@ + + + + + + + + + + Deal - Example Scripts + + + + + + + + + + + + + + +
    Plane Dealing image

    Deal 3.1

    +

    Examples

    +
    +
    +
    + +
      +
    • Example 1: North is 44 in majors and short in +a minor, with 11 to 15 points. +
    • Example 2: South holds a specific hand and +east opens two clubs. +
    • Example 3: Holding a specific hand, south +on lead after opponents bid: 1S(W)-1NT-2NT-3NT. +
    • Example 4: South opens a weak two in spades +or hearts +
    • Example 5: Playing Blue Club, responder +to 1C opening has three or more controls +
    • Shape class variants of above examples: + +
    • Example 6: Find deals where north and south are void in the same suit, +using several different methods. + +
    • Smart stacking examples: + +
    +
    +
    +Silhouette +Thomas Andrews +(deal@thomasoandrews.com) +Copyright 1996-2008. Deal is covered by the +GNU General Public License. +

    +Plane Dealing graphic +above created using +POV-Ray. +

    +
    diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/ext-ref.html /tmp/sFHmVEdqkv/deal-3.1.4/html/ext-ref.html --- deal-3.0.8/html/ext-ref.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/ext-ref.html 2008-06-11 02:20:28.000000000 +0530 @@ -0,0 +1,63 @@ + + + + + + Deal - Other References and Resources + + + + + + + +Back to Deal Top Page. + + + + + + +
    Jack of Hearts

    Deal 3.1

    +

    Other References and Resources

    +
    +
      +
    • Tcl Resources +
    • Other Dealers +
    +
    +
    + +

    Tcl Resources

    +John Ousterhout wrote Tcl originally as a research project, and +then Sun hired him, forming the Scriptics group around Ousterhout +and Tcl. The Scriptics group was spun off into a separate company. +The Scriptics website is +the best place to go for the latest information about Tcl, online +documentation, etc. + + +

    Other Dealers

    + +
      +
    • Aside from Deal, the most often cited dealer on rec.games.bridge is +Dealer, +originally written by Hans van Staveren. +
    • There are quite a few more dealers listed at the +Great Bridge Links +Software Page. +
    + +
    +
    +Silhouette +Thomas Andrews +(deal@thomasoandrews.com) +Copyright 1996-2008. Deal is covered by the +GNU General Public License. +

    +Plane Dealing graphic +above created using +POV-Ray. +

    + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/GIBstuff.html /tmp/sFHmVEdqkv/deal-3.1.4/html/GIBstuff.html --- deal-3.0.8/html/GIBstuff.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/GIBstuff.html 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,165 @@ + + + + + + + + + +Deal 3.1 - GIB interfaces + + +
    +

    Deal 3.1 - GIB interfaces

    +

    If you add the line: +

    +source lib/gib.tcl
    +
    +

    it will include the GIB interface library. +

    +This code only works on Windows. + +

    gib::directory

    +This command tells Deal where GIB is installed. If GIB is installed +in the standard Windows directory, +C:\Program Files\GIB, +then you don't need to call this. But if it is installed elsewhere, +you need to call this procedure: +
    +source lib/gib.tcl
    +
    +gib::directory "c:/Games/GIB"
    +
    +Note that Tcl uses forward-slash characters, / to seperate directory patchs. +

    +You can also just edit gib.tcl to permanently change the default. +

    +Another thing you might want to change is where the gib library +places temporary files. Currently, gib.tcl has the directory +C:\temp hard-coded for the temporary files. If you +don't have such a directory, and don't want to create one, then you'll +need to edit gib.tcl . + +

    deal:tricks

    +

    Note: In past releases, you would use the gib::tricks command, but that is obsolete in Deal 3.1.

    +

    By default, deal::tricks uses the built-in double dummy solver written by Bo Haglund. But when you include lib/gib.tcl, deal::tricks changes to call GIB's double dummy solver.

    +

    The procedure deal::tricks returns the number of tricks +a hand can make in a specific denomination (suit or notrump.) +For example: +

    +source lib/gib.tcl
    +
    +main {
    +
    +  accept if {[deal::tricks south notrump]>=12}
    +
    +}
    +
    + +finds deals where south can make 12 or more tricks in notrump, +double-dummy. +

    +This is going to be slow - each call to deal::tricks can take +over a second - so you might try to put some additional +conditions: +

    +source lib/gib.tcl
    +
    +main {
    +
    +  reject if {[hcp north]+[hcp south]<26}
    +
    +  accept if {[deal::tricks south notrump]>=12}
    +
    +}
    +
    +That might miss the occasional freakish slam, but it will be considerably +faster. + +

    +The deal::tricks procedure caches values, +so that multiple calls with the same parameters on the same deal +result in quick turn-around. +

    +This is useful if we are using the parscore +in our query, or if we use the output format, gibpar, +discussed later. + +

    parscore

    + +

    This routine determines the double-dummy par score for a deal. Because +it calls deal::tricks 20 times - once for each declarer and denomination - it +can take 20 seconds or more per deal. Not good for huge batches. +

    Parscore takes as input the dealer and vulnerability: +

    +set result [parscore north NS]
    +set contract [lindex $result 0]
    +set declarer [lindex $result 1]
    +set score    [lindex $result 2]
    +set tricks   [lindex $result 3]
    +set auction  [lindex $result 4]
    +
    +Vulnerability can be one of None, NS, EW, +or All. +

    +The result returned is fairly complex - it consists of a list of elements. +

      +
    • The first element is a contract, in the form "2 spades doubled" or "2 spades." [ Double-dummy par scores are, of course, never redoubled. ] +
    • The second element is the declarer. +
    • The third element is the score +
    • The fourth element is the number of tricks declarer can take. +
    • The fifth is a stupid auction to get to the contract. If north is dealer +and east is declarer in the double-dummy par contract of 4 clubs doubled, +the auction will be "Pass 4C X Pass Pass Pass". Not very inspired, but +needed for the gibpar application, below. +
    + +[Why do we need to know the dealer? Suppose north and east are +the only ones who can make 1NT, and that no higher contracts make. Then +double-dummy par is 1NT by east if east is dealer, while it is 1NT by north +if anybody else is dealer.] + +

    The gibpar format

    + +As soon as I got GIB, I wanted to use Deal to generate PBN files for +GIB to use in play. It was trickier than I thought - GIB apparently +wants a *score* in the PBN file. This was why I created the +parscore command above - so that I could write out a PBN +file with a score which was objective, rather than random. +

    +This format is used like any other format: +

    +C:\Deal30> deal -i format/gibpar 36 > myfile.pbn
    +
    + +As with any other Deal format, format/gibpar can be used with filters: + +
    +C:\Deal30> deal -i format/gibpar -i ex/1.tcl > myfile.pbn
    +
    + +Once you've generated this PBN file, you can load it into GIB via the +"Load Saved Deal" command. +

    +Competing against double-dummy par is grueling work - it's essentially +playing a team game where everybody at the other table is an +infallible psychic - both your "opponents" and your teammates. +That means that any swings are due to errors at your table +and/or luck. They will always bid that making 15% grand at the +other table, for example. +


    +
    +Silhouette + Thomas Andrews +(thomaso@best.com) + Copyright 1996-2008. Deal is covered by the +GNU General Public License. +

    +Plane Dealing graphic +above created using +POV-Ray. +

    +
    Binary files /tmp/SqcgMuwVDH/deal-3.0.8/html/graphics/falling_small.jpg and /tmp/sFHmVEdqkv/deal-3.1.4/html/graphics/falling_small.jpg differ Binary files /tmp/SqcgMuwVDH/deal-3.0.8/html/graphics/idealbg.jpg and /tmp/sFHmVEdqkv/deal-3.1.4/html/graphics/idealbg.jpg differ Binary files /tmp/SqcgMuwVDH/deal-3.0.8/html/graphics/new01.gif and /tmp/sFHmVEdqkv/deal-3.1.4/html/graphics/new01.gif differ Binary files /tmp/SqcgMuwVDH/deal-3.0.8/html/graphics/StampSm.gif and /tmp/sFHmVEdqkv/deal-3.1.4/html/graphics/StampSm.gif differ Binary files /tmp/SqcgMuwVDH/deal-3.0.8/html/graphics/warning.gif and /tmp/sFHmVEdqkv/deal-3.1.4/html/graphics/warning.gif differ diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/history.html /tmp/sFHmVEdqkv/deal-3.1.4/html/history.html --- deal-3.0.8/html/history.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/history.html 2008-06-11 02:20:28.000000000 +0530 @@ -0,0 +1,121 @@ + + + + + + + + + + + Deal - A Brief History + + + + + + + + + + + + + + + + +
    Plane Dealing image

    Deal 3.1

    +

    A brief history

    +
    +
    +
    D
    eal +was originally conceived in 1988 for +bidding practice. I was a math graduate student just learning +bridge and another grad student, Robin Pemantle, suggested a way to practice bidding. +His idea was to have the computer deal out twenty or so hands, and +then offer each hand up to you, randomly, for bidding. This way, +you could bid all four hands in each of twenty deals, and, if you +tried hard, you could avoid remembering which hand was which. +

    +I mentioned that idea to my partner at the time, Nathan Glasser, +and he wrote a program called bid, which is still + +available from the bridge archives. +

    +The problem with bid was that it could not +be used for practicing specific auctions. John Oswalt solved +this in a rather crude fashion. His modification forced you to re-link +your application each time you wrote a new query (in C). + +

    +After using this modified version for a while, I got frustrated and +wrote a very crude interpreter. It was a "stack-based" language +so I wouldn't have to write a parser. It was very much like the Unix "dc" +calculator, only without all the features. (That's a joke, but I guess +you wouldn't get it if you didn't know dc.) +

    +I could have used a fully interpreted language, like Perl, but for +the types of simulations I was doing, I need very fast execution +of the computation routines, and so implementing the core in an +interpreted language was going to slow down the program too much. +

    +In about 1992 I first stumble across the Tcl language. Immediately, +I saw that I could use it in my dealer. Tcl was an interpreted +language which had excellent support for extensibility via fast +C routines. It turned out that Nathan's +code did not easily fit into my new scheme, so I rewrote the dealer +from scratch. I had my first version done quickly, and released the +first public version (v0.5 I called it, in retrospect) in 1993. +

    +The next version (v1.0) was released about two years later, and basically +cleaned up the query interface. In the haze of my memory, I can not +recall what features were added, certainly "vectors" and "shape classes." +

    +Version 2.0 uses new optimization methods, some of which +were suggested to me by the very same Nathan Glasser. There are some +other new features, including shape functions, customizable +output formatting, and more built-in formats. +

    +Version 3.0, is the next major release. Major changes are: +

      +
    • GNU GPL license - making it free for all use +
    • Much faster execution using Tcl 8.x features. +
    • Addition of 'holding functions' - like 'vectors' but more suitable +for complex evaluations like "losers" and "CCCC." +
    • "Smart stacking" for finding rare hands. +
    +

    +Version 3.1 has Bo Haglund's double dummy solver builtin, so you can call a 'tricks' function to get double dummy data. + +

    +While Deal is a labor of love for me, it makes it easier +to love the project if I get feedback which shows people are using +Deal. Even if you tried Deal and did not like +it, please let me know. +


    +
    +Silhouette +Thomas Andrews +(deal@thomasoandrews.com) +Copyright 1996-2008. Deal is covered by the +GNU General Public License. +

    +Plane Dealing graphic +above created using +POV-Ray. +

    +
    + + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/holding.html /tmp/sFHmVEdqkv/deal-3.1.4/html/holding.html --- deal-3.0.8/html/holding.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/holding.html 2008-06-11 02:20:28.000000000 +0530 @@ -0,0 +1,157 @@ + + +Holding Procedures + + +

    Holding Procedures in Deal 3.1 and iDeal

    + +

    Introduction

    +One of the main new bridge evaluation features in Deal 3.1 and iDeal +is the ability to define fast procedures for evaluating a single holding. +

    +In Deal 2.0, we were able to define +Vector functions, which assigned +integer values to each card. This covered a lot of standard evaluation +techniques, but not the more complicated forms. Evaluators like +"quick tricks" and "losers," while still computed suit by suit and totaled, +cannot be defined by assigning values to cards alone. +

    +The solution is to allow the creation of general procedures for evaluating +a holding, while still taking advantage of fast lookup tables. Thus, +the introduction of the holdingProc command. + +

    The holdingProc Command

    + +holdingProc looks like a normal Tcl definition of a procedure. For example, +we might write: +
    +
    +holdingProc HCP {A K Q J} {
    +    expr {$A*4+$K*3+$Q*2+$J}
    +}
    +
    +
    +to define a function called HCP. This function behaves exactly +the same as the builtin hcp routine - the user can ask for +the total points in a hand or for a specific suit in the hand: +
    +
    +set n [HCP north]
    +set hs [HCP north spades]
    +
    +
    +When evaluated, the parameter A is set to one if the holding has the ace, +and zero otherwise. +

    +That's a simple example, but let's say we want to do some smart reevaluation. +For example, we might want to add a point for each card in a suit beyond +the fourth. We also might want to evaluate a stiff king as two points, rather +than three, a stiff queen as zero, and a doubleton queen as one. +

    +We can do this by adding a "length" parameter to the parameters list: +

    +
    +holdingProc SmartHCP {A K Q J length} {
    +
    +    if {$length>=4} {
    +        # Normal evaluation, +1 for each card longer than the fourth
    +	return [expr {$A*4+$K*3+$Q*2+$J+($len-4)}]
    +    }
    +
    +    if {$length==3} {
    +        # Normal evaluation for 3-card suits
    +	return [expr {$A*4+$K*3+$Q*2+$J}]
    +    }
    +
    +    if {$length==2} {
    +        # Jacks in doubletons are worth zero, queens one
    +	return [expr {$A*4+$K*3+$Q}]
    +    }
    +
    +    if {$length==1} {
    +        # Queens and jacks in singletons are worth zero, kings two
    +	return [expr {$A*4+$K*2}]
    +    }
    +
    +    return 0
    +}
    +
    +
    + +Even though this code is slow, it is only evaluated at most 160 times, after +which values are reused, yielding remarkably fast evaluations. One deal, +you might get a holding of KQ75 which this routine evaluates +as if it were evaluating KQxx. The next hand, it sees the +holding KQ82 and, seeing this also as KQxx, remembers +the previous value. +

    Types of Holding Procedures

    + +By default, the holding procedure assumes that the values returned are integers, +so that when it tries to add up the values of all four suits, it applies +an integer sum. +

    +If you want the return value interpreted as a double, you can specify it +in the declaration. For example, we can define a quick tricks procedure: +

    +
    +holdingProc -double QuickTricks {A K Q J T length} {
    +    if {$A&&$K} { return 2 }
    +    if {$A} { return 1 }
    +    if {$K && ($Q || ($J && $T))} {
    +         return 1
    +    }
    +    if {$K && $length>1} {
    +            return 0.5
    +    }
    +    return 0
    +}
    +
    +
    +

    +You can define the type to be any of the following: +

    +
    -integer +
    The default, adds integer values when evaluated across multiple suits. +
    -double +
    Adds resulting values as doubles when evaluated across multiple suits. +
    -boolean +
    When evaluated on a hand, lists the suits, by name, which evaluate as true. +For example, if you defined 'biddableSuit' it would return the list +"spades hearts" for the hand KT954 AJ32 94 92. +
    -string +
    Returns a list of values when evaluated on multiple suits. +
    +

    Arguments Allowed

    +The arguments are interpreted based on the first character of their name, +or, in the case of spots, via the idiom 'x.' For example, we could +have defined SmartHCP as: +
    +
    +holdingProc SmartHCP {ace King QuizShow j len} {
    +      ...
    +}
    +
    +
    +They can occur in any order. +

    +For spot cards, you can use arguments named "x2", "x3", "x4", .., and "x9." +The ten can be passed as "x10" or "T." +

    +One last possible parameter is anything beginning with an "s" or "S", which means +that the holding is passed as a string. This is useful when you already have +a hash table somewhere for stored data. For example, the 'ddeval' code which +comes with iDeal and Deal 3.1 uses a table of raw data created in +advance. +


    +
    +Silhouette +Thomas Andrews +(deal@thomasoandrews.com) +Copyright 1996-2008. Deal is covered by the +GNU General Public License. +

    +Plane Dealing graphic +above created using +POV-Ray. +

    + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/hooks.html /tmp/sFHmVEdqkv/deal-3.1.4/html/hooks.html --- deal-3.0.8/html/hooks.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/hooks.html 2008-06-11 02:20:28.000000000 +0530 @@ -0,0 +1,3 @@ +Hooks + +

    Hooks: Not yet implemented or documented

    diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/index.html /tmp/sFHmVEdqkv/deal-3.1.4/html/index.html --- deal-3.0.8/html/index.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/index.html 2008-06-11 02:20:28.000000000 +0530 @@ -0,0 +1,91 @@ + + + + + Deal 3.1 Home Page + + + + + + + + + + + + + +
    +

    Deal 3.1

    +

    A bridge hand generator

    by Thomas Andrews

    +

    Latest version: 3.1.4

    +
    +Features: +
    +
  • Easy to use for quick, simple dealing +
  • Customizable output formats +
  • Infinitely extensible via TCL +
  • Easily portable to most platforms +
  • Free (GNU public license) +
  • Deal 3.1
    +
    +
    +
    +

    Information found on these pages:

    + + +

    Things you can do with Deal:

    +
      +
    • Dealing: Generate random deals for your club. +
    • Bidding practice: Practice general bidding, + or specific situations +
    • Settle arguments: Was bidding game wise over + that limit raise? Was that the spade nine really the best lead? +
    • Statistical experiments: How often does a bid + occur? How often does this slam make? +
    • "Problem solver" contests: Solve magazine + problems, and learn where even the experts go wrong +
    • Interface with other programs: Deal 3.1 comes + with the ability to call the GIB double dummy solver. +
    + +

    What is Tcl?

    + +Tcl, pronounced "tickle," stands for "Tool command language." +If you are a Windows user, think of it as the Unix equivalent to +Visual Basic. But, unlike Visual Basic, Tcl works on almost all +operating systems, not just those made by Bill Gates. +

    +Tcl is used in a variety of different software, from testing tools +to web software (AOL Server, Vignette) and, of most interest to bridge +players, Floater, the free online bridge program. +

    +The people in charge of Tcl are +Scriptics. But don't let their web site fool you - the basic software is free. + +

    + +


    +
    +Silhouette +Thomas Andrews +(deal@thomasoandrews.com) +Copyright 1996-2008. Deal is covered by the +GNU General Public License. +

    +Plane Dealing graphic +above created using +POV-Ray. +

    diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/license.html /tmp/sFHmVEdqkv/deal-3.1.4/html/license.html --- deal-3.0.8/html/license.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/license.html 2008-06-11 02:20:28.000000000 +0530 @@ -0,0 +1,43 @@ + + + + + + + + + +Deal Licensing News + + + + +
    +

    Deal Licensing News

    +Deal is now licensed under the +GNU public license. +

    This means, very roughly, that +anybody may download it for free, but, if they redistribute it, they +must include the source code, including any changes they made to the +source code, with this same license. +

    +Past versions of Deal came with the license, "Free for +non-commercial use." This was too vague - what is a "commercial +use?" +


    +
    +Silhouette +Thomas Andrews +(deal@thomasoandrews.com) +Copyright 1996-2008. Deal is covered by the +GNU General Public License. +

    +Plane Dealing graphic +above created using +POV-Ray. +

    +
    + + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/look.css /tmp/sFHmVEdqkv/deal-3.1.4/html/look.css --- deal-3.0.8/html/look.css 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/look.css 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,69 @@ +body { + background-image: url(graphics/idealbg.jpg) +} + +A:link { + color: #663300; +} + +A:visited { + color: #990000 ; +} + +A:hover { + color: white ; + background: #336699 +} + +A:active { + color: #000099 +} + +A.image:hover { + background: transparent ; +} + +div.header { + text-align: center +} + +span.alert { + color: red ; + background: transparent +} + +span.code { + font-family: Courier, monospace ; + white-space: nowrap ; +} + +div.codesample, pre.codesample { + width: 0 ; + font-family: Courier, monospace; + font-size: small ; + white-space: pre ; + margin-left: 10% ; + padding-bottom: 1em; + padding-top: 1em; + margin-top: 0.25in ; + margin-bottom: 0.25in ; + border-top: thin groove ; + line-height: 120%; + border-bottom: thin groove +} + +div.back { + margin-left: 5% ; + margin-right: 5% ; + text-align: right +} + +div.toplevel,table.toplevel { + width:90% ; + margin-left: 5%; + margin-right: 5%; +} + +span.reference { + font-style: italic ; +} diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/newfeatures.html /tmp/sFHmVEdqkv/deal-3.1.4/html/newfeatures.html --- deal-3.0.8/html/newfeatures.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/newfeatures.html 2008-06-11 02:20:28.000000000 +0530 @@ -0,0 +1,228 @@ + + + + + Deal 3.1 - New Features + + + + + + + +Back to Deal Top Page. + + + +
    +

    Deal 3.1 - New Features

    +
      +
    • General performance improvements using Tcl 8.x features +
    • Fast holding procedures +
    • Interface to the GIB double dummy solver +
    • More input formats, and extensible input formats +
    • Smart hand stacking +
    + +
    + + +

    Performance Improvements

    +There are a number of performance improvements in Deal 3.1. + +

    Tcl 8.x Improvements

    +In early releases of Tcl (7.x and earlier) the interpreter treated +everything as a string. That meant that Tcl data and procedures were +regularly parsed and reparsed, which made it a fairly slow language. +Tcl 8.x changed that - it uses +internal objects which have optional string representations. +

    +This means that the first time you pass the string "AK4" to a +Deal procedure, it will parse it into an +internal represention, and then never parses it again. The +internals of Deal now take advantage of this +in quite a lot of places. + +

    Fast and general holding procedures

    +Many bridge evaluators can be seen as evaluating the holdings +in each suit, and then adding up the values. For example, +in the hand: +
    +  Spades: AKx
    +  Hearts: KQJ
    +Diamonds: xxxx
    +   Clubs: Axx
    +
    +We compute the high card points as 7, 6, 0, and 4, in spades, hearts, +diamonds, and clubs, for a total of 17 points. We compute losers +in the suits as 1, 1, 3, and 2, for a total of 7 losers. +

    +In Deal 2.0, you could define a very limited set of procedures of this +sort - the so-called vector procedures. +You could, for example, define "high card points" or "controls," but +not "losers." +

    +In Deal 3.1, virtually any such procedure can be written. +

    +See seperate document for more details. + +

    Other Features

    +

    GIB interfaces

    + +Deal 3.1 now has a a set of tools for people who own +GIB. Specifically, +it provides a procedure for determing the number of tricks +available on a deal, double dummy. +

    +See separate document for details. +

    Input formats

    +Deal 3.1 now lets you read deals from a file easily. It is +also easy to write extensions which change the way Deal 3.1 +reads from files or generates deals. +

    +To access an input format, you can either add the line: +

    +deal::input formatName [args...]
    +
    +or, from the command line, use the -I switch: +
    +deal -I "FormatName[ args...]" ...
    +
    +Deal 3.1 includes the following input formats: +
    +
    line +
    This reads in deals in the format written by deal with the -l +flag. For example, you can generate a file of 1000 deals then run two +seperate queries on the file with: +
    +deal -l 1000 > sample.txt
    +deal -I "line sample.txt" -i query1.tcl > out1.txt
    +deal -I "line sample.txt" -i query2.tcl > out2.txt
    +
    +If no file is given, the lines are read from standard input. +

    +

    giblib +
    Matt Ginsberg has made available a large file of 700,000+ deals +with double dummy data. This input format lets read this data +file sequentially. Calls to the GIB procedure gib::tricks +take the data from this file, rather than calling the double-dummy +solver. +
    +deal::input giblib [filename]
    +
    + +If no file is given, Deal looks in the +current directory for a file named library.dat. +

    +The data file is not included in this release - it's really huge. +See the +GIB research project page for more details. +

    smartstack +
    The deal of the smartstack is to find certain rare +types of deals very quickly, not using the standard dealing techniques, +but using a more complicated and data-heavy approach. +Smart stacking is documented +seperately below. +
    +To add a new input format named Foo, you write a file named +input/Foo.tcl which contains a Tcl package named Foo +with procedures called set_input and next. +See the input formats included with Deal for examples. +The next procedure should return an error when it has +reached the end of input. +

    +An input format does not have to read from a file. For example, +the smartstack code is a factory which builds deals +on the fly with one hand fitting a certain condition. + +

    Smart Stacking

    +Deal, by default, just keeps dealing hands until it finds one that +fits a pattern. This can be too slow sometimes when looking for +specific hands. +

    +Suppose we want north to have a balanced hand with 22 or 23 high card +points. We can force this +by using the smartstack input format: +

    +deal::input smartstack north balanced hcp 22 23
    +
    +The arguments tell the stacker to randomly build north hands that +are balanced with high card points in the range of 22 and 23. +

    +Any shape class can be used in the place of balanced, +and any holding procedure can be used in place of hcp +in the above example. If an evaluator is not passed in, there +is no range requirement. If you wish no shape restrictions, +use the shapeclass AnyShape. +

    +Specific cards can still be placed in specific hands: +

    +        deal::input smartstack north balanced hcp {20 21}
    +	south is K52 KJ3 98542 AK
    +        north gets AS QS QH
    +
    +Smart stacking can also put restrictions on specific suits: + +
    +deal::input smartstack north balanced hcp 20 21
    +smartstack::holding diamonds controls 2 3
    +
    +This requires north to have 2-3 controls in diamonds. +

    +The tighter the restrictions, the faster Deal +will be able to build hands which satisfy them. +

    +Any additional conditions you want to place on any of the hands can +still be placed in main, as usual. +

    Performance issues

    +Smart stacking costs a lot of initial overhead. For example, on +my Linux computer, ex/1-shapeclass.tcl in the release +has no startup +time, and takes about 0.014 seconds per match found. The equivalent +script using smartstack, ex/1-stack.tcl, +takes almost 13 seconds at startup +time, but then takes onlu 0.002 seconds per match found. So +if I'm generating 10,000 with these deals, it takes about +36 with smart stacking, and about 140 seconds without. But if +I'm generating 1,000, they take about the same time, and if I'm generating +only 10, using smart stacking is costly. +

    +Is smart stacking ever useful when dealing with small sample requests? +Definitely - if the hand is *very* specific and/or rare. For example, +the two above scripts use a point range of 11-15, but if they are +changed to seek 21-22 hcp hands of the same shape, they both take about 10 +seconds to find 10 deals, but the smart stacker takes only 14 seconds +to find 1,000, while the standard algorithm takes 1,000 second! +

    +Originally, I was going to call the "smart stacker" by the name, +"deal factory." Like a real world factory, there is a large startup +cost, but after it is built, it builds deals to specification far +faster. The more specific your needs and/or the larger supply you +need, the more useful that initial investment is. +

    +If I use smartstack to generate balanced hands with 20 points, it has +a startup time of about 20 seconds. If I request balanced 25-counts, +17 seconds, balanced 29-counts 12 seconds. After startup, the amount +of time to find examples is almost nil. Without smartstack, it takes +about five minutes to generate ten examples of balanced 29-counts. +With smartstack, only 13 seconds. +

    +For the evaluator, don't use one that has too many possible values, +or the size of the stacker's table balloons horribly. +For example, in each suit, the values possible for hcp are +0-10. But if you were to use something really complex with floating +point values, you might screw the pooch. No smart checking is applied +when building the table, either, so Deal might just appear to churn. +


    +
    +Silhouette +Thomas Andrews +(deal@thomasoandrews.com) +Copyright 1996-2008. Deal is covered by the +GNU General Public License. +

    +Plane Dealing graphic +above created using +POV-Ray. +

    diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/Optimization.html /tmp/sFHmVEdqkv/deal-3.1.4/html/Optimization.html --- deal-3.0.8/html/Optimization.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/Optimization.html 2008-06-11 02:20:27.000000000 +0530 @@ -0,0 +1,131 @@ + + + + + + + + + + Optimizing Dealing - Some Ideas + + + + + + +
    +

    Optimizing Dealing - Some Ideas

    +
    +

    +After doing some profiling, I found 'deal' spends most of its time +in the random number generator. This is apparently a problem +other people have encountered, and at least one of the publicly +available dealers actually cheats around this somewhat by using +a bad methodology. +

    +To stay out of the random number generator as much as possible, +I made improvements so that 'deal' only deals cards to a hand +when information is requested about that hand. +

    +For example, with the script: +

    +main {
    +    #west has 15-17 HCP and east has a 5-card heart suit
    +    reject unless {[balanced west]}                     # line A
    +    set whcp [hcp west]                          
    +    reject if {$whcp>17} {$whcp<15}
    +    accept if {[hearts east]>=5}                        # line B
    +}
    +
    +Each time through the main loop, 'deal' starts with no cards dealt. +When it reaches line (A), a question is asked about the west hand. +No cards have been dealt yet, so 'deal' parcels out 13 random cards +to west (requiring 13 calls to the random number generator.) +'Deal' then checks whether the hand is in fact balanced, and if not, +it rejects the hand. +

    +If the hand is balanced, 'deal' computes the HCP, rejecting the deal +if west isn't between 15 and 17 HCP. Only at line (B) do we request +that east have 5 or more hearts, at which point "deal" gives 13 cards +to east and then checks the conditional. If the hand is accepted, +the rest of the deal is completed. +

    +Under this implementation, you can often come close to tripling the speed of +complex queries. +

    +Other optimizations are possible. +

    +Let's say you want to deal hands where south has a solid seven card +or longer minor suit and no side aces or kings, and north holds: +"S: AK H: K52 D: 98765 C: 962". To do this simulation +now, we place north's card, and then deal the rest of south's cards, +rejecting deals which don't satisfy our conditions. This might take a while. +

    +Theoretically, we could do this much faster by picking a shape for south +using relative probabilities, and deal him cards which fit that shape. +So, for instance, the number of ways to assign random cards to north +to give north a 3-2-7-1 shape is +(11 choose 3) * (10 choose 2) * (8 choose 7) * (10 choose 1)=594000, +while the number of ways for him to have 3-2-1-7 shape is (11 choose 3) * +(10 choose 2) * (8 choose 1) * (10 choose 7)=7128000. +

    +It should come as no surprise that it is more likely that south has seven clubs +than that south has seven diamonds, given north's shape. +

    +Since there are only 560 total possible shapes without any +restrictions, we can certainly run through all possible shapes and determine +their relative odds. Then we can pick one of these possible shapes +randomly, with the proper probability distributions, and assign cards at +random, suit by suit, to bring the south hand to the proper shape. At this +point, we check to determine that the other properties are met. +

    +This would certainly greatly improve the performance in certain "rare +hand" situations. It's not clear how much it could improve more +general randomizations. What if we simply need north to be balanced? +Or for north to have a 5-card major? Would this sort of optimization +improve things? +

    +Also, this methodology makes it much harder to *prove* that the hand +generator is correct. The code to handle the probability computations +has to be impeccable. +

    +Lastly, I can't see any way to automatically get the hand shape information +needed for such optimizations; if I controlled the parser, I might be +able to intelligently glean the information from the specification, but +since I've chosen Tcl as my scripting language, I'm somewhat stuck in +that regard. The user will almost certainly have to provide the +optimization request directly. +

    +

    Why optimize?

    +There is a logical argument against such optimizations, on the other hand. +What are we trying to learn if we are looking at a sample of one in a million +hands? Let's say you play gambling 3NT, and partner opens 3NT with you holding +S: Axxx H: KQx D: Q C: xxxxx. +If we try to simulate this, assuming partner has +7+ solid clubs and no side aces, we might not get a proper hand for a +very long time. On the +other hand, the number of possible hands where partner has "fudged" his +call with AKJTxxxx of diamonds or with only six clubs is considerably higher. +In simulations where hands are not being found after tens of thousands of tries, +it is often right to loosen the parameters. +

    +On the other hand, if you are trying to settle an argument like, "Well, if +you had your bid, that would have been a good slam," then the tighter +parameters might be right, in which case optimizations might be necessary. +


    +
    +Silhouette +Thomas Andrews +(deal@thomasoandrews.com) +Copyright 1996-2008. Deal is covered by the +GNU General Public License. +

    +Plane Dealing graphic +above created using +POV-Ray. +

    +
    + + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/quickdos.html /tmp/sFHmVEdqkv/deal-3.1.4/html/quickdos.html --- deal-3.0.8/html/quickdos.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/quickdos.html 2008-06-11 02:20:28.000000000 +0530 @@ -0,0 +1,641 @@ + + + + + + + + + + + Deal - An Introductory Tutorial for Windows + + + + + + + + + +
    Plane Dealing image

    Deal 3.1

    +

    An Introductory Tutorial for Windows

    +Covering:
      +
    • Dealing hands +
    • Stacking hands +
    • Output formats +
    • Basic scripting with Tcl +
    +
    +
    +
    +

    Prologue

    +First things first, you will need to download +Deal and install it. The rest of this tutorial assumes you have +already done this. +

    +**Warning** It takes careful eyes, at least on the version of Netscape I am +using, to distinguish between normal parentheses, (), and curly +parentheses, {}. Almost all of the paretheses in the script +listings below are curly parentheses. +

    Basic Dealing - The Command Line

    + +

    Basic Dealing - Scripting

    + + +

    Basic Dealing

    + +

    Dealing hands

    +

    +Start a DOS window (or Command Prompt window on NT) and change your directory +to the location where Deal was installed. +

    +C:\> cd "C:\deal30"
    +
    +C:\deal30> 
    +
    + +The most basic version of deal runs with no conditions set on the deal, +and generates 10 deals: +
    +C:\deal30> deal
    +
    + +The output probably scrolled off the screen, so you might want to do +
    +C:\deal30> deal | more
    +
    + +to allow scrolling, or: +
    +C:\deal30> deal > out.txt
    +
    + +which saves the output from deal to the file, out.txt. + +

    +If you give "deal" a number on the command line, it generates that many +deals: +

    +C:\deal30> deal 2
    +          S : T6542
    +          H : A4
    +          D : A93
    +          C : KT2
    + S : Q83            S : K97
    + H : 9873           H : K52
    + D : JT7            D : Q64
    + C : Q74            C : J863
    +          S: AJ
    +          H: QJT6
    +          D: K852
    +          C: A95
    +---------------------------
    +          S : ---
    +          H : 975
    +          D : AT986
    +          C : T9753
    + S : J7             S : AKT6         
    + H : T32            H : KJ864        
    + D : K32            D : J74          
    + C : AJ842          C : 6            
    +          S: Q985432
    +          H: AQ
    +          D: Q5
    +          C: KQ
    +---------------------------
    +C:\deal30> 
    +
    +In this example, Deal dealt two hands, as requested. +

    +

    Stacking a hand

    +Okay, let's take another example. Suppose you opened 3H on the following +hand in a team game: +
    +S: ---
    +H: KQJT62
    +D: T9876
    +C: 84
    +
    +You stumble into a six heart contract, when in fact, six diamonds has better +play opposite partner's hand. Partner swears that opening 3H with this +hand loses more often than it wins. You disagree. How do you resolve +this? +

    +Deal can help. Just run it as: + +

    +C:\deal30> deal -S "- KQJT62 T9876 84" 25
    +          S : KJ2
    +          H : 954
    +          D : A5
    +          C : AKT65
    + S : T9764          S : AQ853        
    + H : A              H : 873          
    + D : J2             D : KQ43         
    + C : QJ973          C : 2            
    +          S: ---
    +          H: KQJT62
    +          D: T9876
    +          C: 84
    +---------------------------
    +          S : KJT64
    +          H : 5
    +          D : K42
    +          C : AQ65
    + S : 9875           S : AQ32         
    + H : A93            H : 874          
    + D : AJ5            D : Q3           
    + C : KJ9            C : T732         
    +          S: ---
    +          H: KQJT62
    +          D: T9876
    +          C: 84
    +---------------------------
    +	.... (rest of 25 hands ellided) ...
    +
    + +You inspect the 25 hands dealt, guessing how the auction would +proceed. Sometimes, your answers will be inconclusive, but more +often one or both partners learns something from the simulation. +

    +There are, of course, also -N, -E, and -W options +for the other three seats. +

    Formatting output

    +Perhaps you'd like the hands to be written in some other format. +This can be arranged fairly easily. +

    +For example, suppose you wish to deal 8 hands for practice bidding +with partner. In that case, you would use the "practice" format: + +

    +C:\deal30> deal -i format/practice 8 > out.all
    +C:\deal30> more out.east
    +                              east hands
    +============================================================================
    +     *1*                 *2*                 *3*                 *4*
    +  S 84                S T7                S QT3               S AJ9654
    +  H J8642             H Q65               H Q983              H K8
    +  D Q843              D KJ42              D 865               D J
    +  C 73                C T842              C AJ9               C K532
    +
    +=============================================================================
    +     *5*                 *6*                 *7*                 *8*
    +  S J7                S 85                S AQT764            S 3
    +  H Q9864             H AK4               H K5                H JT4
    +  D 874               D A764              D 9                 D QJT86
    +  C J85               C Q862              C T976              C AK82
    +
    +=============================================================================
    +
    + + +The -i flag tells Deal to include the named file, +in this case, the file named format/practice. This file redefines +the output format. At the end of this run, you should get five files: +out.north, out.east, out.south, +out.west, and out.all. +

    +Now you can print out these files, pass them out amongst four people, +and practice your bidding, using out.all at the end to make +a double dummy assessment of the auction results. +

    +What if you only have two people, and you want to practice uninterrupted +auctions? You could print out the north and south hands, and practice +with those, but that would be an artificial +test, because you obviously can't assume an uncontested auction for +arbitrary deals. +

    +When we learn about writing scripts for Deal, we will solve with this problem by filtering out hands we think would lead to competitive +bidding. +

    +What are the formats that come with the kit? Well, you can simply list +the format sub-directory to find out. Here are the ones there +as of this writing: +

    +
    none +
    This script set the formatting routine to a null routine. + Not useful, so far, but useful, for example, when doing + statistical analysis. +
    numeric +
    This formatter writes the deal as a line which looks something + like: +
    +3031333123220300123320212213021202022103101101003113
    +
    + It's a line of 52 numbers, where 0, 1, 2, and 3 mean + north, east, south, and west, respectively. + The first digit tells where the ace of spades goes, the + second digit tells where the king of spades goes, etc. +
    okb +
    This formatter writes the output with the same spacing as the old +OKbridge screen. +
    practice +
    We've just seen this one - for seperating out hands for +practice bidding. +
    +There is one last output format, which, for historical reasons, +has its own command line switch, -l. + +
    +C:\deal30> deal -l 3
    +AJ9 976532 K92 A|86 A AT87 987653|Q732 JT8 543 T42|KT54 KQ4 QJ6 KQJ
    +K94 J93 QJ3 7653|A8 A8765 97 KQ98|JT2 Q AKT8654 T4|Q7653 KT42 2 AJ2
    +KJ753 T A4 KQ932|AQ94 AJ92 QT87 J|86 Q764 K9653 74|T2 K853 J2 AT865
    +C:\deal30>
    +
    + +In the past, this was the only way to get alternate formats. The +user would pipe this output to another program, usually a Perl script, +which would parse each line and format the output. +

    +With the addition, in v2.0 of Deal, of user-configurable formatting, +this usage becomes obselete, but I'm leaving the feature because +it has one other use, which will be mentioned later. + +

    Basic Dealing - Scripting

    +

    Our First Script

    +Let's say we want a selection of deals in which north holds a one spade +opener. For now, we will use a crude definition for an opening 1S call - +we will require north to have 5 or more spades and 12 or more points. +

    +Here is the script we write (to a file we'll call onespade): + +

    +main {
    +  if {[spades north]>=5 && [hcp north]>=12} { accept }
    +  reject
    +}
    +
    + + +

    Running the script

    +We run this code by saying: + +
    +C:\deal30> deal -i onespade 2
    +          S : AKQT5
    +          H : A7
    +          D : 8542
    +          C : AT
    + S : 64             S : J98          
    + H : K943           H : 862          
    + D : J              D : AK963        
    + C : KQ8732         C : 54           
    +          S: 732
    +          H: QJT5
    +          D: QT7
    +          C: J96
    +---------------------------
    +          S : AQT73
    +          H : A
    +          D : AJ987
    +          C : 73
    + S : K5             S : J42          
    + H : JT8632         H : KQ95         
    + D : Q63            D : KT4          
    + C : 85             C : K92          
    +          S: 986
    +          H: 74
    +          D: 52
    +          C: AQJT64
    +---------------------------
    +
    + +

    How the script works

    +By default, Deal accepts all hands. With the main code in +onespade, we tell Deal to override that behavior. +

    +This is similar to the way we used scripts to override Deal's +default formatting. Note, we even use the same flag, -i, +to load our formatters and onespade. +

    +What does this main code do? It is run after every deal +is complete, and used to evaluate the hand. In this case, we have only +two lines of code: + +

    +if {[spades north]>=5 && [hcp north]>=12} { accept }
    +reject
    +
    + +The expression [spades north] returns the number of spades +in the north hand. The expression [hcp north] returns +the number of HCP (high card points) in the north hand. The "&&" +is called a logical "and" operator, which returns true if the conditionals +on both sides of it are true. +

    +If the entire expression: +

    +[spades north]>=5 && [hcp north]>=12
    +
    +evaluates as true, the "accept" function is called. This causes +Deal to exit the "main" code and format the hand. +

    +If the expression evalutes as false, Deal goes to the next line +of code, which calls the "reject" function. This tells Deal to +discard the hand, and exit the "main" code. +

    +Deal keeps trying until the requested number of deals is accepted. +

    +What happens if a deal is not explicitly accepted or rejected? +If neither accept nor reject is called, the deal +is rejected. That means that in our first script, the reject +call was redundant, and we could have simply written the script as: + +

    +main {
    +  if {[spades north]>=5 && [hcp north]>=12} { accept }
    +}
    +
    + +

    Monitoring Deal

    +You might want to try running this script with the -v switch: +
    +C:\deal30> deal -v -i onespade
    +
    +The -v flag tells Deal to give a progress report, which looks +like: + +
    +...
    +Deal 1 found after 2 tries
    +...
    +Deal 2 found after 21 tries
    +...
    +Deal 3 found after 31 tries
    +
    + +This will give you some idea of how rare your condition is, and +also gives a good progress report when Deal is +writing to a file or running with a "silent" format, like +format/none. These status messages are written to "stderr", +which means that the output from Deal can be +redirected to a file without obscuring these messages.

    + +

    Using formats with your script

    + +If we wanted to use another output format with this script, we could do so +on the command line, as follows: +
    +C:\deal30> deal -i format/practice -i onespade
    +
    +Or, alternately, we could add an explicit "source" command to our +script: + +
    +source format/practice
    +
    +main {
    +        if {[spades north]>=5 && [hcp north]>=12} { accept }
    +}
    +
    + + +In fact, this second format unveils the secret of the -i flag - +it is simply a request to "source" a file. In fact, if you were to +write your own formatter, you would not have to put the file in +the "format" directory. +If you put it in the current directory, you could then say: +
    +C:\deal30> deal -i myformatter 100
    +
    +and it would work fine. The "format" subdirectory is just a convenience. +You will often want to re-use a format, and placing them in one place +lets you find out which formats are available. + +

    Stacking hands with a script

    + +Let's say you were dealt the hand: +
    +S: ---
    +H: 98532
    +D: A864
    +C: T962
    +
    +the previous day at a Swiss Teams event. +

    +Your partner opened 1S, and, playing 2/1 Game Force, you chose to +pass. This turns out well for you on this deal, because at the other +table, the opponents played in three spades, down 1. Afterwards, +you wonder if you really made the right decision. Your intuition +tells you that it was the right choice, but you realize there are +risks in both passing and bidding, and you know that intuition is +very bad at assessing levels of risk. +

    +Deal can help. Using our script, onespade, +we can run the following simulation: +

    +C:\deal30> deal -S "- 96532 A864 T962" -i onespade
    +
    +The -S flag stacks the south hand with the hand you held, +and the script runs exactly the same thereafter. You can now peruse +the output to see whether it was a good idea or a bad idea to pass. +

    +As with the formatting, we can also do our deck-stacking in our script. + +

    +south is - 98532 A864 T962
    +
    +main {
    +  if {[spades north]>=5 && [hcp north]>=12} { accept }
    +}
    +
    + + +Notice, we do our deck-stacking outside of the evaluation loop. +Remember, the main expression is responsible for evaluating the deals +after Deal finishes dealing the hands. +We obviously want the stacking instruction to occur before +dealing occurs, so the stacking command must be outside the main +evaluation. +

    +

    A partial list of routines

    +For evaluation routines, we have seen the hcp and spades +routines, as well as the "accept" and "reject" directives. +Obviously, there are also routines called hearts, + diamonds, and clubs which count their respective +suits. The following functions are also built-ins: +
    +
    controls
    This function computes the number of +controls held by a hand. +
    losers
    This function does a crude computation of +the losing trick count for a hand (it actually compute's half-losers, +so when [losers south] returns 14, that really means 7 losers.) +
    balanced
    This function returns true (1) if the +hand name passed is balanced in the usual sense - no shortness, at most +one doubleton, and no five-card major. It returns false (0) otherwise. +
    semibalanced
    Returns true (1) if the hand passed +has no shortness and no six-card major or seven-card minor, and false +(0) otherwise. +
    +The three functions, controls, hcp, and losers, +all have the property that we can compute them one suit at a time, and +sum the result for the entire hand. The implementation takes advantage +of this and allows the user to request these values for specific suits: + +
    +main {
    +  if {[hcp south hearts spades]>10} {accept}
    +}
    +
    + +This script accepts a deal if south has ten or more points in hearts +and spades. controls and losers can be used similarly. +Any function of this sort we will call "additive." We will see later that +we can define a wide class of interesting +additive functions. +

    +The functions balanced and semi_balanced are entirely +dependent on the shape of the hand, and not on which cards the hand holds. We +will call these "shape functions." We will find out later how to +define incredibly fast shape functions. + +

    A Second Script - defining Tcl procedures

    + +Let's say we want to write a script which accepts a deal if north +has a strong notrump (15 to 17 range) and south has about invitational +values and a 5-card major. + +

    +Our script , which we will call jacobytest might look something like: + + +

    +# In deal 2.0, you don't need this next line, but deal 3.1 does - 
    +# without this line, the "balanced" routine is not defined.
    +
    +main {
    +	if {![balanced north]} {reject}
    +
    +	set hn [hcp north]
    +	if {$hn>17 || $hn<15} {reject}
    +
    +	set hs [hcp south]
    +	if {$hs<8 || $hs>9} {reject}
    +
    +	if {[spades south]==5 || [hearts south]==5} { accept }
    +}
    +
    + + +We have used one of our new functions here, balanced, as +well as a new Tcl feature, variables. We could, of course, not used +variables, but then we would have had to write the lines: +
    +if {[hcp north]>17 || [hcp north]<15} {reject}
    +
    +That is going to be slower, with one more function call. Not appreciable +today, with a simple query, but when you might be processing a million or +more hands at a time, you learn to be frugal. +

    +Suddenly, you realize you want to test this situation with a 12-14 notrump, +instead. Or you realize you often want to reuse this concept. You +can do so by defining Tcl procedures. +

    + +

    +proc notrump {hand min max} {
    +  if {![balanced $hand]} {return 0}
    +
    +  set hc [hcp $hand]
    +  if {$hc < $min || $hc>$max} { return 0}
    +
    +  return 1
    +}
    +
    +proc jacobyinvite {hand ntmin ntmax} {
    +
    +  if {[spades $hand]!=5 && [hearts $hand]!=5} {return 0}
    +
    +  set hc [hcp $hand]
    +  if {$hc+$ntmin <= 25 && $hc+$ntmax>=24} { return 1 }
    +
    +  return 0
    +
    +}
    +
    +set NTmin 12
    +set NTmax 14
    +
    +main {
    +  if {![notrump north $NTmin $NTmax]} { reject }
    +  if {[jacobyinvite south $NTmin $NTmax]} { accept }
    +}
    +
    + +You are unlikely to need the jacobyinvite function +beyond this script, but the notrump function will be something +you will want +to use again and again. You might even put it in a library of routines, called +mylibrary and source that library every time you need one or more +of the routines for a script: +
    +source mylibrary
    +
    +rather than rewriting the routine every time. +

    +In fact, the Deal kit comes with a file called lib/utility.tcl, which is just such a library of routines the author of Deal + found himself re-using. + +

    Revisiting accept and reject

    +The directives, accept and reject, can be used +in more complicated ways that are sometimes more efficient and +sometimes more readable. +

    +Here is the main script from the notrump example +using some odd constructs: +

    +main {
    +  reject unless {[notrump north $NTmin $NTmax]}
    +  accept if {[jacobyinvite south $NTmin $NTmax]}
    +}
    +
    +Some people might find this more readable. The first line says +we are going to reject the deal unless the condition +is true. The second conditional says we are going to accept +the deal if the expression evaluates as true. +

    +Multiple arguments are allowed. The following command: +

    +reject unless {expr1} {expr2} ... {exprn}
    +
    +runs through all of the expressions until it finds one which evaluates +as "true". If it does not find a true value, it rejects the hand. +Otherwise, deal goes on to the next line in evaluating main. +

    +For reject if the deal is rejected if any one of the expressions +is true. Similarly, accept if accepts a deal if one of the +expressions is true. For accept unless, the deal is accepted +unless the one of the expressions is true. + +


    +This concludes the Introductory Tutorial. I hope +it inspires you to check out the Deal - Advanced +Guide and to learn more about Tcl. +Or check out the index of all deal commands. +
    +
    +Silhouette +Thomas Andrews +(deal@thomasoandrews.com) +Copyright 1996-2008. Deal is covered by the +GNU General Public License. +

    +Plane Dealing graphic +above created using +POV-Ray. +

    +
    diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/quickstart.html /tmp/sFHmVEdqkv/deal-3.1.4/html/quickstart.html --- deal-3.0.8/html/quickstart.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/quickstart.html 2008-06-11 02:20:28.000000000 +0530 @@ -0,0 +1,599 @@ + + + + + + + + + + + Deal - An Introductory Tutorial + + + + + + + + + + + + +
    Plane Dealing image +
    +

    Deal 3.1

    +

    An Introductory Tutorial

    +
    +Covering:
      +
    • Dealing hands +
    • Stacking hands +
    • Output formats +
    • Basic scripting with Tcl +
    +
    + +
    +
    +

    Prologue

    +First things first, you will need to download +Deal and build it. The rest of this tutorial assumes you have +already done this. +

    +**Warning** It takes careful eyes, at least on the version of Netscape I am +using, to distinguish between normal parentheses, (), and curly +parentheses, {}. Almost all of the paretheses in the script +listings below are curly parentheses. +

    Basic Dealing - The Command Line

    + +

    Basic Dealing - Scripting

    + + +

    Basic Dealing

    + +

    Dealing hands

    +At your command or DOS prompt, you say, deal. By default, this deals ten hands. +If you give deal a numeric argument, it will deal that number +of hands you specify. +
    +$ deal 2
    +          S : T6542
    +          H : A4
    +          D : A93
    +          C : KT2
    + S : Q83            S : K97          
    + H : 9873           H : K52          
    + D : JT7            D : Q64          
    + C : Q74            C : J863         
    +          S: AJ
    +          H: QJT6
    +          D: K852
    +          C: A95
    +---------------------------
    +          S : ---
    +          H : 975
    +          D : AT986
    +          C : T9753
    + S : J7             S : AKT6         
    + H : T32            H : KJ864        
    + D : K32            D : J74          
    + C : AJ842          C : 6            
    +          S: Q985432
    +          H: AQ
    +          D: Q5
    +          C: KQ
    +---------------------------
    +$
    +
    + +Deal dealt two hands, as requested. +

    +

    Stacking a hand

    +Okay, let's take another example. Say you opened 3H on the following +hand in a team game: +
    +S: ---
    +H: KQJT62
    +D: T9876
    +C: 84
    +
    +You stumble into a six heart contract, when in fact, six diamonds has better +play opposite partner's hand. Partner swears that opening 3H with this +hand loses more often than it wins. You disagree. How do you resolve +this? +

    +Deal can help. Just run it as: +

    +$ deal -S "- KQJT62 T9876 84" 25
    +          S : KJ2
    +          H : 954
    +          D : A5
    +          C : AKT65
    + S : T9764          S : AQ853        
    + H : A              H : 873          
    + D : J2             D : KQ43         
    + C : QJ973          C : 2            
    +          S: ---
    +          H: KQJT62
    +          D: T9876
    +          C: 84
    +---------------------------
    +          S : KJT64
    +          H : 5
    +          D : K42
    +          C : AQ65
    + S : 9875           S : AQ32         
    + H : A93            H : 874          
    + D : AJ5            D : Q3           
    + C : KJ9            C : T732         
    +          S: ---
    +          H: KQJT62
    +          D: T9876
    +          C: 84
    +---------------------------
    +	.... (rest of 25 hands ellided) ...
    +
    +You inspect the 25 hands dealt, guessing how the auction would +proceed. Sometimes, your answers will be inconclusive, but more +often one or both partners learns something from the simulation. +

    +There are, of course, also -N, -E, and -W options +for the other three seats. +

    Formatting output

    +Perhaps you'd like the hands to be written in some other format. +This can be arranged fairly easily. +

    +For example, suppose you wish to deal 8 hands for practice bidding +with partner. In that case, you would use the "practice" format: +

    +$ deal -i format/practice 8 > out.all
    +$ cat out.east
    +                              east hands
    +============================================================================
    +     *1*                 *2*                 *3*                 *4*
    +  S 84                S T7                S QT3               S AJ9654
    +  H J8642             H Q65               H Q983              H K8
    +  D Q843              D KJ42              D 865               D J
    +  C 73                C T842              C AJ9               C K532
    +
    +=============================================================================
    +     *5*                 *6*                 *7*                 *8*
    +  S J7                S 85                S AQT764            S 3
    +  H Q9864             H AK4               H K5                H JT4
    +  D 874               D A764              D 9                 D QJT86
    +  C J85               C Q862              C T976              C AK82
    +
    +=============================================================================
    +
    + +The -i flag tells Deal to include the named file, +in this case, the file named format/practice. This file redefines +the output format. At the end of this run, you should get five files: +out.north, out.east, out.south, +out.west, and out.all. +

    +Now you can print out these files, pass them out amongst four people, +and practice your bidding, using out.all at the end to make +a double dummy assessment of the auction results. +

    +What if you only have two people, and you want to practice uninterrupted +auctions? You could print out the north and south hands, and practice +with those, but that would be an artificial +test, because you obviously can't assume an uncontested auction for +arbitrary deals. +

    +When we learn about writing scripts for Deal, we will solve with this problem by filtering out hands we think would lead to competitive +bidding. +

    +What are the formats that come with the kit? Well, you can simply list +the format sub-directory to find out. Here are the ones there +as of this writing: +

    +
    none +
    This script set the formatting routine to a null routine. + Not useful, so far, but useful, for example, when doing + statistical analysis. +
    numeric +
    This formatter writes the deal as a line which looks something + like: +
    +3031333123220300123320212213021202022103101101003113
    +
    + It's a line of 52 numbers, where 0, 1, 2, and 3 mean + north, east, south, and west, respectively. + The first digit tells where the ace of spades goes, the + second digit tells where the king of spades goes, etc. +
    okb +
    This formatter writes the output with the same spacing as the old +OKbridge screen. +
    practice +
    We've just seen this one - for seperating out hands for +practice bidding. +
    +There is one last output format, which, for historical reasons, +has its own command line switch, -l. +
    +$ deal -l 3
    +AJ9 976532 K92 A|86 A AT87 987653|Q732 JT8 543 T42|KT54 KQ4 QJ6 KQJ
    +K94 J93 QJ3 7653|A8 A8765 97 KQ98|JT2 Q AKT8654 T4|Q7653 KT42 2 AJ2
    +KJ753 T A4 KQ932|AQ94 AJ92 QT87 J|86 Q764 K9653 74|T2 K853 J2 AT865
    +$
    +
    +In the past, this was the only way to get alternate formats. The +user would pipe this output to another program, usually a Perl script, +which would parse each line and format the output. +

    +With the addition, in v2.0 of Deal, of user-configurable formatting, +this usage becomes obselete, but I'm leaving the feature because +it has one other use, which will be mentioned later. + +

    Basic Dealing - Scripting

    +

    Our First Script

    +Let's say we want a selection of deals in which north holds a one spade +opener. For now, we will use a crude definition for an opening 1S call - +we will require north to have 5 or more spades and 12 or more points. +

    +Here is the script we write (to a file we'll call onespade): +

    +main {
    +  if {[spades north]>=5 && [hcp north]>=12} { accept }
    +  reject
    +}
    +
    + +

    Running the script

    +We run this code by saying: +
    +$ deal -i onespade 2
    +          S : AKQT5
    +          H : A7
    +          D : 8542
    +          C : AT
    + S : 64             S : J98          
    + H : K943           H : 862          
    + D : J              D : AK963        
    + C : KQ8732         C : 54           
    +          S: 732
    +          H: QJT5
    +          D: QT7
    +          C: J96
    +---------------------------
    +          S : AQT73
    +          H : A
    +          D : AJ987
    +          C : 73
    + S : K5             S : J42          
    + H : JT8632         H : KQ95         
    + D : Q63            D : KT4          
    + C : 85             C : K92          
    +          S: 986
    +          H: 74
    +          D: 52
    +          C: AQJT64
    +---------------------------
    +
    +

    How the script works

    +By default, Deal accepts all hands. With the main code in +onespade, we tell Deal to override that behavior. +

    +This is similar to the way we used scripts to override Deal's +default formatting. Note, we even use the same flag, -i, +to load our formatters and onespade. +

    +What does this main code do? It is run after every deal +is complete, and used to evaluate the hand. In this case, we have only +two lines of code: +

    +if {[spades north]>=5 && [hcp north]>=12} { accept }
    +reject
    +
    +The expression [spades north] returns the number of spades +in the north hand. The expression [hcp north] returns +the number of HCP (high card points) in the north hand. The "&&" +is called a logical "and" operator, which returns true if the conditionals +on both sides of it are true. +

    +If the entire expression: +

    +[spades north]>=5 && [hcp north]>=12
    +
    +evaluates as true, the "accept" function is called. This causes +Deal to exit the "main" code and format the hand. +

    +If the expression evalutes as false, Deal goes to the next line +of code, which calls the "reject" function. This tells Deal to +discard the hand, and exit the "main" code. +

    +Deal keeps trying until the requested number of deals is accepted. +

    +What happens if a deal is not explicitly accepted or rejected? +If neither accept nor reject is called, the deal +is rejected. That means that in our first script, the reject +call was redundant, and we could have simply written the script as: +

    +main {
    +  if {[spades north]>=5 && [hcp north]>=12} { accept }
    +}
    +
    +

    Monitoring Deal

    +You might want to try running this script with the -v switch: +
    +$ deal -v -i onespade
    +
    +The -v flag tells Deal to give a progress report, which looks +like: + +
    +...
    +Deal 1 found after 2 tries
    +...
    +Deal 2 found after 21 tries
    +...
    +Deal 3 found after 31 tries
    +
    +This will give you some idea of how rare your condition is, and +also gives a good progress report when Deal is +writing to a file or running with a "silent" format, like +format/none. These status messages are written to "stderr", +which means that the output from Deal can be +redirected to a file without obscuring these messages.

    + +

    Using formats with your script

    + +If we wanted to use another output format with this script, we could do so +on the command line, as follows: +
    +$ deal -i format/practice -i onespade
    +
    +Or, alternately, we could add an explicit "source" command to our +script: +
    +source format/practice
    +
    +main {
    +        if {[spades north]>=5 && [hcp north]>=12} { accept }
    +}
    +
    + +In fact, this second format unveils the secret of the -i flag - +it is simply a request to "source" a file. In fact, if you were to +write your own formatter, you would not have to put the file in +the "format" directory. +If you put it in the current directory, you could then say: +
    +$ deal -i myformatter 100
    +
    +and it would work fine. The "format" subdirectory is just a convenience. +You will often want to re-use a format, and placing them in one place +lets you find out which formats are available. + +

    Stacking hands with a script

    + +Let's say you were dealt the hand: +
    +S: ---
    +H: 98532
    +D: A864
    +C: T962
    +
    +the previous day at a Swiss Teams event. +

    +Your partner opened 1S, and, playing 2/1 Game Force, you chose to +pass. This turns out well for you on this deal, because at the other +table, the opponents played in three spades, down 1. Afterwards, +you wonder if you really made the right decision. Your intuition +tells you that it was the right choice, but you realize there are +risks in both passing and bidding, and you know that intuition is +very bad at assessing levels of risk. +

    +Deal can help. Using our script, onespade, +we can run the following simulation: +

    +$ deal -S "- 96532 A864 T962" -i onespade
    +
    +The -S flag stacks the south hand with the hand you held, +and the script runs exactly the same thereafter. You can now peruse +the output to see whether it was a good idea or a bad idea to pass. +

    +As with the formatting, we can also do our deck-stacking in our script. +

    +south is "- 98532 A864 T962"
    +
    +main {
    +  if {[spades north]>=5 && [hcp north]>=12} { accept }
    +}
    +
    + +Notice, we do our deck-stacking outside of the evaluation loop. +Remember, the main expression is responsible for evaluating the deals +after Deal finishes dealing the hands. +We obviously want the stacking instruction to occur before +dealing occurs, so the stacking command must be outside the main +evaluation. +

    +

    A partial list of routines

    +For evaluation routines, we have seen the hcp and spades +routines, as well as the "accept" and "reject" directives. +Obviously, there are also routines called hearts, + diamonds, and clubs which count their respective +suits. The following functions are also built-ins: +
    +
    controls
    This function computes the number of +controls held by a hand. +
    losers
    This function does a crude computation of +the losing trick count for a hand (it actually compute's half-losers, +so when [losers south] returns 14, that really means 7 losers.) +
    balanced
    This function returns true (1) if the +hand name passed is balanced in the usual sense - no shortness, at most +one doubleton, and no five-card major. It returns false (0) otherwise. +
    semibalanced
    Returns true (1) if the hand passed +has no shortness and no six-card or longer suit, and false (0) otherwise. +
    +The three functions, controls, hcp, and losers, +all have the property that we can compute them one suit at a time, and +sum the result for the entire hand. The implementation takes advantage +of this and allows the user to request these values for specific suits: +
    +main {
    +  if {[hcp south hearts spades]>10} {accept}
    +}
    +
    +This script accepts a deal if south has ten or more points in hearts +and spades. controls and losers can be used similarly. +Any function of this sort we will call "additive." We will see later that +we can define a wide class of interesting +additive functions. +

    +The functions balanced and semi_balanced are entirely +dependent on the shape of the hand, and not on which cards the hand holds. We +will call these "shape functions." We will find out later how to +define incredibly fast shape functions. + +

    A Second Script - defining Tcl procedures

    + +Let's say we want to write a script which accepts a deal if north +has a strong notrump (15 to 17 range) and south has about invitational +values and a 5-card major. + +

    +Our script , which we will call jacobytest might look something like: + +

    +# In deal 3.1, you don't need this next line, but deal 3.1 does - 
    +# without this line, the "balanced" routine is not defined.
    +
    +main {
    +	if {![balanced north]} {reject}
    +
    +	set hn [hcp north]
    +	if {$hn>17 || $hn<15} {reject}
    +
    +	set hs [hcp south]
    +	if {$hs<8 || $hs>9} {reject}
    +
    +	if {[spades south]==5 || [hearts south]==5} { accept }
    +}
    +
    + +We have used one of our new functions here, balanced, as +well as a new Tcl feature, variables. We could, of course, not used +variables, but then we would have had to write the lines: +
    +if {[hcp north]>17 || [hcp north]<15} {reject}
    +
    +That is going to be slower, with one more function call. Not appreciable +today, with a simple query, but when you might be processing a million or +more hands at a time, you learn to be frugal. +

    +Suddenly, you realize you want to test this situation with a 12-14 notrump, +instead. Or you realize you often want to reuse this concept. You +can do so by defining Tcl procedures. +

    +

    +proc notrump {hand min max} {
    +
    +  if {![balanced $hand]} {return 0}
    +
    +  set hc [hcp $hand]
    +  if {$hc < $min || $hc>$max} { return 0}
    +
    +  return 1
    +}
    +
    +proc jacobyinvite {hand ntmin ntmax} {
    +  if {[spades $hand]!=5 && [hearts $hand]!=5} {return 0}
    +
    +  set hc [hcp $hand]
    +  if {$hc+$ntmin <= 25 && $hc+$ntmax>=24} { return 1 }
    +
    +  return 0
    +}
    +
    +set NTmin 12
    +set NTmax 14
    +
    +main {
    +  if {![notrump north $NTmin $NTmax]} { reject }
    +  if {[jacobyinvite south $NTmin $NTmax]} { accept }
    +}
    +
    +You are unlikely to need the jacobyinvite function +beyond this script, but the notrump function will be something +you will want +to use again and again. You might even put it in a library of routines, called +mylibrary and source that library every time you need one or more +of the routines for a script: +
    +source mylibrary
    +
    +rather than rewriting the routine every time. +

    +In fact, the Deal kit comes with a file called library +, which is just such a library of routines the author of Deal + found himself re-using. +


    +

    Revisiting accept and reject

    +The directives, accept and reject, can be used +in more complicated ways that are sometimes more efficient and +sometimes more readable. +

    +Here is the main script from the notrump example +using some odd constructs: +

    +main {
    +  reject unless {[notrump north $NTmin $NTmax]}
    +  accept if {[jacobyinvite south $NTmin $NTmax]}
    +}
    +
    +Some people might find this more readable. The first line says +we are going to reject the deal unless the condition +is true. The second conditional says we are going to accept +the deal if the expression evaluates as true. +

    +Multiple arguments are allowed. The following command: +

    +reject unless {expr1} {expr2} ... {exprn}
    +
    +runs through all of the expressions until it finds one which evaluates +as "true". If it does not find a true value, it rejects the hand. +Otherwise, deal goes on to the next line in evaluating main. +

    +For reject if the deal is rejected if any one of the expressions +is true. Similarly, accept if accepts a deal if one of the +expressions is true. For accept unless, the deal is accepted +unless the one of the expressions is true. + +

    +


    +This concludes the Introductory Tutorial. I hope +it inspires you to check out the Deal - Advanced +Guide and to learn more about Tcl. +Or check out the index of all deal commands. + +
    +
    +Silhouette +Thomas Andrews +(deal@thomasoandrews.com) +Copyright 1996-2008. Deal is covered by the +GNU General Public License. +

    +Plane Dealing graphic +above created using +POV-Ray. +

    +
    + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/reference.html /tmp/sFHmVEdqkv/deal-3.1.4/html/reference.html --- deal-3.0.8/html/reference.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/reference.html 2008-06-11 02:20:28.000000000 +0530 @@ -0,0 +1,605 @@ + + + + + + + + + + Deal - New Features in Version 2.0 + + + + + + + + + + +
    Plane Dealing image

    Deal 2.0

    +

    Reference Guide

    +
    +Covering:
      +
    • Command line arguments +
    • Additive Functions +
    • Shape Functions and Classes +
    • String Boxes and formatting +
    • Often used Tcl features +
    • Library routines +
    +
    +
    +
    + +

    Command Line Options

    + +
    +
    -e expr +
    Evaluate the Tcl expression expr. Not very + useful, but occasionally good for setting variables + which affect the user's script, like: +
    +deal -i userscript -e "set maxnorth 10"
    +
    +
    -v +
    Verbose mode. Lets you know how many hands have + been accepted and how many hands have been tried. +
    -[NSEW] hand-spec +
    Specifies the cards held by the specified hand. + The hand-spec should be of the form: +"AK8532 - KQ72 A65". + Voids must be represented with a '-' character. + hand-spec should be one argument, + so the string should be quoted on the command line. + +
    -i file +
    Source the commands in the file named. The language + used is "Tcl". Read the man page for Tcl for help + in writing Tcl code. Additions to Tcl specific to deal are + listed in this manual. + +
    -f +
    Instead of dealing new hands, reads hands from + standard input. The hands must be in the format + put out by "deal -l". You might deal, say, 10,000 + hands which satisfy specific criteria, saving them + to a file. Then you can use that output for input + with deal -f to find out which hands satisfy other + constraints. + +
    -t +
    Print distribution table and exit. + The distribution table is an ordered list + of all possible hand patterns for a single + hand. + +
    -l +
    Write deals in a "single-line" format. In previous + releases this was the default format. It is useful + for piping to formatters written in other languages. + Most formatting can be defined internally, using + Tcl now. Still useful with the "-f" option. + +
    + +

    Simple Usage

    + +The most basic usage of the program is to generate random deals +with no conditions: + +
    +% deal 2
    +	  S : QJ9
    +	  H : AJ
    +	  D : T52
    +	  C : AKQ84
    + S : 752            S : AK83         
    + H : T85            H : Q632         
    + D : AK8763         D : J4           
    + C : 2              C : T96          
    +	  S: T64
    +	  H: K974
    +	  D: Q9
    +	  C: J753
    +---------------------------
    +	  S : QJ9
    +	  H : 52
    +	  D : AKJT9
    +	  C : A86
    + S : 763            S : A52          
    + H : T763           H : J98          
    + D : Q54            D : 876          
    + C : T95            C : KQJ7         
    +	  S: KT84
    +	  H: AKQ4
    +	  D: 32
    +	  C: 432
    +---------------------------
    +
    + + If you want a raw format, more readable by external programs, + use the -l flag, which prints deals in a single-line format: + +
    +% deal -l 5
    +K75 T987 AQT5 95|AQ86 2 943 QJ643|JT32 J43 KJ KT82|94 AKQ65 8762 A7
    +QJ96 KQ6 T95 K76|T5 J953 A72 AJT9|8432 A7 83 Q8432|AK7 T842 KQJ64 5
    +K52 QJT9 AKQ K63|AJ AK7542 T732 8|94 3 J965 QJT972|QT8763 86 84 A54
    +A76 A764 43 KJT2|J9 KJ53 K986 A87|K8543 T82 72 953|QT2 Q9 AQJT5 Q64
    +Q6 QJ75 3 AJ7642|AT9874 KT963 AT |K32 4 QJ2 KQ9853|J5 A82 K987654 T
    +
    + + + +This output form is crude; it is meant to be post-processed. Each +line is of the form: +
    + "North|East|South|West" + +
    +Each hand is specified by: +
    + + "Spades Hearts Diamonds Clubs" + +
    + where the space character separates each suit. + +In the examples above, the east hand in the last deal is: +
    +"AT9874 KT963 AT "
    +
    +which might be written more verbosely as: + +
    +S: AT9874   H: KT963   D: AT   C: ---
    +
    +I've included three formatters with the package, one of which creates +a TeX file for the hands generated, the other two simple text files. +The formatters are Perl scripts, +so if you don't have +Perl on your system they won't work. To format, you just run deal with +the -l flag, and pipe to the formatter: + +
    +% deal -l 5 | perl ./compactdeal
    +Deal # 1          - AKQT43 AKT65 A3
    +JT65 82 QJ32 752                    AKQ82 6 94 KJ984
    +                  9743 J975 87 QT6
    +------------------------
    +Deal # 2          3 QJT43 A8742 K4
    +QT4 86 T93 AJ973                    AK52 2 QJ65 T862
    +                  J9876 AK975 K Q5
    +------------------------
    +Deal # 3          A76 KT9 QJ84 K53
    +T952 A832 A95 Q8                    J Q76 KT632 J762
    +                  KQ843 J54 7 AT94
    +------------------------
    +Deal # 4          AQ752 J632 - 8652
    +6 AK74 A863 AKT9                    KJ98 Q95 J752 QJ
    +                  T43 T8 KQT94 743
    +------------------------
    +Deal # 5          A4 AJ72 852 AKQT
    +63 T9654 QT9 865                    QJ852 Q J764 J94
    +                  KT97 K83 AK3 732
    +------------------------
    +
    + +
    +% deal -l 2 | perl ./formatdeal
    +Deal 1         S : 75                     |
    +               H : Q4                     |
    +               D : QJ962                  |
    +               C : AT64                   |
    +     S : KQ63           S : J98           |
    +     H : K732           H : T985          |
    +     D : K75            D : A843          |
    +     C : 83             C : J2            |
    +               S : AT42                   |
    +               H : AJ6                    |
    +               D : T                      |
    +               C : KQ975                  |
    +-------------------------------------------
    +Deal 2         S : AKQJ                   |
    +               H : J43                    |
    +               D : KQ4                    |
    +               C : 762                    |
    +     S : 73             S : 9865          |
    +     H : QT76           H : AK82          |
    +     D : J972           D : T86           |
    +     C : JT4            C : A9            |
    +               S : T42                    |
    +               H : 95                     |
    +               D : A53                    |
    +               C : KQ853                  |
    +-------------------------------------------
    +
    + + +

    Putting Conditions on the Deal

    + + There are two distinct types of conditions which can be placed on + a hand. +

    + One is the rigid placement of cards, as in, `South gets the ace of + clubs,' or `East is "AK52 AK32 9652 6"'. Card placements are done + before any randomnizations. +

    + + Card placements are ignored when using deal with the -f option. This + is because `deal' is reading already built hands. + +

    + The other conditionals are evaluated conditionals, like "South + has at least 4 hearts" or "West has 11 to 15 HCP" or "North has + exactly one of the ace and king of clubs." +

    + + The flow of control is: +

      +
    1. Place known cards +
    2. Deal rest of the cards at random +
    3. Determine whether to accept or reject deal. If rejected, + go to 2. +
    + +This is less than optimal in many ways. The optimizing problem here +is pretty painful, though, and, although I have some ideas for solutions, +I'm trying to be careful to do it right; in the meantime, this +method will have to do. + +

    +Scripts use the Tcl language, with bridge-related additions. +To understand these scripts, you should read the Tcl man +page. + +

    + +An example script (ex/1.tcl from the kit): +

    +
    +##############################################
    +# Look for deals where north has 44 in the majors, a short minor,
    +# and 11-15 HCP.
    +# To execute:
    +#       deal -i ex/1.tcl [num]
    +##############################################
    +main {
    +                                          # Pitch deals
    +                                          # where north does
    +                                          # not have four spades
    +        reject if {[spades north]!=4}
    +
    +                                          # Pitch deals
    +                                          # where north does
    +                                          # not have four hearts
    +        reject if {[hearts north]!=4}
    +
    +                                          # Pitch deals
    +                                          # where north has
    +                                          # 2 or 3 diamonds
    +        set d [diamonds north]
    +        reject if {$d==2} {$d==3}
    +
    +                                          # Accept deals
    +                                          # where north has
    +                                          # 11-15 HCP.
    +        set hcp_n [north]
    +        accept if {$hcp_n>=11 && $hcp_n<=15}
    +}
    +##############################################
    +
    +
    +The "main" command defines the expression which is to be evaluated +to ascertain whether a deal is accepted or rejected. This occurs after +all cards have been dealt. If the hand is never explicitly accepted, +the hand is rejected. + +

    +We can run this example as: +

    +
    +        % deal -i ex/1.tcl 10
    +
    +
    + +This will produce ten deals where north has a mini-Roman hand with +a short minor. +

    + +"deal" takes a "-v" flag which lets the user know about progress +in the hand generation; how many hands have been searched, and +how many have been checked. + +

    +
    +% deal -l -v -i ex/1.tcl 5
    +KJ92 AQ42 7 K842|8 KT9763 A862 95|Q73 J JT94 QJ763|AT654 85 KQ53 AT
    +Deal 1 found after 61 tries
    +AJ62 AQ84 9 J764|K84 J2 875 KT932|QT T73 AJ643 Q85|9753 K965 KQT2 A
    +Deal 2 found after 269 tries
    +JT86 AQJ8  KQ543|9 T9432 542 A976|K7532 K6 KQJ7 T2|AQ4 75 AT9863 J8
    +Deal 3 found after 303 tries
    +A652 AT94 A985 2|3 QJ532 T63 J543|QT74 8 K7 KT9876|KJ98 K76 QJ42 AQ
    +Deal 4 found after 394 tries
    +AJ65 9743 K AJT8|T742 T6 T764 972|KQ83 AQ5 Q32 643|9 KJ82 AJ985 KQ5
    +Deal 5 found after 523 tries
    +
    +
    +The progress output is sent to "stderr", so you can still pipe the +hands to a formatter or file without trouble. +

    +You can specify on the command line that you want South to hold a specific +hand: +

    +        % deal -v -i ex/1.tcl -S 'AK52 42 K52 7642' 10
    +
    + +Here are some of the procedures built in to the program which +have been added to Tcl for Deal. + +
    +
    accept +
    Accept the current deal. Use only from "main". +
    accept if expr [expr...] +
    Accept the current deal if one of + the expressions is true. Use only + from "main". Stops evaluating + exprs when it finds a true one. +
    accept unless expr [expr...] +
    Accept the current deal unless one of + the expressions is true. Use only + from "main". Stops evaluating exprs + when it finds a true one. +

    +

    reject
    Reject the current deal. Use only + from "main". +
    reject if expr [expr...] +
    Reject the current deal if one of + the expressions is true. Use only + from "main". Stops evaluating + exprs when it finds a true one. +
    reject unless expr [expr...] +
    Reject the current deal unless one of + the expressions is true. Use only + from "main". Stops evaluating + exprs when it finds a true one. +

    +

    spades hand, hearts hand, + diamonds hand, clubs hand +
    Returns the number of cards held in the suit by hand hand +

    +

    controls hand [suit] +
    Return the number of controls (A=2, + K=1) held in the suit given. If no + suit given, the total number of + controls. +

    +

    hand is hand-spec +
    This places all the cards of one hand. +The hand spec looks like: +
    +"AKQ - T642 QT9876" +
    +The format is pretty inflexible. +Example: + +
    +east is "AKQ AKQ AKQ AKQT" +
    + +This is the same as saying: +
    +-E 'AKQ AKQ AKQ AKQT' +
    +on the command line. +

    +

    hand gets card [card...] +
    Places individual cards in to the hand. +Example: +
    +north gets AC +
    +places the ace of clubs in the north hand. +

    +

    hand has card [card...] +
    Checks to see if the hand holds + the specified cards, e.g. +
    + if {[north has AC]} {...} +
    +

    + +

    hand shape +
    Returns a string of the 4 suit lengths, in the order S,H,D,C, e.g. +
    +puts stderr [south shape]
    +4 3 2 4 +
    +

    + +

    hand pattern +
    Return a string of the 4 suit lengths, sorted in descending +order: +
    +puts stderr [south pattern]
    +4 4 3 2 +
    +

    +

    hand +
    Return the HCP total for the hand, e.g. +
    +reject if {[north]>=16} +
    +
    +[Design note: this treatment might go away. I have serious problems +with making high card points so prominent, and [south] might +be better used as a method of extracting a tcl list like: +{AK} {QJ65} {T9872} {53} +. If I were to do this, I would add a function, hcp. +Of course, you can implement the hcp function +yourself with defvector. ] +
    +
    defvector name val [val ...] + +
    A vector is a fast counting procedure. The "vector" for counting +HCP is (4,3,2,1,0,0,0,0,0,0,0,0,0). We can define +
    +defvector Hcp 4 3 2 1 +
    + +and then use "Hcp" as a procedure later: + +
    +reject if {[Hcp north]>=16} +
    + +Or +
    +defvector Top3 1 1 1 +
    + +creates a procedure for counting how many aces, kings, and queens are held. +

    +One nice thing about these routines is that they are fast. +Clever use of vectors speeds up all sorts of evaluation routines. +

    +

    vector suit [suit ...] +
    Counts the hand using the vector. +If a list of suits is given, only those +suits are counted. Otherwise, all suits +are counted. E.g., +
    +defvector AKQ 3 2 1
    +AKQ south hearts spades +
    +counts the Ace-King-Queen points held by the south hand in hearts and spades. +

    +

    shapeclass name { code } +
    This, like defvector, is an optimization + issue. E.g., + +
    +shapeclass michaels {return [expr $h>=5 && $s>=5]}
    +main { accept if {[michaels north]}} +
    +A shapeclass generates a lookup table +the first time it is called, and fast +shape matching occurs each time after. +

    +

    shapecond name { expression } +
    This is just a shorthand for: +
    + +shapeclass name {return [expr expression] } + +
    + +
    definedclass hand +
    Returns true if the hand is in the shape + class and false otherwise. +

    +

    definedclass compile +
    +
    Returns a string of 0's, 1's and whitespaces + for faster shapeclass reuse. Really for my personal use, + but included here for completeness. +

    + +

    shapeclass.binary name { bits } +
    This is how to define the "compiled" form of the shapeclass + definitions, only really useful for shape + classes which are reused often. +

    +

    balanced hand +
    Returns true if the hand is "balanced" + in the classical Goren-style: 4333s, + 4432s, and 5332s with 5-card minor. + This could be implemented as a shapeclass, + but there still remains an internal definition + which is pretty fast. +

    +

    losers hand [suit ...] +
    Returns the number of losing tricks for + the hand, or, if suits are given, the + number of losing tricks in those suits. +

    + + + You can, of course, create new routines with Tcl, and then call + them from the "main" procedure. + +

    + +There are many examples in the kit; look them over. There is also +a file called "library" which defines some useful procedures. + +

    Hints

    + + Clever use of count vectors can solve many problems efficiently. + For example, if you and your partner play that a weak two promises + 2 of the top 3 or 3 of the top 5, you could define: + +
    + defvector Weak2Quality 2 2 2 1 1 +
    + + This vector evaluates to 4 or greater whenever the suit has the + right quality, so we could check for a weak-two spade suit with: + +
    + reject if {[spades north]!=6} {[Weak2Quality north spades]<4} +
    + + The program doesn't do much optimization, but you can do some + yourself. Try not to use logical conjunctions in "require" and "accept" + parameters. It is better to say: + +
    + accept unless {[north]<13} {[hearts north]<7} +
    + + than to say: + +
    + accept if {[north]>=13 && [hearts north]>=7} +
    + + That's because the {[hearts north]<7} expressions doesn't get + evaluated if {[north]<13} evaluated as true. +

    + It is even better to do: + +

    + accept unless {[hearts north]<7} {[north]<13} +
    + + Why? Because you are eliminating more hands initially. (Also, + the suit-length functions are faster than most since the numbers + are incidentally calculated at deal-time.) +

    + Automated optimization is another area which I'm considering for + later versions of this program. + +

    Who to Blame

    +Questions, comments and great thoughts are welcome. Just send me email +at the address at the bottom of this page. + +
    +
    +Silhouette + Thomas Andrews +(deal@thomasoandrews.com) + Copyright 1996-2005. Deal is covered by the +GNU General Public License. +
    +
    + + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/sig.html /tmp/sFHmVEdqkv/deal-3.1.4/html/sig.html --- deal-3.0.8/html/sig.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/sig.html 2008-06-11 02:20:28.000000000 +0530 @@ -0,0 +1,12 @@ +
    +
    +Silhouette +Thomas Andrews +(deal@thomasoandrews.com) +Copyright 1996-2008. Deal is covered by the +GNU General Public License. +

    +Plane Dealing graphic +above created using +POV-Ray. +

    diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/html/statistics.html /tmp/sFHmVEdqkv/deal-3.1.4/html/statistics.html --- deal-3.0.8/html/statistics.html 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/html/statistics.html 2008-06-11 02:20:28.000000000 +0530 @@ -0,0 +1,109 @@ + + + + + + + + +Statistics in Deal and iDeal + + +
    +

    Statistics in Deal

    +

    +One can, of course, implement statistical functions in pure Tcl, but +the number crunching of Tcl is not particularly fast, so I've implemented +two methods in C which do some rudimentary statistics. +

    +The two procedures are sdev and correlate. +

    +

    The sdev declaration

    +The call: +
    +sdev fitstats
    +
    +defines a new procedure, fitstats, which is used to accumulate +data. After it is defined, we can add data to it: +
    +fitstats add 4
    +fitstats add 5
    +fitstats add 6
    +
    +Then we can dump the data with: +
    +set average [fitstats average]
    +set deviation [fitstats sdev]
    +
    + +In Deal 3.1 you might write: +
    +# Determine the avearge spade length of north if south has
    +# five spades.
    +
    +#
    +# Use "format/none" because we are not interested in specific
    +# deals.
    +#
    +source format/none
    +
    +#
    +# Declare the statistical collector
    +#
    +sdev fitstats
    +
    +main {
    +  reject unless {[spades south]==5}
    +
    +  fitstats add [spades north]
    +
    +  accept
    +}
    +     
    +deal_finished {
    +  puts "Count=[fitstats count]"
    +  puts "Average=[fitstats average]"
    +  puts "Deviation=[fitstats sdev]"
    +}
    +
    + +The code in deal_finished is executed once, after the appropriate +set of deals are generated. Saving this code to the file "fit.tcl" we +can run it: +
    +\deal30> deal -i fit.tcl 100000
    +Count=100000
    +Average=2.67254
    +Deviation=1.20679325006
    +
    +

    The correlation declaration

    +The correlation declaration defines a routine much like +the sdev correlation. It computes the linear correlation +between two data bits. In tclsh, with iDeal: +
    +% correlation baz
    +% baz add 10 20
    +% baz add 20 30
    +% baz add 30 40
    +% baz add 40 50
    +% baz correlate
    +1.0
    +%
    +
    + +
    +
    +Silhouette +Thomas Andrews +(deal@thomasoandrews.com) +Copyright 1996-2008. Deal is covered by the +GNU General Public License. +

    +Plane Dealing graphic +above created using +POV-Ray. +

    +
    + + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/input/ddline.tcl /tmp/sFHmVEdqkv/deal-3.1.4/input/ddline.tcl --- deal-3.0.8/input/ddline.tcl 2001-10-09 20:48:57.000000000 +0530 +++ deal-3.1.4/input/ddline.tcl 2008-05-22 06:27:00.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: ddline.tcl,v 1.4 2008/05/22 00:57:00 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -20,13 +22,19 @@ ::deal::nostacking - proc set_input {{fname {}} {suitorder {spades hearts diamonds clubs}}} { + proc set_input {{fname {}} {skip 0} {suitorder {spades hearts diamonds clubs}}} { variable glob if {$fname!=""} { set glob(filehandle) [open $fname r] } else { set glob(filehandle) stdin } + + while {$skip>0} { + incr skip -1 + gets $glob(filehandle) line + } + set glob(suitorder) $suitorder lappend glob(suitorder) notrump deal_reset_cmds ::ddline::next @@ -57,9 +65,12 @@ tricks $part(dd$hand) \ holding $h { set holdings($suit) $holding - ::deal::metadata tricks.$hand.$suit {expr $tricks} + ::deal::metadata ddline.$hand.$suit {expr $tricks} } deck_stack_hand $hand [list $holdings(spades) $holdings(hearts) $holdings(diamonds) $holdings(clubs)] } } + } + +set deal::tricksCache ddline diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/input/giblib.tcl /tmp/sFHmVEdqkv/deal-3.1.4/input/giblib.tcl --- deal-3.0.8/input/giblib.tcl 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/input/giblib.tcl 2008-05-22 06:27:00.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: giblib.tcl,v 1.2 2008/05/22 00:57:00 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -15,7 +17,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -source /usr/share/deal/lib/gib.tcl +source lib/gib.tcl # # The giblib implements the ability to read files of the diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/input/line.tcl /tmp/sFHmVEdqkv/deal-3.1.4/input/line.tcl --- deal-3.0.8/input/line.tcl 2002-12-19 20:51:31.000000000 +0530 +++ deal-3.1.4/input/line.tcl 2008-05-22 06:27:00.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: line.tcl,v 1.5 2008/05/22 00:57:00 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -41,7 +43,6 @@ set file [lindex $args 0] set handle [open $file "r"] } - deal_reset_cmds {::input::next} } proc next {} { @@ -56,6 +57,7 @@ return -code return } + set hands [split $line "|"] foreach hand {north east south west} val [split $line "|"] { deck_stack_hand $hand [split $val " "] } diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/input/pbn.tcl /tmp/sFHmVEdqkv/deal-3.1.4/input/pbn.tcl --- deal-3.0.8/input/pbn.tcl 2001-10-09 20:48:57.000000000 +0530 +++ deal-3.1.4/input/pbn.tcl 2008-05-22 06:27:00.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: pbn.tcl,v 1.2 2008/05/22 00:57:00 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/input/smartstack.tcl /tmp/sFHmVEdqkv/deal-3.1.4/input/smartstack.tcl --- deal-3.0.8/input/smartstack.tcl 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/input/smartstack.tcl 2008-05-22 06:27:00.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: smartstack.tcl,v 1.2 2008/05/22 00:57:00 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -15,7 +17,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -source /usr/share/deal/lib/handFactory.tcl +source lib/handFactory.tcl namespace eval smartstack { diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/input/symmetric.tcl /tmp/sFHmVEdqkv/deal-3.1.4/input/symmetric.tcl --- deal-3.0.8/input/symmetric.tcl 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/input/symmetric.tcl 2008-05-22 06:27:00.000000000 +0530 @@ -0,0 +1,92 @@ +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# $Id: symmetric.tcl,v 1.4 2008/05/22 00:57:00 thomaso Exp $ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# +# read the output from a line input +# +# This reads input in the same format as the -l output from deal. +# +namespace eval symmetric { + + ::deal::nostacking + variable number 0 + variable current 0 + variable increment 1 + variable endnumber + variable cards {K Q J T 9 8 7 6 5 4 3 2} + + proc finalize {} { + } + + proc initialize {start incr end} { + variable number + variable increment + variable endnumber + + set number $start + set increment $incr + set endnumber $end + + deal_reset_cmds {::symmetric::next} + } + + proc generate {num} { + variable current + variable cards + reset_deck + set holding(0) "A" + set holding(1) "" + set holding(2) "" + set holding(3) "" + + set current $num + foreach card $cards { + set suit [expr {$num%4}] + append holding($suit) $card + set num [expr {($num-$suit)/4}] + } + + deck_stack_hand south $holding(0) $holding(1) $holding(2) $holding(3) + deck_stack_hand west $holding(1) $holding(2) $holding(3) $holding(0) + deck_stack_hand north $holding(2) $holding(3) $holding(0) $holding(1) + deck_stack_hand east $holding(3) $holding(0) $holding(1) $holding(2) + deal_deck + } + + proc next {} { + variable number + variable increment + variable endnumber + + if {$number>=$endnumber} { + return -code return + } + + generate $number + incr number $increment + + deal_reset_cmds {::symmetric::next} + } + + proc set_input {{start 0} {increment 1} {end 16777216}} { + initialize $start $increment $end + } +} + + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/lib/bid.tcl /tmp/sFHmVEdqkv/deal-3.1.4/lib/bid.tcl --- deal-3.0.8/lib/bid.tcl 2001-10-09 20:48:24.000000000 +0530 +++ deal-3.1.4/lib/bid.tcl 2008-05-22 06:26:08.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: bid.tcl,v 1.2 2008/05/22 00:56:08 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/lib/binky.tcl /tmp/sFHmVEdqkv/deal-3.1.4/lib/binky.tcl --- deal-3.0.8/lib/binky.tcl 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/lib/binky.tcl 2008-05-29 19:30:10.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: binky.tcl,v 1.3 2008/05/29 14:00:10 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -16,7 +18,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -source /usr/share/deal/lib/handProc.tcl +source lib/handProc.tcl namespace eval binky { variable binkyData @@ -36,7 +38,8 @@ set result [lindex $binkyData($key) $column] return $result } - return -13.00 + puts stderr "Got unknown key $key" + return -1000.00 } proc ddvalue {column holding len} { diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/lib/ddeval.tcl /tmp/sFHmVEdqkv/deal-3.1.4/lib/ddeval.tcl --- deal-3.0.8/lib/ddeval.tcl 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/lib/ddeval.tcl 2008-05-22 06:26:08.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: ddeval.tcl,v 1.2 2008/05/22 00:56:08 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -16,7 +18,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -source /usr/share/deal/lib/handProc.tcl +source lib/handProc.tcl namespace eval ddeval { variable ddData diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/lib/evaluators.tcl /tmp/sFHmVEdqkv/deal-3.1.4/lib/evaluators.tcl --- deal-3.0.8/lib/evaluators.tcl 2001-10-09 20:48:24.000000000 +0530 +++ deal-3.1.4/lib/evaluators.tcl 2008-05-22 06:26:08.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: evaluators.tcl,v 1.2 2008/05/22 00:56:08 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/lib/features.tcl /tmp/sFHmVEdqkv/deal-3.1.4/lib/features.tcl --- deal-3.0.8/lib/features.tcl 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/lib/features.tcl 2008-06-11 01:42:13.000000000 +0530 @@ -0,0 +1,157 @@ +# +# deal.tcl - this file is sourced at startup by Deal 3.0 or later +# +# Copyright (C) 1996-2001, Thomas Andrews +# +# $Id: features.tcl,v 1.1 2008/06/10 20:12:13 thomaso Exp $ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +proc dds_reset_command {} { + dds_reset + deal_reset_cmds [list dds_reset_command] +} + + +namespace eval deal { + + variable metadata + variable unicode 1 + + # + # Put data in the cache, to be unset at next call + # to deal_deck + # + proc metadata {name code} { + variable metadata + if {![info exists metadata($name)]} { + if {[catch {set metadata($name) [uplevel $code]}]} { + global errorInfo + puts stderr "Error: $errorInfo" + } else { + deal_reset_cmds [list unset ::deal::metadata($name)] + } + } + return $metadata($name) + } + + proc loop {} { + next + write + } + + + proc input {format args} { + uplevel #0 [list source "input/$format.tcl" ] + set command [list "${format}::set_input"] + foreach arg $args { + lappend command $arg + } + uplevel #0 $command + } + + proc debug {args} { + puts stderr $args + } + + # Cause an error if any hand stacking has occured + proc nostacking {} { + set format [uplevel {namespace current}] + proc ::stack_hand {args} \ + "error \"No hand stacking with input format $format\"" + proc ::stack_cards {args} \ + "error \"No card stacking with input format $format\"" + foreach hand {south north east west} { + foreach holding [stacked $hand] { + if {[holding length $holding]!=0} { + error "Stacking cards is not consistent with input format $format" + } + } + } + } +} + +# These two routines used to be defined in C, but it's better for them +# to fit the pattern of shape functions. + +if {[string equal [info commands dds_reset] "dds_reset"]} { + dds_reset_command +} +shapecond balanced {($h<5)&&($s<5)&&($s*$s+$h*$h+$d*$d+$c*$c)<=47} +shapecond semibalanced {$h<=5&&$s<=5&&$d<=6&&$c<=6&&$c>=2&&$d>=2&&$h>=2&&$s>=2} +shapecond AnyShape {1} +source format/default + +# +# The three routines, joinclass, negateclass, intersectclass, used to be +# implemented in C, but were never documented and recently crashed Deal 3.0.x +# when called. I've reimplemented them here in pure Tcl. +# +proc joinclass {newclass args} { + set values [list 0] + foreach class $args { + lappend values "\[$class eval \$s \$h \$d \$c\]" + } + + shapecond ___tempclass [join $values "||"] + + # make sure it is compiled first - use temporary name + # in case we are re-using an old name for a class + ___tempclass eval 13 0 0 0 + rename ___tempclass $newclass +} + +proc negateclass {newclass class} { + shapecond ___tempclass "!\[$class eval \$s \$h \$d \$c\]" + ___tempclass eval 13 0 0 0 + rename ___tempclass $newclass +} + +proc intersectclass {newclass args} { + + set values [list 1] + foreach class $args { + lappend values "\[$class eval \$s \$h \$d \$c\]" + } + shapecond ___tempclass [join $values "&&"] + ___tempclass eval 13 0 0 0 + rename ___tempclass $newclass +} + +namespace eval deal { + + variable tricksCmd ::tricks + variable tricksCache "tricks" + + # + # "tricks" - Determine the number of tricks declarer can + # make in the denomination given. + # + proc tricks {declarer denom} { + variable tricksCmd + variable tricksCache + ::deal::metadata "$tricksCache.$declarer.$denom" [list $tricksCmd $declarer $denom] + } + +} + +# +# Returns all of the hands in a list +# +proc full_deal {} { + return [list [north] [east] [south] [west]] +} + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/lib/gib.tcl /tmp/sFHmVEdqkv/deal-3.1.4/lib/gib.tcl --- deal-3.0.8/lib/gib.tcl 2001-10-09 20:48:24.000000000 +0530 +++ deal-3.1.4/lib/gib.tcl 2008-05-22 06:26:08.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: gib.tcl,v 1.3 2008/05/22 00:56:08 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -140,11 +142,16 @@ # make in the denomination given. # proc tricks {declarer denom} { - ::deal::metadata "tricks.$declarer.$denom" { + ::deal::metadata "gib.$declarer.$denom" { rectify_tricks $declarer [nstricks $declarer $denom] } } + proc tricksCmd {declarer denom} { + rectify_tricks $declarer [nstricks $declarer $denom] + } + + # # determine which leads hold declarer to his tricks # @@ -275,7 +282,7 @@ set results [list $contract] foreach hand {south west north east} { set tr [expr {15&$trickvalue}] - ::deal::metadata tricks.$hand.$contract { + ::deal::metadata gib.$hand.$contract { gib::rectify_tricks $hand $tr } set trickvalue [expr {$trickvalue/16}] @@ -333,4 +340,6 @@ namespace export get_next_deal initialize finalize } +set deal::tricksCmd ::gib::tricksCmd +set deal::tricksCache gib #gib::directory "c:/games/gib" diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/lib/handFactory.tcl /tmp/sFHmVEdqkv/deal-3.1.4/lib/handFactory.tcl --- deal-3.0.8/lib/handFactory.tcl 2001-10-09 20:48:24.000000000 +0530 +++ deal-3.1.4/lib/handFactory.tcl 2008-05-22 06:26:08.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: handFactory.tcl,v 1.2 2008/05/22 00:56:08 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/lib/handProc.tcl /tmp/sFHmVEdqkv/deal-3.1.4/lib/handProc.tcl --- deal-3.0.8/lib/handProc.tcl 2001-10-09 20:48:24.000000000 +0530 +++ deal-3.1.4/lib/handProc.tcl 2008-05-22 06:26:08.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: handProc.tcl,v 1.2 2008/05/22 00:56:08 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/lib/parscore.tcl /tmp/sFHmVEdqkv/deal-3.1.4/lib/parscore.tcl --- deal-3.0.8/lib/parscore.tcl 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/lib/parscore.tcl 2008-05-22 06:26:08.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: parscore.tcl,v 1.5 2008/05/22 00:56:08 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -16,8 +18,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -source /usr/share/deal/lib/score.tcl -source /usr/share/deal/lib/gib.tcl +source lib/score.tcl proc rlist {A B C D} {list $D $C $B $A} @@ -44,8 +45,11 @@ append first $rest } - proc parscore {dealer whovul} { + deal::metadata parscore.$dealer.$whovul [list parscore_uncached $dealer $whovul] +} + +proc parscore_uncached {dealer whovul} { if {"$whovul"=="EW"} { set vul(EW) vul set vul(NS) nonvul @@ -62,9 +66,10 @@ global parscore - foreach hand {north east south west} { - foreach denom {notrump spades hearts diamonds clubs} { - set tricks($hand:$denom) [gib::tricks $hand $denom] + # Quick call to precompute tricks + foreach denom {notrump spades hearts diamonds clubs} { + foreach hand {north east south west} { + set tricks($hand:$denom) [deal::tricks $hand $denom] } } @@ -79,12 +84,18 @@ set passes(2) "Pass Pass" set passes(1) "Pass" set passes(0) "" + set biggestfit 0 for {set level 1} {$level<=7} {incr level} { set anymake 0 foreach denom {clubs diamonds hearts spades notrump} { set passcount 4 foreach declarer $hands { + if {$denom == "notrump"} { + set fit 14 + } else { + set fit [expr {[$denom $declarer]+[$denom [partner $declarer]]}] + } incr passcount -1 set pair $parscore(pair:$declarer) if {$tricks($declarer:$denom)<6+$level} { @@ -99,7 +110,8 @@ set mult $parscore(mult:$declarer) set newscore [score $contract $vul($pair) $tricks($declarer:$denom)] #puts "Comparing [expr {$mult*$newscore}] in $contract by $declarer to $bestscore in $bestcontract by $bestdeclarer" - if {$newscore>$mult*$bestscore} { + if {$newscore>$mult*$bestscore || (($newscore==$mult*$bestscore) && $fit>$biggestfit) } { + set biggestfit $fit set bestcontract $contract set bestdeclarer $declarer set bestscore [expr {$mult*$newscore}] diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/lib/score.tcl /tmp/sFHmVEdqkv/deal-3.1.4/lib/score.tcl --- deal-3.0.8/lib/score.tcl 2001-10-31 20:06:59.000000000 +0530 +++ deal-3.1.4/lib/score.tcl 2008-05-22 06:26:08.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: score.tcl,v 1.2 2008/05/22 00:56:08 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/lib/shapes.tcl /tmp/sFHmVEdqkv/deal-3.1.4/lib/shapes.tcl --- deal-3.0.8/lib/shapes.tcl 2001-10-09 20:48:24.000000000 +0530 +++ deal-3.1.4/lib/shapes.tcl 2008-05-22 06:26:08.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: shapes.tcl,v 1.2 2008/05/22 00:56:08 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/lib/utility.tcl /tmp/sFHmVEdqkv/deal-3.1.4/lib/utility.tcl --- deal-3.0.8/lib/utility.tcl 2001-10-09 20:48:24.000000000 +0530 +++ deal-3.1.4/lib/utility.tcl 2008-05-22 06:26:08.000000000 +0530 @@ -1,6 +1,8 @@ # # Copyright (C) 1996-2001, Thomas Andrews # +# $Id: utility.tcl,v 1.2 2008/05/22 00:56:08 thomaso Exp $ +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/LICENSE /tmp/sFHmVEdqkv/deal-3.1.4/LICENSE --- deal-3.0.8/LICENSE 2001-02-20 01:15:36.000000000 +0530 +++ deal-3.1.4/LICENSE 2008-06-11 02:09:37.000000000 +0530 @@ -3,6 +3,8 @@ Deal is released under the GNU General Public License. See the file, GPL, for the complete text of the license. +The DDS code is under a different license and copyright. + The file random.c has a seperate copyright: /* Binary files /tmp/SqcgMuwVDH/deal-3.0.8/makecounttable and /tmp/sFHmVEdqkv/deal-3.1.4/makecounttable differ diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/makecounttable.c /tmp/sFHmVEdqkv/deal-3.1.4/makecounttable.c --- deal-3.0.8/makecounttable.c 2001-02-19 23:19:04.000000000 +0530 +++ deal-3.1.4/makecounttable.c 2008-05-15 05:49:24.000000000 +0530 @@ -56,7 +56,7 @@ int main() { int i; make_counttable(); - printf("int counttable[]={"); + printf("unsigned short int counttable[]={"); for (i=0; i<8192; i++) { if (0==i%16) { printf("\n"); diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/Makefile /tmp/sFHmVEdqkv/deal-3.1.4/Makefile --- deal-3.0.8/Makefile 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/Makefile 2008-08-04 15:31:44.000000000 +0530 @@ -7,16 +7,19 @@ # Makefile for "deal", a bridge hand generator. # -TCL_DIR=/usr/local +TCL_DIR=/usr CC=gcc -#DEBUG_FLAGS=-pg -g -ansi -Wall -DEBUG_FLAGS=-g -ansi -Wall +MAC_ARCH = +MAC_ARCH_UNIVERSAL = -arch i386 -arch ppc +#DEBUG_FLAGS=-g -ansi -Wall -O2 $(MAC_ARCH) +#CPPFLAGS = -fno-rtti -g -O2 $(MAC_ARCH) +DEBUG_FLAGS=-g -ansi -Wall $(MAC_ARCH) +CPPFLAGS =-g -fno-rtti -Winline -Wall $(MAC_ARCH) # Change TCL_INCL to point to the directory containing Tcl's # include files -TCL_INCL=/usr/include/tcl8.4 -#TCL_INCL=./tcl8.1.1/generic +TCL_INCL=/usr/include/tcl # Change TCL_LIB to point to the directory where you have a copy # of libtcl. @@ -24,10 +27,7 @@ TCL_LIB=$(TCL_DIR)/lib ###### -# For Solaris2, you need some more libraries -# -#LDFLAGS= -L$(TCL_LIB) -ltcl80 -lm -ldl -lsocket -lnsl -LDFLAGS= -ltcl8.4 -lm +LDFLAGS= -L$(TCL_LIB) -ltcl -lm @@ -52,33 +52,37 @@ #EXTRA_CFLAGS = #EXTRA_CFLAGS = -DUSE_RAND48 -COMPILE.c= $(CC) $(CFLAGS) $(CPPFLAGS) -c +COMPILE.c= $(CC) $(CFLAGS) -c CFLAGS+= $(DEBUG_FLAGS) -I$(TCL_INCL) $(EXTRA_CFLAGS) OBJS=random.o additive.o hand.o deal.o formats.o tcl_deal.o maindeal.o stat.o counttable.o \ - vector.o dist.o stringbox.o dealtypes.o keywords.o holdings.o $(EXTRA_OBJS) -SRCS=additive.c hand.c deal.c formats.c tcl_deal.c dist.c vector.c stat.c counttable.c stringbox.c dealtypes.c holdings.c keywords.c maindeal.c random.c -SRCKIT=additive.c hand.c deal.c formats.c tcl_deal.c dist.c vector.c stat.c makecounttable.c stringbox.c dealtypes.c holdings.c keywords.c maindeal.c random.c -HFILES=deck.h deal.h tcl_incl.h vector.h stat.h tcl_dist.h dist.h formats.h additive.h stringbox.h dealtypes.h holdings.h keywords.h ansidecl.h + vector.o dist.o stringbox.o dealtypes.o keywords.o holdings.o tcl_dds.o dds.o $(EXTRA_OBJS) +SRCS=additive.c hand.c deal.c formats.c tcl_deal.c dist.c vector.c stat.c counttable.c stringbox.c dealtypes.c holdings.c keywords.c maindeal.c random.c dds.cpp +SRCKIT=additive.c hand.c deal.c formats.c tcl_deal.c dist.c vector.c stat.c makecounttable.c stringbox.c dealtypes.c holdings.c keywords.c maindeal.c random.c tcl_dds.c dds.cpp +HFILES=deck.h deal.h tcl_incl.h vector.h stat.h tcl_dist.h dist.h formats.h additive.h stringbox.h dealtypes.h holdings.h keywords.h ansidecl.h dds.h ddsInterface.h Holding.h EXAMPLES= ex/*.tcl +TESTS=tests +HTML=html BUILDFILES=Makefile Make.dep -OTHERFILES=CHANGES LICENSE GPL input format lib deal.tcl docs +OTHERFILES=CHANGES LICENSE GPL input format lib deal.tcl -SOURCEKIT=$(SRCKIT) $(HFILES) $(EXAMPLES) $(BUILDFILES) $(OTHERFILES) $(EXTRAS) +SOURCEKIT=$(SRCKIT) $(HFILES) $(EXAMPLES) $(BUILDFILES) $(OTHERFILES) $(EXTRAS) $(TESTS) $(HTML) +BINKIT=$(EXAMPLES) $(OTHERFILES) $(TESTS) $(HTML) UUKIT=$(EXAMPLES) $(OTHERFILES) deal +BINARY=./deal deal: $(OBJS) - $(CC) $(CFLAGS) $(OBJS) -o deal $(LDFLAGS) + g++ $(CFLAGS) $(OBJS) -o deal $(LDFLAGS) +universal: + $(MAKE) clean + $(MAKE) MAC_ARCH="$(MAC_ARCH_UNIVERSAL)" deal.cgi: make clean make CFLAGS="$(CFLAGS) -DCGI" -ideal: $(OBJS) - proof $(CC) $(CFLAGS) $(OBJS) -o ideal $(LDFLAGS) - vector.so: vector.c $(CC) -c $(CFLAGS) -PIC vector.c ld vector.o -o vector.so @@ -91,23 +95,6 @@ $(CC) -c $(CFLAGS) -PIC stringbox.c ld stringbox.o -o stringbox.so -ccenter: - #load $(CFLAGS) $(SRCS) $(LDFLAGS) - -ccentero: $(OBJS) - #load -w $(CFLAGS) $(OBJS) $(LDFLAGS) - -cov: - $(MAKE) CC="covc" - cat qccov_work/*.M > deal.M - -expert: - $(MAKE) CC="exbuild $(CC)" - -rtc: - $(MAKE) clean - $(MAKE) CC="/s/latest/CenterLine/bin/ncc -rtc -Xa" DEBUG_FLAGS=-g deal - $(SRCS): deal.h counttable.c: makecounttable @@ -116,67 +103,97 @@ makecounttable: makecounttable.c $(CC) $(CFLAGS) makecounttable.c -o makecounttable $(LDFLAGS) -checkin: - checkin.script $(SOURCEKIT) - -checkout: - co -u $(SOURCEKIT) - -firstcheckin: - ci $(SOURCEKIT) - -shar: - mv Make.dep Make.dep.saved - touch Make.dep - shar $(SOURCEKIT) >deal.shar - mv Make.dep.saved Make.dep - KITNAME=deal -DEAL_VERSION=305 -OLD_VERSION=304 +DEAL_VERSION=314 +OLD_VERSION=313 RELEASE=$(KITNAME)$(DEAL_VERSION) SRCDIR=$(RELEASE) +BINDIR=$(RELEASE)-bin SRCZIP=$(SRCDIR).zip -EXEZIP=$(SRCDIR)exe.zip +EXEZIP=$(SRCDIR)win.zip DOCZIP=$(SRCDIR)doc.zip SRCTAR=$(SRCDIR).tar SRCGZIP=$(SRCTAR).gz BINZIP=$(KITNAME)exe.zip +DMG=$(BINDIR).dmg DIFFZIP=deal$(DEAL_VERSION)diff.zip OLDZIP=../deal/deal$(OLD_VERSION).zip OLDDIR=$(KITNAME)$(OLD_VERSION) +DOCDEST=html +DOCTYPE=release -FTP=../ftp +SMALLTESTCOUNT=10 -allzip: zip xzip dzip gzip diffzip +allzip: zip dmg CHANGES: docs/html/CHANGES.txt cp docs/html/CHANGES.txt CHANGES zip: $(SRCZIP) +dmg: $(DMG) + xzip: $(EXEZIP) dzip: $(DOCZIP) -$(SRCDIR): $(SOURCEKIT) docs/html docs/graphics +documentation: + rm -rf $(DOCDEST) + mkdir $(DOCDEST) + cp -r docs/graphics $(DOCDEST)/graphics + cp -r docs/html/*.css docs/html/ex $(DOCDEST) + cd docs/html; for file in *.html; do \ + php process.php $(DOCTYPE) $$file > ../../$(DOCDEST)/$$file ; done + +sitedoc: + $(MAKE) DOCDEST=site DOCTYPE=site documentation + +newsite: + $(MAKE) clean + $(MAKE) universal + $(MAKE) dmg + cp $(DMG) site + $(MAKE) zip + cp $(SRCZIP) site + $(MAKE) xzip + cp $(EXEZIP) site + + +$(BINDIR): $(BINKIT) sitedoc documentation + rm -rf $(BINDIR) + mkdir $(BINDIR) + /bin/ls -1d $(BINKIT) | xargs tar cf - | (cd $(BINDIR) ; tar xf -) + find $(BINDIR) -name CVS -print | xargs /bin/rm -rf + +$(SRCDIR): $(SOURCEKIT) docs/html docs/graphics documentation mv Make.dep Make.dep.saved touch Make.dep rm -rf $(SRCDIR) mkdir $(SRCDIR) - ls -1d $(SOURCEKIT) | xargs tar cf - | (cd $(SRCDIR) ; tar xf -) + /bin/ls -1d $(SOURCEKIT) | xargs tar cf - | (cd $(SRCDIR) ; tar xf -) mv Make.dep.saved Make.dep $(SRCZIP): $(SRCDIR) - zip -r $(SRCZIP) $(SRCDIR) -x \*~ + zip -r $(SRCZIP) $(SRCDIR) -x \*~ -x *CVS/\* $(EXEZIP): $(SRCDIR) - rm -f $(EXEZIP) - zip -r $(EXEZIP) $(SRCDIR)/ex $(SRCDIR)/input $(SRCDIR)/format $(SRCDIR)/docs $(SRCDIR)/CHANGES $(SRCDIR)/LICENSE $(SRCDIR)/GPL -x \*~ + rm -f $(EXEZIP) $(SRCDIR)/deal + test -f deal.exe + test -f tcl85.dll + cp deal.exe $(SRCDIR) + cp tcl85.dll $(SRCDIR) + zip -r $(EXEZIP) $(SRCDIR)/ex $(SRCDIR)/input $(SRCDIR)/format $(SRCDIR)/docs $(SRCDIR)/CHANGES $(SRCDIR)/LICENSE $(SRCDIR)/GPL $(SRCDIR)/lib $(SRCDIR)/deal.tcl $(SRCDIR)/deal.exe $(SRCDIR)/tcl85.dll $(SRCDIR)/tests $(SRCDIR)/html -x \*~ -x *CVS/\* + +$(DMG): $(BINDIR) deal + cp deal $(BINDIR)/deal + /bin/rm -rf dmg $(DMG) + mkdir dmg + cp -r $(BINDIR) dmg/$(SRCDIR) + hdiutil create -srcfolder dmg -volname "Deal $(DEAL_VERSION)" $(DMG) $(DOCZIP): $(SRCDIR) rm -f $(DOCZIP) - zip -r $(DOCZIP) $(SRCDIR)/CHANGES $(SRCDIR)/LICENSE $(SRCDIR)/GPL $(SRCDIR)/docs -x \*~ + zip -r $(DOCZIP) $(SRCDIR)/CHANGES $(SRCDIR)/LICENSE $(SRCDIR)/GPL $(SRCDIR)/docs -x \*~ -x *CVS/\* gzip: $(SRCTAR).gz @@ -205,26 +222,27 @@ tar cvf deal.tar $(SOURCEKIT) mv Make.dep.saved Make.dep +test: ./deal + $(BINARY) -I "line tests/input/sample.line" -i format/ddline 100 > test.out + if cmp test.out tests/output/sample.ddline ; then echo PASS; else echo FAIL ; fi + +smalltest: ./deal + $(BINARY) -I "line tests/input/sample.line" -i format/ddline $(SMALLTESTCOUNT) > test.out + head -$(SMALLTESTCOUNT) tests/output/sample.ddline > correct.out + diff test.out correct.out + if cmp test.out correct.out ; then echo PASS; else echo FAIL ; fi + +great88: ./deal + $(BINARY) -x tests/great88 | fgrep FAIL || echo "PASSED" + +html: documentation ftp: $(SRCZIP) cp $(SRCZIP) $(FTP) -uu: deal - touch uu.header - cp uu.header deal.uu - rm -f $(TARFILE).[zZ] - strip deal - tar crf $(TARFILE) $(UUKIT) - $(COMPRESSOR) $(TARFILE) - uuencode $(TARFILE).[zZ] $(TARFILE).[zZ] >>deal.uu - depends: - $(CC) $(CFLAGS) -M *.c >Make.dep - -test: - ##setopt sys_load_cflags #$${sys_load_cflags} -L/tmp + $(CC) $(CFLAGS) -M *.c *.cpp >Make.dep clean: - rm -rf deal $(OBJS) $(SRCDIR) $(SRCZIP) $(SRCGZIP) $(DOCZIP) $(EXEZIP) - + rm -rf deal $(OBJS) $(SRCDIR) $(SRCZIP) $(SRCGZIP) $(DOCZIP) $(DMG) $(EXEZIP) $(BINDIR) site include Make.dep diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/stat.c /tmp/sFHmVEdqkv/deal-3.1.4/stat.c --- deal-3.0.8/stat.c 2001-02-19 22:43:42.000000000 +0530 +++ deal-3.1.4/stat.c 2008-05-15 05:49:24.000000000 +0530 @@ -17,10 +17,6 @@ */ -#ifndef lint -static char rcsid [] = "$Header: /home/thomaso/deal30/RCS/stat.c,v 1.1 1999/03/15 17:30:02 thomaso Exp $"; -#endif - #include "math.h" #include "deal.h" #include "stat.h" @@ -428,7 +424,7 @@ int tcl_sdev_define ( TCL_PARAMS ) TCL_DECL { - char *name=argv[1]; + CONST84 char *name=argv[1]; SDev *sd; argc--; argv++; sd=sdevNew(); diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/tcl_dds.c /tmp/sFHmVEdqkv/deal-3.1.4/tcl_dds.c --- deal-3.0.8/tcl_dds.c 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/tcl_dds.c 2008-06-05 21:16:13.000000000 +0530 @@ -0,0 +1,401 @@ +#include "deal.h" +#include "tcl_incl.h" +#include "dealtypes.h" +#include "ddsInterface.h" + +#ifdef BENCH +int totalNodes = 0; +#endif + +static int LastTrump = -1; +static int CountCalls = 0; + +static int parse_diagram(Tcl_Interp *interp,Tcl_Obj *diagram, struct deal *aDeal, int *handLength) { + int retval,length; + int suitHoldings[4]; + int countHand[4]; + Tcl_Obj **hands; + int hand,suit; + + for (suit=0; suit<4; suit++) { + suitHoldings[suit]=0; + for (hand=0; hand<4; hand++) { + aDeal->remainCards[hand][suit]=0; + } + } + + retval = Tcl_ListObjGetElements(interp,diagram,&length,&hands); + if (retval !=TCL_OK) { + return TCL_ERROR; + } + if (length!=4) { + return TCL_ERROR; + } + + for (hand=0; hand<4; hand++) { + int suitCount; + Tcl_Obj **suits; + countHand[hand] = 0; + retval = Tcl_ListObjGetElements(interp,hands[hand],&suitCount, &suits); + if (retval != TCL_OK) { + return TCL_ERROR; + } + if (suitCount>4) { + return TCL_ERROR; + } + for (suit=0; suitremainCards[hand][suit] = holding << 2; + suitLength = counttable[holding]; + countHand[hand] += suitLength; + if (suitHoldings[suit] & holding) { + /* Not disjoint */ + return TCL_ERROR; + } + suitHoldings[suit] |= (holding); + } + } + + for (hand=1; hand<4; hand++) { + if (countHand[hand] != countHand[0]) { + /* Hands not all same size */ + return TCL_ERROR; + } + } + *handLength = countHand[0]; + + return TCL_OK; + +} + +static int tcl_double_dummy_reset(TCLOBJ_PARAMS) TCLOBJ_DECL +{ + LastTrump = -1; + return TCL_OK; +} + +static int tcl_dds(TCLOBJ_PARAMS) TCLOBJ_DECL +{ + static int doInit=1, + DiagramFlagID=-1, + GoalFlagID=-1, + NoReuseFlagID=-1, + ReuseFlagID=-1, + LeaderFlagID=-1, + TrickFlagID=-1; + + int goal=-1; + int playerGoal = -1; + int hand, suit,result; + int mode=-1; + int declarer = 2; + struct deal d; + int status; + int handLength; + int cardsPlayedToTrick=0; + int played[4]; + Tcl_Obj *diagram = NULL; + + struct futureTricks futp; + if (doInit) { + ReuseFlagID=Keyword_addKey("-reuse"); + NoReuseFlagID=Keyword_addKey("-noreuse"); + DiagramFlagID=Keyword_addKey("-diagram"); + GoalFlagID=Keyword_addKey("-goal"); + LeaderFlagID=Keyword_addKey("-leader"); + TrickFlagID=Keyword_addKey("-trick"); + doInit=0; + } + + memset(&(d.currentTrickSuit), 0, 3*sizeof(int)); + memset(&(d.currentTrickRank), 0, 3*sizeof(int)); + d.trump=4; /* notrump */ + d.first=-1; /* unknown */ + + for (suit=0; suit<4; suit++) { + played[suit] = 0; + } + + while (objc > 1) { + int id = Keyword_getIdFromObj(interp,objv[1]); + objv++; objc--; + if (id == ReuseFlagID) { + mode=2; + continue; + } + if (id == NoReuseFlagID) { + mode=1; + continue; + } + if (id == DiagramFlagID || id == GoalFlagID || id == LeaderFlagID || id == TrickFlagID) { + Tcl_Obj *arg = objv[1]; + if (objc>1) { + objc--; objv++; + } else { + return TCL_ERROR; + } + + if (id == DiagramFlagID) { + if (diagram!=NULL) { + return TCL_ERROR; + } + diagram = arg; + } else if (id == GoalFlagID ) { + if (TCL_ERROR == Tcl_GetIntFromObj(interp,arg,&goal) || (goal!=-1 && (goal<1 && goal>13))) { + Tcl_AppendResult(interp,"Invalid tricks goal: ",Tcl_GetString(arg),NULL); + return TCL_ERROR; + } + + } else if (id == LeaderFlagID) { + d.first = getHandNumFromObj(interp,arg); + if (d.first == NOSEAT) { + Tcl_AppendResult(interp,"invalid seat name passed to -leader: ",Tcl_GetString(arg),NULL); + return TCL_ERROR; + } + } else if (id == TrickFlagID) { + Tcl_Obj **cards; + int playNo,rank; + if (cardsPlayedToTrick!=0) { + Tcl_AppendResult(interp,"No additional tricks after an incomplete trick",NULL); + } + + if (TCL_ERROR == Tcl_ListObjGetElements(interp,arg,&cardsPlayedToTrick,&cards) || + cardsPlayedToTrick>3) { + Tcl_AppendResult(interp,"Invalid -trick argument: ",Tcl_GetString(arg),NULL); + return TCL_ERROR; + } + + for (playNo=0; playNo 2) { + d.trump = getDenomNumFromObj(interp,objv[2]); + if (d.trump==-1) { + Tcl_AppendResult(interp,"Invalid denomination: ", Tcl_GetString(objv[2]), NULL); + return TCL_ERROR; + } + } + + if (objc > 1) { + declarer = getHandNumFromObj(interp,objv[1]); + if (declarer == NOSEAT) { + Tcl_AppendResult(interp,"invalid declarer name passed: ",Tcl_GetString(objv[1]),NULL); + return TCL_ERROR; + } + } + + if (d.first==-1) { + d.first = (declarer+1)%4; + } + + + if (diagram != NULL) { + int retval = parse_diagram(interp,diagram, &d,&handLength); + if (retval != TCL_OK) { + return TCL_ERROR; + } + } else { + finish_deal(); + handLength = 13; + for (hand=0; hand<4; hand++) { + /* Double dummy solver has north hand zero */ + int ddsHand = hand; + for (suit=0; suit<4; suit++) { + d.remainCards[ddsHand][suit] = globalDeal.hand[hand].suit[suit] << 2; + } + } + } + + for (hand=0; hand<4; hand++) { + for (suit=0; suit<4; suit++) { + int oldCards = d.remainCards[hand][suit]; + d.remainCards[hand][suit] &= (~played[suit]); + if (d.remainCards[hand][suit]!=oldCards) { + } + } + } + + if (goal>0) { + if ((d.first + cardsPlayedToTrick + declarer)&1) { + playerGoal = (handLength + 1)-goal; /* Goal passed to DDS */ + } else { + playerGoal = goal; /* Goal passed to DDS */ + } + } + + if (CountCalls == 0) { + mode = 0; + } else if ( mode == -1 ) { + if (d.trump != LastTrump || diagram != NULL) { + mode = 1; + } else { + mode = 2; + } + } + + /* fprintf(stderr,"mode = %d\n",mode); */ + status = SolveBoard(d,playerGoal,1,mode,&futp); + LastTrump = d.trump; + CountCalls++; + + if (status != 1) { + Tcl_SetObjResult(interp,Tcl_NewIntObj(status)); + Tcl_AppendResult(interp,": dds failed due to error status from double dummy solver",NULL); + return TCL_ERROR; + } +#ifdef BENCH + totalNodes += futp.totalNodes; + printf("nodes=%d totalNodes=%d\n",futp.totalNodes,totalNodes); +#endif + if (futp.score[0]==-2) { + /* Defender takes all the tricks */ + result = 0; + } else if (futp.score[0]==-1) { + if (goal>0) { + result = 1; + } else { + result = handLength; + } + } else { + + if ((d.first + cardsPlayedToTrick + declarer)&1) { + result = handLength-futp.score[0]; + } else { + result = futp.score[0]; + } + + if (goal>0) { + result = (result>=goal); + } + } + Tcl_SetObjResult(interp,Tcl_NewIntObj(result)); + return TCL_OK; +} + +/* This code directly borrows from Alex Martelli's Python interface to dds. */ +static int tcl_double_dummy_solve(TCLOBJ_PARAMS) TCLOBJ_DECL +{ + int goal=-1; + int leaderGoal = -1; + int hand, suit,result; + int mode; + struct deal d; + int status; + + struct futureTricks futp; + memset(&(d.currentTrickSuit), 0, 3*sizeof(int)); + memset(&(d.currentTrickRank), 0, 3*sizeof(int)); + d.trump=4; /* notrump */ + d.first=WEST; /* west */ + finish_deal(); + + if (objc > 2) { + d.trump = getDenomNumFromObj(interp,objv[2]); + if (d.trump==-1) { + Tcl_AppendResult(interp,"Invalid denomination: ", Tcl_GetString(objv[2]), NULL); + return TCL_ERROR; + } + } + if (objc > 1) { + int declarer = getHandNumFromObj(interp,objv[1]); + if (declarer == NOSEAT) { + Tcl_AppendResult(interp,"invalid seat name passed: ",Tcl_GetString(objv[1]),NULL); + return TCL_ERROR; + } + d.first = (declarer+1)%4; + } + + if (objc > 3) { + if (TCL_ERROR == Tcl_GetIntFromObj(interp,objv[3],&goal) || (goal!=-1 && (goal<1 && goal>13))) { + Tcl_AppendResult(interp,"Invalid tricks goal: ",Tcl_GetString(objv[3]),NULL); + return TCL_ERROR; + } + } + + if (goal>0) { + leaderGoal = 14-goal; /* Goal passed to DDS */ + } + + + for (hand=0; hand<4; hand++) { + /* Double dummy solver has north hand zero */ + int ddsHand = hand; + for (suit=0; suit<4; suit++) { + d.remainCards[ddsHand][suit] = globalDeal.hand[hand].suit[suit] << 2; + } + } + + if (d.trump != LastTrump) { + if (CountCalls == 0) { + mode = 0; + } else { + mode = 1; + } + } else { + mode = 2; + } + /* fprintf(stderr,"mode = %d\n",mode); */ + status = SolveBoard(d,leaderGoal,1,mode,&futp); + LastTrump = d.trump; + CountCalls++; + + if (status != 1) { + Tcl_SetObjResult(interp,Tcl_NewIntObj(status)); + Tcl_AppendResult(interp,"dds failed due to error status from double dummy solver",NULL); + return TCL_ERROR; + } +#ifdef BENCH + totalNodes += futp.totalNodes; + printf("nodes=%d totalNodes=%d\n",futp.totalNodes,totalNodes); +#endif + if (futp.score[0]==-2) { + /* Defender takes all the tricks */ + result = 0; + } else if (futp.score[0]==-1) { + if (goal>0) { + result = 1; + } else { + result = 13; + } + } else { + result = 13-futp.score[0]; + if (goal>0) { + result = (result>=goal); + } + } + Tcl_SetObjResult(interp,Tcl_NewIntObj(result)); + return TCL_OK; +} + +int DDS_Init(interp) + Tcl_Interp *interp; +{ + DDSInitStart(); + Tcl_CreateObjCommand(interp,"tricks",tcl_double_dummy_solve,NULL,NULL); + Tcl_CreateObjCommand(interp,"dds",tcl_dds,NULL,NULL); + Tcl_CreateObjCommand(interp,"dds_reset",tcl_double_dummy_reset,NULL,NULL); + return TCL_OK; +} diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/tcl_deal.c /tmp/sFHmVEdqkv/deal-3.1.4/tcl_deal.c --- deal-3.0.8/tcl_deal.c 2008-08-04 15:31:44.000000000 +0530 +++ deal-3.1.4/tcl_deal.c 2008-06-11 01:28:50.000000000 +0530 @@ -17,10 +17,6 @@ */ -#ifndef lint -static char rcsid [] = "$Header: /home/thomaso/deal30/RCS/tcl_deal.c,v 1.3 1999/07/09 00:31:40 thomaso Exp thomaso $"; -#endif - #include #include @@ -28,8 +24,6 @@ #include #include #include -#include -#include #include "deal.h" #include "vector.h" @@ -41,25 +35,23 @@ #include "dealtypes.h" #include "holdings.h" #include -#ifdef WIN32 #include "getopt.h" -#endif #include #include "tcl_incl.h" typedef struct formatter { - char *(*fn)(); + char *(*fn)(); } *FormatFN; Tcl_Interp *interp; void Tcl_ObjDelete(ClientData data) { - Tcl_DecrRefCount((Tcl_Obj *)data); + Tcl_DecrRefCount((Tcl_Obj *)data); } void Tcl_AllocDelete(ClientData data) { - Tcl_Free((char *)data); + Tcl_Free((char *)data); } int (*next_deal)() = start_deal; @@ -71,63 +63,66 @@ static Tcl_Obj *resetCmds=NULL; static void create_cache_reset() { - if (resetCmds==NULL) { - Tcl_IncrRefCount(resetCmds=Tcl_NewListObj(0,0)); - cachesize=0; - } + if (resetCmds==NULL) { + Tcl_IncrRefCount(resetCmds=Tcl_NewListObj(0,0)); + cachesize=0; + } } static int do_reset_commands(Tcl_Interp *interp) { - if (resetCmds!=NULL && cachesize!=0) { - /* - * Allow the resetCmds to cache data in the - * next resetCmds - */ - Tcl_Obj *oldCmds=resetCmds; - int i,count; - Tcl_Obj **code; - int result; - - cachesize=0; - resetCmds=NULL; - - result=Tcl_ListObjGetElements(interp,oldCmds,&count,&code); - if (result==TCL_OK) { - for (i=count-1; i>=0; i--) { - result=Tcl_GlobalEvalObj(interp,code[i]); - if (result==TCL_RETURN) { - /*fprintf(stderr,"Got return in reset\n");*/ - return TCL_RETURN; - } + if (resetCmds!=NULL && cachesize!=0) { + /* + * Allow the resetCmds to cache data in the + * next resetCmds + */ + Tcl_Obj *oldCmds=resetCmds; + int i,count; + Tcl_Obj **code; + int result; + + cachesize=0; + resetCmds=NULL; + + result=Tcl_ListObjGetElements(interp,oldCmds,&count,&code); + if (result==TCL_OK) { + for (i=count-1; i>=0; i--) { + result=Tcl_GlobalEvalObj(interp,code[i]); + if (result==TCL_RETURN) { + /*fprintf(stderr,"Got return in reset\n");*/ + return TCL_RETURN; } - Tcl_ListObjReplace(interp,oldCmds,0,count,0,0); - } - Tcl_DecrRefCount(oldCmds); + if (result==TCL_ERROR) { + return TCL_ERROR; } + } + Tcl_ListObjReplace(interp,oldCmds,0,count,0,0); + } + Tcl_DecrRefCount(oldCmds); + } - return TCL_OK; + return TCL_OK; } static void add_reset_cmd(Tcl_Interp *interp,Tcl_Obj *code) { - int length; - if (resetCmds==NULL) { - create_cache_reset(); - } - - Tcl_ListObjLength(interp,resetCmds,&length); + int length; + if (resetCmds==NULL) { + create_cache_reset(); + } + + Tcl_ListObjLength(interp,resetCmds,&length); - Tcl_ListObjAppendElement(interp,resetCmds,code); - cachesize++; + Tcl_ListObjAppendElement(interp,resetCmds,code); + cachesize++; } static int add_reset_cmds(TCLOBJ_PARAMS) TCLOBJ_DECL { - int i=1; - while (ifn(); if (format!=NULL) { - Tcl_SetResult(interp,format,TCL_DYNAMIC); - return TCL_OK; + Tcl_SetResult(interp,format,TCL_DYNAMIC); + return TCL_OK; } else { - Tcl_AppendResult(interp,argv[0]," failed due to error: ", - Tcl_PosixError(interp),NULL); - return TCL_ERROR; + Tcl_AppendResult(interp,argv[0]," failed due to error: ", + Tcl_PosixError(interp),NULL); + return TCL_ERROR; } } @@ -186,84 +181,84 @@ finish_deal(); format=fmt->fn(); if (argc==2) { - file=stderr; + file=stderr; } if (format!=NULL) { - fputs(format,file); - Tcl_Free(format); - return TCL_OK; + fputs(format,file); + Tcl_Free(format); + return TCL_OK; } else { - Tcl_AppendResult(interp,argv[0]," failed due to error: ", - Tcl_PosixError(interp),NULL); - return TCL_ERROR; + Tcl_AppendResult(interp,argv[0]," failed due to error: ", + Tcl_PosixError(interp),NULL); + return TCL_ERROR; } } int tcl_flush_deal (TCLOBJ_PARAMS) TCLOBJ_DECL { - return TCL_OK; /* Default write flushing routing */ + return TCL_OK; /* Default write flushing routing */ } int tcl_rotate_deal (TCL_PARAMS) TCL_DECL { - if (argc!=2) { - Tcl_AppendResult(interp, - "wrong # of args: \"",argv[0]," \"",NULL); - return TCL_ERROR; - } - rotate_deal(atoi(argv[1])); - return TCL_OK; + if (argc!=2) { + Tcl_AppendResult(interp, + "wrong # of args: \"",argv[0]," \"",NULL); + return TCL_ERROR; + } + rotate_deal(atoi(argv[1])); + return TCL_OK; } int tcl_stacked_cards (TCLOBJ_PARAMS) TCLOBJ_DECL { - Tcl_Obj *holdings[4]; - int handnum, suit; - int h[4]; - - if (objc!=2) { - Tcl_AddErrorInfo(interp,"Usage: stacked_cards \n"); - return TCL_ERROR; - } - - handnum=getHandNumFromObj(interp,objv[1]); - if (handnum==NOSEAT) { - Tcl_AddErrorInfo(interp,"Invalid hand name\n"); - return TCL_ERROR; - } - - get_stacked_cards(handnum,h); - for (suit=0; suit<4; suit++) { - holdings[suit]=Tcl_NewHoldingObj(h[suit]); - } - Tcl_SetObjResult(interp,Tcl_NewListObj(4,holdings)); - return TCL_OK; + Tcl_Obj *holdings[4]; + int handnum, suit; + int h[4]; + + if (objc!=2) { + Tcl_AddErrorInfo(interp,"Usage: stacked_cards \n"); + return TCL_ERROR; + } + + handnum=getHandNumFromObj(interp,objv[1]); + if (handnum==NOSEAT) { + Tcl_AddErrorInfo(interp,"Invalid hand name\n"); + return TCL_ERROR; + } + + get_stacked_cards(handnum,h); + for (suit=0; suit<4; suit++) { + holdings[suit]=Tcl_NewHoldingObj(h[suit]); + } + Tcl_SetObjResult(interp,Tcl_NewListObj(4,holdings)); + return TCL_OK; } int tcl_rand_cmd( TCLOBJ_PARAMS ) TCLOBJ_DECL { - long res,tclres,modulus; - res=random(); - if (objc>1) { - tclres=Tcl_GetLongFromObj(interp,objv[1],&modulus); - if (tclres==TCL_ERROR) { return TCL_ERROR; } - res %= modulus; - Tcl_SetObjResult(interp,Tcl_NewIntObj(res)); - } - else { - double dres = res * 1.0 / LONG_MAX; - Tcl_SetObjResult(interp,Tcl_NewDoubleObj(dres)); - } - return TCL_OK; + long res,tclres,modulus; + res=random(); + if (objc>1) { + tclres=Tcl_GetLongFromObj(interp,objv[1],&modulus); + if (tclres==TCL_ERROR) { return TCL_ERROR; } + res %= modulus; + Tcl_SetObjResult(interp,Tcl_NewIntObj(res)); + } + else { + double dres = res * 1.0 / LONG_MAX; + Tcl_SetObjResult(interp,Tcl_NewDoubleObj(dres)); + } + return TCL_OK; } int tcl_after_set(TCLOBJ_PARAMS) TCLOBJ_DECL { if (objc!=2) { - return TCL_ERROR; + return TCL_ERROR; } if (after_exp != 0) { - Tcl_DecrRefCount(after_exp); + Tcl_DecrRefCount(after_exp); } Tcl_IncrRefCount(after_exp=Tcl_DuplicateObj(objv[1])); @@ -272,22 +267,26 @@ int tcl_seed_deal(TCLOBJ_PARAMS) TCLOBJ_DECL { - int result,value; - if (objc!=2) { - return TCL_ERROR; - } - result=Tcl_GetIntFromObj(interp,objv[1],&value); - if (result==TCL_OK) { - srand(value); - } - return TCL_OK; + int result,value; + if (objc!=2) { + return TCL_ERROR; + } + result=Tcl_GetIntFromObj(interp,objv[1],&value); + if (result==TCL_OK) { +#ifdef USE_RAND48 + srand48(value); +#else + srandom(value); +#endif + } + return TCL_OK; } int tcl_main_set(TCLOBJ_PARAMS) TCLOBJ_DECL { if (objc!=2) { - return TCL_ERROR; + return TCL_ERROR; } if (main_exp != 0) { Tcl_DecrRefCount(main_exp); } Tcl_IncrRefCount(main_exp=Tcl_DuplicateObj(objv[1])); @@ -298,31 +297,31 @@ { int result; if (objc!=2) { - return TCL_ERROR; + return TCL_ERROR; } while (1) { - result=tcl_deal_deck(cd,interp,objc,objv); - if (result==TCL_RETURN) { - return TCL_RETURN; - } - if (result==TCL_ERROR) { - return TCL_ERROR; - } - result=Tcl_GlobalEvalObj(interp,main_exp); - if (result==TCL_ERROR) { - /* fprintf(stderr,"Error in eval loop: %s\n",Tcl_GetStringResult(interp)); */ - return result; - } - if (result==TCL_RETURN) { - Tcl_Obj *output=Tcl_GetObjResult(interp); - int value; - if (Tcl_GetIntFromObj(interp,output,&value)!=TCL_ERROR && value>0) { - break; - } - } + result=tcl_deal_deck(cd,interp,objc,objv); + if (result==TCL_RETURN) { + return TCL_RETURN; + } + if (result==TCL_ERROR) { + return TCL_ERROR; + } + result=Tcl_GlobalEvalObj(interp,main_exp); + if (result==TCL_ERROR) { + /* fprintf(stderr,"Error in eval loop: %s\n",Tcl_GetStringResult(interp)); */ + return result; + } + if (result==TCL_RETURN) { + Tcl_Obj *output=Tcl_GetObjResult(interp); + int value; + if (Tcl_GetIntFromObj(interp,output,&value)!=TCL_ERROR && value>0) { + break; + } + } #ifdef DEBUG - fprintf(stderr,"Rejected after %d cards dealt\n",complete_deal.dealt); + fprintf(stderr,"Rejected after %d cards dealt\n",complete_deal.dealt); #endif } return Tcl_GlobalEvalObj(interp,objv[1]); @@ -330,6 +329,11 @@ static Tcl_Obj *logicObj[2]={ NULL, NULL}; +static int tcl_init(TCLOBJ_PARAMS) TCLOBJ_DECL +{ + return Tcl_Init(interp); +} + /* * implements the 'accept' and 'reject' commands */ @@ -343,53 +347,54 @@ int length; if (logicObj[0]==NULL) { - logicObj[0]=Tcl_NewBooleanObj(0); - Tcl_IncrRefCount(logicObj[0]); - logicObj[1]=Tcl_NewBooleanObj(1); - Tcl_IncrRefCount(logicObj[1]); + logicObj[0]=Tcl_NewBooleanObj(0); + Tcl_IncrRefCount(logicObj[0]); + logicObj[1]=Tcl_NewBooleanObj(1); + Tcl_IncrRefCount(logicObj[1]); } data=(int)cd; /* True if 'accept', false if 'reject' */ if (objc==1) { - Tcl_SetObjResult(interp,logicObj[data ? 1 : 0]); - return TCL_RETURN; + Tcl_SetObjResult(interp,logicObj[data ? 1 : 0]); + return TCL_RETURN; } logic=Tcl_GetStringFromObj(objv[1],&length); if (0==strcmp(logic,"if")) { - iffound=logicObj[data!=0]; - found=TCL_RETURN; - ifnotfound=logicObj[data==0]; - nfound=TCL_OK; + iffound=logicObj[data!=0]; + found=TCL_RETURN; + ifnotfound=logicObj[data==0]; + nfound=TCL_OK; } else if (0==strcmp(logic,"unless")) { - iffound=logicObj[data==0]; - found=TCL_OK; - ifnotfound=logicObj[data!=0]; - nfound=TCL_RETURN; + iffound=logicObj[data==0]; + found=TCL_OK; + ifnotfound=logicObj[data!=0]; + nfound=TCL_RETURN; } else { - return TCL_ERROR; + return TCL_ERROR; } for (i=2; i1) { - fprintf(stderr,"Condition %s passed\n",Tcl_GetStringFromObj(objv[i],&length)); - } - return found; - } + if (value) { + Tcl_IncrRefCount(iffound); + Tcl_SetObjResult(interp,iffound); + if (verbose>1) { + fprintf(stderr,"Condition %s passed\n",Tcl_GetStringFromObj(objv[i],&length)); + } + return found; + } } Tcl_IncrRefCount(ifnotfound); Tcl_SetObjResult(interp,ifnotfound); return nfound; } + DEAL31_API int *Deal_Init(Tcl_Interp *interp) { int result; @@ -402,22 +407,22 @@ initializeDealTypes(interp); compact->fn=&format_deal_compact; Tcl_CreateCommand(interp,"write_deal_compact",tcl_write_deal, - (ClientData)compact,NULL); + (ClientData)compact,NULL); Tcl_CreateCommand(interp,"format_deal_compact",tcl_format_deal, - (ClientData)compact,NULL); + (ClientData)compact,NULL); deffmt->fn=&format_deal_verbose; Tcl_CreateCommand(interp,"write_deal",tcl_write_deal, - (ClientData)deffmt,NULL); + (ClientData)deffmt,NULL); Tcl_CreateCommand(interp,"format_deal",tcl_format_deal, - (ClientData)deffmt,NULL); + (ClientData)deffmt,NULL); Tcl_CreateCommand(interp,"write_deal_verbose",tcl_write_deal, - (ClientData)deffmt,NULL); + (ClientData)deffmt,NULL); Tcl_CreateObjCommand(interp,"flush_deal",tcl_flush_deal, - NULL,NULL); + NULL,NULL); Tcl_CreateObjCommand(interp,"stacked",tcl_stacked_cards, - NULL,NULL); + NULL,NULL); Tcl_CreateCommand(interp,"rotatedeal",tcl_rotate_deal,NULL,NULL); @@ -429,6 +434,7 @@ Vector_Init(interp); Stringbox_Init(interp); IDealHolding_Init(interp); + DDS_Init(interp); Tcl_CreateObjCommand(interp,"deal_deck",tcl_deal_deck,NULL,NULL); @@ -445,18 +451,21 @@ Tcl_CreateObjCommand(interp,"deal_reset_cmds",add_reset_cmds,NULL,NULL); - result=Tcl_VarEval(interp,"source /usr/share/deal/deal.tcl",NULL); + Tcl_CreateObjCommand(interp,"deal_init_tcl",tcl_init,NULL,NULL); + + result=Tcl_VarEval(interp,"source deal.tcl",NULL); if (result==TCL_ERROR) { - tcl_error(interp); + tcl_error(interp); } + Tcl_VarEval(interp,"reset_deck",NULL); return TCL_OK; } int old_main(argc,argv) -int argc; -char *argv[]; + int argc; + char *argv[]; { int i; @@ -474,99 +483,104 @@ extern char *optarg; time(&for_seeding); - for_seeding ^= getpid(); +#ifdef USE_RAND48 + srand48(for_seeding); +#else + srandom(for_seeding); +#endif init_name_tables(); Deal_Init(interp); - while (-1!=(opt=getopt(argc,argv,"lve:S:N:E:W:i:ts:fo:VI:"))) { - switch (opt) { - case 'l': - writecmd="write_deal_compact"; - break; - case 'V': - verbose=2; - break; - case 'v': - verbose=1; - break; - case 'e': - result=Tcl_VarEval(interp,optarg,NULL); - if (result==TCL_ERROR) { + while (-1!=(opt=getopt(argc,argv,"lve:S:N:E:W:i:ts:fo:VI:x:"))) { + switch (opt) { + case 'l': + writecmd="write_deal_compact"; + break; + case 'V': + verbose=2; + break; + case 'v': + verbose=1; + break; + case 'e': + result=Tcl_VarEval(interp,optarg,NULL); + if (result==TCL_ERROR) { tcl_error(interp); - } - break; - - case 'I': - result=Tcl_VarEval(interp,"deal::input ",optarg,NULL); - if (result==TCL_ERROR) { - tcl_error(interp); - } - break; - - case 'S': - case 'N': - case 'E': - case 'W': - { - int hand=hand_name_table[opt]; - int tclret=Tcl_VarEval(interp, - handname[hand]," is ",optarg,NULL); - - if (TCL_OK!=tclret) { - fprintf(stderr,"Failure attempts to stack hand %s\n",optarg); - Tcl_GlobalEval(interp,"puts stderr $errorInfo"); - exit(1); - } - - } - break; + } + break; - case 's': - for_seeding=atoi(optarg); - break; - case 'i': - sprintf(tcl_command_string,"source %s",optarg); - result=Tcl_VarEval(interp,tcl_command_string,NULL); - if (result==TCL_ERROR) { + case 'I': + result=Tcl_VarEval(interp,"deal::input ",optarg,NULL); + if (result==TCL_ERROR) { tcl_error(interp); - } - break; - - case 't': - printDistTable(); - exit(1); - default: - fprintf(stderr,"usage: %s [-ltv] [-e ex] [-i file] [-I format] [-s n] [-[NSEW] spec] [count]\n", - argv[0]); -#ifdef __CENTERLINE__ - centerline_stop(""); -#endif + } + break; + + case 'S': + case 'N': + case 'E': + case 'W': + { + int hand=hand_name_table[opt]; + int tclret=Tcl_VarEval(interp, + handname[hand]," is ",optarg,NULL); + + if (TCL_OK!=tclret) { + fprintf(stderr,"Failure attempts to stack hand %s\n",optarg); + Tcl_GlobalEval(interp,"puts stderr $errorInfo"); exit(1); } - } - + + } + break; + + case 's': + for_seeding=atoi(optarg); #ifdef USE_RAND48 - srand48(for_seeding); + srand48(for_seeding); #else - srandom(for_seeding); + srandom(for_seeding); #endif + + break; + case 'x': + case 'i': + sprintf(tcl_command_string,"source %s",optarg); + result=Tcl_VarEval(interp,tcl_command_string,NULL); + if (result==TCL_ERROR) { + tcl_error(interp); + } + if (opt=='x') { + exit(0); + } + break; + + case 't': + printDistTable(); + exit(1); + default: + fprintf(stderr,"usage: %s [-v] [-s seed] [-i includeFile] [-I inputFormat] [count]\n", + argv[0]); + exit(1); + } + } argc-=optind-1; argv+=optind-1; if (argc>1 && isdigit(*argv[1])) { - count=atoi(argv[1]); - argc--; argv++; + count=atoi(argv[1]); + argc--; argv++; } if (main_exp!=(Tcl_Obj *)0) { - sprintf(tcl_command_string,"deal_loop %s",writecmd); - argc--; argv++; + sprintf(tcl_command_string,"deal_loop %s",writecmd); + argc--; argv++; } else { - sprintf(tcl_command_string,"deal_deck ; %s",writecmd); + sprintf(tcl_command_string,"deal_deck ; %s",writecmd); } command=Tcl_NewStringObj(tcl_command_string,strlen(tcl_command_string)); @@ -574,26 +588,26 @@ Tcl_IncrRefCount(command); for (i=1; i<=count; i++) { - char *s; - result=Tcl_GlobalEvalObj(interp,command); - if (result==TCL_ERROR) { tcl_error(interp); } - - if (result==TCL_RETURN) { break; } - - s=Tcl_GetStringResult(interp); - if (*s=='e' && (0==strcmp("exit",s))) { - break; - } - - if (verbose) { - fprintf(stderr,"Deal %d found after %d tries\n",i,count_deals); - } + const char *s; + result=Tcl_GlobalEvalObj(interp,command); + if (result==TCL_ERROR) { tcl_error(interp); } + + if (result==TCL_RETURN) { break; } + + s=Tcl_GetStringResult(interp); + if (*s=='e' && (0==strcmp("exit",s))) { + break; + } + + if (verbose) { + fprintf(stderr,"Deal %d found after %d tries\n",i,count_deals); + } } result=Tcl_VarEval(interp,flushcmd,NULL); if (result==TCL_ERROR) { tcl_error(interp); exit(1); } if (after_exp) { - result=Tcl_GlobalEvalObj(interp,after_exp); - if (result==TCL_ERROR) { tcl_error(interp); exit(1); } + result=Tcl_GlobalEvalObj(interp,after_exp); + if (result==TCL_ERROR) { tcl_error(interp); exit(1); } } return 0; } diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/tcl_incl.h /tmp/sFHmVEdqkv/deal-3.1.4/tcl_incl.h --- deal-3.0.8/tcl_incl.h 2001-10-09 20:56:58.000000000 +0530 +++ deal-3.1.4/tcl_incl.h 2008-05-15 05:49:24.000000000 +0530 @@ -18,7 +18,7 @@ #ifndef __TCL_INCL__ #include #ifdef __STDC__ -#define TCL_PARAMS ClientData cd,Tcl_Interp *interp,int argc,char *argv[] +#define TCL_PARAMS ClientData cd,Tcl_Interp *interp,int argc, CONST84 char *argv[] #define TCLOBJ_PARAMS ClientData cd,Tcl_Interp *interp,int objc,Tcl_Obj * CONST objv[] #define TCL_DECL #define TCLOBJ_DECL diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/tests/great88 /tmp/sFHmVEdqkv/deal-3.1.4/tests/great88 --- deal-3.0.8/tests/great88 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/tests/great88 2008-06-04 13:03:01.000000000 +0530 @@ -0,0 +1,635 @@ +proc problem {id title diagram goal {denomination notrump} {leader south}} { + set tricks [dds -diagram $diagram -leader $leader south $denomination] + if {$tricks != $goal} { + set result FAIL + } else { + set result PASS + } + puts "$result: Problem $id ($title) makes $tricks tricks with goal $goal" +} + +# Tribe 1 - Eliminations, Endplays of Position + +problem 1 Avoidance { + {A987 - A} + {Q5 987 -} + {64 K2 2} + {K2 AQ3 -} + } 3 notrump + +problem 2 {The Pitt coup} { + {A2 753} + {Q9 64 Q} + {KJ - 753} + {3 Q98 A} + } 5 spades + +problem 3 {Gambit and jettison} { + {A 873 A} + {6 9 K KJ} + {- A6 - Q43} + {8 Q Q98 -} + } 4 spades + +problem 4 {Forced finesse} { + {842 32} + {A76 K8} + {KQ3 AQ} + {J9 75 2} + } 4 notrump + +problem 5 {Strip setup finesse} { + {7 - Q63 A} + {9 - JT8 7} + {- - K94 65} + {5 - - K984} + } 4 spades + +problem 6 {Double strip finesse} { + {- 86 - A96} + {5 A53 - 5} + {A 742 - 2} + {- 9 8 874} + } 4 notrump + +problem 7 {Crossruff strip} { + {97 - 72 2} + {- Q3 Q KQ} + {86 - A8 8} + {J J KJ J} + } 3 spades + +problem 8 {Jettison entry strip} { + {2 32 - A2} + {- - J9 KJ6} + {- - A43 Q3} + {- KQ KQ 8} + } 4 spades + +problem 9 {Jettison two-entry strip} { + {- A7 - QJ5} + {- 65 AK9 -} + {J J9 QJ -} + {8 K3 - K9} + } 4 spades + +problem 10 {Double-entry strip} { + {743 A A -} + {Q Q Q QJ} + {KJ2 - - 32} + {A65 K K} + } 4 notrump + +problem 11 {Fork strip} { + {52 5 5 5} + {98 9 9 9} + {AQ A 3 A} + {K63 K A -} + } 4 notrump + +problem 12 {Total fork strip} { + {T42 - A 4} + {QJ7 - J Q} + {K85 8 6 -} + {A96 - 3 5} + } 3 hearts + +problem 13 {Progressive fork strip} { + {Q3 - - KQJ} + {KT2 - - 64} + {AJ97 J - -} + {8654 A - -} + } 4 notrump + +problem 14 {Transfer fork strip} { + {6 4 - AJ5} + {- - 65 Q84} + {- - 72 K63} + {- Q K4 92} + } 4 spades + +problem 15 {Jettison double fork strip} { + {- - J T862} + {7 8 - A97} + {J 642 5 -} + {9 953 8 -} + } 3 spades + +problem 16 {Repeat-jettison fork strip} { + {- A A KJ7} + {5 - Q9 AQ} + {Q 2 KJ8 -} + {J 3 764} + } 4 spades + +problem 17 {Two-fork double strip} { + {- 8 J7 A9} + {- Q7 A8 8} + {A A93 6 -} + {- 65 Q Q6} + } 4 notrump + +problem 18 {Double blocked fork strip} { + {- Q9 J95} + {- KT73 Q} + {9 8 A64} + {4 J K73} + } 3 spades + +problem 19 {Crossruff or finesse strip} { + {T 5 - AT5} + {- JT KQ J} + {5 A - 432} + {- KQ - KQ9} + } 4 spades + +problem 20 {Crossruff entry strip} { + {3 4 A 32} + {- K K KQJ} + {54 A - 75} + {- 75 98 A} + } 4 spades + +problem 21 {Crossruff fork strip} { + {A AQ Q A} + {- K5 K KQ} + {3 32 3 3} + {- J9 J J9} + } 4 spades + +problem 22 {Crossruff split-fork strip} { + {3 Q - KT3} + {- A9 - Q75} + {4 6 - A94} + {- K A J86} + } 4 spades + +problem 23 {Entry or fork strip} { + {3 72 Q2} + {2 J54 J} + {- AK3 A7} + {- Q98 K9} + } 4 notrump + +problem 24 {Jettison-entry fork strip} { + {K984 - K -} + {AJ - - 876} + {- Q65 72 -} + {- 98 A65 -} + } 3 notrump + +problem 25 {Blocked fork strip or entry} { + {KJ3 - K 8} + {Q7 - QJ 9} + {- J 84 J6} + {- 9 9 Q72} + } 4 notrump + +problem 26 {Crossruff entry fork strip} { + {3 32 - 53} + {- - 98754 -} + {75 75 - 2} + {- 64 6 64} + } 4 spades + +# Tribe 2 - Coups, Endplays of Time + +problem 27 {En passant} { + {A54 2 - 2} + {7 - A7 87} + {- 3 32 A3} + {98 9 9 9} + } 4 spades + +problem 28 {Grand coup} { + {- 42 AK A} + {K4 - 43 4} + {AQ2 - 2 2} + {J9 - J9 J} + } 5 spades + +problem 29 {Grand coup fork strip} { + {876 A - 9} + {3 K K KQ} + {AJT2 - A -} + {KQ9 9 9 -} + } 4 spades + +problem 30 {Overruff grand coup} { + {Q972 - - Q} + {- - K6 K62} + {54 4 5 4} + {JT8 32 - -} + } 4 spades + +problem 31 {Repeating grand coup} { + {AK - - QT8} + {J9765 - - -} + {QT8 A A -} + {432 8 8 -} + } 5 spades + +problem 32 {Undercut} { + {- 4 A65 A} + {KQT - K 4} + {AJ2 6 4 -} + {- A QJ98 -} + } 4 spades + +problem 33 {Uppercut} { + {Q7 8 J A} + {A65 - 2 8} + {42 42 4 -} + {983 A 9 -} + } 2 spades + +problem 34 {Smother play} { + {A42 2 - 2} + {T9 T9 T -} + {QJ87 7 - -} + {K653 3 - -} + } 4 spades + +problem 35 {Double smother} { + {AT3 - AK -} + {J6 6 6 6} + {K92 A - 4} + {Q85 5 5 -} + } 5 spades + +# Tribe 3 - Squeezes, Endplays of Mass + +problem 36 {Double squeeze} { + {A2 2 - KQ} + {KJ - A 86} + {3 - 2 A72} + {Q9 A - J9} + } 5 notrump + +problem 37 {Double squeeze} { + {94 - 2 K3} + {A5 Q - J8} + {Q63 2 - 6} + {J - 8 972} + } 4 spades + +problem 38 {Double automatic squeeze} { + {AQ3 - - K4} + {J87 A - 7} + {2 2 2 A2} + {K96 - A 9} + } 5 notrump + +problem 39 {Split squeeze} { + {K3 - 74 A} + {J - QJ K9} + {A2 - A Q2} + {Q - - J875} + } 5 notrump + +problem 40 {Overtake squeeze} { + {A964 - - K} + {T8752 - - -} + {KQJ K K -} + {3 A2 A A} + } 4 notrump + +problem 41 {Progressive squeeze} { + {3 A3 Q 4} + {Q82 - J A} + {A7 7 K8 -} + {K9 K9 9 -} + } 5 notrump + +problem 42 {Transfer repeat squeeze} { + {A7 4 6 7} + {J9 - 98 Q} + {Q8 - A54 -} + {K654 - Q -} + } 5 notrump + +problem 43 {Three-two squeeze} { + {- A4 4 42} + {- - A3 863} + {7 7 - AQ7} + {- K6 K J9} + } 5 notrump + +problem 44 {Finesse jettison squeeze} { + {K8 - 953 -} + {- J JT7 9} + {- 9 Q8 63} + {Q764 - K -} + } 4 notrump + +problem 45 {Progressive jettison squeeze} { + {A4 9 A 5} + {- 73 764 -} + {96 K4 8 -} + {QJ - KJ Q} + } 4 notrump + +problem 46 {Progressive jettison squeeze or squeeze} { + {- A3 A9 Q} + {- 75 876 -} + {9 86 QJ -} + {- Q4 K4 K} + } 5 notrump + + +problem 47 {Trump squeeze} { + {KJ84 - - K} + {Q65 - - 32} + {A73 K K -} + {T9 A A A} + } 5 spades + +problem 48 {Squeeze or forced finesse} { + {KQ KQ J} + {9 A K93} + {2 3 AQ7} + {A8765 - -} + } 4 notrump + +problem 49 {Finesse squeeze} { + {82 - A9 2} + {- 62 8 74} + {- 54 Q A6} + {- 73 KJ 9} + } 5 spades + +# Tribe 4: Compund and Hybrid Endings + +problem 50 {One-way finesse or fork strip} { + {KJ - - A62} + {AQ9 - J7 -} + {853 - K4 -} + {- - Q5 QJ5} + } 3 notrump + +problem 51 {Forced jettison strip squeeze} { + {- A AJ64 -} + {8 - Q98 K} + {9 Q97 - 7} + {J JT86 - -} + } 3 spades + +problem 52 {Crossruff strip triple squeeze} { + {6 76 - 76} + {9 QJ - QJ} + {7 K8 Q 8} + {- - KJ876 -} + } 3 spades + +problem 53 {Forced triple squeeze (with fork strip)} { + {9 Q8 - Q7} + {- J7 - J64} + {A6 9 9 9} + {T8 - T T8} + } 4 notrump + +problem 54 {Squeeze strip or suitout} { + {- 76 A2 2} + {- J8 KQ K} + {7 AQ5 7 -} + {- K94 95 -} + } 4 spades + +problem 55 {Triple squeeze forced finesse} { + {Q6 3 8 2} + {K 82 A 8} + {- A4 K AK} + {T4 T - T4} + } 4 notrump + +problem 56 {Jettison squeeze finesse} { + {A K2 K2 -} + {42 - - QJ9} + {53 - - AK3} + {K A A 87} + } 4 notrump + +problem 57 {Squeeze or strip squeeze} { + {- AQ9 KQ -} + {7 KJ AJ -} + {K 2 2 JT} + {4 - - Q654} + } 4 spades + +problem 58 {Triple squeeze scoop strip} { + {K874 - - 2} + {A65 - - 98} + {2 9 9 AK} + {QJ Q Q Q} + } 4 notrump + +problem 59 {Triple squeeze entry strip} { + {A654 K - -} + {T987 - - K} + {KQJ - K 2} + {32 A A A} + } 4 notrump + +problem 60 {Jettison triple squeeze entry strip} { + {43 2 J A} + {K - 98 54} + {A - 432 6} + {95 9 - K9} + } 4 notrump + +problem 61 {Fork squeeze entry strip} { + {- A52 - A9} + {- J K9 K8} + {- K73 Q7 -} + {- Q86 - 64} + } 4 notrump + +problem 62 {Squeeze finesse} { + {K2 9 9 K} + {J864 - - J} + {A95 - - A2} + {Q3 A A Q} + } 5 notrump + +problem 63 {Finesse threat 3-2 squeeze} { + {2 - K5 A7} + {- J8 J97 -} + {- 2 AT43 -} + {- 9 Q8 J9} + } 5 spades + +problem 64 {Hexagon squeeze finesse} { + {2 A9 2 2} + {K Q Q4 J} + {- 2 A9 AK} + {A K4 K Q} + } 5 notrump + +problem 65 {One-way squeeze scoop finesse} { + {KJ2 K - 2} + {Q54 3 - 4} + {A63 - - AK} + {987 A - 3} + } 5 notrump + +problem 66 {Automatic squeeze scoop finesse} { + {- - T5 A52} + {98 - Q76 -} + {- 9 K8 K9} + {- - 93 T86} + } 5 notrump + +problem 67 {Squeeze ruffout} { + {A5 - K98 -} + {7 - - QJ87} + {93 T95 - -} + {- KQ QJT -} + } 5 spades + +problem 68 {Squeeze overruff} { + {Q5 5 - KQ} + {K KT 87 -} + {- A87 T 9} + {- J64 J 5} + } 5 clubs + +problem 69 {Repeat-squeeze entry strip} { + {2 K4 K K} + {AK97 9 - -} + {QJ64 8 - -} + {8 A2 Q Q} + } 2 notrump + +problem 70 {Forced unblock triple-squeeze scoop} { + {QJ8 7 7 -} + {- 9 J J94} + {965 - - Q8} + {AK7 - - K7} + } 2 notrump + +problem 71 {Squeeze unblock finesse} { + {Q5 32 - J} + {A64 K9 - -} + {K8 AJ - 9} + {JT97 - - A} + } 3 notrump + +problem 72 {Blocked fork strip} { + {- Q7 J92} + {- K952 Q} + {J 8 A73} + {3 J K85} + } 3 spades + +problem 73 {En passant mutate} { + {86 74 - 8} + {AQ 6 76 -} + {K AJ QT -} + {- Q98 KJ -} + } 4 spades + +problem 74 {Repeated trump discard} { + {42 QJ9 - -} + {KQ8 - QJ -} + {AJ63 - - 8} + {9 7 976 -} + } 4 spades west + +problem 75 {Squeeze scoop ruffout} { + {- K9 K AQ} + {- A8 - K54} + {97 - 9 97} + {- QJ Q J6} + } 5 spades + +problem 76 {Coup or squeeze} { + {864 - - Q9} + {- 5 JT K8} + {- 7 7 A42} + {75 - 6 T7} + } 5 spades + +problem 77 {Triple-squeeze ruffout} { + {52 - 98 9} + {J 2 KQ Q} + {A4 - 74 7} + {- KQ975 - -} + } 4 spades west + +problem 78 {Progressive squeeze jettison scoop} { + {5 95 - A7} + {- Q8 - JT9} + {- J 76 Q3} + {9 AT - K8} + } 4 notrump + +problem 79 {Double squeeze strip} { + {- A97 83 -} + {- T86 T9 -} + {8 QJ3 - Q} + {K5 K54 - -} + } 4 notrump + +problem 80 {One-way squeeze or ditto} { + {7 Q7 7 7} + {- - A6 864} + {- J J4 J5} + {A 986 5 -} + } 4 notrump + +problem 81 {En passant or double squeeze} { + {J5 5 - J8} + {- - 98 Q74} + {3 - J3 K3} + {Q9 Q - 96} + } 4 spades + +problem 82 {Squeeze entry strip} { + {5 Q6 AJ -} + {9 J9 K K} + {8 - Q54 8} + {Q6 - 976 -} + } 4 notrump + +problem 83 {Double-squeeze scoop} { + {- - 86 AQ6} + {- 98 - K84} + {J J - 953} + {- - JT JT7} + } 3 notrump + +problem 84 {Jettison strip mutate} { + {- A A K92} + {3 J5 - AT} + {5 Q6 T8 -} + {- K 973 Q} + } 4 spades + +problem 85 {Split squeeze entry strip} { + {J53 - AQ} + {KQ9 - KJ} + {82 Q73 -} + {- 964 42} + } 3 notrump + +problem 86 {Hexagon squeeze finesse} { + {- 9 A9 75} + {- Q7 Q7 Q} + {8 K8 8 8} + {- J J6 J6} + } 4 notrump + +problem 87 {Endplays in series} { + {9 A8 - 87} + {T - T9 T9} + {- 92 5 A4} + {K K765 - -} + } 4 notrump + +problem 88 {Contra squeeze} { + {- A T43 A} + {A2 K J K} + {KQJ - K2 -} + {- - AQ765 -} + } 3 notrump + diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/tests/input/sample.line /tmp/sFHmVEdqkv/deal-3.1.4/tests/input/sample.line --- deal-3.0.8/tests/input/sample.line 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/tests/input/sample.line 2008-05-22 07:07:25.000000000 +0530 @@ -0,0 +1,100 @@ +8532 Q7 AK4 T952| A962 JT932 AK43|A JT8543 876 Q76|KQJT9764 K Q5 J8 +A 87 QJT642 Q752|QJ986 A AK5 KT63|KT75432 JT6 AJ9| KQ95432 9873 84 +AT54 Q9 842 AT75|K87 KT876 Q9 KQ9|Q63 AJ KJ753 J63|J92 5432 AT6 842 +AQ64 42 QJ843 83|97 QT76 97 QJ975|J8532 J853 6 AT6|KT AK9 AKT52 K42 +AJ K964 AQ65 J74|T973 J5 K94 A962|85 8 JT832 KT853|KQ642 AQT732 7 Q +AKT KQ752 6 T643|Q9843 J9752 AQ9|652 T84 AQ8 J875|J7 AJ963 KT43 K2 +AQ73 JT75 5 A862|86 KQ9 KJ87 KJT4|J2 A862 QT96 Q73|KT954 43 A432 95 +AJ743 Q6 JT5 K65|96 J85 A86 JT943|KQT AT42 Q43 A82|852 K973 K972 Q7 +T5 T643 Q85 Q542|8643 92 JT742 76|AQJ92 8 K63 AT93|K7 AKQJ75 A9 KJ8 +A874 94 AK93 QT3|T3 KJT7 QJT5 AJ2|J952 AQ53 842 K8|KQ6 862 76 97654 +Q764 T5 AK2 KQ86|T95 7 QT9873 J74|2 AQJ86432 4 T32|AKJ83 K9 J65 A95 +AT96 Q2 K73 AQJ4|Q3 AJT93 QJ2 K98|KJ52 K75 986 T53|874 864 AT54 762 +AQ6 T8752 2 Q863|852 AQJ9 QJT96 4|J9743 63 3 KT972|KT K4 AK8754 AJ5 +654 Q982 T93 732|QT7 AKJ64 QJ AQJ|AJ9 T73 A87542 9|K832 5 K6 KT8654 +AKQJ 3 AJ95 Q864|72 762 T8 JT9753|84 AKJ984 K43 AK|T9653 QT5 Q762 2 +JT987 753 J73 A4|K63 KT6 AKQ52 K5|AQ4 J92 T94 T832|52 AQ84 86 QJ976 +KJ6 J52 4 T75432|AQ9 4 KT982 AKQ9|8432 KQT97 A75 J|T75 A863 QJ63 86 +A5 T985 AQ872 K5|QJ74 K63 J9 Q963|92 QJ74 T43 AJ42|KT863 A2 K65 T87 +AJ82 Q8 8 AKQJ76|54 KT AQ97654 82|KT73 A7542 J T53|Q96 J963 KT32 94 +4 42 K32 T965432|AT952 J7 AJ84 K7|KQJ3 Q5 Q75 AQJ8|876 AKT9863 T96 +AKQ42 KT93 KT62|53 Q76 QT9632 93|J876 J84 AKJ5 87|T9 A52 874 AQJ54 +8765 K7 AT53 853|QJT J Q842 JT976|K92 AT9652 97 KQ|A43 Q843 KJ6 A42 +Q7 J9743 Q975 T8|JT94 KQT A6 K972|K65 62 T832 QJ54|A832 A85 KJ4 A63 +753 Q872 Q742 T3|AKT9642 T63 85 8|8 A4 AJ3 J976542|QJ KJ95 KT96 AKQ +9843 8 J76542 AT|K76 A32 Q98 KJ32|AQ52 QJT64 AT 97|JT K975 K3 Q8654 +Q52 T94 A853 K92|AT974 KJ82 KJ 74|863 3 Q72 AQJT65|KJ AQ765 T964 83 +KT65 AT5 AKJ J63|AJ7 Q32 QT7 A742|84 KJ4 8652 KT98|Q932 9876 943 Q5 +QJ2 AT543 K93 65|AT63 KQJ762 T7 4|987 8 QJ8 AKQJ98|K54 9 A6542 T732 +A5 JT74 AQJ T842|QJ4 9 T87643 963|T9872 KQ52 2 J75|K63 A863 K95 AKQ +AK73 AJ9842 Q52 |JT5 Q75 A974 Q65|9642 T3 KJ3 KJ98|Q8 K6 T86 AT7432 +75 652 AK743 Q95|KT43 A943 J8 AKJ|6 KQ87 T962 T742|AQJ982 JT Q5 863 +Q93 A62 J642 K96|AJ87 J9854 A9 JT|K42 KT7 KQ73 Q32|T65 Q3 T85 A8754 +J9753 Q532 AT K4|AQT82 964 73 832|K4 AKT8 Q964 J97|6 J7 KJ852 AQT65 +Q8765 AKJ KQ743|A932 KQJ985 3 J5|4 A6432 Q654 T62|KJT T7 T9872 A98 +KQT42 K864 K62 3|AJ87 T5 T8753 Q5|63 AJ73 Q9 KT872|95 Q92 AJ4 AJ964 +K5 Q4 K854 KJ982|QJ96 A9732 732 3|A84 KJT6 J96 Q74|T732 85 AQT AT65 +KT953 J T KJT974|Q72 T75 J7642 86|AJ6 962 853 AQ53|84 AKQ843 AKQ9 2 +T653 KQT72 J97 T|92 J86 AT84 6532|KQ 9 Q653 AJ9874|AJ874 A543 K2 KQ +AK75 9743 KQ K94|32 AKQ6 AJ3 AQJ2|T986 5 76542 T53|QJ4 JT82 T98 876 +AJ87 Q864 QJ53 T|5 A3 A87 KQJ9843|KQT63 K75 K92 72|942 JT92 T64 A65 +J98 97 JT96 AJ95|T AK8542 542 Q32|KQ642 QJ3 A87 T7|A753 T6 KQ3 K864 +Q AT J9864 Q9642|J98652 QJ Q2 JT8|AKT43 32 T75 AK5|7 K987654 AK3 73 +93 AT5 A763 AQ85|QT2 J432 QJT5 K2|7 K96 9842 T9764|AKJ8654 Q87 K J3 +KQ7 Q962 KT5 K95|A943 A87 A32 QT6|852 KJT4 QJ84 72|JT6 53 976 AJ843 +K653 KQ2 AKT9 Q3|7 A5 J542 AKT654|QJT JT98 Q873 72|A9842 7643 6 J98 +Q5 T8 AKJ943 875|KJ93 J6432 Q QJ6|AT864 A T86 AT32|72 KQ975 752 K94 +4 KT3 AKT4 JT652|AKQ65 Q 97652 AK|T932 97654 J Q94|J87 AJ82 Q83 873 +Q7 T964 K6 Q9765|KJ8632 7 J93 842|A5 QJ82 AQ72 AT3|T94 AK53 T854 KJ +643 JT6 AK3 K932|T97 A872 J97 Q76|K82 KQ3 Q8 AJT85|AQJ5 954 T6542 4 +KJ732 AJ653 KJ 8|9 T87 Q97654 954|QT84 94 AT83 KQ2|A65 KQ2 2 AJT763 +Q852 KT QT86 A85|KT97 4 A954 KQ63|43 AQJ75 732 J92|AJ6 98632 KJ T74 +A9765 A87 AQ A85|Q 654 87642 QT96|T43 JT3 JT9 7432|KJ82 KQ92 K53 KJ +AKQ73 AT52 Q63 Q|J54 3 AKJ92 9432|62 KQ8 8754 A876|T98 J9764 T KJT5 +AQ7 A965 A52 Q62|KJ96 QJ42 64 873|43 K83 KQJT9 AK5|T852 T7 873 JT94 +KJ9643 A QJ6 K64|A82 QT52 A42 A87|QT75 K3 985 QJT5| J98764 KT73 932 +AJ875 AKJ7 5 KJ8|Q42 KQ76 A97654|K6 QT8532 AT2 T3|T93 964 J9843 Q2 +T95432 A7543 5 5|AJ7 QJ8 A43 AQ83|86 92 J876 T7642|KQ KT6 KQT92 KJ9 +AKT53 87 Q83 AK3|J2 AJT9 J6 J9764|Q9874 Q65 A4 T82|6 K432 KT9752 Q5 +T643 92 K9853 86|A52 AK73 Q72 K93|Q8 J8654 AJT64 2|KJ97 QT AQJT754 +K9743 T63 A72 KJ|T65 AJ92 65 Q652|AJ82 Q8 KJ943 A4|Q K754 QT8 T9873 +QJ543 K9 AQT83 4|AKT98 J865 AT83|6 432 KJ542 QJ97|72 AQT7 976 K652 +T2 JT864 J2 K542|Q7 KQ9753 Q98 J7|J A2 AKT64 AQ983|AK986543 753 T6 +QT8 2 T653 KT954|AK7 Q3 9742 AQ87|95 AKJ8654 J8 J2|J6432 T97 AKQ 63 +Q8 A92 JT975 KJT|AJ9 J6 Q632 AQ53|T7642 K873 A4 64|K53 QT54 K8 9872 +K54 Q65 AJ9862 K|J7 AKT83 5 AJ985|AQT8 J KQT73 QT2|9632 9742 4 7643 +T4 A972 AKJT985|K3 J85 JT974 Q76|AQJ9 KT43 K63 43|87652 Q6 AQ852 2 +T72 QJT3 A32 K84|K8643 A64 QJ5 53|J5 K952 8764 972|AQ9 87 KT9 AQJT6 +T986 K764 KQ652|AQ7 A82 JT85 A83|3 QJT95 AQ732 J9|KJ542 3 K964 T74 +J765432 A95 3 65|T8 Q4 Q852 AQJ74|AKQ KT863 4 K932|9 J72 AKJT976 T8 +Q93 AT64 5432 62|542 Q8 AQT AQT93|AJT7 KJ7 KJ97 J4|K86 9532 86 K875 +JT6 QJ986 JT7 AK|K82 T54 AQ8653 9|A93 K3 K942 Q732|Q754 A72 JT8654 +K642 A843 K7652|A973 QJ52 765 98|QJT85 T43 J AQJ3| AK9876 KQT92 T4 +AT74 K9762 5 K82|Q6 T5 9843 JT964|K82 J843 J762 Q3|J953 AQ AKQT A75 +T6 A43 754 AKQ73|K852 KQJ765 542|A974 T98 AQJ3 T6|QJ3 2 KT9862 J98 +A964 8 A73 AKQ76|K3 AQ64 T62 9852|75 KJT973 J9854 |QJT82 52 KQ JT43 +KT54 AK 732 KJ75|9 J6542 KJ85 QT9|AQ2 QT3 AT4 8643|J8763 987 Q96 A2 +JT985 KQ94 Q3 A7|K64 AT752 76 QJ9|Q3 83 AK52 T8632|A72 J6 JT984 K54 +AJT9 6 J94 Q9654|765 83 A AKT8732|Q3 A4 KT876532 J|K842 KQJT9752 Q +AQ75 JT J6 K9653|32 87 KQ9874 JT4|K984 Q932 T A872|JT6 AK654 A532 Q +652 T7 872 AT943|AKT743 64 KJ 762|QJ9 KJ932 Q94 QJ|8 AQ85 AT653 K85 +A643 QJ9632 6 J8|J72 74 QJT85 QT6|Q85 KT85 A974 75|KT9 A K32 AK9432 +KJT432 T Q9762 T|A5 AKJ98 KJ8 K92|876 Q6543 4 8643|Q9 72 AT53 AQJ75 +T AQJ9542 AK A32|K9864 K3 JT75 KJ|AQJ3 T8 Q8 Q9854|752 76 96432 T76 +KJ KT94 QT4 A653|QT87432 J3 A3 97|A965 A765 K6 KQ8| Q82 J98752 JT42 +AKT86 T84 T52 K5|3 KJ2 K764 JT876|Q94 AQ3 AJ98 Q43|J752 9765 Q3 A92 +KJ 764 KJT96 A86|763 932 Q7542 Q5|T984 AT5 A3 J732|AQ52 KQJ8 8 KT94 +652 T2 J432 QJ75|K87 AQ7 987 KT83|AJT4 965 KQ65 A6|Q93 KJ843 AT 942 +A9632 86 Q2 9765|KQJ8 AQT4 T64 AJ|T754 95 AJ7 KQT2| KJ732 K9853 843 +3 Q93 AK7 AKJ853|JT876 42 J85 Q62|Q5 AKJ765 QT96 7|AK942 T8 432 T94 +QJ6 A976 KQJ6 Q9|AT75 K8 T7 AKT42|K8432 JT5 A9 765|9 Q432 85432 J83 +AQ76 KJ62 JT62 7|T3 AQT53 K3 KJ53|984 84 AQ87 AQ96|KJ52 97 954 T842 +A75 K52 AJ4 AJ97|QJ6 AT76 T95 T64|T9832 QJ4 3 K532|K4 983 KQ8762 Q8 +A532 A765 7 KQ32|KJ8 Q3 QT53 AJ95|64 K984 AKJ94 T8|QT97 JT2 862 764 +T Q762 AQ K87642|KQJ95 AT985 J7 9|A862 3 K86543 Q3|743 KJ4 T92 AJT5 +J972 KJT854 A KJ|T A9762 KT932 87|AQ3 QJ876 Q6432|K8654 Q3 54 AT95 +82 T7642 53 Q742|K97653 5 Q76 JT5|QT4 K3 T92 AK986|AJ AQJ98 AKJ84 3 +AQJ8 Q AT8532 J4|763 T962 K74 976|KT42 K5 J9 KQT53|95 AJ8743 Q6 A82 +AJ64 843 862 J43|K97 A7 KQT94 975|Q2 KQT96 J5 QT82|T853 J52 A73 AK6 +AJ763 K84 J5432 |98 6 QT7 AQJ9863|QT4 AT95 AK96 KT|K52 QJ732 8 7542 +AT63 J8 KT542 KQ|KQ92 75432 A J64|8 QT96 9763 8732|J754 AK QJ8 AT95 diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/tests/output/sample.ddline /tmp/sFHmVEdqkv/deal-3.1.4/tests/output/sample.ddline --- deal-3.0.8/tests/output/sample.ddline 1970-01-01 05:30:00.000000000 +0530 +++ deal-3.1.4/tests/output/sample.ddline 2008-05-22 07:00:13.000000000 +0530 @@ -0,0 +1,100 @@ +8532.Q7.AK4.T952|.A962.JT932.AK43|A.JT8543.876.Q76|KQJT9764.K.Q5.J8|2 7 4 4 4|10 6 9 8 7|2 7 3 4 3|10 6 9 8 7 +A.87.QJT642.Q752|QJ986.A.AK5.KT63|KT75432.JT6..AJ9|.KQ95432.9873.84|7 2 6 6 7|5 11 7 5 6|7 2 5 6 6|4 10 7 5 6 +AT54.Q9.842.AT75|K87.KT876.Q9.KQ9|Q63.AJ.KJ753.J63|J92.5432.AT6.842|8 6 9 8 7|5 7 4 5 5|8 6 8 8 7|5 7 4 5 5 +AQ64.42.QJ843.83|97.QT76.97.QJ975|J8532.J853.6.AT6|KT.AK9.AKT52.K42|8 5 6 3 6|5 8 7 9 7|8 5 6 3 6|5 8 7 9 7 +AJ.K964.AQ65.J74|T973.J5.K94.A962|85.8.JT832.KT853|KQ642.AQT732.7.Q|3 3 9 9 6|10 10 3 4 6|3 3 9 9 6|10 10 3 4 6 +AKT.KQ752.6.T643|Q9843..J9752.AQ9|652.T84.AQ8.J875|J7.AJ963.KT43.K2|4 7 3 7 4|9 6 10 5 7|4 7 3 7 5|9 6 10 6 8 +AQ73.JT75.5.A862|86.KQ9.KJ87.KJT4|J2.A862.QT96.Q73|KT954.43.A432.95|6 9 6 7 6|7 4 7 5 7|6 8 6 7 6|7 4 7 5 6 +AJ743.Q6.JT5.K65|96.J85.A86.JT943|KQT.AT42.Q43.A82|852.K973.K972.Q7|10 8 8 7 9|3 4 4 6 3|10 8 8 7 9|3 4 4 6 3 +T5.T643.Q85.Q542|8643.92.JT742.76|AQJ92.8.K63.AT93|K7.AKQJ75.A9.KJ8|7 3 6 8 5|6 8 7 4 8|7 5 6 8 5|6 8 7 4 8 +A874.94.AK93.QT3|T3.KJT7.QJT5.AJ2|J952.AQ53.842.K8|KQ6.862.76.97654|10 7 9 7 8|3 6 4 6 5|10 7 9 7 8|3 5 4 6 4 +Q764.T5.AK2.KQ86|T95.7.QT9873.J74|2.AQJ86432.4.T32|AKJ83.K9.J65.A95|5 10 4 7 7|7 2 8 6 4|5 10 4 7 7|7 2 9 6 4 +AT96.Q2.K73.AQJ4|Q3.AJT93.QJ2.K98|KJ52.K75.986.T53|874.864.AT54.762|9 6 7 9 7|3 7 6 4 5|9 6 7 9 7|3 7 6 4 5 +AQ6.T8752.2.Q863|852.AQJ9.QJT96.4|J9743.63.3.KT972|KT.K4.AK8754.AJ5|5 3 0 8 2|4 8 11 4 8|5 3 0 8 2|6 9 12 5 11 +654.Q982.T93.732|QT7.AKJ64.QJ.AQJ|AJ9.T73.A87542.9|K832.5.K6.KT8654|2 3 6 1 2|10 10 6 11 10|2 3 6 1 2|10 10 6 11 10 +AKQJ.3.AJ95.Q864|72.762.T8.JT9753|84.AKJ984.K43.AK|T9653.QT5.Q762.2|12 12 13 10 13|1 1 0 3 0|12 12 13 10 13|1 1 0 3 0 +JT987.753.J73.A4|K63.KT6.AKQ52.K5|AQ4.J92.T94.T832|52.AQ84.86.QJ976|6 2 3 2 4|7 10 10 10 9|6 2 3 2 4|7 10 10 10 7 +KJ6.J52.4.T75432|AQ9.4.KT982.AKQ9|8432.KQT97.A75.J|T75.A863.QJ63.86|5 6 1 5 1|8 7 12 8 8|5 6 1 5 1|8 7 12 8 8 +A5.T985.AQ872.K5|QJ74.K63.J9.Q963|92.QJ74.T43.AJ42|KT863.A2.K65.T87|6 10 10 7 7|7 3 3 6 5|6 10 10 7 7|7 3 3 6 5 +AJ82.Q8.8.AKQJ76|54.KT.AQ97654.82|KT73.A7542.J.T53|Q96.J963.KT32.94|11 9 5 11 6|1 4 8 2 2|11 9 5 11 6|1 4 8 2 2 +4.42.K32.T965432|AT952.J7.AJ84.K7|KQJ3.Q5.Q75.AQJ8|876.AKT9863.T96.|4 2 2 8 2|9 10 8 4 10|4 2 2 8 2|9 10 8 4 6 +AKQ42.KT93..KT62|53.Q76.QT9632.93|J876.J84.AKJ5.87|T9.A52.874.AQJ54|11 10 7 8 9|2 3 6 5 4|11 10 7 8 9|2 3 6 5 4 +8765.K7.AT53.853|QJT.J.Q842.JT976|K92.AT9652.97.KQ|A43.Q843.KJ6.A42|5 7 4 3 4|6 6 8 10 7|6 7 4 3 4|6 6 8 10 7 +Q7.J9743.Q975.T8|JT94.KQT.A6.K972|K65.62.T832.QJ54|A832.A85.KJ4.A63|2 4 5 3 3|11 9 8 10 10|2 4 5 3 3|11 9 8 10 10 +753.Q872.Q742.T3|AKT9642.T63.85.8|8.A4.AJ3.J976542|QJ.KJ95.KT96.AKQ|2 3 4 7 2|11 9 8 6 11|2 3 4 7 2|11 9 8 6 11 +9843.8.J76542.AT|K76.A32.Q98.KJ32|AQ52.QJT64.AT.97|JT.K975.K3.Q8654|9 6 8 4 5|4 6 5 8 8|9 6 8 4 5|4 6 5 8 8 +Q52.T94.A853.K92|AT974.KJ82.KJ.74|863.3.Q72.AQJT65|KJ.AQ765.T964.83|2 1 5 8 3|9 10 7 5 6|2 1 5 8 3|9 10 7 5 6 +KT65.AT5.AKJ.J63|AJ7.Q32.QT7.A742|84.KJ4.8652.KT98|Q932.9876.943.Q5|7 7 8 8 8|6 5 5 5 5|7 7 8 8 8|6 6 5 5 5 +QJ2.AT543.K93.65|AT63.KQJ762.T7.4|987.8.QJ8.AKQJ98|K54.9.A6542.T732|5 5 7 10 8|7 8 5 3 4|5 5 7 10 8|7 8 5 3 4 +A5.JT74.AQJ.T842|QJ4.9.T87643.963|T9872.KQ52.2.J75|K63.A863.K95.AKQ|5 7 4 6 7|6 5 9 6 6|5 7 4 6 7|7 5 9 7 6 +AK73.AJ9842.Q52.|JT5.Q75.A974.Q65|9642.T3.KJ3.KJ98|Q8.K6.T86.AT7432|10 10 7 7 9|3 3 6 6 4|10 10 7 7 9|3 3 6 6 4 +75.652.AK743.Q95|KT43.A943.J8.AKJ|6.KQ87.T962.T742|AQJ982.JT.Q5.863|3 6 8 6 3|10 7 5 7 8|3 6 8 6 3|10 7 5 7 8 +Q93.A62.J642.K96|AJ87.J9854.A9.JT|K42.KT7.KQ73.Q32|T65.Q3.T85.A8754|5 6 8 6 8|7 6 4 6 4|6 5 8 6 8|7 6 4 6 4 +J9753.Q532.AT.K4|AQT82.964.73.832|K4.AKT8.Q964.J97|6.J7.KJ852.AQT65|7 8 6 5 7|5 4 6 7 5|7 8 6 5 7|5 4 6 7 5 +Q8765..AKJ.KQ743|A932.KQJ985.3.J5|4.A6432.Q654.T62|KJT.T7.T9872.A98|6 4 8 9 4|6 8 5 4 5|6 4 8 9 4|6 8 5 4 5 +KQT42.K864.K62.3|AJ87.T5.T8753.Q5|63.AJ73.Q9.KT872|95.Q92.AJ4.AJ964|6 8 4 6 5|7 5 8 7 7|6 8 5 6 6|7 5 8 7 7 +K5.Q4.K854.KJ982|QJ96.A9732.732.3|A84.KJT6.J96.Q74|T732.85.AQT.AT65|6 7 7 9 8|7 6 5 4 4|6 7 7 9 8|7 6 5 4 4 +KT953.J.T.KJT974|Q72.T75.J7642.86|AJ6.962.853.AQ53|84.AKQ843.AKQ9.2|11 2 1 11 2|2 10 10 2 2|11 2 1 11 2|2 10 10 2 2 +T653.KQT72.J97.T|92.J86.AT84.6532|KQ.9.Q653.AJ9874|AJ874.A543.K2.KQ|5 6 7 7 6|7 7 5 6 6|5 6 7 7 6|7 7 5 6 6 +AK75.9743.KQ.K94|32.AKQ6.AJ3.AQJ2|T986.5.76542.T53|QJ4.JT82.T98.876|8 3 7 4 3|5 10 6 9 10|7 3 5 3 3|5 10 6 9 10 +AJ87.Q864.QJ53.T|5.A3.A87.KQJ9843|KQT63.K75.K92.72|942.JT92.T64.A65|10 8 8 3 4|3 5 4 9 8|10 8 8 3 4|3 4 4 9 8 +J98.97.JT96.AJ95|T.AK8542.542.Q32|KQ642.QJ3.A87.T7|A753.T6.KQ3.K864|7 4 6 5 7|6 9 7 7 6|7 4 6 5 6|6 9 7 7 6 +Q.AT.J9864.Q9642|J98652.QJ.Q2.JT8|AKT43.32.T75.AK5|7.K987654.AK3.73|8 4 10 9 9|5 9 3 3 4|8 4 10 9 9|5 9 3 3 4 +93.AT5.A763.AQ85|QT2.J432.QJT5.K2|7.K96.9842.T9764|AKJ8654.Q87.K.J3|4 5 5 8 4|9 8 5 5 8|4 5 5 8 4|9 8 5 5 8 +KQ7.Q962.KT5.K95|A943.A87.A32.QT6|852.KJT4.QJ84.72|JT6.53.976.AJ843|5 8 7 4 5|8 5 5 8 7|4 8 7 4 5|8 5 5 8 7 +K653.KQ2.AKT9.Q3|7.A5.J542.AKT654|QJT.JT98.Q873.72|A9842.7643.6.J98|6 5 8 3 5|6 5 5 9 8|6 5 8 3 5|6 5 5 9 8 +Q5.T8.AKJ943.875|KJ93.J6432.Q.QJ6|AT864.A.T86.AT32|72.KQ975.752.K94|9 4 11 10 9|4 9 2 3 3|9 4 11 9 9|4 9 2 3 3 +4.KT3.AKT4.JT652|AKQ65.Q.97652.AK|T932.97654.J.Q94|J87.AJ82.Q83.873|3 5 3 7 4|9 6 9 5 9|3 5 3 7 4|9 7 9 5 9 +Q7.T964.K6.Q9765|KJ8632.7.J93.842|A5.QJ82.AQ72.AT3|T94.AK53.T854.KJ|4 9 7 9 6|8 4 5 4 5|4 9 7 9 6|8 4 5 4 5 +643.JT6.AK3.K932|T97.A872.J97.Q76|K82.KQ3.Q8.AJT85|AQJ5.954.T6542.4|7 7 6 9 8|6 6 7 3 5|7 7 6 9 8|6 6 7 3 5 +KJ732.AJ653.KJ.8|9.T87.Q97654.954|QT84.94.AT83.KQ2|A65.KQ2.2.AJT763|10 8 7 4 7|3 4 6 8 3|10 8 7 4 10|3 5 6 8 3 +Q852.KT.QT86.A85|KT97.4.A954.KQ63|43.AQJ75.732.J92|AJ6.98632.KJ.T74|4 6 5 3 5|9 7 8 9 7|3 6 4 3 5|9 7 8 9 8 +A9765.A87.AQ.A85|Q.654.87642.QT96|T43.JT3.JT9.7432|KJ82.KQ92.K53.KJ|6 5 5 6 6|6 7 8 7 6|7 6 5 6 7|6 7 8 7 6 +AKQ73.AT52.Q63.Q|J54.3.AKJ92.9432|62.KQ8.8754.A876|T98.J9764.T.KJT5|10 9 8 5 10|3 3 5 8 3|9 7 5 4 8|3 3 5 8 3 +AQ7.A965.A52.Q62|KJ96.QJ42.64.873|43.K83.KQJT9.AK5|T852.T7.873.JT94|8 11 12 10 12|5 2 1 3 1|8 10 12 10 12|5 2 1 3 1 +KJ9643.A.QJ6.K64|A82.QT52.A42.A87|QT75.K3.985.QJT5|.J98764.KT73.932|9 4 5 7 7|4 9 7 6 5|9 4 5 7 7|4 9 7 6 5 +AJ875.AKJ7.5.KJ8|Q42..KQ76.A97654|K6.QT8532.AT2.T3|T93.964.J9843.Q2|11 12 5 5 10|2 1 8 7 2|11 12 5 5 10|2 1 8 7 2 +T95432.A7543.5.5|AJ7.QJ8.A43.AQ83|86.92.J876.T7642|KQ.KT6.KQT92.KJ9|5 3 1 1 1|7 10 12 12 12|5 3 1 1 1|7 10 12 12 12 +AKT53.87.Q83.AK3|J2.AJT9.J6.J9764|Q9874.Q65.A4.T82|6.K432.KT9752.Q5|10 4 5 6 8|3 8 8 7 5|10 5 5 6 8|3 8 8 7 5 +T643.92.K9853.86|A52.AK73.Q72.K93|Q8.J8654.AJT64.2|KJ97.QT..AQJT754|1 4 7 0 0|12 8 5 13 8|1 4 7 0 0|12 8 5 13 8 +K9743.T63.A72.KJ|T65.AJ92.65.Q652|AJ82.Q8.KJ943.A4|Q.K754.QT8.T9873|10 5 10 5 9|3 8 3 8 4|10 5 10 5 9|3 8 3 8 4 +QJ543.K9.AQT83.4|AKT98.J865..AT83|6.432.KJ542.QJ97|72.AQT7.976.K652|5 3 9 3 6|8 10 4 10 7|5 3 9 3 6|8 10 4 10 7 +T2.JT864.J2.K542|Q7.KQ9753.Q98.J7|J.A2.AKT64.AQ983|AK986543..753.T6|4 8 9 10 5|8 4 2 1 2|5 8 10 10 5|8 4 2 1 2 +QT8.2.T653.KT954|AK7.Q3.9742.AQ87|95.AKJ8654.J8.J2|J6432.T97.AKQ.63|3 6 4 5 6|10 6 9 7 6|3 6 4 5 6|10 6 9 8 6 +Q8.A92.JT975.KJT|AJ9.J6.Q632.AQ53|T7642.K873.A4.64|K53.QT54.K8.9872|6 5 5 4 4|7 7 7 9 8|6 5 5 4 4|7 7 7 9 8 +K54.Q65.AJ9862.K|J7.AKT83.5.AJ985|AQT8.J.KQT73.QT2|9632.9742.4.7643|10 6 11 6 10|3 7 1 7 3|10 6 11 6 10|3 7 1 7 3 +T4.A972..AKJT985|K3.J85.JT974.Q76|AQJ9.KT43.K63.43|87652.Q6.AQ852.2|9 12 5 12 8|3 1 8 1 3|9 12 5 12 9|3 1 8 1 3 +T72.QJT3.A32.K84|K8643.A64.QJ5.53|J5.K952.8764.972|AQ9.87.KT9.AQJT6|2 6 4 2 3|10 7 8 10 9|2 6 4 2 3|10 7 8 10 9 +T986.K764..KQ652|AQ7.A82.JT85.A83|3.QJT95.AQ732.J9|KJ542.3.K964.T74|3 10 5 6 3|8 3 8 7 8|3 10 5 6 3|8 3 8 7 8 +J765432.A95.3.65|T8.Q4.Q852.AQJ74|AKQ.KT863.4.K932|9.J72.AKJT976.T8|10 9 4 5 5|3 4 9 8 4|10 9 4 5 5|3 4 9 8 4 +Q93.AT64.5432.62|542.Q8.AQT.AQT93|AJT7.KJ7.KJ97.J4|K86.9532.86.K875|8 8 8 5 6|4 5 4 8 7|8 8 8 5 6|4 5 4 8 6 +JT6.QJ986.JT7.AK|K82.T54.AQ8653.9|A93.K3.K942.Q732|Q754.A72..JT8654|6 8 7 7 9|6 3 5 6 3|7 8 7 7 9|5 3 5 6 3 +K642..A843.K7652|A973.QJ52.765.98|QJT85.T43.J.AQJ3|.AK9876.KQT92.T4|11 2 3 11 6|1 8 7 1 7|11 2 5 12 6|2 8 8 1 7 +AT74.K9762.5.K82|Q6.T5.9843.JT964|K82.J843.J762.Q3|J953.AQ.AKQT.A75|7 9 5 4 6|6 4 8 8 5|7 9 5 5 7|6 4 8 8 6 +T6.A43.754.AKQ73|K852.KQJ765..542|A974.T98.AQJ3.T6|QJ3.2.KT9862.J98|7 7 9 9 9|6 6 4 3 4|7 6 9 9 9|6 6 4 3 4 +A964.8.A73.AKQ76|K3.AQ64.T62.9852|75.KJT973.J9854.|QJT82.52.KQ.JT43|7 10 10 7 7|6 3 2 6 4|7 10 10 7 7|5 3 2 6 4 +KT54.AK.732.KJ75|9.J6542.KJ85.QT9|AQ2.QT3.AT4.8643|J8763.987.Q96.A2|9 6 7 9 9|4 7 6 3 4|9 6 7 9 9|4 7 6 3 4 +JT985.KQ94.Q3.A7|K64.AT752.76.QJ9|Q3.83.AK52.T8632|A72.J6.JT984.K54|7 6 6 7 7|5 7 7 6 5|7 6 6 7 7|5 7 7 6 5 +AJT9.6.J94.Q9654|765.83.A.AKT8732|Q3.A4.KT876532.J|K842.KQJT9752.Q.|7 4 11 6 9|5 9 1 6 3|7 4 11 6 9|6 9 1 6 3 +AQ75.JT.J6.K9653|32.87.KQ9874.JT4|K984.Q932.T.A872|JT6.AK654.A532.Q|9 6 3 8 5|4 7 10 4 7|9 6 3 8 5|4 7 10 4 7 +652.T7.872.AT943|AKT743.64.KJ.762|QJ9.KJ932.Q94.QJ|8.AQ85.AT653.K85|3 5 3 4 3|10 8 9 8 9|3 5 3 4 3|10 8 10 9 9 +A643.QJ9632.6.J8|J72.74.QJT85.QT6|Q85.KT85.A974.75|KT9.A.K32.AK9432|6 8 2 2 2|7 5 11 10 7|6 8 2 2 2|7 5 11 10 7 +KJT432.T.Q9762.T|A5.AKJ98.KJ8.K92|876.Q6543.4.8643|Q9.72.AT53.AQJ75|7 1 2 0 1|6 11 10 13 12|7 1 2 0 1|6 12 11 13 12 +T.AQJ9542.AK.A32|K9864.K3.JT75.KJ|AQJ3.T8.Q8.Q9854|752.76.96432.T76|8 11 7 11 11|5 2 6 2 2|8 11 7 11 11|5 2 6 2 2 +KJ.KT94.QT4.A653|QT87432.J3.A3.97|A965.A765.K6.KQ8|.Q82.J98752.JT42|9 10 8 9 11|4 2 5 3 2|9 11 8 10 11|4 2 5 3 2 +AKT86.T84.T52.K5|3.KJ2.K764.JT876|Q94.AQ3.AJ98.Q43|J752.9765.Q3.A92|11 9 9 7 11|2 4 2 6 2|11 9 9 7 10|2 4 2 6 2 +KJ.764.KJT96.A86|763.932.Q7542.Q5|T984.AT5.A3.J732|AQ52.KQJ8.8.KT94|6 5 7 6 6|7 7 6 6 6|6 5 7 6 6|7 7 6 6 6 +652.T2.J432.QJ75|K87.AQ7.987.KT83|AJT4.965.KQ65.A6|Q93.KJ843.AT.942|7 4 9 5 6|6 8 4 7 7|7 4 9 5 6|5 8 4 7 7 +A9632.86.Q2.9765|KQJ8.AQT4.T64.AJ|T754.95.AJ7.KQT2|.KJ732.K9853.843|6 3 3 6 5|7 10 10 7 8|6 3 3 6 5|7 10 10 7 8 +3.Q93.AK7.AKJ853|JT876.42.J85.Q62|Q5.AKJ765.QT96.7|AK942.T8.432.T94|7 12 12 11 8|5 0 0 2 1|7 12 12 11 8|5 0 0 2 1 +QJ6.A976.KQJ6.Q9|AT75.K8.T7.AKT42|K8432.JT5.A9.765|9.Q432.85432.J83|9 7 7 5 6|4 6 6 8 6|9 7 7 5 6|4 6 6 8 6 +AQ76.KJ62.JT62.7|T3.AQT53.K3.KJ53|984.84.AQ87.AQ96|KJ52.97.954.T842|9 9 10 8 9|4 4 3 5 4|9 8 10 7 9|4 4 3 5 4 +A75.K52.AJ4.AJ97|QJ6.AT76.T95.T64|T9832.QJ4.3.K532|K4.983.KQ8762.Q8|10 8 6 10 9|3 5 6 3 4|10 8 6 10 9|3 5 6 3 4 +A532.A765.7.KQ32|KJ8.Q3.QT53.AJ95|64.K984.AKJ94.T8|QT97.JT2.862.764|8 11 9 8 8|5 2 4 5 5|8 11 9 8 8|5 2 4 5 5 +T.Q762.AQ.K87642|KQJ95.AT985.J7.9|A862.3.K86543.Q3|743.KJ4.T92.AJT5|3 3 8 8 3|8 8 5 4 6|3 3 8 9 3|8 8 5 4 6 +J972.KJT854.A.KJ|T.A9762.KT932.87|AQ3..QJ876.Q6432|K8654.Q3.54.AT95|8 7 7 8 7|4 5 5 4 5|8 7 7 8 8|4 5 5 4 5 +82.T7642.53.Q742|K97653.5.Q76.JT5|QT4.K3.T92.AK986|AJ.AQJ98.AKJ84.3|0 3 0 7 0|11 9 12 6 8|0 3 0 7 3|11 9 12 6 8 +AQJ8.Q.AT8532.J4|763.T962.K74.976|KT42.K5.J9.KQT53|95.AJ8743.Q6.A82|10 6 10 10 7|3 7 3 3 3|10 6 10 10 7|3 7 3 3 3 +AJ64.843.862.J43|K97.A7.KQT94.975|Q2.KQT96.J5.QT82|T853.J52.A73.AK6|4 6 4 6 4|9 6 9 7 9|4 6 4 6 4|8 6 9 7 8 +AJ763.K84.J5432.|98.6.QT7.AQJ9863|QT4.AT95.AK96.KT|K52.QJ732.8.7542|12 10 13 5 12|1 3 0 8 1|12 10 13 5 12|1 3 0 8 1 +AT63.J8.KT542.KQ|KQ92.75432.A.J64|8.QT96.9763.8732|J754.AK.QJ8.AT95|2 4 8 3 3|10 9 5 9 8|2 4 8 3 3|10 9 5 9 8 diff -Nru /tmp/SqcgMuwVDH/deal-3.0.8/vector.c /tmp/sFHmVEdqkv/deal-3.1.4/vector.c --- deal-3.0.8/vector.c 2001-02-19 22:44:53.000000000 +0530 +++ deal-3.1.4/vector.c 2008-05-15 05:49:24.000000000 +0530 @@ -79,7 +79,7 @@ int tcl_vector_define ( TCL_PARAMS ) TCL_DECL { int i; - char *name=argv[1]; + CONST84 char *name=argv[1]; LazyVectorData vec; if (argc<=1) { Tcl_AppendResult(interp,"usage: ",argv[0],