home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / rec / games / bridge / 6499 < prev    next >
Encoding:
Text File  |  1992-11-15  |  35.4 KB  |  1,420 lines

  1. Newsgroups: rec.games.bridge
  2. Path: sparky!uunet!van-bc!cs.ubc.ca!destroyer!gumby!wupost!darwin.sura.net!paladin.american.edu!news.univie.ac.at!hp4at!mcsun!sun4nl!star.cs.vu.nl!sater.home.cs.vu.nl!sater
  3. From: sater@sater.home.cs.vu.nl (Hans van Staveren)
  4. Subject: dealer program source, second release
  5. Message-ID: <Bxs2v1.356@sater.home.cs.vu.nl>
  6. Organization: The home machine of Hans van Staveren
  7. Date: Sun, 15 Nov 1992 22:09:00 GMT
  8. Lines: 1410
  9.  
  10. The dealer program I posted has released moderately positive response.
  11. One bug was detected, and there were some suggestions for improvement.
  12. Here is the second release.
  13.  
  14. Bugs fixed:
  15.     the shape() call returned integers not equal to 1 when true,
  16.     this screwed up things when used in a context not boolean
  17. Extra features:
  18. - It is now possible to predeal certain cards to certain players,
  19.   and distribute the rest at random.
  20. - The shape() operator now has better possibilities to include and exclude
  21.   shapes. Like any 54 in the majors but no void is now trivial to express.
  22.  
  23. Thanks to the people that made suggestions.
  24.  
  25.     Hans van Staveren
  26.     Amsterdam, Holland
  27.  
  28. : This is a shar archive.  Extract with sh, not csh.
  29. : This archive ends with exit, so do not worry about trailing junk.
  30. echo 'Extracting README'
  31. sed 's/^X//' > README << '+ END-OF-FILE README'
  32. XThis program is hereby put in the public domain. Do with it whatever
  33. Xyou want, but I would like you not to redistribute it in modified form
  34. Xwithout mentioning the fact of modification. I will accept bug reports
  35. Xand modification requests, without any obligation of course, but fixing
  36. Xbugs someone else put in is beyond me.
  37. X
  38. XWhen you report bugs please mention the version number in the source
  39. Xfiles, and preferably send context diffs if you changed anything.
  40. XI might put in your fixes, and distribute a new version someday.
  41. X
  42. XI would prefer if you did *not* use this program for generating hands
  43. Xfor tournaments. I have not investigated the random number generation
  44. Xclosely enough for me to be comfortable with that thought.
  45. X
  46. X    Hans van Staveren
  47. X    Amsterdam
  48. X    Holland
  49. X    <sater@sater.home.cs.vu.nl>
  50. + END-OF-FILE README
  51. chmod 'u=r,g=r,o=r' 'README'
  52. echo 'SENT: -r--r--r--  1 sater         792 Nov  4 20:52 README'
  53. echo -n 'RCVD: '
  54. /bin/ls -l README
  55. echo 'Extracting Description'
  56. sed 's/^X//' > Description << '+ END-OF-FILE Description'
  57. X    DEALER, a bridge hand generator program
  58. X    Hans van Staveren <sater@sater.home.cs.vu.nl>
  59. X
  60. XThe program dealer can be used to generate hands for partnerships
  61. Xbidding training or for generating statistics that can be used to
  62. Xdesign conventions, or win postmortems.
  63. X
  64. XThe program reads the description from standard input, and writes
  65. Xresults on standard output.
  66. X
  67. XIn general the input specifies a condition and an action, and the
  68. Xprogram will generate a lot of hands, and if the condition is satisfied
  69. Xexecute the action.
  70. X
  71. XA simple example:
  72. X
  73. X    shape(north, any 4333 + any 4423) and hcp(north)>=19
  74. X
  75. Xas input will print 40 hands with strong balanced Norths.
  76. X
  77. XHere is a partial explanation of all possible inputs: if you really want
  78. Xto know all read the source.
  79. X
  80. Xgenerate <number>
  81. X    generate <number> hands. If you do not specify this a million
  82. X    will be generated
  83. Xproduce <number>
  84. X    produce <number> hands that satisfy the condition. If you do specify
  85. X    this and you want the hands to be printed you get 40. If you only
  86. X    asked for statistics or so you will get a hundred thousand.
  87. X<identifier> = <expression>
  88. X    defines <identifier> to represent <expression>
  89. Xpredeal <predeallist>
  90. X    can be used to assign certain cards to certain hands, for example
  91. X    to check probabilities for actual play. See the example in
  92. X    Descr.6c for enlightenment.
  93. Xcondition <expression>
  94. X    for every hand generated <expression> is calculated. If it is
  95. X    non zero the corresponding action is executed. If you do not
  96. X    specify a condition the constant 1 will be assumed.
  97. X    The word condition can actually be omitted.
  98. Xaction <actionlist>
  99. X    list of actions to be executed. If you do not specify an action
  100. X    the "printall" action is assumed.
  101. X
  102. XThe "generate" and "produce" numbers are upper limits. The first one
  103. Xto become true will terminate the program.
  104. X
  105. XAn expression looks like a C expression, with all normal operators
  106. Xpresent. If you look for leftshift, or exponentiation forget it,
  107. Xbut all normal ones are there, with their normal priorities.
  108. XParentheses can be used, and all in all it is just like C.
  109. XThe && form can be used, or the word "and". The same goes for "or"
  110. Xand "not".
  111. X
  112. XThe special operators needed in a bridge-dealer program are provided:
  113. X
  114. X<suit> ( <compass> ) , eg hearts(west)
  115. X    the number of cards in the suit held by the player
  116. Xhcp ( <compass> ), eg hcp(north)
  117. X    the number of high card points held by the player, 4321 count.
  118. Xhcp ( <compass>, <suit> ), eg hcp(south, spades)
  119. X    the number of high card points in the specified suit
  120. Xhascard ( <compass>, <card> ), eg hascard(east, TC)
  121. X    whether east holds the 10 (T) of clubs
  122. Xshape ( <compass>, shapelist),
  123. X        eg shape(north, any 4333 + 54xx - any 0xxx)
  124. X    whether north holds one of the shapes in the list,
  125. X    in this case either a 4333 in any suit, or 5 spades and 4 hearts,
  126. X    but no void anywhere.
  127. X    A shapelist is a list of shapes combined with + or - signs.
  128. X    The word any prepended to a shape means that any suit can match
  129. X    the numbers, without the word any the shapes are the normal ones
  130. X    in the order spades, hearts, diamonds and clubs.
  131. X    Instead of a digit the letter 'x' can be given to match any length.
  132. X    All of this means that "any 55xx" means any shape with two five
  133. X    card suits.
  134. X    This operator is one of the most important in the program and is
  135. X    very efficiently implemented. Any shape() call, no matter how
  136. X    complicated is executed in constant time. Use shape()
  137. X    for all length expressions if you can.
  138. X
  139. XThe different actions are:
  140. Xprintall
  141. X    prints all four hands next to each other. This is the default.
  142. Xprint (<list of compasses>), eg print(east,west)
  143. X    print all hands specified on separate pages. This is the best
  144. X    way to generate hands to be used for partnership training.
  145. X    One of the partners gets one page, and one the other and they can
  146. X    start practicing.
  147. Xaverage "optional string" <expr>, eg    average "points" hcp(north)
  148. X    calculates and prints the average of the expression over all
  149. X    hands satisfying the condition. The optional strings is printed
  150. X    before the average.
  151. Xfrequency "optional string" ( <expr>, <lowbnd>, <highbnd> )
  152. X    calculates and prints a histogram of the values of <expr>,
  153. X    between the bounds <lowbnd> and <highbnd> inclusive.
  154. X    The optional string is printed before it.
  155. X
  156. XThe speed of the program obviously depends on the machine it runs on.
  157. XOn my home machine, a SparcStation 1+, it generates more than 3000 hands
  158. Xa second if the condition is not too complicated. I rarely play more than
  159. X150 hands a week, so in about two seconds I can generate the boards of a year.
  160. X
  161. XIt satisfies me.
  162. X
  163. XPortability:
  164. XThe program has been developed under SunOS on Sun hardware. I am a reasonably
  165. Xcompetent programmer though, and I expect the program to be highly portable.
  166. XThe most suspect part is in the initialisation of the random number generator.
  167. XThe system call used here might need to be changed on other OSes.
  168. + END-OF-FILE Description
  169. chmod 'u=r,g=r,o=r' 'Description'
  170. echo 'SENT: -r--r--r--  1 sater        4836 Nov 15 23:00 Description'
  171. echo -n 'RCVD: '
  172. /bin/ls -l Description
  173. echo 'Extracting Makefile'
  174. sed 's/^X//' > Makefile << '+ END-OF-FILE Makefile'
  175. X# $Header: /home/sater/bridge/dealer/RCS/Makefile,v 1.2 1992/11/15 22:00:48 sater Exp $
  176. XCFLAGS=-O -DNDEBUG
  177. X
  178. Xdealer: dealer.o defs.o
  179. X    $(CC) $(CFLAGS) -o dealer dealer.o defs.o -ll
  180. X
  181. Xlint: dealer.c defs.c
  182. X    lint dealer.c defs.c
  183. X
  184. Xclean:
  185. X    rm -f defs.c scan.c *.o dealer
  186. X
  187. Xsharf: README Description Makefile dealer.c defs.y scan.l tree.h
  188. X    shar README Description Makefile dealer.c defs.y scan.l tree.h Descr.* >sharf
  189. X
  190. Xdealer.o: tree.h
  191. Xdefs.o:    scan.c tree.h
  192. + END-OF-FILE Makefile
  193. chmod 'u=r,g=r,o=r' 'Makefile'
  194. echo 'SENT: -r--r--r--  1 sater         449 Nov 15 23:00 Makefile'
  195. echo -n 'RCVD: '
  196. /bin/ls -l Makefile
  197. echo 'Extracting dealer.c'
  198. sed 's/^X//' > dealer.c << '+ END-OF-FILE dealer.c'
  199. X#include <stdio.h>
  200. X#include <sys/time.h>
  201. X#include "tree.h"
  202. X#include <assert.h>
  203. X
  204. Xstatic char rcsid[] = "$Header: /home/sater/bridge/dealer/RCS/dealer.c,v 1.3 1992/11/15 21:26:08 sater Exp $";
  205. X
  206. Xtypedef unsigned char card;
  207. X
  208. Xchar *player_name[] = { "North", "East", "South", "West" };
  209. Xchar representation[] = "23456789TJQKA";
  210. X
  211. Xint points[13] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4 };
  212. Xtypedef card deal[52];
  213. X
  214. X/*
  215. X * Various handshapes can be asked for. For every shape the user is
  216. X * interested in a number is generated. In every distribution that fits that
  217. X * shape the corresponding bit is set in the distrbitmaps 4-dimensional array.
  218. X * This makes looking up a shape a small constant cost.
  219. X */
  220. X#define MAXDISTR    8*sizeof(int)
  221. Xint ***distrbitmaps[14];
  222. X
  223. Xstruct handstat {
  224. X    int    hs_length[NSUITS];    /* distribution */
  225. X    int    hs_points[NSUITS];    /* 4321 HCP per suit */
  226. X    int    hs_totalpoints;        /* Sum of above four */
  227. X    int    hs_bits;        /* Bitmap to check distribution */
  228. X};
  229. X
  230. Xint will_print;        /* Is there a print action? */
  231. X
  232. Xpraction() {
  233. X
  234. X    if (will_print++)
  235. X        yyerror("Only one printaction maximum");
  236. X}
  237. X
  238. Xchar * mycalloc(nel, siz)
  239. Xunsigned nel, siz;
  240. X{
  241. X    char *p, *calloc();
  242. X
  243. X    p = calloc(nel, siz);
  244. X    if (p)
  245. X        return p;
  246. X    fprintf(stderr, "Out of memory\n");
  247. X    exit(-1);
  248. X    /*NOTREACHED*/
  249. X}
  250. X
  251. Xinitdistr() {
  252. X    int ***p4,**p3,*p2;
  253. X    int clubs, diamonds, hearts;
  254. X    
  255. X    /*
  256. X     * Allocate the four dimensional pointer array
  257. X     */
  258. X
  259. X    for(clubs=0;clubs<=13;clubs++) {
  260. X    p4 = (int ***) mycalloc((unsigned)14-clubs, sizeof(*p4));
  261. X    distrbitmaps[clubs] = p4;
  262. X    for(diamonds=0;diamonds<=13-clubs;diamonds++) {
  263. X        p3 = (int **) mycalloc((unsigned)14-clubs-diamonds, sizeof(*p3));
  264. X        p4[diamonds] = p3;
  265. X        for(hearts=0;hearts<=13-clubs-diamonds;hearts++) {
  266. X        p2 = (int *) mycalloc((unsigned)14-clubs-diamonds-hearts, sizeof(*p2));
  267. X        p3[hearts] = p2;
  268. X        }
  269. X    }
  270. X    }
  271. X}
  272. X
  273. Xsetshapebit(cl, di, ht, sp, msk, excepted)
  274. X{
  275. X
  276. X    if (excepted)
  277. X        distrbitmaps[cl][di][ht][sp] &= ~msk;
  278. X    else
  279. X        distrbitmaps[cl][di][ht][sp] |= msk;
  280. X}
  281. X
  282. Xnewpack(d)
  283. Xdeal d;
  284. X{
  285. X    int suit, rank, place;
  286. X
  287. X    place = 0;
  288. X    for (suit=SUIT_CLUB; suit <= SUIT_SPADE; suit++)
  289. X        for(rank=0; rank<13; rank++)
  290. X            d[place++] = MAKECARD(suit, rank);
  291. X}
  292. X
  293. Xemptypack(d)
  294. Xdeal d;
  295. X{
  296. X    int i;
  297. X
  298. X    for (i=0; i<52; i++)
  299. X        d[i] = NO_CARD;
  300. X}
  301. X
  302. Xhascard(d, player, onecard)
  303. Xdeal d;
  304. Xint player;
  305. Xcard onecard;
  306. X{
  307. X    int i;
  308. X
  309. X    for(i=player*13; i<(player+1)*13; i++)
  310. X        if (d[i] == onecard)
  311. X            return 1;
  312. X    return 0;
  313. X}
  314. X
  315. Xmake_card(rankchar, suitchar)
  316. Xchar rankchar, suitchar;
  317. X{
  318. X    int rank, suit;
  319. X
  320. X    for (rank=0;rank<13 && representation[rank]!=rankchar;rank++)
  321. X        ;
  322. X    assert(rank<13);
  323. X    switch(suitchar) {
  324. X    case 'C':    suit = 0; break;
  325. X    case 'D':    suit = 1; break;
  326. X    case 'H':    suit = 2; break;
  327. X    case 'S':    suit = 3; break;
  328. X    default:    assert(0);
  329. X    }
  330. X    return MAKECARD(suit, rank);
  331. X}
  332. X
  333. Xint use_compass[NSUITS];
  334. X
  335. Xanalyze(d, hs)
  336. Xdeal d;
  337. Xstruct handstat *hs;
  338. X{
  339. X    int player,base,next,c,r,s;
  340. X    card curcard;
  341. X
  342. X    for (player = COMPASS_NORTH, base = 0; player <= COMPASS_WEST;
  343. X                        player++, hs++, base += 13) {
  344. X        /*
  345. X         * If the expressions in the input never mention a player
  346. X         * we do not calculate his hand statistics.
  347. X         */
  348. X        if (use_compass[player]==0)
  349. X            continue;
  350. X        next = base;
  351. X        for (s=SUIT_CLUB; s<=SUIT_SPADE; s++) {
  352. X            hs->hs_length[s] = 0;
  353. X            hs->hs_points[s] = 0;
  354. X        }
  355. X        for (c=0; c<13; c++) {
  356. X            curcard = d[next++];
  357. X            s = C_SUIT(curcard);
  358. X            r = C_RANK(curcard);
  359. X            hs->hs_length[s]++;
  360. X            hs->hs_points[s] += points[r];
  361. X        }
  362. X        hs->hs_totalpoints = 0;
  363. X        for (s=SUIT_CLUB; s<=SUIT_SPADE; s++)
  364. X            hs->hs_totalpoints += hs->hs_points[s];
  365. X        hs->hs_bits = distrbitmaps
  366. X                [hs->hs_length[SUIT_CLUB]]
  367. X                [hs->hs_length[SUIT_DIAMOND]]
  368. X                [hs->hs_length[SUIT_HEART]]
  369. X                [hs->hs_length[SUIT_SPADE]];
  370. X    }
  371. X}
  372. X
  373. X
  374. Xprintdeal(d)
  375. Xdeal d;
  376. X{
  377. X    int suit,player,rank,cards;;
  378. X
  379. X    for( suit=SUIT_SPADE; suit>= SUIT_CLUB; suit--) {
  380. X        cards=10;
  381. X        for (player=COMPASS_NORTH; player<=COMPASS_WEST; player++) {
  382. X            while (cards<10) {
  383. X                printf("  ");
  384. X                cards++;
  385. X            }
  386. X            cards=0;
  387. X            for (rank = 12; rank >=0; rank--) {
  388. X                if (hascard(d, player, MAKECARD(suit, rank))) {
  389. X                    printf("%c ", representation[rank]);
  390. X                    cards++;
  391. X                }
  392. X            }
  393. X            if (cards == 0) {
  394. X                printf("- ");
  395. X                cards++;
  396. X            }
  397. X        }
  398. X        printf("\n");
  399. X    }
  400. X    printf("\n");
  401. X}
  402. X
  403. Xint nprod,maxproduce;
  404. Xint ngen,maxgenerate;
  405. Xstruct tree defaulttree = {TRT_NUMBER, NIL, NIL, 1, 0};
  406. Xstruct tree *decisiontree = &defaulttree;
  407. Xstruct action defaultaction = { (struct action *) 0, ACT_PRINTALL };
  408. Xstruct action *actionlist = &defaultaction;
  409. X
  410. Xdeal fullpack;
  411. Xdeal stacked_pack;
  412. Xdeal curdeal;
  413. X
  414. Xstruct handstat hs[4];
  415. X
  416. Xsetup_deal() {
  417. X    register i,j;
  418. X
  419. X    j = 0;
  420. X    for (i=0; i<52; i++) {
  421. X        if (stacked_pack[i] != NO_CARD) {
  422. X            curdeal[i] = stacked_pack[i];
  423. X        } else {
  424. X            while (fullpack[j] == NO_CARD)
  425. X                j++;
  426. X            curdeal[i] = fullpack[j++];
  427. X            assert(j <= 52);
  428. X        }
  429. X    }
  430. X}
  431. X
  432. Xpredeal(player, onecard)
  433. Xint player;
  434. Xcard onecard;
  435. X{
  436. X    int i,j;
  437. X
  438. X    for(i=0; i<52; i++) {
  439. X        if (fullpack[i] == onecard) {
  440. X            fullpack[i] = NO_CARD;
  441. X            for(j=player*13; j<(player+1)*13; j++)
  442. X                if (stacked_pack[j] == NO_CARD) {
  443. X                    stacked_pack[j] = onecard;
  444. X                    return;
  445. X                }
  446. X            yyerror("More than 13 cards for one player");
  447. X        }
  448. X    }
  449. X    yyerror("Card predealt twice");
  450. X}
  451. X
  452. X
  453. X#define RANDBITS 16
  454. X#define NRANDVALS (1<<RANDBITS)
  455. X
  456. Xunsigned char zero52[NRANDVALS];
  457. X
  458. Xinitrandom() {
  459. X    struct timeval tv;
  460. X    int i, i_cycle;
  461. X    int val;
  462. X
  463. X    /*
  464. X     * The most suspect part of this program
  465. X     */
  466. X    gettimeofday(&tv, (void *) 0);
  467. X    srandom(tv.tv_sec^tv.tv_usec);
  468. X    /*
  469. X     * End of suspect part
  470. X     *
  471. X     * Now initialize array zero52 with numbers 0..51
  472. X     * repeatedly. This whole charade is just to prevent having
  473. X     * to do divisions.
  474. X     */
  475. X    val = 0;
  476. X    for (i=0, i_cycle=0; i< NRANDVALS; i++) {
  477. X        while (stacked_pack[val] != NO_CARD) {
  478. X            /* this slot is predealt, do not use it */
  479. X            val++;
  480. X            if (val==52) {
  481. X                val=0;
  482. X                i_cycle = i;
  483. X            }
  484. X        }
  485. X        zero52[i] = val++;
  486. X        if (val==52) {
  487. X            val=0;
  488. X            i_cycle = i+1;
  489. X        }
  490. X    }
  491. X    /*
  492. X     * Fill the last part of the array with 0xFF, just to prevent
  493. X     * that 0 occurs more than 51. This is probably just for hack value
  494. X     */
  495. X    while (i > i_cycle) {
  496. X        zero52[i-1] = 0xFF;
  497. X        i--;
  498. X    }
  499. X}
  500. X
  501. Xshuffle(d)
  502. Xdeal d;
  503. X{
  504. X    int i,j;
  505. X    card t;
  506. X
  507. X    /*
  508. X     * Algorithm according to Knuth. For each card exchange with
  509. X     * a random other card. This is supposed to be the perfect
  510. X     * shuffle algorithm. It only depends on a valid random number
  511. X     * generator.
  512. X     */
  513. X    for (i=0; i<52; i++) {
  514. X        if (stacked_pack[i] == NO_CARD) {
  515. X            do
  516. X                /* Upper bits most random */
  517. X                j = zero52[random()>>(31-RANDBITS)];
  518. X            while (j==0xFF);
  519. X            t = d[j]; d[j] = d[i]; d[i] = t;
  520. X        }
  521. X    }
  522. X}
  523. X
  524. Xevaltree(t)
  525. Xstruct tree *t;
  526. X{
  527. X
  528. X    switch(t->tr_type) {
  529. X    default:
  530. X        assert(0);
  531. X    case TRT_NUMBER:
  532. X        return t->tr_int1;
  533. X    case TRT_AND2:
  534. X        return evaltree(t->tr_leaf1) && evaltree(t->tr_leaf2);
  535. X    case TRT_OR2:
  536. X        return evaltree(t->tr_leaf1) || evaltree(t->tr_leaf2);
  537. X    case TRT_ARPLUS:
  538. X        return evaltree(t->tr_leaf1) +  evaltree(t->tr_leaf2);
  539. X    case TRT_ARMINUS:
  540. X        return evaltree(t->tr_leaf1) -  evaltree(t->tr_leaf2);
  541. X    case TRT_ARTIMES:
  542. X        return evaltree(t->tr_leaf1) *  evaltree(t->tr_leaf2);
  543. X    case TRT_ARDIVIDE:
  544. X        return evaltree(t->tr_leaf1) /  evaltree(t->tr_leaf2);
  545. X    case TRT_ARMOD:
  546. X        return evaltree(t->tr_leaf1) %  evaltree(t->tr_leaf2);
  547. X    case TRT_CMPEQ:
  548. X        return evaltree(t->tr_leaf1) == evaltree(t->tr_leaf2);
  549. X    case TRT_CMPNE:
  550. X        return evaltree(t->tr_leaf1) != evaltree(t->tr_leaf2);
  551. X    case TRT_CMPLT:
  552. X        return evaltree(t->tr_leaf1) <  evaltree(t->tr_leaf2);
  553. X    case TRT_CMPLE:
  554. X        return evaltree(t->tr_leaf1) <= evaltree(t->tr_leaf2);
  555. X    case TRT_CMPGT:
  556. X        return evaltree(t->tr_leaf1) >  evaltree(t->tr_leaf2);
  557. X    case TRT_CMPGE:
  558. X        return evaltree(t->tr_leaf1) >= evaltree(t->tr_leaf2);
  559. X    case TRT_NOT:
  560. X        return !evaltree(t->tr_leaf1);
  561. X    case TRT_LENGTH:    /* suit, compass */
  562. X        assert(t->tr_int1>=SUIT_CLUB && t->tr_int1<=SUIT_SPADE);
  563. X        assert(t->tr_int2>=COMPASS_NORTH && t->tr_int2<=COMPASS_WEST);
  564. X        return hs[t->tr_int2].hs_length[t->tr_int1];
  565. X    case TRT_HCPTOTAL:    /* compass */
  566. X        assert(t->tr_int1>=COMPASS_NORTH && t->tr_int1<=COMPASS_WEST);
  567. X        return hs[t->tr_int1].hs_totalpoints;
  568. X    case TRT_HCP:        /* compass, suit */
  569. X        assert(t->tr_int1>=COMPASS_NORTH && t->tr_int1<=COMPASS_WEST);
  570. X        assert(t->tr_int2>=SUIT_CLUB && t->tr_int2<=SUIT_SPADE);
  571. X        return hs[t->tr_int1].hs_points[t->tr_int2];
  572. X    case TRT_SHAPE:        /* compass, shapemask */
  573. X        assert(t->tr_int1>=COMPASS_NORTH && t->tr_int1<=COMPASS_WEST);
  574. X        assert(t->tr_int2>=0 && t->tr_int2<MAXDISTR);
  575. X        return (hs[t->tr_int1].hs_bits&t->tr_int2) != 0;
  576. X    case TRT_HASCARD:    /* compass, card */
  577. X        assert(t->tr_int1>=COMPASS_NORTH && t->tr_int1<=COMPASS_WEST);
  578. X        return hascard(curdeal, t->tr_int1, t->tr_int2);
  579. X    }
  580. X}
  581. X    
  582. Xinteresting()
  583. X{
  584. X    return evaltree(decisiontree);
  585. X}
  586. X
  587. Xdeal *deallist;
  588. X
  589. Xsetup_action() {
  590. X    struct action *acp;
  591. X        
  592. X    /*
  593. X     * Initialize all actions
  594. X     */
  595. X    for (acp=actionlist; acp!=0; acp = acp->ac_next) {
  596. X    switch(acp->ac_type) {
  597. X    default:
  598. X        assert(0);
  599. X        /*NOTREACHED*/
  600. X    case ACT_PRINTALL:
  601. X        break;
  602. X    case ACT_PRINT:
  603. X        deallist = (deal *) mycalloc(maxproduce, sizeof(deal));
  604. X        break;
  605. X    case ACT_AVERAGE:
  606. X        break;
  607. X    case ACT_FREQUENCY:
  608. X        acp->ac_u.acu_f.acuf_freqs = (long *) mycalloc(
  609. X        acp->ac_u.acu_f.acuf_highbnd - acp->ac_u.acu_f.acuf_lowbnd + 1,
  610. X                            sizeof(long));
  611. X        break;
  612. X    }
  613. X    }
  614. X}
  615. X
  616. Xaction() {
  617. X    struct action *acp;
  618. X    int expr;
  619. X
  620. X    for (acp=actionlist; acp!=0; acp = acp->ac_next) {
  621. X    switch(acp->ac_type) {
  622. X    default:
  623. X        assert(0);
  624. X        /*NOTREACHED*/
  625. X    case ACT_PRINTALL:
  626. X        printdeal(curdeal);
  627. X        break;
  628. X    case ACT_PRINT:
  629. X        bcopy(curdeal, deallist[nprod], sizeof(deal));
  630. X        break;
  631. X    case ACT_AVERAGE:
  632. X        acp->ac_int1 += evaltree(acp->ac_expr1);
  633. X        break;
  634. X    case ACT_FREQUENCY:
  635. X        expr = evaltree(acp->ac_expr1);
  636. X        if (expr < acp->ac_u.acu_f.acuf_lowbnd)
  637. X        acp->ac_u.acu_f.acuf_uflow++;
  638. X        else if (expr > acp->ac_u.acu_f.acuf_highbnd)
  639. X        acp->ac_u.acu_f.acuf_oflow++;
  640. X        else
  641. X        acp->ac_u.acu_f.acuf_freqs[expr-acp->ac_u.acu_f.acuf_lowbnd]++;
  642. X        break;
  643. X        
  644. X    }
  645. X    }
  646. X}
  647. X
  648. Xprinthands(boardno, dealp, player, nhands)
  649. Xint boardno, player, nhands;
  650. Xdeal *dealp;
  651. X{
  652. X    int i, suit,rank,cards;;
  653. X
  654. X    for(i=0; i<nhands; i++)
  655. X        printf("%4d.%15c", boardno+i+1, ' ');
  656. X    printf("\n");
  657. X    for( suit=SUIT_SPADE; suit>= SUIT_CLUB; suit--) {
  658. X        cards=10;
  659. X        for (i=0; i<nhands; i++) {
  660. X            while (cards<10) {
  661. X                printf("  ");
  662. X                cards++;
  663. X            }
  664. X            cards=0;
  665. X            for (rank = 12; rank >=0; rank--) {
  666. X                if (hascard(dealp[i], player, MAKECARD(suit, rank))) {
  667. X                    printf("%c ", representation[rank]);
  668. X                    cards++;
  669. X                }
  670. X            }
  671. X            if (cards == 0) {
  672. X                printf("- ");
  673. X                cards++;
  674. X            }
  675. X        }
  676. X        printf("\n");
  677. X    }
  678. X    printf("\n");
  679. X}
  680. X
  681. Xcleanup_action() {
  682. X    struct action *acp;
  683. X    int player,i;
  684. X        
  685. X    for (acp=actionlist; acp!=0; acp = acp->ac_next) {
  686. X    switch(acp->ac_type) {
  687. X    default:
  688. X        assert(0);
  689. X        /*NOTREACHED*/
  690. X    case ACT_PRINTALL:
  691. X        break;
  692. X    case ACT_PRINT:
  693. X        for (player = COMPASS_NORTH; player<=COMPASS_WEST; player++) {
  694. X        if (!(acp->ac_int1 & (1<<player)))
  695. X            continue;
  696. X        printf("\n\n%s hands:\n\n\n\n", player_name[player]);
  697. X        for (i=0; i<nprod; i+=4)
  698. X            printhands(i, deallist+i, player, nprod-i>4 ? 4 : nprod-i);
  699. X        printf("\f");
  700. X        }
  701. X        break;
  702. X    case ACT_AVERAGE:
  703. X        if (acp->ac_str1)
  704. X        printf("%s: ", acp->ac_str1);
  705. X        printf("%g\n", (double) acp->ac_int1/nprod);
  706. X        break;
  707. X    case ACT_FREQUENCY:
  708. X        printf("Frequency %s:\n", acp->ac_str1 ? acp->ac_str1 : "");
  709. X        if (acp->ac_u.acu_f.acuf_uflow)
  710. X        printf("Low\t%8d\n", acp->ac_u.acu_f.acuf_uflow);
  711. X        for (i=acp->ac_u.acu_f.acuf_lowbnd; i <= acp->ac_u.acu_f.acuf_highbnd; i++)
  712. X        printf("%5d\t%8d\n", i, acp->ac_u.acu_f.acuf_freqs[i-acp->ac_u.acu_f.acuf_lowbnd]);
  713. X        if (acp->ac_u.acu_f.acuf_oflow)
  714. X        printf("High\t%8d\n", acp->ac_u.acu_f.acuf_oflow);
  715. X        break;
  716. X    }
  717. X    }
  718. X}
  719. X
  720. Xint verbose = 1;
  721. X
  722. Xmain(argc, argv)
  723. Xint argc;
  724. Xchar **argv;
  725. X{
  726. X    extern int optind;
  727. X    extern char *optarg;
  728. X    char c;
  729. X    int errflg = 0;
  730. X
  731. X    while ((c = getopt(argc, argv, "v")) != -1) {
  732. X        switch(c) {
  733. X        case 'v':
  734. X            verbose ^= 1;
  735. X            break;
  736. X        case '?':
  737. X            errflg = 1;
  738. X            break;
  739. X        }
  740. X    }
  741. X    if (argc - optind>1 || errflg) {
  742. X        fprintf(stderr, "Usage: %s [-v] [inputfile]\n", argv[0]);
  743. X        exit(-1);
  744. X    }
  745. X    if (optind < argc && freopen(argv[optind], "r", stdin) == NULL) {
  746. X        perror(argv[optind]);
  747. X        exit(-1);
  748. X    }
  749. X    newpack(fullpack);
  750. X    emptypack(stacked_pack);
  751. X    initdistr();
  752. X    yyparse();
  753. X    initrandom();
  754. X    if (maxgenerate==0)
  755. X        maxgenerate = 1000000;
  756. X    if (maxproduce==0)
  757. X        maxproduce =
  758. X            actionlist == &defaultaction || will_print
  759. X            ? 40 : 100000;
  760. X
  761. X    setup_action();
  762. X    setup_deal();
  763. X    for(ngen=nprod=0; ngen<maxgenerate && nprod < maxproduce; ngen++) {
  764. X        shuffle(curdeal);
  765. X        analyze(curdeal, hs);
  766. X        if (interesting()) {
  767. X            action();
  768. X            nprod++;
  769. X        }
  770. X    }
  771. X    cleanup_action();
  772. X    if (verbose)
  773. X        printf("Generated %d hands, produced %d.\n", ngen, nprod);
  774. X    return 0;
  775. X}
  776. + END-OF-FILE dealer.c
  777. chmod 'u=r,g=r,o=r' 'dealer.c'
  778. echo 'SENT: -r--r--r--  1 sater       12668 Nov 15 22:26 dealer.c'
  779. echo -n 'RCVD: '
  780. /bin/ls -l dealer.c
  781. echo 'Extracting defs.y'
  782. sed 's/^X//' > defs.y << '+ END-OF-FILE defs.y'
  783. X%{
  784. X#include <stdio.h>
  785. X#include <string.h>
  786. X#include "tree.h"
  787. X
  788. Xstatic char rcsid[] = "$Header: /home/sater/bridge/dealer/RCS/defs.y,v 1.4 1992/11/15 22:01:03 sater Exp $";
  789. X
  790. Xint predeal_compass;        /* global variable for predeal communication */
  791. X%}
  792. X
  793. X%union {
  794. X    int    y_int;
  795. X    char    *y_str;
  796. X    struct tree *y_tree;
  797. X    struct action *y_action;
  798. X    char    y_distr[4];
  799. X}
  800. X
  801. X%left OR2
  802. X%left AND2
  803. X%left CMPEQ, CMPNE
  804. X%left CMPLT, CMPLE, CMPGT, CMPGE
  805. X%left ARPLUS, ARMINUS
  806. X%left ARTIMES, ARDIVIDE, ARMOD
  807. X%nonassoc NOT
  808. X
  809. X%token GENERATE, PRODUCE, HCP, SHAPE, ANY, EXCEPT, CONDITION, ACTION
  810. X%token PRINT, PRINTALL, AVERAGE, HASCARD, FREQUENCY, PREDEAL
  811. X%token <y_int> NUMBER
  812. X%token <y_str> HOLDING
  813. X%token <y_str> STRING
  814. X%token <y_str> IDENT
  815. X%token <y_int> COMPASS
  816. X%token <y_int> SUIT
  817. X%token <y_int> CARD
  818. X%token <y_distr> DISTR
  819. X
  820. X%type <y_tree>    expr
  821. X%type <y_int> compass, printlist, shlprefix, any
  822. X%type <y_distr> shape
  823. X%type <y_action> actionlist action
  824. X%type <y_str> optstring
  825. X
  826. X%start defs
  827. X
  828. X%%
  829. X
  830. Xdefs
  831. X    : /* empty */
  832. X    | defs def
  833. X    ;
  834. X
  835. Xdef
  836. X    : GENERATE NUMBER
  837. X        { extern int maxgenerate; maxgenerate = $2; }
  838. X    | PRODUCE NUMBER
  839. X        { extern int maxproduce; maxproduce = $2; }
  840. X    | PREDEAL predealargs
  841. X    | CONDITION expr
  842. X        { extern struct tree *decisiontree; decisiontree = $2; }
  843. X    | expr
  844. X        { extern struct tree *decisiontree; decisiontree = $1; }
  845. X    | IDENT '=' expr
  846. X        { new_var($1, $3); }
  847. X    | ACTION actionlist
  848. X        { extern struct action *actionlist; actionlist = $2; }
  849. X    ;
  850. X
  851. Xpredealargs
  852. X    : predealarg
  853. X    | predealargs predealarg
  854. X    ;
  855. X
  856. Xpredealarg
  857. X    :  COMPASS { predeal_compass = $1;} holdings
  858. X    ;
  859. X
  860. Xholdings
  861. X    : HOLDING
  862. X        { predeal_holding(predeal_compass, $1); }
  863. X    | holdings ',' HOLDING
  864. X        { predeal_holding(predeal_compass, $3); }
  865. X    ;
  866. X
  867. Xcompass
  868. X    : COMPASS
  869. X        { extern int use_compass[NSUITS]; use_compass[$1] = 1; $$= $1; }
  870. X    ;
  871. X
  872. Xshape
  873. X    : DISTR
  874. X        { bcopy($1, $$, 4); };
  875. X    | NUMBER
  876. X        { if ($1<1000 || $1>=10000) yyerror("bad shape");
  877. X          $$[0] ='0'+$1/1000;  $$[1]='0'+$1/100%10;
  878. X          $$[2] ='0'+$1/10%10; $$[3]='0'+$1%10;
  879. X        }
  880. X    ;
  881. X
  882. Xshlprefix
  883. X    : ','
  884. X        { $$ = 0; }
  885. X    | ARPLUS
  886. X        { $$ = 0; }
  887. X    | /* empty */
  888. X        { $$ = 0; }
  889. X    | ARMINUS
  890. X        { $$ = 1; }
  891. X    ;
  892. X
  893. Xany
  894. X    : /* empty */
  895. X        { $$ = 0; }
  896. X    | ANY
  897. X        { $$ = 1; }
  898. X    ;
  899. X
  900. Xshapelistel
  901. X    : shlprefix any shape
  902. X        { insertshape($3, $2, $1); }
  903. X    ;
  904. X        
  905. Xshapelist
  906. X    : shapelistel
  907. X    | shapelist shapelistel
  908. X    ;
  909. X
  910. Xexpr
  911. X    : NUMBER
  912. X        { $$ = newtree(TRT_NUMBER, NIL, NIL, $1, 0); }
  913. X    | IDENT
  914. X        { $$ = var_lookup($1, 1); }
  915. X    | SUIT '(' compass ')'
  916. X        { $$ = newtree(TRT_LENGTH, NIL, NIL, $1, $3); }
  917. X    | HCP '(' compass ')'
  918. X        { $$ = newtree(TRT_HCPTOTAL, NIL, NIL, $3, 0); }
  919. X    | HCP '(' compass ',' SUIT ')'
  920. X        { $$ = newtree(TRT_HCP, NIL, NIL, $3, $5); }
  921. X    | SHAPE '(' compass ',' shapelist ')'
  922. X        { $$ = newtree(TRT_SHAPE, NIL, NIL, $3, 1<<(shapeno++)); }
  923. X    | HASCARD '(' COMPASS ',' CARD ')'
  924. X        { $$ = newtree(TRT_HASCARD, NIL, NIL, $3, $5); }
  925. X    | '(' expr ')'
  926. X        { $$ = $2; }
  927. X    | expr CMPEQ expr
  928. X        { $$ = newtree(TRT_CMPEQ, $1, $3, 0, 0); }
  929. X    | expr CMPNE expr
  930. X        { $$ = newtree(TRT_CMPNE, $1, $3, 0, 0); }
  931. X    | expr CMPLT expr
  932. X        { $$ = newtree(TRT_CMPLT, $1, $3, 0, 0); }
  933. X    | expr CMPLE expr
  934. X        { $$ = newtree(TRT_CMPLE, $1, $3, 0, 0); }
  935. X    | expr CMPGT expr
  936. X        { $$ = newtree(TRT_CMPGT, $1, $3, 0, 0); }
  937. X    | expr CMPGE expr
  938. X        { $$ = newtree(TRT_CMPGE, $1, $3, 0, 0); }
  939. X    | expr AND2 expr
  940. X        { $$ = newtree(TRT_AND2, $1, $3, 0, 0); }
  941. X    | expr OR2 expr
  942. X        { $$ = newtree(TRT_OR2, $1, $3, 0, 0); }
  943. X    | expr ARPLUS expr
  944. X        { $$ = newtree(TRT_ARPLUS, $1, $3, 0, 0); }
  945. X    | expr ARMINUS expr
  946. X        { $$ = newtree(TRT_ARMINUS, $1, $3, 0, 0); }
  947. X    | expr ARTIMES expr
  948. X        { $$ = newtree(TRT_ARTIMES, $1, $3, 0, 0); }
  949. X    | expr ARDIVIDE expr
  950. X        { $$ = newtree(TRT_ARDIVIDE, $1, $3, 0, 0); }
  951. X    | expr ARMOD expr
  952. X        { $$ = newtree(TRT_ARMOD, $1, $3, 0, 0); }
  953. X    | NOT expr
  954. X        { $$ = newtree(TRT_NOT, $2, NIL, 0, 0); }
  955. X    ;
  956. Xactionlist
  957. X    : action
  958. X        { $$ = $1; }
  959. X    | action ',' actionlist
  960. X        { $$ = $1; $$->ac_next = $3; }
  961. X    | /* empty */
  962. X        { $$ = 0; }
  963. X    ;
  964. Xaction
  965. X    : PRINTALL
  966. X        { praction();
  967. X          $$ = newaction(ACT_PRINTALL, NIL, (char *) 0, 0);
  968. X        }
  969. X    | PRINT '(' printlist ')'
  970. X        { praction();
  971. X          $$ = newaction(ACT_PRINT, NIL, (char *) 0, $3);
  972. X        }
  973. X    | AVERAGE optstring expr
  974. X        { $$ = newaction(ACT_AVERAGE, $3, $2, 0); }
  975. X    | FREQUENCY optstring '(' expr ',' NUMBER ',' NUMBER ')'
  976. X        { $$ = newaction(ACT_FREQUENCY, $4, $2, 0);
  977. X          $$->ac_u.acu_f.acuf_lowbnd = $6;
  978. X          $$->ac_u.acu_f.acuf_highbnd = $8;
  979. X        }
  980. X    ;
  981. Xoptstring
  982. X    : /* empty */
  983. X        { $$ = (char *) 0; }
  984. X    | STRING
  985. X        { $$ = $1; }
  986. X    ;
  987. Xprintlist
  988. X    : COMPASS
  989. X        { $$ = (1<<$1); }
  990. X    | printlist ',' COMPASS
  991. X        { $$ = $1|(1<<$3); }
  992. X    ;
  993. X%%
  994. X
  995. Xstruct var {
  996. X    struct var *v_next;
  997. X    char *v_ident;
  998. X    struct tree *v_tree;
  999. X} *vars=0;
  1000. X
  1001. Xstruct tree *var_lookup(s, mustbethere)
  1002. Xchar *s;
  1003. X{
  1004. X    struct var *v;
  1005. X
  1006. X    for(v=vars; v!=0; v = v->v_next)
  1007. X        if (strcmp(s, v->v_ident)==0)
  1008. X            return v->v_tree;
  1009. X    if (mustbethere)
  1010. X        yyerror("unknown variable");
  1011. X    return 0;
  1012. X}
  1013. X
  1014. Xnew_var(s, t)
  1015. Xchar *s;
  1016. Xstruct tree *t;
  1017. X{
  1018. X    struct var *v;
  1019. X    char *mycalloc();
  1020. X
  1021. X    if (var_lookup(s, 0)!=0)
  1022. X        yyerror("redefined variable");
  1023. X    v = (struct var *) mycalloc(1, sizeof(*v));
  1024. X    v->v_next = vars;
  1025. X    v->v_ident = s;
  1026. X    v->v_tree = t;
  1027. X    vars = v;
  1028. X}
  1029. X
  1030. Xint lino=1;
  1031. X
  1032. Xyyerror(s)
  1033. Xchar *s;
  1034. X{
  1035. X
  1036. X    fprintf(stderr, "line %d: %s\n", lino, s);
  1037. X    exit(-1);
  1038. X}
  1039. X
  1040. Xint perm[24][4] = {
  1041. X    {    0,    1,    2,    3    },
  1042. X    {    0,    1,    3,    2    },
  1043. X    {    0,    2,    1,    3    },
  1044. X    {    0,    2,    3,    1    },
  1045. X    {    0,    3,    1,    2    },
  1046. X    {    0,    3,    2,    1    },
  1047. X    {    1,    0,    2,    3    },
  1048. X    {    1,    0,    3,    2    },
  1049. X    {    1,    2,    0,    3    },
  1050. X    {    1,    2,    3,    0    },
  1051. X    {    1,    3,    0,    2    },
  1052. X    {    1,    3,    2,    0    },
  1053. X    {    2,    0,    1,    3    },
  1054. X    {    2,    0,    3,    1    },
  1055. X    {    2,    1,    0,    3    },
  1056. X    {    2,    1,    3,    0    },
  1057. X    {    2,    3,    0,    1    },
  1058. X    {    2,    3,    1,    0    },
  1059. X    {    3,    0,    1,    2    },
  1060. X    {    3,    0,    2,    1    },
  1061. X    {    3,    1,    0,    2    },
  1062. X    {    3,    1,    2,    0    },
  1063. X    {    3,    2,    0,    1    },
  1064. X    {    3,    2,    1,    0    },
  1065. X};
  1066. X
  1067. Xint shapeno;
  1068. Xinsertshape(s, any, neg_shape)
  1069. Xchar s[4];
  1070. X{
  1071. X    int i,j,p;
  1072. X    int xcount=0, ccount=0;
  1073. X    char copy_s[4];
  1074. X
  1075. X    for (i=0;i<4;i++) {
  1076. X        if (s[i]=='x')
  1077. X            xcount++;
  1078. X        else
  1079. X            ccount += s[i]-'0';
  1080. X    }
  1081. X    switch(xcount) {
  1082. X    case 0:
  1083. X        if (ccount!=13)
  1084. X            yyerror("wrong number of cards in shape");
  1085. X        for (p=0; p<(any? 24 : 1); p++)
  1086. X            setshapebit(s[perm[p][3]]-'0', s[perm[p][2]]-'0',
  1087. X                s[perm[p][1]]-'0', s[perm[p][0]]-'0',
  1088. X                1<<shapeno, neg_shape);
  1089. X        break;
  1090. X    default:
  1091. X        if (ccount>13)
  1092. X            yyerror("too many cards in ambiguous shape");
  1093. X        bcopy(s, copy_s, 4);
  1094. X        for(i=0; copy_s[i] != 'x'; i++)
  1095. X            ;
  1096. X        if (xcount==1) {
  1097. X            copy_s[i] = 13-ccount+'0';    /* could go above '9' */
  1098. X            insertshape(copy_s, any, neg_shape);
  1099. X        } else {
  1100. X            for (j=0; j<=13-ccount; j++) {
  1101. X                copy_s[i] = j+'0';
  1102. X                insertshape(copy_s, any, neg_shape);
  1103. X            }
  1104. X        }
  1105. X        break;
  1106. X    }
  1107. X}
  1108. X
  1109. Xstruct tree *newtree(type, p1, p2, i1, i2)
  1110. Xint type;
  1111. Xstruct tree *p1, *p2;
  1112. Xint i1,i2;
  1113. X{
  1114. X    char *mycalloc();
  1115. X    struct tree *p;
  1116. X
  1117. X    p = (struct tree *) mycalloc(1, sizeof(*p));
  1118. X    p->tr_type = type;
  1119. X    p->tr_leaf1 = p1;
  1120. X    p->tr_leaf2 = p2;
  1121. X    p->tr_int1 = i1;
  1122. X    p->tr_int2 = i2;
  1123. X    return p;
  1124. X}
  1125. X
  1126. Xstruct action *newaction(type, p1, s1, i1)
  1127. Xint type;
  1128. Xstruct tree *p1;
  1129. Xchar *s1;
  1130. Xint i1;
  1131. X{
  1132. X    char *mycalloc();
  1133. X    struct action *a;
  1134. X
  1135. X    a = (struct action *) mycalloc(1, sizeof(*a));
  1136. X    a->ac_type = type;
  1137. X    a->ac_expr1 = p1;
  1138. X    a->ac_str1 = s1;
  1139. X    a->ac_int1 = i1;
  1140. X    return a;
  1141. X}
  1142. X
  1143. Xchar *mystrcpy(s)
  1144. Xchar *s;
  1145. X{
  1146. X    char *cs;
  1147. X    char *mycalloc();
  1148. X
  1149. X    cs = mycalloc(strlen(s)+1, sizeof(char));
  1150. X    strcpy(cs, s);
  1151. X    return cs;
  1152. X}
  1153. X
  1154. Xpredeal_holding(compass, holding)
  1155. Xchar *holding;
  1156. X{
  1157. X    int suit;
  1158. X
  1159. X    suit = *holding++;
  1160. X    while (*holding) {
  1161. X        predeal(compass, make_card(*holding, suit));
  1162. X        holding++;
  1163. X    }
  1164. X}
  1165. X
  1166. X#include "scan.c"
  1167. + END-OF-FILE defs.y
  1168. chmod 'u=r,g=r,o=r' 'defs.y'
  1169. echo 'SENT: -r--r--r--  1 sater        7238 Nov 15 23:01 defs.y'
  1170. echo -n 'RCVD: '
  1171. /bin/ls -l defs.y
  1172. echo 'Extracting scan.l'
  1173. sed 's/^X//' > scan.l << '+ END-OF-FILE scan.l'
  1174. X/* $Header: /home/sater/bridge/dealer/RCS/scan.l,v 1.2 1992/11/15 21:26:43 sater Exp $ */
  1175. X%%
  1176. X"&&"        return(AND2);
  1177. Xand        return(AND2);
  1178. X"||"        return(OR2);
  1179. Xor        return(OR2);
  1180. X"!"        return(NOT);
  1181. Xnot        return(NOT);
  1182. X"=="        return(CMPEQ);
  1183. X"!="        return(CMPNE);
  1184. X"<"        return(CMPLT);
  1185. X"<="        return(CMPLE);
  1186. X">"        return(CMPGT);
  1187. X">="        return(CMPGE);
  1188. X"+"        return(ARPLUS);
  1189. X"-"        return(ARMINUS);
  1190. X"*"        return(ARTIMES);
  1191. X"/"        return(ARDIVIDE);
  1192. X"%"        return(ARMOD);
  1193. Xgenerate    return(GENERATE);
  1194. Xproduce        return(PRODUCE);
  1195. Xpredeal        return(PREDEAL);
  1196. Xcondition    return(CONDITION);
  1197. Xaction        return(ACTION);
  1198. Xprint        return(PRINT);
  1199. Xprintall    return(PRINTALL);
  1200. Xaverage        return(AVERAGE);
  1201. Xfrequency    return(FREQUENCY);
  1202. Xnorth        { yylval.y_int = COMPASS_NORTH; return COMPASS; }
  1203. Xeast        { yylval.y_int = COMPASS_EAST; return COMPASS; }
  1204. Xsouth        { yylval.y_int = COMPASS_SOUTH; return COMPASS; }
  1205. Xwest        { yylval.y_int = COMPASS_WEST; return COMPASS; }
  1206. Xclubs        { yylval.y_int = SUIT_CLUB; return SUIT; }
  1207. Xdiamonds    { yylval.y_int = SUIT_DIAMOND; return SUIT; }
  1208. Xhearts        { yylval.y_int = SUIT_HEART; return SUIT; }
  1209. Xspades        { yylval.y_int = SUIT_SPADE; return SUIT; }
  1210. Xhcp        return(HCP);
  1211. Xhascard        return(HASCARD);
  1212. Xshape        return(SHAPE);
  1213. Xany        return(ANY);
  1214. X[CDHS]A?K?Q?J?T?9?8?7?6?5?4?3?2?    { yylval.y_str = mystrcpy(yytext); return HOLDING; }
  1215. X[2-9TJQKA][CDHS]    { yylval.y_int = make_card(yytext[0], yytext[1]);
  1216. X              return(CARD);
  1217. X            }
  1218. X\"[^"]*\"    { yytext[yyleng-1] = 0; yylval.y_str = mystrcpy(yytext+1); return STRING; }
  1219. X[0-9]+        { yylval.y_int = atoi(yytext); return NUMBER; }
  1220. X[0-9x]{4}    { strncpy(yylval.y_distr, yytext, 4); return DISTR; }
  1221. X[a-zA-Z][a-zA-Z0-9_]*    { yylval.y_str = mystrcpy(yytext); return IDENT; }
  1222. X[ \t]        ;
  1223. X\n        { lino++; }
  1224. X^\#.*\n        { lino++; }
  1225. X.        return(yytext[0]);
  1226. + END-OF-FILE scan.l
  1227. chmod 'u=r,g=r,o=r' 'scan.l'
  1228. echo 'SENT: -r--r--r--  1 sater        1713 Nov 15 22:26 scan.l'
  1229. echo -n 'RCVD: '
  1230. /bin/ls -l scan.l
  1231. echo 'Extracting tree.h'
  1232. sed 's/^X//' > tree.h << '+ END-OF-FILE tree.h'
  1233. X/*
  1234. X * decision tree and other expression stuff
  1235. X */
  1236. X
  1237. Xstruct tree {
  1238. X    int        tr_type;
  1239. X    struct tree     *tr_leaf1, *tr_leaf2;
  1240. X    int        tr_int1;
  1241. X    int        tr_int2;
  1242. X};
  1243. X
  1244. X#define NIL    ((struct tree *) 0)
  1245. X
  1246. X#define SUIT_CLUB    0
  1247. X#define SUIT_DIAMOND    1
  1248. X#define SUIT_HEART    2
  1249. X#define SUIT_SPADE    3
  1250. X#define NSUITS        4
  1251. X
  1252. X#define MAKECARD(suit, rank)    (((suit)<<6)|(rank))
  1253. X#define C_SUIT(c)        ((c)>>6)
  1254. X#define C_RANK(c)        ((c)&0x3F)
  1255. X#define NO_CARD            0xFF
  1256. X
  1257. X#define COMPASS_NORTH    0
  1258. X#define COMPASS_EAST    1
  1259. X#define COMPASS_SOUTH    2
  1260. X#define COMPASS_WEST    3
  1261. X
  1262. X#define TRT_NUMBER    0
  1263. X#define TRT_AND2    1
  1264. X#define TRT_OR2        2
  1265. X#define TRT_CMPEQ    3
  1266. X#define TRT_CMPNE    4
  1267. X#define TRT_CMPLT    5
  1268. X#define TRT_CMPLE    6
  1269. X#define TRT_CMPGT    7
  1270. X#define TRT_CMPGE    8
  1271. X#define TRT_LENGTH    9
  1272. X#define TRT_ARPLUS    10
  1273. X#define TRT_ARMINUS    11
  1274. X#define TRT_ARTIMES    12
  1275. X#define TRT_ARDIVIDE    13
  1276. X#define TRT_ARMOD    14
  1277. X#define TRT_HCPTOTAL    15
  1278. X#define TRT_HCP        16
  1279. X#define TRT_SHAPE    17
  1280. X#define TRT_NOT        18
  1281. X#define TRT_HASCARD    19
  1282. X
  1283. X
  1284. X/*
  1285. X * Actions to be taken
  1286. X */
  1287. Xstruct action {
  1288. X    struct action    *ac_next;
  1289. X    int        ac_type;
  1290. X    struct tree    *ac_expr1;
  1291. X    int        ac_int1;
  1292. X    char        *ac_str1;
  1293. X    union {
  1294. X        struct {
  1295. X            long    acuf_lowbnd;
  1296. X            long    acuf_highbnd;
  1297. X            long    acuf_uflow;
  1298. X            long    acuf_oflow;
  1299. X            long    *acuf_freqs;
  1300. X        } acu_f;
  1301. X    } ac_u;
  1302. X};
  1303. X
  1304. X#define ACT_PRINTALL    0
  1305. X#define ACT_PRINT    1
  1306. X#define ACT_AVERAGE    2
  1307. X#define ACT_FREQUENCY    3
  1308. + END-OF-FILE tree.h
  1309. chmod 'u=r,g=r,o=r' 'tree.h'
  1310. echo 'SENT: -r--r--r--  1 sater        1317 Nov 15 22:27 tree.h'
  1311. echo -n 'RCVD: '
  1312. /bin/ls -l tree.h
  1313. echo 'Extracting Descr.6c'
  1314. sed 's/^X//' > Descr.6c << '+ END-OF-FILE Descr.6c'
  1315. X# A typical play decision, here is the hand, the bidding and trick one
  1316. X#
  1317. X#    J x x x x x x
  1318. X#    J x
  1319. X#    x x
  1320. X#    9 5
  1321. X#
  1322. X#
  1323. X#    A
  1324. X#    A Q
  1325. X#    A
  1326. X#    A Q J 10 x x x x x
  1327. X#
  1328. X#    W    N    E    S
  1329. X#    p    p    1D    dbl
  1330. X#    1H    2S    3H    4C
  1331. X#    p    4S    p    6C
  1332. X#    all pass
  1333. X#
  1334. X# The lead is a small diamond to the K and A, how to play?
  1335. X# Two possibilities, play for the drop of the KC or lead the QC,
  1336. X# cross to the 9 and take the heart finesse.
  1337. X#
  1338. X# the inferences from bidding and trick one are encoded below
  1339. Xpredeal
  1340. X    north SJ865432, HJ5, D72, C95
  1341. X    west DQ5
  1342. X    south SA, HAQ, DA, CAQJT87642
  1343. X    east DKJ
  1344. Xcondition
  1345. X    hcp(east)>=10 && shape(west, x5xx) && shape(east, x45x + x46x + x47x)
  1346. Xaction
  1347. X    average "king drops" shape(west, xxx1),
  1348. X    average "finesse" hascard(east, KH)
  1349. + END-OF-FILE Descr.6c
  1350. chmod 'u=r,g=r,o=r' 'Descr.6c'
  1351. echo 'SENT: -r--r--r--  1 sater         699 Nov 15 22:56 Descr.6c'
  1352. echo -n 'RCVD: '
  1353. /bin/ls -l Descr.6c
  1354. echo 'Extracting Descr.controls'
  1355. sed 's/^X//' > Descr.controls << '+ END-OF-FILE Descr.controls'
  1356. X# Calculates frequency of controls (A=2, K=1) in a strong balanced hand
  1357. Xcontrols=
  1358. X    2*hascard(north, AS) + hascard(north, KS) +
  1359. X    2*hascard(north, AH) + hascard(north, KH) +
  1360. X    2*hascard(north, AD) + hascard(north, KD) +
  1361. X    2*hascard(north, AC) + hascard(north, KC)
  1362. X
  1363. Xcondition
  1364. X    shape(north, any 4333 + any 4432 + any 5332) and
  1365. X        hcp(north)>=20 and hcp(north)<=22
  1366. X
  1367. Xaction
  1368. X    frequency "controls" (controls, 5, 9)
  1369. + END-OF-FILE Descr.controls
  1370. chmod 'u=r,g=r,o=r' 'Descr.controls'
  1371. echo 'SENT: -r--r--r--  1 sater         404 Nov 15 22:56 Descr.controls'
  1372. echo -n 'RCVD: '
  1373. /bin/ls -l Descr.controls
  1374. echo 'Extracting Descr.notrump'
  1375. sed 's/^X//' > Descr.notrump << '+ END-OF-FILE Descr.notrump'
  1376. X# Generate hands for practicing bidding after 1NT
  1377. X
  1378. Xeast_notrump =
  1379. X    shape(east, any 4333 + any 4432 + any 5332 - 5xxx - x5xx)
  1380. X    && hcp(east)>=15 && hcp(east)<=17
  1381. X
  1382. Xwest_interesting_low = hcp(west)>=7 and hcp(west)<=9 
  1383. Xwest_interesting_high = hcp(west)>=13 and hcp(west)<=18
  1384. X
  1385. Xcondition
  1386. X    east_notrump and ( west_interesting_low or west_interesting_high)
  1387. Xaction
  1388. X    print(east, west)
  1389. + END-OF-FILE Descr.notrump
  1390. chmod 'u=r,g=r,o=r' 'Descr.notrump'
  1391. echo 'SENT: -r--r--r--  1 sater         375 Nov 15 22:56 Descr.notrump'
  1392. echo -n 'RCVD: '
  1393. /bin/ls -l Descr.notrump
  1394. echo 'Extracting Descr.weaktwo'
  1395. sed 's/^X//' > Descr.weaktwo << '+ END-OF-FILE Descr.weaktwo'
  1396. X# calculates some statistics of hands deemed to be weak two's
  1397. X# I do not claim this definition of a weak two will satisfy everybody
  1398. X
  1399. Xweaktwospades = 
  1400. X    shape(north, 6xxx - any 0xxx) and
  1401. X    hcp(north) >= 5 and hcp(north) <= 11 and
  1402. X    hcp(north, spades) >= hcp(north)/2
  1403. X
  1404. Xheartfit =
  1405. X    hearts(north) + hearts(south) >= 8
  1406. X
  1407. Xcondition weaktwospades
  1408. Xaction
  1409. X    frequency "points" (hcp(north), 5, 11) ,
  1410. X    average "hearts" hearts(north) ,
  1411. X    average "Ace of spades" hascard(north, AS) ,
  1412. X    average "Jack of spades" hascard(north, JS) ,
  1413. X    average "Heart fit" heartfit
  1414. + END-OF-FILE Descr.weaktwo
  1415. chmod 'u=r,g=r,o=r' 'Descr.weaktwo'
  1416. echo 'SENT: -r--r--r--  1 sater         542 Nov 15 22:56 Descr.weaktwo'
  1417. echo -n 'RCVD: '
  1418. /bin/ls -l Descr.weaktwo
  1419. exit 0
  1420.