File: giblib.tcl

package info (click to toggle)
deal 3.1.9-11
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 1,540 kB
  • sloc: ansic: 5,224; cpp: 4,186; tcl: 3,125; makefile: 205; sh: 10
file content (191 lines) | stat: -rw-r--r-- 4,720 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#
# Copyright (C) 1996-2001, Thomas Andrews
#
# $Id: giblib.tcl 255 2008-09-15 12:43:02Z thomasoa $
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
source /usr/share/deal/lib/gib.tcl

#
# The giblib implements the ability to read files of the
# format of Matt Ginsberg's 'library.dat' file.  The file contains
# deals along with the double dummy results of all possible contracts
# played from all directions.
#
# The date file is the "binary" file described at the bottom 
# http://www.cirl.uoregon.edu/ginsberg/gibresearch.html .
#
namespace eval giblib {

    ::deal::nostacking

    variable file "library.dat"
    variable trial 0
    variable filehandle {}

    proc readNextData {} {
	variable filehandle
	set haveRead 0
	set data ""
	while {$haveRead<26} {
	    if {[eof $filehandle]} { return "" }
	    append data [read $filehandle [expr 26-$haveRead]]
	    set haveRead [string length $data]
	}
	return $data
    }

    set who(00) west
    set who(01) north
    set who(10) east
    set who(11) south
    set binary(0000) 0
    set binary(0001) 1
    set binary(0010) 2
    set binary(0011) 3
    set binary(0100) 4
    set binary(0101) 5
    set binary(0110) 6
    set binary(0111) 7
    set binary(1000) 8
    set binary(1001) 9
    set binary(1010) 10
    set binary(1011) 11
    set binary(1100) 12
    set binary(1101) 13
    set binary(1110) 14
    set binary(1111) 15

    variable cardNames [list A K Q J T 9 8 7 6 5 4 3 2]
    variable trial 1
    variable deal

    variable suitOrder [list spades hearts diamonds clubs]
    proc parseData {data} {
	set count [binary scan $data "B32B32B32B32SSSSS" \
		cards(spades) cards(hearts) cards(diamonds) cards(clubs) \
		tricks(notrump) tricks(spades) tricks(hearts) tricks(diamonds) tricks(clubs) ]
	set suitno 0
	
	variable cardNames
	variable who
	variable suitOrder

	set decoded [list]
	foreach hand {north east south west} {
	    foreach suit $suitOrder {
		set holding($hand-$suit) ""
	    }
	}

	foreach suit $suitOrder {
	    binary scan $cards($suit) a6a2a2a2a2a2a2a2a2a2a2a2a2a2 dummy c(2) c(3) c(4) c(5) \
		    c(6) c(7) c(8) c(9) c(T) c(J) c(Q) c(K) c(A)

	    foreach card $cardNames {
		set whom $who($c($card))
		append holding($whom-$suit) $card
	    }
	}
	reset_deck
	foreach hand {north east south west} {
	    deck_stack_hand $hand $holding($hand-spades) $holding($hand-hearts) \
		    $holding($hand-diamonds) $holding($hand-clubs)
	}

	set ddresults [list]
	foreach contract "notrump $suitOrder" {
	    # trick to turning small into unsigned int
	    set trickvalue [expr {( $tricks($contract) + 0x10000 ) % 0x10000} ]
	    set results [list $contract]
	    foreach hand {south west north east} {
		set tr [expr {15&$trickvalue}]
		::deal::metadata tricks.$hand.$contract {
		    gib::rectify_tricks $hand $tr
		}
		set trickvalue [expr {$trickvalue/16}]
	    }
	}
    }

    proc openlib {} {
	variable file
	set fh [open $file r]
	fconfigure $fh -translation binary
	return $fh
    }

    proc initialize {{filename unset}} {
	
	variable filehandle
	variable trial

	if {"$filehandle"!=""} { finalize }

	if {"$filename"!="unset"} {
	    variable file
	    set file $filename
	}

	set filehandle [openlib]
	set trial 0
    }

    proc get_next_deal {} {
	variable trial
	set data [readNextData]
	if {[string length $data]!=26} {
	    return 0
	}
	parseData $data
	incr trial
    }

    proc finalize {} {
	variable filehandle
	if {"$filehandle"!=""} {
	    close $filehandle	
	    set filehandle {}
	}
    }

    proc stackhand {name hand} {
	error "Can't stack hands when reading deals from files"
    }

    proc stackcards {name args} {
	error "Can't stack cards when reading deals from files"
    }

    namespace export get_next_deal initialize finalize

    proc set_input {{filename {}}} {
        variable file
	if {$filename==""} {
	    set filename $file
	}
	initialize $filename
	deal_reset_cmds ::giblib::next
    }

    proc next {} {
	deal_reset_cmds ::giblib::next
	if {[catch {giblib::get_next_deal}]} {
	    # All done
	    return -code return
	}
    }
}