This is meant to be a comprehensive list of commands in Deal which are not native to Tcl. If you want to learn Tcl, I will be providing a set of pointers later. |
|
north
, east
, south
, west
, hand
UsageThese are very strange commands - they really have too much stuffed into them. That's a historical anomoly which I'm reluctant to abandon.east [ -void string] [ suitname ... ] hand {hand string} [ -void string] [ suitname ... ] south subcommand [ ... args ... ] hand {hand string} subcommand [ ... args ... ] With no subcommands, the routine is used for formatting the hand as a string. For example, if south is: Then the results of various commands are:S: AJ5432 H: KT94 D: void C: K93 The -void switch exists precisely for formatting the output.south => {AJ5432 KT94 {} K93} south spades => AJ5432 south hearts clubs => {KT94 K93} south -void - => {AJ5432 KT94 - K93} south -void --- diamonds => --- set h {AK4 {} A95432 JT98} hand $h => {AK4 {} A95432 JT98} hand $h spades => AK4 hand $h hearts clubs => {{} JT98} hand $h -void - => {AK4 - A95432 JT98}
The various subcommands will be treated in seperate sections.
The |
| |
Subcommand:
|
accept
and reject
Usageaccept [ [ if | unless ] expr expr ...] reject [ [ if | unless ] expr expr ...] SummaryWithout arguments,accept and reject are the
same as return 1 return
0 With arguments it's a little more obscure. This returns 1 if the expression matches. It is equivalent to:accept if {$h>4} The code:if {$h>4} { return 1 } Is logically equivalent to:accept if {$h>4} {$s>4} That is, the values are accepted if either of the expressions evaluates as true.if {$h>4 || $s>4} { return 1}
The This is equivalent to:accept unless {$h>4} {$s>4} if {!($h>4) || !($s>4)} { return 1 } The means we return with a true value unless one of the expressions is true. If one of the values is true, we simply go on to the next line.
ExamplesVirtually all of the examples included in the release contain an instance of "accept" or "reject." |
|
main
Usagemain { block of code } SummaryThis defines the primary block of code evaluated after each deal is generated. If the code returns true, |
|
whogets
UsageThis returns the name of the person holding the card cardname.whogets cardname |
|
deal_finished
UsageThis defines the code called at the completion of generating all deals. This is code you would use to dump statistics, for example.deal_finished { block of code } |
|
The handname parameter can be one ofWeak2Bid handname Weak2Bid hand {AKQxxx xxx xxx x}
north
, south
, east
, west
.
Shape procedures and holding
procedures fit the hand procedure calling method, along with other
options.
This follows the hand procedure outline with the addition of thebalanced handname balanced hand {AJ43 AKxx xxx K5} balanced eval 4 3 4 2 balanced shape {4 3 4 2}
eval
option.
defvector
and
holdingProc
.
This is an
abstraction of a very common bridge evaluation technique. The most
commonly used holding functions are high card points,
losing trick count, controls. For example, when
counting the losers in the hand AKxx Axx KQJxxx x
, we
find 1 loser in spades, 2 losers in hearts, 1 loser in diamonds,
and one loser in clubs. We define the total losers to be the sum
across all suits, and get 5 losers, total.
The interface lets you evaluate the entire hand, or only selected suits in a hand, or a specific list of holdings.
In the first two cases, if no suits are named, all suits are evaluated, and the results are accumulated. In the case of thehcp handname [ suitname ... ] hcp hand {AKJxxx K xxx xxx} [ suitname ... ] hcp holding AK43 [ ... ]
holding
call,
the specific holdings passed in are evaluated.
Note, I've been saying "accumulated" rather than added. In some cases, you might have an accumulation method different from addition. For example, you might return the standard opening leads from a holding:
Each suit would create a list of proposed leads, and the result would be a list of lists of all standard leads from all holdings. Here, the accumulation is to simply make a list.openingLead holding KQJ7 => K openingLead south => {K} {7 2} {4} {J}
balanced
and semibalanced
Usagebalanced handname balanced hand {text hand} balanced eval s h d c SummaryThese are both shape procedures.
|
|
clubs
, diamonds
, hearts
, spades
UsageThese implement the hand procedure interface, and return the suit lengths for the appropriate suit. |
|
hcp
UsageThis procedure computes standard high card points - ace is 4, king is 3, queen is 2, jack is 1. The procedure implements the holding procedure interface.hcp handname hcp handname suitname [suitname ...] hcp hand {s h d c} hcp hand {s h d c} suitname [suitname ...] |
|
losers
UsageThis implements a holding procedure which computes the number of half losers. This is for historical reasons - the only holding functions allowed in past releases returned integer values, but I wanted to have some refinements over raw losing trick count.losers handname losers handname suitname [suitname ...] losers hand {s h d c} losers hand {s h d c} suitname [suitname ...] |
|
lho
, partner
, rho
Usagelho handname rho handname partner handname SummaryThese routines accept one hand name and return another. For example, "lho north east ," and
"partner east west ."
|
|
holding
Usageholding length AJxx => 4 holding contains AJ64 A6 => 1 (true) holding contains AJ64 A65 => 0 (false) holding encode AJ4 => 4612 (binary: 1001000000100 ) holding decode 4612 => AJ4 holding matches AKxx AK42 => 1 (true) holding disjoint AJ65 KT82 => 1 (true) holding disjoint A65 A32 => 0 (false) holding index AKJ4 0 => A holding index AKJ4 1 => K holding index AKJ4 3 => 4 holding index AKJ4 -2 => J holding index AKJ4 10 => "" Summary |
|
score
Usagesource lib/score.tcl ... score contract vulnerability tricks SummaryThis routine computes the standard duplicate bridge score for a contract from the point of view of declarer, if declaring side takes the given number of tricks.The contract is passed as a list: The vulnerablity is one of the words2 spades 2 spades undoubled 4 clubs doubled 6 notrump redoubled vul or
nonvul .
The tricks is the number of tricks taken by declarer. Examplesscore {2 spades} nonvul 8 => 110 score {2 spades doubled} nonvul 8 => 470 score {2 spades redoubled} nonvul 8 => 640 score {2 spades doubled} vul 8 => 670 score {2 spades} nonvul 7 => -50 score {2 spades doubled} nonvul 7 => -100 score {2 spades doubled} vul 7 => -200 |
|
gib::directory
Usagesource lib/gib.tcl ... gib::directory path SummaryThis tells the GIB-related routines where GIB is installed.
If this routine is not called, it defaults to GIB's default install
directory,
Note: your path should include forward slashes ' |
|
gib::tricks
Usagesource lib/gib.tcl ... gib::tricks declarer denomination SummaryDenomination can be a suit name or "notrump ."
Declarer can be any hand name.
This routine returns the double-dummy number of tricks available in this deal, in the given denomination by the given declarer.
If GIB is installed anywhere unusual, you will need to call
|
|
parscore
Usagesource lib/parscore.tcl ... set result [parscore dealer vul] set contract [lindex $result 0] set declarer [lindex $result 1] set score [lindex $result 2] set tricks [lindex $result 3] set auction [lindex $result 4] SummaryThis computes the double-dummy par result for the hand.
The parscore routine returns a list of five values - the contract (in
the same form that is used by the Dealer is relevant on a few occasions. If both south and west can make 1NT, for example, and no 2-level contracts make, then "par" is 1NT by whomever gets a chance to bid it first.
If GIB is installed anywhere unusual, you will need to call
|
|
defvector
Usagedefvector vec aceVal [ kingVal ... ] vec handname vec SummaryThis defines a holding procedure which assigns integer values to the various cards in the hand. For exampleDefines a holding procedure which counts the ace as worth 6 points, the king as worth 4, the queen as 2, and the jack as 1.defvector hcp6421 6 4 2 1
Vectors are limited to being integer-valued. For more complicated
holding procedures, use |
|
holdingProc
UsageTemporarily, see the seperate documentation. |
|
shapeclass
, shapecond
, and shapefunc
UsageA shape class (or equivalently, a shape condition) also has the list subcommand:shapeclass name {... code ...} shapecond name {expr} shapefunc name {... code ...} name [ north | south | east | west ] name eval s h d c name shape {s h d c} name list SummaryThese commands create new procedures which fit the shape function interface.
is the equivalent of:shapecond name {expr} The code or expr is allowed to use the variablesshapeclass name { if {expr} { return 1 } else { return 0 } s , h , d , or c .
More details can be found in the Advanced Guide.
The Why are there two subcommands, "eval" and "shape" which do the roughly the same things? Let's say you have a class named "SemiBalanced" already defined, which includes 5-card majors. You want to define a "Balanced" class which excludes the 5-card majors. You can do this with the call: On the other hand, if you have a shape - output by the, say, a call to [north shape] you can evaluate it as:shapecond Balanced {[SemiBalanced eval $s $h $d $c] && $s<5 && $h<5} In fact, this is exactly equivalent to callingSemiBalanced shape [north shape] only slightly slower.SemiBalanced north |
|
sdev
Usagesdev name name add data [ data ... ] name count name average name sdev name rms SummaryThe "sdev" command defines a new Tcl procedure with the given name, which behaves as a data collection object. You can add data points to it, or you can retrieve the current number of data points, the average of the data points, the standard deviation of the data points, or the "root mean square" of the data points.
|
|
correlation
Usagecorrelation name name add xval yval [ xval yval ... ] name count name correlate name average [ x | y ] name sdev [ x | y ] name rms [ x | y ] SummaryThecorrelation declaration defines a routine much like
the sdev command, but each datapoint is a pair of values,
and it computes the linear correlation between the x and y
values.
You can also get individual data for the
If there is no data, it returns an error on
If there is only one pair entered, it will throw an error on
|
|
deal_deck
Usagedeal_deck Summarydeal_deck is called at every new deal,
even when all 52 cards are specified (stacked) precisely.
Imagine stacking cards as stacking them in an undealt deck,
but that the cards are only distributed to the hands when
deal_deck is called.
Most of the time, you won't need to call deal_deck directly, but it is useful to understand its behavior if you are going to write advanced procedures like input formats. Stacked cards are permanently stacked until the deck is reset. In this code: The output is "AKQ32". Usestack_hand south {AKQ32 AJ53 K54 2} deal_deck deal_deck puts [south spades] reset_deck
to undo card stackings.
The
|
reset_deck
Usagereset_deck SummaryThis forgets about all stacked cards. The deck, from Deal's point of view, plus a list of cards which must go to specific hands. The cards which are assigned to specific hands are "stacked." The cards which are not stacked can go anywhere at the next call to deal_deck. |
|
stack_hand
and stack_cards
Usagestack_hand handname hand stack_cards handname suitname holding [...] SummaryBy default, these two routines just call deck_stack_hand and deck_stack_cards, respectively - that is, they forcibly place cards in the deck.But these routines are meant to be overridden. For example, when using one of the input formats which reads deals from a file, the format will redefine these two procedures to give errors. A more complicated re-definition occurs in the% deal -I "line foo.txt" -e "stack_cards south spades AJ" Tcl stack dump of error info: No card stacking with input format ::line ... smartstack input format, which alters its hand
generation depending on what cards are stacked where.
|
|
deck_stack_hand
and deck_stack_cards
Usagedeck_stack_hand handname hand deck_stack_cards handname suitname holding [...] SummaryThese routines are the "underlying" deck-stacking routines. Any cards stacked with these routines remain stacked until the next call toreset_deck
|
|
stacked
Usagestacked handname SummaryDetermines what cards are stacked to this hand, returning them as a list of holdings:writes out the list:south gets AS KH 3H QD JD TC 9C 8C puts [stacked south] This is useful for the smartstacker, because we don't want to force the user to stack cards *after* specifying conditions.A K3 QJ T98 The call tostack_hand north {AJT KT3 KJ 75432} deal::input smartstack south balanced hcp 20 21 stack_hand occurs before smartstack
is loaded, so stack_hand has not been redefined. So what
smartstack does is read the cards already stacked, and
use that for its initial conditions.
|
|
deal::nostacking
Usage::deal::nostacking SummaryThis procedure redefines the stack_hand and stack_cards procedures to generate error messages, and generates an error if any cards are currently stacked.This is used in all of the input formats which read complete deals from files, and thus are incompatible with stacking. |
|
deal_reset_cmds
Usagedeal_reset_cmds {...code...} [ ... ] SummaryThis adds a set of commands that are to be called before the next deal. The code is executed at the next call to thedeal_deck procedure, which, unless
you are doing something complicated, means it is called at the beginning
of each time through the evaluation loop.
It is also used for defining input formats, so that deals can be read from files. For example, the "line" input format has the following routine declared: namespace eval line { #.... proc next {} { variable handle set length -1 catch { set length [gets $handle line] } # ... process the line, or handle oef stuff ... # ... deal_reset_cmds {::line::next} } } The key is that when line::next is done, it re-registers itself, making sure that it is called next time through as well.
The code passed in to |
|
deal::metadata
Usagedeal::metadata name {...code...} SummaryCurrently, this is just a peculiar way of caching slow evaluation routines. At the moment, the only place it is used is ingib::tricks .
When you call This isn't really necessary or efficient in most cases, but with evaluations which take some time, e.g. GIB calls, it improves things. |
|
deal::input
Usagedeal::input formatName args SummaryThedeal::input command is used to define an input source
for deals. It works as follows:
|
|
giblib
Usageor on the command line:deal::input giblib [filename] or% deal -I giblib % deal -I "giblib filename" SummarySpecifies that deals are read from the specified file in the format of Matt Ginsberg's library.dat file. This includes double-dummy tricks data, so that later calls togib::tricks
will not entail calls to the GIB binaries.
If no filename is given, the library tries to read from a file called "library.dat" in the current directory.
The |
|
line
Usagedeal::input line [filename] SummarySpecifies that deals are read from the specified file in the format written by Deal's "-l" option.If no filename is given, the library reads from standard input. This way, you can create a single data file and then run several different queries against it: [ The% deal -l 100000 > sample % deal -e "deal::input line sample" -i query1 % deal -e "deal::input line sample" -i query2 -e option just evaluates the code in the next
argument as Tcl code. Alternative, you can use the -I
option, which is shorthand for input formats:
The% deal -I "line sample" -i query1 -I args option is exactly the same as -e "deal::input args"
|
|
smartstack
Usageor on the command line:deal::input smartstack hand shapeclass [holdproc min max] % deal -I "smartstack shapeclass ..." SummaryThis is the most complicated Deal input method in the current release. It does not read deals from a file - it is, instead, a different path to generation of deals. The purpose of this format is to allow fast generations of deals where one hand fits a very specific description. For example, if you want to find hands where south has a balanced 27-count, you could write:On my computer, that returns the first deal in 14 seconds, and every deal after that takes a tiny fraction of a second. That's becausedeal::input smartstack south balanced hcp 27 27 smartstack
first builds a large "factory" in memory, but once it is built, the
factory spits out hands matching this condition very quickly.
By contrast, a standard "deal" script to find balanced 27-counts
takes about 2.8 seconds to find each deal. That means that if you only
want to find about five deals of this sort, the old style program
is faster, but if you want a lot more, use
One interesting feature of
The |
|
write_deal
Usagewrite_deal SummaryThis is the the name of a procedure which is called when deals are accepted. By default, it writes the result in the format:New output formats are defined by redefining this routine.S: 98632 H: A4 D: AJ754 C: J S: K S: AJT7 H: J3 H: QT95 D: T98 D: Q2 C: AKT7532 C: 984 S: Q54 H: K8762 D: K63 C: Q6 -------------------------- |
|
flush_deal
Usageflush_deal SummaryThis routine is called at the very end of a run for deal. It does nothing, by default, but some output formats may require it if data is cached. |
|