The Input File
Basic Layout
The basic lay-out of the file is:
 command1 "parameters for command 1"
 command2 "parameters for command 2"
 ...
 condition "list of conditions"
 action "list of actions"
The exact format is free, as long as it is unambigous, the program will
understand it; in other words, lines can be broken freely, wherever it is
desired to do so. Any line starting with a #-sign is regarded as a comment
and ignored.
Comments can also be placed at the end of any line, from a marker
of "//" all the way to the end of the line; or, independent of line
structure, by starting the comment with a marker of "/*" and ending it
with a marker of "*/".
Lexical structure
All the words recognized by the program act as keywords, that is,
reserved words -- you cannot use those words as identifiers for
other purposes, or you will get a syntax error.
For many such keywords, both the singular and plural forms are recognized
and accepted interchangeably; this also means both forms are reserved.  
This plural/singular duality applies to the following keywords:  club,
diamond, heart, spade, notrump, hcp, jack, queen, king,
ace, loser, control, trick and imp.
Inputs
The program knows several basic commands, each consisting of a keyword and
a parameter.  A parameter can be a single value or an expression that will be evaluated for every
generated deal.  Besides that, the program allows the user to create
identifiers and assign expressions to them.  
The identifiers can be used as parameters for the basic commands or inside
other expressions, and this is exactly
equivalent to using the expressions they
denote.
- generate (number)
 generate (number) hands. If you do not specify this, then a million
       hands will be generated
- produce (number)
 Produce (number) hands that satisfy the condition. If you do specify
       this and you want the hands to be printed you get 40. If you only
       asked for statistics or so you will get a 100,000.
       The "generate" and "produce" numbers are upper limits. The first one
       to become true will terminate the program.
 
- vulnerable ({none|NS|EW|all})
 Sets the vulnerability for the hand to 1 of the 4 possibilities, with
       none the default if the command is not in the input file.
       This command is primarily intended for cases where 
       action-list includes the
       printpbn action and the hands will be fed
       into another program for further analysis.  These programs often
       require that the dealer and vulnerability are known.  This command
       allows the user to set the vulnerability, the next command allows
       him to set the dealer.
 
- dealer (compass)
 Sets the dealer on the hand to north, south, east or west, with
       north the default if the command is not in the input file.
- predeal (predeallist)
 This command can be used to assign specific cards to a player, for 
       example in problems like the common "you hold SAQ542, HKJ87, D32, CAK"
       and the auction starts 1C on your left, 2D by partner, pass on your
       left.  With the predeal command, you can assign these 13 cards to
       this player.  Then you create expressions
       describing the 1C opener
       and the 2D overcall.  Finally, you generate a number of hands fitting
       the conditions and (hopefully) find the solution for your problem. 
       The predeallist consists of a player, followed by holding in one or
       more suits separated by commas.  A holding in a suit consist of a
       suit-symbol (S, H,  D or C) followed by cards (AKQJ, T for 10, 9..2).
        
       A player can be pre-dealt any number of cards, e.g. for a play
       problem it is possible to give dummy and declarer their specific
       hands and the opening-leader the card he just led.  The program
       then generates hands by dividing the remaining 25 cards over the
       two other players.
        
       An alternate form of predeal specification is 
       (suit)(player)==1 (for example: 
       "spades(north)==1" and 
       variants thereof for different suits, compass positions, numbers); this
       will ensure that (player) gets exactly the number of spades specified,
       (in this case, one), but that spade can be any card (except for the
       ones predealt to other players).  
       predeal (player),(card) 
       will just force the program to give these cards to this player, 
       without any restrictions for the remaining cards. 
       For example, predeal north,S2 will give north the 2 of
       spades.  However, all other spade cards can still be dealt to north,
       so north will not necessarily have a singleton spade 2.
        
       Note that predeal is not compatible with a command-line switch
       of "-l", and only makes much sense for hands that are not
       permuted if the command-line switches of "-2" or "-3" are given
       ("-3" is generally used with predeal for North, "-2" with predeal
       for North and South) to specify "swapping" (the default is "-0",
       "no swapping").
 
- pointcount (list of numbers)
 Points to give to the various cards, starting from the ace and ending
       with the 2.  The hcp() function uses this. Default
       is the standard 4, 3, 2, 1 (and 0 for all other cards) scale.
- altcount (number) (list of numbers)
 Similar to pointcount, but for 10 "alternate counts" numbered
       0 to 9, so that several things about a hand can be "counted".
       The ptN() functions use this (names are pt0,
       pt1, etc, up to pt9, and there are also synonyms such
       as tens, jacks, etc; default for what is being counted
       varies for each of the 10 alternate counts).
