Holding Procedures in Deal 3.1 and iDeal


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

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

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

The holdingProc Command

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

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

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

holdingProc SmartHCP {A K Q J length} {

    if {$length>=4} {
        # Normal evaluation, +1 for each card longer than the fourth
	return [expr {$A*4+$K*3+$Q*2+$J+($len-4)}]

    if {$length==3} {
        # Normal evaluation for 3-card suits
	return [expr {$A*4+$K*3+$Q*2+$J}]

    if {$length==2} {
        # Jacks in doubletons are worth zero, queens one
	return [expr {$A*4+$K*3+$Q}]

    if {$length==1} {
        # Queens and jacks in singletons are worth zero, kings two
	return [expr {$A*4+$K*2}]

    return 0
Even though this code is slow, it is only evaluated at most 160 times, after which values are reused, yielding remarkably fast evaluations. One deal, you might get a holding of KQ75 which this routine evaluates as if it were evaluating KQxx. The next hand, it sees the holding KQ82 and, seeing this also as KQxx, remembers the previous value.

Types of Holding Procedures

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

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

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

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

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

Arguments Allowed

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

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

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

Silhouette Thomas Andrews (deal@thomasoandrews.com) Copyright 1996-2010. Deal is covered by the GNU General Public License.

Plane Dealing graphic above created using POV-Ray.