home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-11-15 | 35.4 KB | 1,420 lines |
- Newsgroups: rec.games.bridge
- 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
- From: sater@sater.home.cs.vu.nl (Hans van Staveren)
- Subject: dealer program source, second release
- Message-ID: <Bxs2v1.356@sater.home.cs.vu.nl>
- Organization: The home machine of Hans van Staveren
- Date: Sun, 15 Nov 1992 22:09:00 GMT
- Lines: 1410
-
- The dealer program I posted has released moderately positive response.
- One bug was detected, and there were some suggestions for improvement.
- Here is the second release.
-
- Bugs fixed:
- the shape() call returned integers not equal to 1 when true,
- this screwed up things when used in a context not boolean
- Extra features:
- - It is now possible to predeal certain cards to certain players,
- and distribute the rest at random.
- - The shape() operator now has better possibilities to include and exclude
- shapes. Like any 54 in the majors but no void is now trivial to express.
-
- Thanks to the people that made suggestions.
-
- Hans van Staveren
- Amsterdam, Holland
-
- : This is a shar archive. Extract with sh, not csh.
- : This archive ends with exit, so do not worry about trailing junk.
- echo 'Extracting README'
- sed 's/^X//' > README << '+ END-OF-FILE README'
- XThis program is hereby put in the public domain. Do with it whatever
- Xyou want, but I would like you not to redistribute it in modified form
- Xwithout mentioning the fact of modification. I will accept bug reports
- Xand modification requests, without any obligation of course, but fixing
- Xbugs someone else put in is beyond me.
- X
- XWhen you report bugs please mention the version number in the source
- Xfiles, and preferably send context diffs if you changed anything.
- XI might put in your fixes, and distribute a new version someday.
- X
- XI would prefer if you did *not* use this program for generating hands
- Xfor tournaments. I have not investigated the random number generation
- Xclosely enough for me to be comfortable with that thought.
- X
- X Hans van Staveren
- X Amsterdam
- X Holland
- X <sater@sater.home.cs.vu.nl>
- + END-OF-FILE README
- chmod 'u=r,g=r,o=r' 'README'
- echo 'SENT: -r--r--r-- 1 sater 792 Nov 4 20:52 README'
- echo -n 'RCVD: '
- /bin/ls -l README
- echo 'Extracting Description'
- sed 's/^X//' > Description << '+ END-OF-FILE Description'
- X DEALER, a bridge hand generator program
- X Hans van Staveren <sater@sater.home.cs.vu.nl>
- X
- XThe program dealer can be used to generate hands for partnerships
- Xbidding training or for generating statistics that can be used to
- Xdesign conventions, or win postmortems.
- X
- XThe program reads the description from standard input, and writes
- Xresults on standard output.
- X
- XIn general the input specifies a condition and an action, and the
- Xprogram will generate a lot of hands, and if the condition is satisfied
- Xexecute the action.
- X
- XA simple example:
- X
- X shape(north, any 4333 + any 4423) and hcp(north)>=19
- X
- Xas input will print 40 hands with strong balanced Norths.
- X
- XHere is a partial explanation of all possible inputs: if you really want
- Xto know all read the source.
- X
- Xgenerate <number>
- X generate <number> hands. If you do not specify this a million
- X will be generated
- Xproduce <number>
- X produce <number> hands that satisfy the condition. If you do specify
- X this and you want the hands to be printed you get 40. If you only
- X asked for statistics or so you will get a hundred thousand.
- X<identifier> = <expression>
- X defines <identifier> to represent <expression>
- Xpredeal <predeallist>
- X can be used to assign certain cards to certain hands, for example
- X to check probabilities for actual play. See the example in
- X Descr.6c for enlightenment.
- Xcondition <expression>
- X for every hand generated <expression> is calculated. If it is
- X non zero the corresponding action is executed. If you do not
- X specify a condition the constant 1 will be assumed.
- X The word condition can actually be omitted.
- Xaction <actionlist>
- X list of actions to be executed. If you do not specify an action
- X the "printall" action is assumed.
- X
- XThe "generate" and "produce" numbers are upper limits. The first one
- Xto become true will terminate the program.
- X
- XAn expression looks like a C expression, with all normal operators
- Xpresent. If you look for leftshift, or exponentiation forget it,
- Xbut all normal ones are there, with their normal priorities.
- XParentheses can be used, and all in all it is just like C.
- XThe && form can be used, or the word "and". The same goes for "or"
- Xand "not".
- X
- XThe special operators needed in a bridge-dealer program are provided:
- X
- X<suit> ( <compass> ) , eg hearts(west)
- X the number of cards in the suit held by the player
- Xhcp ( <compass> ), eg hcp(north)
- X the number of high card points held by the player, 4321 count.
- Xhcp ( <compass>, <suit> ), eg hcp(south, spades)
- X the number of high card points in the specified suit
- Xhascard ( <compass>, <card> ), eg hascard(east, TC)
- X whether east holds the 10 (T) of clubs
- Xshape ( <compass>, shapelist),
- X eg shape(north, any 4333 + 54xx - any 0xxx)
- X whether north holds one of the shapes in the list,
- X in this case either a 4333 in any suit, or 5 spades and 4 hearts,
- X but no void anywhere.
- X A shapelist is a list of shapes combined with + or - signs.
- X The word any prepended to a shape means that any suit can match
- X the numbers, without the word any the shapes are the normal ones
- X in the order spades, hearts, diamonds and clubs.
- X Instead of a digit the letter 'x' can be given to match any length.
- X All of this means that "any 55xx" means any shape with two five
- X card suits.
- X This operator is one of the most important in the program and is
- X very efficiently implemented. Any shape() call, no matter how
- X complicated is executed in constant time. Use shape()
- X for all length expressions if you can.
- X
- XThe different actions are:
- Xprintall
- X prints all four hands next to each other. This is the default.
- Xprint (<list of compasses>), eg print(east,west)
- X print all hands specified on separate pages. This is the best
- X way to generate hands to be used for partnership training.
- X One of the partners gets one page, and one the other and they can
- X start practicing.
- Xaverage "optional string" <expr>, eg average "points" hcp(north)
- X calculates and prints the average of the expression over all
- X hands satisfying the condition. The optional strings is printed
- X before the average.
- Xfrequency "optional string" ( <expr>, <lowbnd>, <highbnd> )
- X calculates and prints a histogram of the values of <expr>,
- X between the bounds <lowbnd> and <highbnd> inclusive.
- X The optional string is printed before it.
- X
- XThe speed of the program obviously depends on the machine it runs on.
- XOn my home machine, a SparcStation 1+, it generates more than 3000 hands
- Xa second if the condition is not too complicated. I rarely play more than
- X150 hands a week, so in about two seconds I can generate the boards of a year.
- X
- XIt satisfies me.
- X
- XPortability:
- XThe program has been developed under SunOS on Sun hardware. I am a reasonably
- Xcompetent programmer though, and I expect the program to be highly portable.
- XThe most suspect part is in the initialisation of the random number generator.
- XThe system call used here might need to be changed on other OSes.
- + END-OF-FILE Description
- chmod 'u=r,g=r,o=r' 'Description'
- echo 'SENT: -r--r--r-- 1 sater 4836 Nov 15 23:00 Description'
- echo -n 'RCVD: '
- /bin/ls -l Description
- echo 'Extracting Makefile'
- sed 's/^X//' > Makefile << '+ END-OF-FILE Makefile'
- X# $Header: /home/sater/bridge/dealer/RCS/Makefile,v 1.2 1992/11/15 22:00:48 sater Exp $
- XCFLAGS=-O -DNDEBUG
- X
- Xdealer: dealer.o defs.o
- X $(CC) $(CFLAGS) -o dealer dealer.o defs.o -ll
- X
- Xlint: dealer.c defs.c
- X lint dealer.c defs.c
- X
- Xclean:
- X rm -f defs.c scan.c *.o dealer
- X
- Xsharf: README Description Makefile dealer.c defs.y scan.l tree.h
- X shar README Description Makefile dealer.c defs.y scan.l tree.h Descr.* >sharf
- X
- Xdealer.o: tree.h
- Xdefs.o: scan.c tree.h
- + END-OF-FILE Makefile
- chmod 'u=r,g=r,o=r' 'Makefile'
- echo 'SENT: -r--r--r-- 1 sater 449 Nov 15 23:00 Makefile'
- echo -n 'RCVD: '
- /bin/ls -l Makefile
- echo 'Extracting dealer.c'
- sed 's/^X//' > dealer.c << '+ END-OF-FILE dealer.c'
- X#include <stdio.h>
- X#include <sys/time.h>
- X#include "tree.h"
- X#include <assert.h>
- X
- Xstatic char rcsid[] = "$Header: /home/sater/bridge/dealer/RCS/dealer.c,v 1.3 1992/11/15 21:26:08 sater Exp $";
- X
- Xtypedef unsigned char card;
- X
- Xchar *player_name[] = { "North", "East", "South", "West" };
- Xchar representation[] = "23456789TJQKA";
- X
- Xint points[13] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4 };
- Xtypedef card deal[52];
- X
- X/*
- X * Various handshapes can be asked for. For every shape the user is
- X * interested in a number is generated. In every distribution that fits that
- X * shape the corresponding bit is set in the distrbitmaps 4-dimensional array.
- X * This makes looking up a shape a small constant cost.
- X */
- X#define MAXDISTR 8*sizeof(int)
- Xint ***distrbitmaps[14];
- X
- Xstruct handstat {
- X int hs_length[NSUITS]; /* distribution */
- X int hs_points[NSUITS]; /* 4321 HCP per suit */
- X int hs_totalpoints; /* Sum of above four */
- X int hs_bits; /* Bitmap to check distribution */
- X};
- X
- Xint will_print; /* Is there a print action? */
- X
- Xpraction() {
- X
- X if (will_print++)
- X yyerror("Only one printaction maximum");
- X}
- X
- Xchar * mycalloc(nel, siz)
- Xunsigned nel, siz;
- X{
- X char *p, *calloc();
- X
- X p = calloc(nel, siz);
- X if (p)
- X return p;
- X fprintf(stderr, "Out of memory\n");
- X exit(-1);
- X /*NOTREACHED*/
- X}
- X
- Xinitdistr() {
- X int ***p4,**p3,*p2;
- X int clubs, diamonds, hearts;
- X
- X /*
- X * Allocate the four dimensional pointer array
- X */
- X
- X for(clubs=0;clubs<=13;clubs++) {
- X p4 = (int ***) mycalloc((unsigned)14-clubs, sizeof(*p4));
- X distrbitmaps[clubs] = p4;
- X for(diamonds=0;diamonds<=13-clubs;diamonds++) {
- X p3 = (int **) mycalloc((unsigned)14-clubs-diamonds, sizeof(*p3));
- X p4[diamonds] = p3;
- X for(hearts=0;hearts<=13-clubs-diamonds;hearts++) {
- X p2 = (int *) mycalloc((unsigned)14-clubs-diamonds-hearts, sizeof(*p2));
- X p3[hearts] = p2;
- X }
- X }
- X }
- X}
- X
- Xsetshapebit(cl, di, ht, sp, msk, excepted)
- X{
- X
- X if (excepted)
- X distrbitmaps[cl][di][ht][sp] &= ~msk;
- X else
- X distrbitmaps[cl][di][ht][sp] |= msk;
- X}
- X
- Xnewpack(d)
- Xdeal d;
- X{
- X int suit, rank, place;
- X
- X place = 0;
- X for (suit=SUIT_CLUB; suit <= SUIT_SPADE; suit++)
- X for(rank=0; rank<13; rank++)
- X d[place++] = MAKECARD(suit, rank);
- X}
- X
- Xemptypack(d)
- Xdeal d;
- X{
- X int i;
- X
- X for (i=0; i<52; i++)
- X d[i] = NO_CARD;
- X}
- X
- Xhascard(d, player, onecard)
- Xdeal d;
- Xint player;
- Xcard onecard;
- X{
- X int i;
- X
- X for(i=player*13; i<(player+1)*13; i++)
- X if (d[i] == onecard)
- X return 1;
- X return 0;
- X}
- X
- Xmake_card(rankchar, suitchar)
- Xchar rankchar, suitchar;
- X{
- X int rank, suit;
- X
- X for (rank=0;rank<13 && representation[rank]!=rankchar;rank++)
- X ;
- X assert(rank<13);
- X switch(suitchar) {
- X case 'C': suit = 0; break;
- X case 'D': suit = 1; break;
- X case 'H': suit = 2; break;
- X case 'S': suit = 3; break;
- X default: assert(0);
- X }
- X return MAKECARD(suit, rank);
- X}
- X
- Xint use_compass[NSUITS];
- X
- Xanalyze(d, hs)
- Xdeal d;
- Xstruct handstat *hs;
- X{
- X int player,base,next,c,r,s;
- X card curcard;
- X
- X for (player = COMPASS_NORTH, base = 0; player <= COMPASS_WEST;
- X player++, hs++, base += 13) {
- X /*
- X * If the expressions in the input never mention a player
- X * we do not calculate his hand statistics.
- X */
- X if (use_compass[player]==0)
- X continue;
- X next = base;
- X for (s=SUIT_CLUB; s<=SUIT_SPADE; s++) {
- X hs->hs_length[s] = 0;
- X hs->hs_points[s] = 0;
- X }
- X for (c=0; c<13; c++) {
- X curcard = d[next++];
- X s = C_SUIT(curcard);
- X r = C_RANK(curcard);
- X hs->hs_length[s]++;
- X hs->hs_points[s] += points[r];
- X }
- X hs->hs_totalpoints = 0;
- X for (s=SUIT_CLUB; s<=SUIT_SPADE; s++)
- X hs->hs_totalpoints += hs->hs_points[s];
- X hs->hs_bits = distrbitmaps
- X [hs->hs_length[SUIT_CLUB]]
- X [hs->hs_length[SUIT_DIAMOND]]
- X [hs->hs_length[SUIT_HEART]]
- X [hs->hs_length[SUIT_SPADE]];
- X }
- X}
- X
- X
- Xprintdeal(d)
- Xdeal d;
- X{
- X int suit,player,rank,cards;;
- X
- X for( suit=SUIT_SPADE; suit>= SUIT_CLUB; suit--) {
- X cards=10;
- X for (player=COMPASS_NORTH; player<=COMPASS_WEST; player++) {
- X while (cards<10) {
- X printf(" ");
- X cards++;
- X }
- X cards=0;
- X for (rank = 12; rank >=0; rank--) {
- X if (hascard(d, player, MAKECARD(suit, rank))) {
- X printf("%c ", representation[rank]);
- X cards++;
- X }
- X }
- X if (cards == 0) {
- X printf("- ");
- X cards++;
- X }
- X }
- X printf("\n");
- X }
- X printf("\n");
- X}
- X
- Xint nprod,maxproduce;
- Xint ngen,maxgenerate;
- Xstruct tree defaulttree = {TRT_NUMBER, NIL, NIL, 1, 0};
- Xstruct tree *decisiontree = &defaulttree;
- Xstruct action defaultaction = { (struct action *) 0, ACT_PRINTALL };
- Xstruct action *actionlist = &defaultaction;
- X
- Xdeal fullpack;
- Xdeal stacked_pack;
- Xdeal curdeal;
- X
- Xstruct handstat hs[4];
- X
- Xsetup_deal() {
- X register i,j;
- X
- X j = 0;
- X for (i=0; i<52; i++) {
- X if (stacked_pack[i] != NO_CARD) {
- X curdeal[i] = stacked_pack[i];
- X } else {
- X while (fullpack[j] == NO_CARD)
- X j++;
- X curdeal[i] = fullpack[j++];
- X assert(j <= 52);
- X }
- X }
- X}
- X
- Xpredeal(player, onecard)
- Xint player;
- Xcard onecard;
- X{
- X int i,j;
- X
- X for(i=0; i<52; i++) {
- X if (fullpack[i] == onecard) {
- X fullpack[i] = NO_CARD;
- X for(j=player*13; j<(player+1)*13; j++)
- X if (stacked_pack[j] == NO_CARD) {
- X stacked_pack[j] = onecard;
- X return;
- X }
- X yyerror("More than 13 cards for one player");
- X }
- X }
- X yyerror("Card predealt twice");
- X}
- X
- X
- X#define RANDBITS 16
- X#define NRANDVALS (1<<RANDBITS)
- X
- Xunsigned char zero52[NRANDVALS];
- X
- Xinitrandom() {
- X struct timeval tv;
- X int i, i_cycle;
- X int val;
- X
- X /*
- X * The most suspect part of this program
- X */
- X gettimeofday(&tv, (void *) 0);
- X srandom(tv.tv_sec^tv.tv_usec);
- X /*
- X * End of suspect part
- X *
- X * Now initialize array zero52 with numbers 0..51
- X * repeatedly. This whole charade is just to prevent having
- X * to do divisions.
- X */
- X val = 0;
- X for (i=0, i_cycle=0; i< NRANDVALS; i++) {
- X while (stacked_pack[val] != NO_CARD) {
- X /* this slot is predealt, do not use it */
- X val++;
- X if (val==52) {
- X val=0;
- X i_cycle = i;
- X }
- X }
- X zero52[i] = val++;
- X if (val==52) {
- X val=0;
- X i_cycle = i+1;
- X }
- X }
- X /*
- X * Fill the last part of the array with 0xFF, just to prevent
- X * that 0 occurs more than 51. This is probably just for hack value
- X */
- X while (i > i_cycle) {
- X zero52[i-1] = 0xFF;
- X i--;
- X }
- X}
- X
- Xshuffle(d)
- Xdeal d;
- X{
- X int i,j;
- X card t;
- X
- X /*
- X * Algorithm according to Knuth. For each card exchange with
- X * a random other card. This is supposed to be the perfect
- X * shuffle algorithm. It only depends on a valid random number
- X * generator.
- X */
- X for (i=0; i<52; i++) {
- X if (stacked_pack[i] == NO_CARD) {
- X do
- X /* Upper bits most random */
- X j = zero52[random()>>(31-RANDBITS)];
- X while (j==0xFF);
- X t = d[j]; d[j] = d[i]; d[i] = t;
- X }
- X }
- X}
- X
- Xevaltree(t)
- Xstruct tree *t;
- X{
- X
- X switch(t->tr_type) {
- X default:
- X assert(0);
- X case TRT_NUMBER:
- X return t->tr_int1;
- X case TRT_AND2:
- X return evaltree(t->tr_leaf1) && evaltree(t->tr_leaf2);
- X case TRT_OR2:
- X return evaltree(t->tr_leaf1) || evaltree(t->tr_leaf2);
- X case TRT_ARPLUS:
- X return evaltree(t->tr_leaf1) + evaltree(t->tr_leaf2);
- X case TRT_ARMINUS:
- X return evaltree(t->tr_leaf1) - evaltree(t->tr_leaf2);
- X case TRT_ARTIMES:
- X return evaltree(t->tr_leaf1) * evaltree(t->tr_leaf2);
- X case TRT_ARDIVIDE:
- X return evaltree(t->tr_leaf1) / evaltree(t->tr_leaf2);
- X case TRT_ARMOD:
- X return evaltree(t->tr_leaf1) % evaltree(t->tr_leaf2);
- X case TRT_CMPEQ:
- X return evaltree(t->tr_leaf1) == evaltree(t->tr_leaf2);
- X case TRT_CMPNE:
- X return evaltree(t->tr_leaf1) != evaltree(t->tr_leaf2);
- X case TRT_CMPLT:
- X return evaltree(t->tr_leaf1) < evaltree(t->tr_leaf2);
- X case TRT_CMPLE:
- X return evaltree(t->tr_leaf1) <= evaltree(t->tr_leaf2);
- X case TRT_CMPGT:
- X return evaltree(t->tr_leaf1) > evaltree(t->tr_leaf2);
- X case TRT_CMPGE:
- X return evaltree(t->tr_leaf1) >= evaltree(t->tr_leaf2);
- X case TRT_NOT:
- X return !evaltree(t->tr_leaf1);
- X case TRT_LENGTH: /* suit, compass */
- X assert(t->tr_int1>=SUIT_CLUB && t->tr_int1<=SUIT_SPADE);
- X assert(t->tr_int2>=COMPASS_NORTH && t->tr_int2<=COMPASS_WEST);
- X return hs[t->tr_int2].hs_length[t->tr_int1];
- X case TRT_HCPTOTAL: /* compass */
- X assert(t->tr_int1>=COMPASS_NORTH && t->tr_int1<=COMPASS_WEST);
- X return hs[t->tr_int1].hs_totalpoints;
- X case TRT_HCP: /* compass, suit */
- X assert(t->tr_int1>=COMPASS_NORTH && t->tr_int1<=COMPASS_WEST);
- X assert(t->tr_int2>=SUIT_CLUB && t->tr_int2<=SUIT_SPADE);
- X return hs[t->tr_int1].hs_points[t->tr_int2];
- X case TRT_SHAPE: /* compass, shapemask */
- X assert(t->tr_int1>=COMPASS_NORTH && t->tr_int1<=COMPASS_WEST);
- X assert(t->tr_int2>=0 && t->tr_int2<MAXDISTR);
- X return (hs[t->tr_int1].hs_bits&t->tr_int2) != 0;
- X case TRT_HASCARD: /* compass, card */
- X assert(t->tr_int1>=COMPASS_NORTH && t->tr_int1<=COMPASS_WEST);
- X return hascard(curdeal, t->tr_int1, t->tr_int2);
- X }
- X}
- X
- Xinteresting()
- X{
- X return evaltree(decisiontree);
- X}
- X
- Xdeal *deallist;
- X
- Xsetup_action() {
- X struct action *acp;
- X
- X /*
- X * Initialize all actions
- X */
- X for (acp=actionlist; acp!=0; acp = acp->ac_next) {
- X switch(acp->ac_type) {
- X default:
- X assert(0);
- X /*NOTREACHED*/
- X case ACT_PRINTALL:
- X break;
- X case ACT_PRINT:
- X deallist = (deal *) mycalloc(maxproduce, sizeof(deal));
- X break;
- X case ACT_AVERAGE:
- X break;
- X case ACT_FREQUENCY:
- X acp->ac_u.acu_f.acuf_freqs = (long *) mycalloc(
- X acp->ac_u.acu_f.acuf_highbnd - acp->ac_u.acu_f.acuf_lowbnd + 1,
- X sizeof(long));
- X break;
- X }
- X }
- X}
- X
- Xaction() {
- X struct action *acp;
- X int expr;
- X
- X for (acp=actionlist; acp!=0; acp = acp->ac_next) {
- X switch(acp->ac_type) {
- X default:
- X assert(0);
- X /*NOTREACHED*/
- X case ACT_PRINTALL:
- X printdeal(curdeal);
- X break;
- X case ACT_PRINT:
- X bcopy(curdeal, deallist[nprod], sizeof(deal));
- X break;
- X case ACT_AVERAGE:
- X acp->ac_int1 += evaltree(acp->ac_expr1);
- X break;
- X case ACT_FREQUENCY:
- X expr = evaltree(acp->ac_expr1);
- X if (expr < acp->ac_u.acu_f.acuf_lowbnd)
- X acp->ac_u.acu_f.acuf_uflow++;
- X else if (expr > acp->ac_u.acu_f.acuf_highbnd)
- X acp->ac_u.acu_f.acuf_oflow++;
- X else
- X acp->ac_u.acu_f.acuf_freqs[expr-acp->ac_u.acu_f.acuf_lowbnd]++;
- X break;
- X
- X }
- X }
- X}
- X
- Xprinthands(boardno, dealp, player, nhands)
- Xint boardno, player, nhands;
- Xdeal *dealp;
- X{
- X int i, suit,rank,cards;;
- X
- X for(i=0; i<nhands; i++)
- X printf("%4d.%15c", boardno+i+1, ' ');
- X printf("\n");
- X for( suit=SUIT_SPADE; suit>= SUIT_CLUB; suit--) {
- X cards=10;
- X for (i=0; i<nhands; i++) {
- X while (cards<10) {
- X printf(" ");
- X cards++;
- X }
- X cards=0;
- X for (rank = 12; rank >=0; rank--) {
- X if (hascard(dealp[i], player, MAKECARD(suit, rank))) {
- X printf("%c ", representation[rank]);
- X cards++;
- X }
- X }
- X if (cards == 0) {
- X printf("- ");
- X cards++;
- X }
- X }
- X printf("\n");
- X }
- X printf("\n");
- X}
- X
- Xcleanup_action() {
- X struct action *acp;
- X int player,i;
- X
- X for (acp=actionlist; acp!=0; acp = acp->ac_next) {
- X switch(acp->ac_type) {
- X default:
- X assert(0);
- X /*NOTREACHED*/
- X case ACT_PRINTALL:
- X break;
- X case ACT_PRINT:
- X for (player = COMPASS_NORTH; player<=COMPASS_WEST; player++) {
- X if (!(acp->ac_int1 & (1<<player)))
- X continue;
- X printf("\n\n%s hands:\n\n\n\n", player_name[player]);
- X for (i=0; i<nprod; i+=4)
- X printhands(i, deallist+i, player, nprod-i>4 ? 4 : nprod-i);
- X printf("\f");
- X }
- X break;
- X case ACT_AVERAGE:
- X if (acp->ac_str1)
- X printf("%s: ", acp->ac_str1);
- X printf("%g\n", (double) acp->ac_int1/nprod);
- X break;
- X case ACT_FREQUENCY:
- X printf("Frequency %s:\n", acp->ac_str1 ? acp->ac_str1 : "");
- X if (acp->ac_u.acu_f.acuf_uflow)
- X printf("Low\t%8d\n", acp->ac_u.acu_f.acuf_uflow);
- X for (i=acp->ac_u.acu_f.acuf_lowbnd; i <= acp->ac_u.acu_f.acuf_highbnd; i++)
- X printf("%5d\t%8d\n", i, acp->ac_u.acu_f.acuf_freqs[i-acp->ac_u.acu_f.acuf_lowbnd]);
- X if (acp->ac_u.acu_f.acuf_oflow)
- X printf("High\t%8d\n", acp->ac_u.acu_f.acuf_oflow);
- X break;
- X }
- X }
- X}
- X
- Xint verbose = 1;
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X extern int optind;
- X extern char *optarg;
- X char c;
- X int errflg = 0;
- X
- X while ((c = getopt(argc, argv, "v")) != -1) {
- X switch(c) {
- X case 'v':
- X verbose ^= 1;
- X break;
- X case '?':
- X errflg = 1;
- X break;
- X }
- X }
- X if (argc - optind>1 || errflg) {
- X fprintf(stderr, "Usage: %s [-v] [inputfile]\n", argv[0]);
- X exit(-1);
- X }
- X if (optind < argc && freopen(argv[optind], "r", stdin) == NULL) {
- X perror(argv[optind]);
- X exit(-1);
- X }
- X newpack(fullpack);
- X emptypack(stacked_pack);
- X initdistr();
- X yyparse();
- X initrandom();
- X if (maxgenerate==0)
- X maxgenerate = 1000000;
- X if (maxproduce==0)
- X maxproduce =
- X actionlist == &defaultaction || will_print
- X ? 40 : 100000;
- X
- X setup_action();
- X setup_deal();
- X for(ngen=nprod=0; ngen<maxgenerate && nprod < maxproduce; ngen++) {
- X shuffle(curdeal);
- X analyze(curdeal, hs);
- X if (interesting()) {
- X action();
- X nprod++;
- X }
- X }
- X cleanup_action();
- X if (verbose)
- X printf("Generated %d hands, produced %d.\n", ngen, nprod);
- X return 0;
- X}
- + END-OF-FILE dealer.c
- chmod 'u=r,g=r,o=r' 'dealer.c'
- echo 'SENT: -r--r--r-- 1 sater 12668 Nov 15 22:26 dealer.c'
- echo -n 'RCVD: '
- /bin/ls -l dealer.c
- echo 'Extracting defs.y'
- sed 's/^X//' > defs.y << '+ END-OF-FILE defs.y'
- X%{
- X#include <stdio.h>
- X#include <string.h>
- X#include "tree.h"
- X
- Xstatic char rcsid[] = "$Header: /home/sater/bridge/dealer/RCS/defs.y,v 1.4 1992/11/15 22:01:03 sater Exp $";
- X
- Xint predeal_compass; /* global variable for predeal communication */
- X%}
- X
- X%union {
- X int y_int;
- X char *y_str;
- X struct tree *y_tree;
- X struct action *y_action;
- X char y_distr[4];
- X}
- X
- X%left OR2
- X%left AND2
- X%left CMPEQ, CMPNE
- X%left CMPLT, CMPLE, CMPGT, CMPGE
- X%left ARPLUS, ARMINUS
- X%left ARTIMES, ARDIVIDE, ARMOD
- X%nonassoc NOT
- X
- X%token GENERATE, PRODUCE, HCP, SHAPE, ANY, EXCEPT, CONDITION, ACTION
- X%token PRINT, PRINTALL, AVERAGE, HASCARD, FREQUENCY, PREDEAL
- X%token <y_int> NUMBER
- X%token <y_str> HOLDING
- X%token <y_str> STRING
- X%token <y_str> IDENT
- X%token <y_int> COMPASS
- X%token <y_int> SUIT
- X%token <y_int> CARD
- X%token <y_distr> DISTR
- X
- X%type <y_tree> expr
- X%type <y_int> compass, printlist, shlprefix, any
- X%type <y_distr> shape
- X%type <y_action> actionlist action
- X%type <y_str> optstring
- X
- X%start defs
- X
- X%%
- X
- Xdefs
- X : /* empty */
- X | defs def
- X ;
- X
- Xdef
- X : GENERATE NUMBER
- X { extern int maxgenerate; maxgenerate = $2; }
- X | PRODUCE NUMBER
- X { extern int maxproduce; maxproduce = $2; }
- X | PREDEAL predealargs
- X | CONDITION expr
- X { extern struct tree *decisiontree; decisiontree = $2; }
- X | expr
- X { extern struct tree *decisiontree; decisiontree = $1; }
- X | IDENT '=' expr
- X { new_var($1, $3); }
- X | ACTION actionlist
- X { extern struct action *actionlist; actionlist = $2; }
- X ;
- X
- Xpredealargs
- X : predealarg
- X | predealargs predealarg
- X ;
- X
- Xpredealarg
- X : COMPASS { predeal_compass = $1;} holdings
- X ;
- X
- Xholdings
- X : HOLDING
- X { predeal_holding(predeal_compass, $1); }
- X | holdings ',' HOLDING
- X { predeal_holding(predeal_compass, $3); }
- X ;
- X
- Xcompass
- X : COMPASS
- X { extern int use_compass[NSUITS]; use_compass[$1] = 1; $$= $1; }
- X ;
- X
- Xshape
- X : DISTR
- X { bcopy($1, $$, 4); };
- X | NUMBER
- X { if ($1<1000 || $1>=10000) yyerror("bad shape");
- X $$[0] ='0'+$1/1000; $$[1]='0'+$1/100%10;
- X $$[2] ='0'+$1/10%10; $$[3]='0'+$1%10;
- X }
- X ;
- X
- Xshlprefix
- X : ','
- X { $$ = 0; }
- X | ARPLUS
- X { $$ = 0; }
- X | /* empty */
- X { $$ = 0; }
- X | ARMINUS
- X { $$ = 1; }
- X ;
- X
- Xany
- X : /* empty */
- X { $$ = 0; }
- X | ANY
- X { $$ = 1; }
- X ;
- X
- Xshapelistel
- X : shlprefix any shape
- X { insertshape($3, $2, $1); }
- X ;
- X
- Xshapelist
- X : shapelistel
- X | shapelist shapelistel
- X ;
- X
- Xexpr
- X : NUMBER
- X { $$ = newtree(TRT_NUMBER, NIL, NIL, $1, 0); }
- X | IDENT
- X { $$ = var_lookup($1, 1); }
- X | SUIT '(' compass ')'
- X { $$ = newtree(TRT_LENGTH, NIL, NIL, $1, $3); }
- X | HCP '(' compass ')'
- X { $$ = newtree(TRT_HCPTOTAL, NIL, NIL, $3, 0); }
- X | HCP '(' compass ',' SUIT ')'
- X { $$ = newtree(TRT_HCP, NIL, NIL, $3, $5); }
- X | SHAPE '(' compass ',' shapelist ')'
- X { $$ = newtree(TRT_SHAPE, NIL, NIL, $3, 1<<(shapeno++)); }
- X | HASCARD '(' COMPASS ',' CARD ')'
- X { $$ = newtree(TRT_HASCARD, NIL, NIL, $3, $5); }
- X | '(' expr ')'
- X { $$ = $2; }
- X | expr CMPEQ expr
- X { $$ = newtree(TRT_CMPEQ, $1, $3, 0, 0); }
- X | expr CMPNE expr
- X { $$ = newtree(TRT_CMPNE, $1, $3, 0, 0); }
- X | expr CMPLT expr
- X { $$ = newtree(TRT_CMPLT, $1, $3, 0, 0); }
- X | expr CMPLE expr
- X { $$ = newtree(TRT_CMPLE, $1, $3, 0, 0); }
- X | expr CMPGT expr
- X { $$ = newtree(TRT_CMPGT, $1, $3, 0, 0); }
- X | expr CMPGE expr
- X { $$ = newtree(TRT_CMPGE, $1, $3, 0, 0); }
- X | expr AND2 expr
- X { $$ = newtree(TRT_AND2, $1, $3, 0, 0); }
- X | expr OR2 expr
- X { $$ = newtree(TRT_OR2, $1, $3, 0, 0); }
- X | expr ARPLUS expr
- X { $$ = newtree(TRT_ARPLUS, $1, $3, 0, 0); }
- X | expr ARMINUS expr
- X { $$ = newtree(TRT_ARMINUS, $1, $3, 0, 0); }
- X | expr ARTIMES expr
- X { $$ = newtree(TRT_ARTIMES, $1, $3, 0, 0); }
- X | expr ARDIVIDE expr
- X { $$ = newtree(TRT_ARDIVIDE, $1, $3, 0, 0); }
- X | expr ARMOD expr
- X { $$ = newtree(TRT_ARMOD, $1, $3, 0, 0); }
- X | NOT expr
- X { $$ = newtree(TRT_NOT, $2, NIL, 0, 0); }
- X ;
- Xactionlist
- X : action
- X { $$ = $1; }
- X | action ',' actionlist
- X { $$ = $1; $$->ac_next = $3; }
- X | /* empty */
- X { $$ = 0; }
- X ;
- Xaction
- X : PRINTALL
- X { praction();
- X $$ = newaction(ACT_PRINTALL, NIL, (char *) 0, 0);
- X }
- X | PRINT '(' printlist ')'
- X { praction();
- X $$ = newaction(ACT_PRINT, NIL, (char *) 0, $3);
- X }
- X | AVERAGE optstring expr
- X { $$ = newaction(ACT_AVERAGE, $3, $2, 0); }
- X | FREQUENCY optstring '(' expr ',' NUMBER ',' NUMBER ')'
- X { $$ = newaction(ACT_FREQUENCY, $4, $2, 0);
- X $$->ac_u.acu_f.acuf_lowbnd = $6;
- X $$->ac_u.acu_f.acuf_highbnd = $8;
- X }
- X ;
- Xoptstring
- X : /* empty */
- X { $$ = (char *) 0; }
- X | STRING
- X { $$ = $1; }
- X ;
- Xprintlist
- X : COMPASS
- X { $$ = (1<<$1); }
- X | printlist ',' COMPASS
- X { $$ = $1|(1<<$3); }
- X ;
- X%%
- X
- Xstruct var {
- X struct var *v_next;
- X char *v_ident;
- X struct tree *v_tree;
- X} *vars=0;
- X
- Xstruct tree *var_lookup(s, mustbethere)
- Xchar *s;
- X{
- X struct var *v;
- X
- X for(v=vars; v!=0; v = v->v_next)
- X if (strcmp(s, v->v_ident)==0)
- X return v->v_tree;
- X if (mustbethere)
- X yyerror("unknown variable");
- X return 0;
- X}
- X
- Xnew_var(s, t)
- Xchar *s;
- Xstruct tree *t;
- X{
- X struct var *v;
- X char *mycalloc();
- X
- X if (var_lookup(s, 0)!=0)
- X yyerror("redefined variable");
- X v = (struct var *) mycalloc(1, sizeof(*v));
- X v->v_next = vars;
- X v->v_ident = s;
- X v->v_tree = t;
- X vars = v;
- X}
- X
- Xint lino=1;
- X
- Xyyerror(s)
- Xchar *s;
- X{
- X
- X fprintf(stderr, "line %d: %s\n", lino, s);
- X exit(-1);
- X}
- X
- Xint perm[24][4] = {
- X { 0, 1, 2, 3 },
- X { 0, 1, 3, 2 },
- X { 0, 2, 1, 3 },
- X { 0, 2, 3, 1 },
- X { 0, 3, 1, 2 },
- X { 0, 3, 2, 1 },
- X { 1, 0, 2, 3 },
- X { 1, 0, 3, 2 },
- X { 1, 2, 0, 3 },
- X { 1, 2, 3, 0 },
- X { 1, 3, 0, 2 },
- X { 1, 3, 2, 0 },
- X { 2, 0, 1, 3 },
- X { 2, 0, 3, 1 },
- X { 2, 1, 0, 3 },
- X { 2, 1, 3, 0 },
- X { 2, 3, 0, 1 },
- X { 2, 3, 1, 0 },
- X { 3, 0, 1, 2 },
- X { 3, 0, 2, 1 },
- X { 3, 1, 0, 2 },
- X { 3, 1, 2, 0 },
- X { 3, 2, 0, 1 },
- X { 3, 2, 1, 0 },
- X};
- X
- Xint shapeno;
- Xinsertshape(s, any, neg_shape)
- Xchar s[4];
- X{
- X int i,j,p;
- X int xcount=0, ccount=0;
- X char copy_s[4];
- X
- X for (i=0;i<4;i++) {
- X if (s[i]=='x')
- X xcount++;
- X else
- X ccount += s[i]-'0';
- X }
- X switch(xcount) {
- X case 0:
- X if (ccount!=13)
- X yyerror("wrong number of cards in shape");
- X for (p=0; p<(any? 24 : 1); p++)
- X setshapebit(s[perm[p][3]]-'0', s[perm[p][2]]-'0',
- X s[perm[p][1]]-'0', s[perm[p][0]]-'0',
- X 1<<shapeno, neg_shape);
- X break;
- X default:
- X if (ccount>13)
- X yyerror("too many cards in ambiguous shape");
- X bcopy(s, copy_s, 4);
- X for(i=0; copy_s[i] != 'x'; i++)
- X ;
- X if (xcount==1) {
- X copy_s[i] = 13-ccount+'0'; /* could go above '9' */
- X insertshape(copy_s, any, neg_shape);
- X } else {
- X for (j=0; j<=13-ccount; j++) {
- X copy_s[i] = j+'0';
- X insertshape(copy_s, any, neg_shape);
- X }
- X }
- X break;
- X }
- X}
- X
- Xstruct tree *newtree(type, p1, p2, i1, i2)
- Xint type;
- Xstruct tree *p1, *p2;
- Xint i1,i2;
- X{
- X char *mycalloc();
- X struct tree *p;
- X
- X p = (struct tree *) mycalloc(1, sizeof(*p));
- X p->tr_type = type;
- X p->tr_leaf1 = p1;
- X p->tr_leaf2 = p2;
- X p->tr_int1 = i1;
- X p->tr_int2 = i2;
- X return p;
- X}
- X
- Xstruct action *newaction(type, p1, s1, i1)
- Xint type;
- Xstruct tree *p1;
- Xchar *s1;
- Xint i1;
- X{
- X char *mycalloc();
- X struct action *a;
- X
- X a = (struct action *) mycalloc(1, sizeof(*a));
- X a->ac_type = type;
- X a->ac_expr1 = p1;
- X a->ac_str1 = s1;
- X a->ac_int1 = i1;
- X return a;
- X}
- X
- Xchar *mystrcpy(s)
- Xchar *s;
- X{
- X char *cs;
- X char *mycalloc();
- X
- X cs = mycalloc(strlen(s)+1, sizeof(char));
- X strcpy(cs, s);
- X return cs;
- X}
- X
- Xpredeal_holding(compass, holding)
- Xchar *holding;
- X{
- X int suit;
- X
- X suit = *holding++;
- X while (*holding) {
- X predeal(compass, make_card(*holding, suit));
- X holding++;
- X }
- X}
- X
- X#include "scan.c"
- + END-OF-FILE defs.y
- chmod 'u=r,g=r,o=r' 'defs.y'
- echo 'SENT: -r--r--r-- 1 sater 7238 Nov 15 23:01 defs.y'
- echo -n 'RCVD: '
- /bin/ls -l defs.y
- echo 'Extracting scan.l'
- sed 's/^X//' > scan.l << '+ END-OF-FILE scan.l'
- X/* $Header: /home/sater/bridge/dealer/RCS/scan.l,v 1.2 1992/11/15 21:26:43 sater Exp $ */
- X%%
- X"&&" return(AND2);
- Xand return(AND2);
- X"||" return(OR2);
- Xor return(OR2);
- X"!" return(NOT);
- Xnot return(NOT);
- X"==" return(CMPEQ);
- X"!=" return(CMPNE);
- X"<" return(CMPLT);
- X"<=" return(CMPLE);
- X">" return(CMPGT);
- X">=" return(CMPGE);
- X"+" return(ARPLUS);
- X"-" return(ARMINUS);
- X"*" return(ARTIMES);
- X"/" return(ARDIVIDE);
- X"%" return(ARMOD);
- Xgenerate return(GENERATE);
- Xproduce return(PRODUCE);
- Xpredeal return(PREDEAL);
- Xcondition return(CONDITION);
- Xaction return(ACTION);
- Xprint return(PRINT);
- Xprintall return(PRINTALL);
- Xaverage return(AVERAGE);
- Xfrequency return(FREQUENCY);
- Xnorth { yylval.y_int = COMPASS_NORTH; return COMPASS; }
- Xeast { yylval.y_int = COMPASS_EAST; return COMPASS; }
- Xsouth { yylval.y_int = COMPASS_SOUTH; return COMPASS; }
- Xwest { yylval.y_int = COMPASS_WEST; return COMPASS; }
- Xclubs { yylval.y_int = SUIT_CLUB; return SUIT; }
- Xdiamonds { yylval.y_int = SUIT_DIAMOND; return SUIT; }
- Xhearts { yylval.y_int = SUIT_HEART; return SUIT; }
- Xspades { yylval.y_int = SUIT_SPADE; return SUIT; }
- Xhcp return(HCP);
- Xhascard return(HASCARD);
- Xshape return(SHAPE);
- Xany return(ANY);
- X[CDHS]A?K?Q?J?T?9?8?7?6?5?4?3?2? { yylval.y_str = mystrcpy(yytext); return HOLDING; }
- X[2-9TJQKA][CDHS] { yylval.y_int = make_card(yytext[0], yytext[1]);
- X return(CARD);
- X }
- X\"[^"]*\" { yytext[yyleng-1] = 0; yylval.y_str = mystrcpy(yytext+1); return STRING; }
- X[0-9]+ { yylval.y_int = atoi(yytext); return NUMBER; }
- X[0-9x]{4} { strncpy(yylval.y_distr, yytext, 4); return DISTR; }
- X[a-zA-Z][a-zA-Z0-9_]* { yylval.y_str = mystrcpy(yytext); return IDENT; }
- X[ \t] ;
- X\n { lino++; }
- X^\#.*\n { lino++; }
- X. return(yytext[0]);
- + END-OF-FILE scan.l
- chmod 'u=r,g=r,o=r' 'scan.l'
- echo 'SENT: -r--r--r-- 1 sater 1713 Nov 15 22:26 scan.l'
- echo -n 'RCVD: '
- /bin/ls -l scan.l
- echo 'Extracting tree.h'
- sed 's/^X//' > tree.h << '+ END-OF-FILE tree.h'
- X/*
- X * decision tree and other expression stuff
- X */
- X
- Xstruct tree {
- X int tr_type;
- X struct tree *tr_leaf1, *tr_leaf2;
- X int tr_int1;
- X int tr_int2;
- X};
- X
- X#define NIL ((struct tree *) 0)
- X
- X#define SUIT_CLUB 0
- X#define SUIT_DIAMOND 1
- X#define SUIT_HEART 2
- X#define SUIT_SPADE 3
- X#define NSUITS 4
- X
- X#define MAKECARD(suit, rank) (((suit)<<6)|(rank))
- X#define C_SUIT(c) ((c)>>6)
- X#define C_RANK(c) ((c)&0x3F)
- X#define NO_CARD 0xFF
- X
- X#define COMPASS_NORTH 0
- X#define COMPASS_EAST 1
- X#define COMPASS_SOUTH 2
- X#define COMPASS_WEST 3
- X
- X#define TRT_NUMBER 0
- X#define TRT_AND2 1
- X#define TRT_OR2 2
- X#define TRT_CMPEQ 3
- X#define TRT_CMPNE 4
- X#define TRT_CMPLT 5
- X#define TRT_CMPLE 6
- X#define TRT_CMPGT 7
- X#define TRT_CMPGE 8
- X#define TRT_LENGTH 9
- X#define TRT_ARPLUS 10
- X#define TRT_ARMINUS 11
- X#define TRT_ARTIMES 12
- X#define TRT_ARDIVIDE 13
- X#define TRT_ARMOD 14
- X#define TRT_HCPTOTAL 15
- X#define TRT_HCP 16
- X#define TRT_SHAPE 17
- X#define TRT_NOT 18
- X#define TRT_HASCARD 19
- X
- X
- X/*
- X * Actions to be taken
- X */
- Xstruct action {
- X struct action *ac_next;
- X int ac_type;
- X struct tree *ac_expr1;
- X int ac_int1;
- X char *ac_str1;
- X union {
- X struct {
- X long acuf_lowbnd;
- X long acuf_highbnd;
- X long acuf_uflow;
- X long acuf_oflow;
- X long *acuf_freqs;
- X } acu_f;
- X } ac_u;
- X};
- X
- X#define ACT_PRINTALL 0
- X#define ACT_PRINT 1
- X#define ACT_AVERAGE 2
- X#define ACT_FREQUENCY 3
- + END-OF-FILE tree.h
- chmod 'u=r,g=r,o=r' 'tree.h'
- echo 'SENT: -r--r--r-- 1 sater 1317 Nov 15 22:27 tree.h'
- echo -n 'RCVD: '
- /bin/ls -l tree.h
- echo 'Extracting Descr.6c'
- sed 's/^X//' > Descr.6c << '+ END-OF-FILE Descr.6c'
- X# A typical play decision, here is the hand, the bidding and trick one
- X#
- X# J x x x x x x
- X# J x
- X# x x
- X# 9 5
- X#
- X#
- X# A
- X# A Q
- X# A
- X# A Q J 10 x x x x x
- X#
- X# W N E S
- X# p p 1D dbl
- X# 1H 2S 3H 4C
- X# p 4S p 6C
- X# all pass
- X#
- X# The lead is a small diamond to the K and A, how to play?
- X# Two possibilities, play for the drop of the KC or lead the QC,
- X# cross to the 9 and take the heart finesse.
- X#
- X# the inferences from bidding and trick one are encoded below
- Xpredeal
- X north SJ865432, HJ5, D72, C95
- X west DQ5
- X south SA, HAQ, DA, CAQJT87642
- X east DKJ
- Xcondition
- X hcp(east)>=10 && shape(west, x5xx) && shape(east, x45x + x46x + x47x)
- Xaction
- X average "king drops" shape(west, xxx1),
- X average "finesse" hascard(east, KH)
- + END-OF-FILE Descr.6c
- chmod 'u=r,g=r,o=r' 'Descr.6c'
- echo 'SENT: -r--r--r-- 1 sater 699 Nov 15 22:56 Descr.6c'
- echo -n 'RCVD: '
- /bin/ls -l Descr.6c
- echo 'Extracting Descr.controls'
- sed 's/^X//' > Descr.controls << '+ END-OF-FILE Descr.controls'
- X# Calculates frequency of controls (A=2, K=1) in a strong balanced hand
- Xcontrols=
- X 2*hascard(north, AS) + hascard(north, KS) +
- X 2*hascard(north, AH) + hascard(north, KH) +
- X 2*hascard(north, AD) + hascard(north, KD) +
- X 2*hascard(north, AC) + hascard(north, KC)
- X
- Xcondition
- X shape(north, any 4333 + any 4432 + any 5332) and
- X hcp(north)>=20 and hcp(north)<=22
- X
- Xaction
- X frequency "controls" (controls, 5, 9)
- + END-OF-FILE Descr.controls
- chmod 'u=r,g=r,o=r' 'Descr.controls'
- echo 'SENT: -r--r--r-- 1 sater 404 Nov 15 22:56 Descr.controls'
- echo -n 'RCVD: '
- /bin/ls -l Descr.controls
- echo 'Extracting Descr.notrump'
- sed 's/^X//' > Descr.notrump << '+ END-OF-FILE Descr.notrump'
- X# Generate hands for practicing bidding after 1NT
- X
- Xeast_notrump =
- X shape(east, any 4333 + any 4432 + any 5332 - 5xxx - x5xx)
- X && hcp(east)>=15 && hcp(east)<=17
- X
- Xwest_interesting_low = hcp(west)>=7 and hcp(west)<=9
- Xwest_interesting_high = hcp(west)>=13 and hcp(west)<=18
- X
- Xcondition
- X east_notrump and ( west_interesting_low or west_interesting_high)
- Xaction
- X print(east, west)
- + END-OF-FILE Descr.notrump
- chmod 'u=r,g=r,o=r' 'Descr.notrump'
- echo 'SENT: -r--r--r-- 1 sater 375 Nov 15 22:56 Descr.notrump'
- echo -n 'RCVD: '
- /bin/ls -l Descr.notrump
- echo 'Extracting Descr.weaktwo'
- sed 's/^X//' > Descr.weaktwo << '+ END-OF-FILE Descr.weaktwo'
- X# calculates some statistics of hands deemed to be weak two's
- X# I do not claim this definition of a weak two will satisfy everybody
- X
- Xweaktwospades =
- X shape(north, 6xxx - any 0xxx) and
- X hcp(north) >= 5 and hcp(north) <= 11 and
- X hcp(north, spades) >= hcp(north)/2
- X
- Xheartfit =
- X hearts(north) + hearts(south) >= 8
- X
- Xcondition weaktwospades
- Xaction
- X frequency "points" (hcp(north), 5, 11) ,
- X average "hearts" hearts(north) ,
- X average "Ace of spades" hascard(north, AS) ,
- X average "Jack of spades" hascard(north, JS) ,
- X average "Heart fit" heartfit
- + END-OF-FILE Descr.weaktwo
- chmod 'u=r,g=r,o=r' 'Descr.weaktwo'
- echo 'SENT: -r--r--r-- 1 sater 542 Nov 15 22:56 Descr.weaktwo'
- echo -n 'RCVD: '
- /bin/ls -l Descr.weaktwo
- exit 0
-