- condition
         (expression)
 For every generated hand, the expression is
       evaluated.  If it is true (non zero), then the corresponding 
       action is executed.  If you do not
       specify a condition the constant 1 (always true) will be assumed.
       The word condition can actually be omitted.  Note that if
       more than one condition is specified, this is not diagnosed
       as an error, but the last condition will override the other(s);
       to have several conditions apply at once, you have to join
       them into a single expression, i.e. a single condition
       statement, joining them with "&&" or equivalently "and".
        
       Deals not meeting the condition are considered to be "generated"
       but not "produced", and no action is undertaken for them.
 
- action (actionlist)
 List of actions to be executed. If you do not specify an action,
       the printall action is assumed.  If
       more than one action is in the list, separate them with commas.
- (identifier) = (expression)
 Defines (identifier) to represent (expression)
Expressions
An expression looks like regular C-code, with all normal operators that
make sense in a bridge program present:
 -  && or and: logical AND
 
-  || or or:  logical OR
 
-  !  or not: logical NOT
 
-  ==: Equal to (note, NOT "=", but rather "=="!!!)
 
-  !=: Not equal to
 
-  < and <=: Less and "Equal or Less" respectively.
 
-  > and >=: Greater and "Greater or equal"
      respectively.
 
-  +, -, *, /: Add, subtract, multiply and divide; note that
 	division truncates to the next lower integer (the program does
	not use "floating point" numbers).
 
-  %: Modulo ("remainder of division by").
 
-  (): Brackets.  The program uses the normal C-rules to evaluate
      expressions.  With brackets this can be changed, e.g. 2*a+b is
      evaluated by multiplying a by 2, then adding b. Changing
      this into 2*(a+b) reverses this. 
 
-  ?: the ternary "selection" operator. The operand before
      the ? is first evaluated; if true, then the one right
      after the ? and before the : is evaluated (and
      its value is that of this entire sub-expression), else, the
      one at the end of the sub-expression, i.e. after the :.
      This operator is usually used for "if-then-else" constructions.
      
      For example: Suppose you want assign the number of hcp in north's longest
      minor to a variable.   With the selection operator, this can be done
      as follows:
minornorth = clubs(north) > diamonds(north) ? hcp(north,clubs) : hcp(north,diamonds)
 The program will first evaluate the "clubs(north)>diamonds(north)" part.
      If this is true, then 
      hcp(north,clubs) will be assigned to minornorth.
      If not, then minornorth will be set to 
      hcp(north,diamonds).
      This line is equivalent to the following piece of C-like code:
if (clubs(north) > diamonds(north) )
  minornorth = hcp(north, clubs);
else
  minornorth = hcp(north, diamonds);
 
 
Besides that, special operators useful in a bridge-program are provided:
 - Suit Lengths- 
   -  (suit) ( (compass) ), eg hearts(west)
 the number of cards in the suit held by the player.  Suit can
           be club(s), diamond(s), heart(s) or spade(s).
 - 
  
- Hand Evaluation- 
   -  hcp ( (compass) ), eg hcp(north)
 the number of high card points held by the player using the 4321
           count, unless overwritten with the pointcount command.
-  hcp ( (compass), (suit) ), eg hcp(south, spades)
 the number of high card points in the specified suit, using the
           4321 count (or alternate assignments provided with the pointcount
	   command).
-  ptN ( (compass) ), eg pt3(north)
 alternate-count number N (from 0 to 9) for the player named
-  ptN ( (compass), (suit) ), eg ptN(south, spades)
 the value of alternate-count number N using the specified suit
           and player
-  tens, jacks, queens, kings, aces, top2, top3, top4, top5, c13
 alternate, readable synonyms for pt0 to pt9 in
           order -- the names correspond to what these alternate-counts
           do count if not overridden with the altcount command:
           number of jacks/queens/kings/aces; numbers of honours in the
           top 2 (AK), 3 (AKQ), 4 (AKQJ), 5 (AKQJT); "c13" points, with
           A=6, K=4, Q=2, J=1 (a version of the "Four Aces" or "Burnstine"
           count using only integers, and with points in each suit that
           sum to 13, whence the name).
           Example: top5(east,spades) number of honours that
           East holds in the Spade suit (unless alternate count number
           8 has been overridden with altcount 8, in which
           case the things being counted can be quite different).
