set script {
# ^^^^
# Cute hack to make the code self-listing - we place the code
# in a variable then evaluate it.
#
#
# load in the CGI and IDeal libraries
#
lappend auto_path ./lib
source cgi.tcl
package require IDeal
source binky2.tcl
source bhcp.tcl
holdingProc fifths {A K Q J T} {
expr {$A*4+$K*2.8+$Q*1.8+$J+$T*0.4}
}
holdingProc bumrap {A K Q J T} {
expr {$A*4.5+$K*3+$Q*1.5+$J*0.75+$T*0.25}
}
set evaluators {
expected.suit {ddh.offense.suit dds.offense.suit}
expected.nt {ddh.offense.nt dds.offense.nt}
binky.suit {binkyh.suit binkys.suit}
binky.nt {binkyh.nt binkys.nt}
binky-hcp.suit {bhcph.suit bhcps.suit}
binky-hcp.nt {bhcph.nt bhcps.nt}
hcp {hcp}
BUM-RAP {bumrap}
Fifths {fifths}
CCCC {CCCC.holding CCCC.shapepoints}
Bissell {Bissell}
}
#
# Define some links
#
link article {Offensive and Defensive Evaluations} ../../valuations/original.html
link binkyarticle {Binky Evaluations} ../../valuations/additive.html
link binkyversushcp {HCP Versus Binky} ../../valuations/points.html
link iDeal {iDeal} /iDeal/notes.html
link sourceListing {source code of this example} "ddeval.cgi?show=1"
link fifthsarticle {Fifths evaluator} "../../valuations/cardvaluesfor3nt.html"
#
# Define the suit images
#
imglink spades images/S.gif alt="S:"
imglink hearts images/H.gif alt="H:"
imglink diamonds images/D.gif alt="D:"
imglink clubs images/C.gif alt="C:"
#
# The list of evaluators used in this example
#
#set evaluators [list offense.suit offense.nt defense.suit defense.nt binky.offense.suit binky.offense.nt binky.defense.suit binky.defense.nt hcp controls CCCC Bissell]
#
# Force loading of ddeval library, then import
#
auto_load ddeval::all
namespace import ddeval::*
#
# Send email about errors to me ...
#
cgi_admin_mail_addr thomaso@best.com
proc ddeval_warn {} {
puts [font color=red {
Warning - bad values for 9+-card suits
Because the double dummy evaluators were determined by analyzing
data, some values and the amount of data I had on 9-card and
longer suits, was small, some hands will yield questionable
values for 'offense.suit', 'defense.suit', etc. If I had
no data for a particular type of hand, they will probably
return negative values...
}]
}
#
# Write out the form for entering a hand. If arguments are passed,
# they are used to fill in the fields, otherwise the fields are left
# empty.
#
proc theform {{spades {}} {hearts {}} {diamonds {}} {clubs {}}} {
cgi_form ddeval method=get {
table cellpadding=0 cellspacing=0 {
hr
tr [th colspan=2 "Enter a new hand"]
foreach suit {spades hearts diamonds clubs} {
table_row {
td align=right [imglink $suit]
table_data align=left {
cgi_text $suit maxlength=13 size=13
}
}
}
table_row {
td
table_data align=right {cgi_submit_button submit=Evaluate}
}
}
}
}
#
# Note placed at the end of end of the document
#
proc endnote {} {
hr
p "
This program is powered by [link iDeal], a fast Tcl-based plugin specialized
for defining procedures of use in bridge programs. You can examine the
[link sourceListing].
"
}
#
# get_suits
#
# Gets the hand from the 'spades', 'hearts', 'diamonds', and 'clubs'
# CGI variables
#
proc get_suits {} {
foreach suit {spades hearts diamonds clubs} {
set $suit ""
cgi_import_as $suit temp
regsub -all "10" $temp "T" temp2
set $suit [string trim $temp2]
}
list $spades $hearts $diamonds $clubs
}
#
# get_hand
#
# Tries to get the hand and place it in the variable passed in.
# First checks for the CGI parameters 'hand', and uses that if
# it exists. Otherwise, calls 'get_suits'.
#
proc get_hand {variable} {
upvar $variable result
if {[catch {cgi_import_as hand result}]} {
if {[catch {set result [get_suits]}]} {
return 0
}
}
# iDeal routine, 'hand' error checks to determine things like,
# 'are there 13 cards', 'are the holdings correct', and then
# normalizes the string representation (capitalizing akqjt,
# lower-casing Xs.)
if {[catch {set result [hand $result]}]} {
global errorInfo
h2 "Input error"
preformatted {puts "Could not determine hand from inputs: $errorInfo"}
return 0
}
return 1
}
proc hand_line {hand} {
foreach suit {spades hearts diamonds clubs} {
puts " [imglink $suit][hand $hand -void - $suit]"
}
}
proc zero {args} { return 0 }
proc evalrow {hand name functions} {
set hfunc [lindex $functions 0]
set sfunc [lindex $functions 1]
if {[string compare $sfunc ""]==0} { set sfunc zero }
table_row {
set vals [list]
lappend vals [set sum [$sfunc hand $hand]]
cgi_html_comment "$vals"
foreach h $hand {
lappend vals [set val [$hfunc holding $h]]
cgi_html_comment "$val $h"
set sum [expr {$sum+$val}]
}
td $name
td align=right $sum
foreach val $vals { td align=right $val }
}
}
cgi_eval {
cgi_title "Evaluators example"
cgi_input {}
cgi_body {
h2 "Evaluators example"
if {![catch {cgi_import show}]} {
hr
h2 "Source code"
preformatted {puts "set script {$script}\n\neval \$script"}
hr
}
set hand ""
if {[get_hand hand]} {
foreach suit $hand {
if {[string length $suit]>=9} {
ddeval_warn
}
}
table border=2 {
table_row {
table_head { puts "Evaluator"}
table_head { puts "Total" }
table_head {
puts [join [hand $hand pattern] "-"]
}
foreach suit {spades hearts diamonds clubs} {
table_head {puts [imglink $suit][hand $hand $suit]}
}
}
foreach {eval functions} $evaluators {
table_row {
evalrow $hand $eval $functions
}
}
}
} else {
p "In the form below, enter a deal, leaving a line empty for
a void. Suit holdings have to be sorted, so [code JQx] is
not allowed, but [code QJx] is. Tens should be entered
as 'T'."
}
eval theform $hand
p "
This is meant to show comparisons between various evaluators,
and specifically the evaluators from my articles, [link article]
and [link binkyarticle]. The expected values are roughly how
many tricks you expect to take, on average, just looking at your
own hand. The Binky Points are such that, when added
to partner's Binky Points, you get a close approximation of the number
of tricks you expect to take."
p "binky-hcp evaluators are the scaled values given in my [link binkyversushcp] article."
p "The [link fifthsarticle] is defined as Ace=4, K=2.8, Q=1.8, J=1, T=0.4. It is a good evaluator for determining whether to bid 3NT."
p "BUM-RAP is Alex Martelli's name for Ace=4.5, K=3, Q=1.5, J=0.75, T=0.25."
p "The implementation of the Kaplan-Reuben CCCC evaluator is somewhat suspect."
endnote
}
}
}
eval $script
In the form below, enter a deal, leaving a line empty for
a void. Suit holdings have to be sorted, so JQx is
not allowed, but QJx is. Tens should be entered
as 'T'.
This is meant to show comparisons between various evaluators, and specifically the evaluators from my articles, Offensive and Defensive Evaluations and Binky Evaluations. The expected values are roughly how many tricks you expect to take, on average, just looking at your own hand. The Binky Points are such that, when added to partner's Binky Points, you get a close approximation of the number of tricks you expect to take.
binky-hcp evaluators are the scaled values given in my HCP Versus Binky article.
The Fifths evaluator is defined as Ace=4, K=2.8, Q=1.8, J=1, T=0.4. It is a good evaluator for determining whether to bid 3NT.
BUM-RAP is Alex Martelli's name for Ace=4.5, K=3, Q=1.5, J=0.75, T=0.25.
The implementation of the Kaplan-Reuben CCCC evaluator is somewhat suspect.
This program is powered by iDeal, a fast Tcl-based plugin specialized for defining procedures of use in bridge programs. You can examine the source code of this example.