-  control ((compass)), eg control(north)
 The number of controls using A=2, K=1.
           It is possible to generate hands with N controls using the 
           hcp()
           function.   However, one has to override the standard 
           pointcount table for that, making it impossible to generate
           hands with requirements on hcp and controls  
           (for example, "
           hcp(north)>6 and control(north)<3").
	   This function solves that problem.
-  control ((compass, (suit)), eg control(north, spades)
 The number of controls using A=2, K=1 in a suit.
-  loser ((compass)), eg loser(north)
 The number of losers in the hand, or the sum of the number of
           losers in each suit.  The program does not apply any
           corrections to the loser-count such as "1 loser less if a player
           has more aces than queens".
-  loser ((compass, (suit)), eg loser(north, spades)
 The number of losers in a suit.  The number of losers in a suit is:
            -  3 cards or more: 3 - 1 for each of A, K or Q held.
            
-  Void: 0 losers.
            
-  Singleton A: 0 losers, any other singleton 1.
            
-  Doubleton AK: 0 losers, Ax or Kx 1, any other doubleton 2.
           
 
-  cccc(compass)
   
-  quality(compass, suit)
 Both quality and cccc use the algorithms described in _The Bridge
       World_, October 1982, with the single exception that the values are
       multiplied by 100 (so that we can use integers for them).  Thus, a
       minimum opening bid is about 1200, rather than 12.00 as expressed in
       the text.
-  tricks(compass, strain)
 Runs GIB's double-dummy engine (BRIDGE under Linux, BRIDGE.EXE
	under Windows/NT or /98), which must be present on the path or
	in the same directory as the Dealer executable (together with,
	on Windows, SH.EXE and CYGWIN.DLL from Cygnus' free Cygwin
	package; this latter is not necessary in Paul Baxter's version), to
    compute the number of tricks that, at double-dummy
	par, will be taken by the given declarer in the given strain
	(suit or notrumps).
-  score(vulnerability, contract, tricks)
 Returns the positive or negative score that declarer will make if
	the given contract, at the given vulnerability condition, is
	played and the given number of tricks are made.
    The syntax for "contract" is of the form "x3N" for 3 no-trumps,
    "x7C" for 7 clubs, etc; the leading "x" is needed.  There is 
    currently no way to specify that the contract is doubled, nor
    that it is re-doubled. The result will be positive if the
    contract makes, negative if it goes down.
-  imps(scoredifference) 
 Translates a score-difference into IMPs (International Match
	Points).  The difference, of course, can be positive or negative,
    and the result of "imps" will then have that same sign.
 - 
  
- Shapes and specific cards- 
   -  shape ( (compass), shapelist)
 This function specifies specific shapes for a player.
        The shapelist is a list of shapes combined with + or -
        signs.  A shape with a + sign is added to the list, a shape with
        a - sign is excluded from the list.
         
        A shape is specified by digits in the normal order spades, hearts,
        diamonds and clubs, so 5431 specifies a hand with 5 spades, 4 hearts,
        3 diamonds and a singleton club.
         
        Digits can be replaced by the letter "x" to match any length,
        so "55xx" specifies a hand with 5 spades, 5 hearts and 3 cards
        in the minors. 
         
        The "any" operator can be prepended to a shape.  This will
        remove the order of the suits, so "any 4333" specifies any
        hand with 1 4-card suit and 3 cards in the 3 other suits.
         
        Adding all this together allows you to write expressions like:
         
        shape(north, any 4333 + 54xx - any 0xxx)
         requiring north to hold any 4333, 5 spades and 4 hearts, but 
        excluding any distribution with a void.
	This operator is one of the most important in the program and is
	very efficiently implemented. Any shape() call, no matter how
	complicated is executed in constant time. Use shape()
	for all length expressions if you can.
    
-  hascard ( (compass), (card) ), eg hascard(east, TC)
 whether east holds the 10 (T) of clubs
 
Actions
Note that multiple "print" actions, while not forbidden, are not
guaranteed to work sensibly.  printoneline and printes are roughly
"designed" to work with each other, but most other combinations will not
produced the overall hoped-for output format; experiment. Actions whose
names do not start with "print", i.e. average and frequency, do generally
co-operate sensibly with each other and with one print action (or a series
of printoneline/printes ones), but, again, experiment is advised.
The different actions are:
-  printall
 prints all four hands next to each other in the order
        north, east, south and west. This is the default.
- print ((list of compasses)), eg print(east,west)
 print all hands specified on separate pages. This is the best
	way to generate hands to be used for partnership training.
	One of the partners gets one page, and one the other and they can
	start practicing.
- printew
 Prints the east and west hands only, with west to the left of
       east.  This is useful for generating examples for bidding 
       sequences.  Generate the 2 hands then add comments in a text editor
       to the file.
-  printpbn
 Print the output in PBN format, for further analysis by other
       programs.
- printcompact [optional expression]
 Print the output, and optionally an expression, in reasonably
       compact form (4 lines per deal).
- printoneline [optional expression]
 Print the output, and optionally an expression, in very
       compact form (1 line per deal).
- printes (list of strings and 
    expressions)
 Prints one or more expressions and strings; separate them with
    commas if there is more than one, and use \n to indicate end
    of line.  Example:
 printes "Number of hearts: ", hearts(north), \n
 This is mainly intended to help you debug complicated
    expressions -- break them up into small pieces and use
    printes to examine their results.
- average "optional string" (expr), eg	average "points" hcp(north)
 calculates and prints the average of the expression over all
       hands satisfying the condition. The optional strings is printed
	before the average.
- frequency "optional string" ( (expr), (lowbnd), (highbnd) )
 calculates and prints a histogram of the values of (expr),
	between the bounds (lowbnd) and (highbnd) inclusive (all
	values lower than lowbnd are cumulated into a first row "Low",
	all higher than highbnd into a last row "High").
	The optional string is printed before the histogram
- frequency "optional string" ( (expr), (lowbnd), (highbnd), (expr2),
		(lowbnd2), (highbnd2) )
 calculates and prints a 2-D histogram of the joint values of (expr),
	between the bounds (lowbnd) and (highbnd) inclusive, and (expr2)
	between the bounds (lowbnd2) and (highbnd2) inclusive; as above,
	"low" and "high" are added for each expression, and, also, the
	marginals of the joint distribution are printed as "Sum" rows
	and columns.  This can give a good idea of the mutual statistical
	influence of two computed expressions upon each other.
	The optional string is printed before the histogram.
The program allows for and unlimited number of actions.  More than one
print action is allowed, but, depending on the actions involved, this may
or may not give the desired results.An example
Back to the "you hold ..." problem.  Suppose we want to generate 25 hands
that match these specifications on a slow machine, so we don't want to
generate too many hands.  This is accomplished with the following input
file:
generate   10000
produce    25
vulnerable EW
dealer     west
predeal    south SAQ542, HKJ87, D32, CAK
west1c   = hcp(west)>11 && clubs(west)>= 3
# Condition describing west's 1C opener.
north2d  = diamonds(north)>=6 && (hcp(north)>5 && hcp(north)<12)
# Condition describing north's 2D overcall.
condition  west1c && north2d
# Require that west bids 1C and north 2D
action     printall
This produces 25 hands, including, for example, with this one:
J 7 3               9 8                 A Q 5 4 2           K T 6 
3                   9 6 4 2             K J 8 7             A Q T 5 
K Q J T 9 8 5       7                   3 2                 A 6 4 
T 5                 9 8 7 4 3 2         A K                 Q J 6 
Note that the hands that you get depend on the seed of the random
generator, so, unless you use the -s flag to
set the random generator seed, the hands that you produce will be
different.
You can now start to analyze the hand and decide on the best action for
east.  However, if you look carefully at the west-hand, then you see that
west could have opened this with a 15-17 NT.  If you look at other hands,
west might have opened 1D, 1H or 1S.  These hands are excluded by:
west1d = diamonds(west)>clubs(west) || ((diamonds(west)==clubs(west))==4)
west1h = hearts(west)>= 5
west1s = spades(west)>= 5
west1n = shape(west, any 4333 + any 4432 + any 5332 - 5xxx - x5xx) &&
         (hcp(west)>14 && hcp(west)<18)
west1c = hcp(west)>11 && clubs(west)>= 3 && 
         (not west1n) && (not west1s) && (not west1h) && (not west1d)
A next run shows that north will occasionally overcall 2D on 8-card suit
or with a side 4 or 5 card major.  These distributions are excluded with:
north2d = (hcp(north)>5 && (hcp(north)<12) &&
          shape (north, xx6x + xx7x - any 4xxx - any 5xxx)
 
making the complete example:
generate   10000
produce    25
vulnerable ew
dealer     west
predeal    south SAQ542, HKJ87, D32, CAK
west1n = shape(west, any 4333 + any 4432 + any 5332 - 5xxx - x5xx) &&
         hcp(west)>14 && hcp(west)<18
west1h = hearts(west)>= 5
west1s = spades(west)>= 5
west1d = diamonds(west)>clubs(west) || ((diamonds(west)==clubs(west))==4)
west1c = (not west1n) && hcp(west)>10 && clubs(west)>=3
         && (not west1h) && (not west1s) && (not west1d)
north2d = (hcp(north)>5 && hcp(north)<12) &&
          shape(north, xx6x + xx7x - any 4xxx - any 5xxx)
condition  west1c && north2d
action     printall
More examples can be found in the Examples directory of the distribution.
 
 
