9 namespace eval calvar {
11 set ::uci::uciInfo(log_stdout4) 0
13 array set engineListBox {}
14 set blunderThreshold 0.2
15 set thinkingTimePerLine 10
16 set thinkingTimePosition 30
18 set currentListMoves {}
24 set initPosAnalysis {}
32 trace add variable ::calvar::working write { ::calvar::traceWorking }
36 proc traceWorking {a b c} {
37 set widget .calvarWin.fCommand.bDone
38 if {$::calvar::working} {
39 $widget configure -state disabled
41 $widget configure -state normal
49 set currentListMoves {}
53 if {[
winfo exists .calvarWin]} {
54 .calvarWin.fText.t delete 1.0 end
64 if {[
winfo exists $w]} {
69 set w ".configCalvarWin"
70 if {[
winfo exists $w]} {
76 wm title $w [
::tr "ConfigureCalvar"]
78 bind $w <F1> { helpWindow CalVar }
82 ttk::frame $w.fengines
83 ttk::label $w.fengines.eng -text $::tr(Engine)
84 listbox $w.fengines.lbEngines -yscrollcommand "$w.fengines.ybar set" -height 5 -width 50 -exportselection 0
85 ttk::scrollbar $w.fengines.ybar -command "$w.fengines.lbEngines yview"
86 pack $w.fengines.eng -side top -anchor w
87 pack $w.fengines.ybar -side right -fill y
88 pack $w.fengines.lbEngines -side left -fill both -expand yes
89 pack $w.fengines -expand yes -fill both -side top
92 foreach e $::engines(list) {
93 if { [
lindex $e 7] != 1} {
incr idx continue}
94 set ::calvar::engineListBox($i) $idx
95 set name [
lindex $e 0]
96 $w.fengines.lbEngines insert end $name
100 $w.fengines.lbEngines selection set 0
104 tk_messageBox -type ok -message "No UCI engine defined" -icon error
111 ttk::frame $w.parameters
112 pack $f -side top -anchor w -pady 10
116 ttk::label $f.lTime -text $::tr(SecondsPerMove)
117 ttk::spinbox $f.sbTime -background white -width 3 -textvariable ::calvar::thinkingTimePerLine -from 5 -to 120 -increment 5 -validate all -validatecommand { regexp {^[0-9]+$} %P }
118 ttk::label $f.lTime2 -text "Position thinking time"
119 ttk::spinbox $f.sbTime2 -background white -width 3 -textvariable ::calvar::thinkingTimePosition -from 5 -to 300 -increment 5 -validate all -validatecommand { regexp {^[0-9]+$} %P }
120 grid $f.lTime -column 0 -row 0 -sticky w
121 grid $f.sbTime -column 1 -row 0 -padx 10 -pady 5
122 grid $f.lTime2 -column 0 -row 1 -sticky w
123 grid $f.sbTime2 -column 1 -row 1 -padx 10
125 ttk::frame $w.fbuttons
126 pack $w.fbuttons -expand yes -fill both
127 ttk::button $w.fbuttons.start -text Start -command {
129 set chosenEngine [.configCalvarWin.fengines.lbEngines curselection]
130 set ::calvar::engineName [.configCalvarWin.fengines.lbEngines get $chosenEngine]
131 destroy .configCalvarWin
132 ::calvar::start $chosenEngine
134 ttk::button $w.fbuttons.cancel -textvar ::tr(Cancel) -command "focus .; destroy $w"
138 bind $w <Escape> { .configCalvarWin.fbuttons.cancel invoke }
139 bind $w <Return> { .configCalvarWin.fbuttons.start invoke }
141 bind $w <Configure> "recordWinSize $w"
147 proc start { engine { n 4 } } {
152 if {[
winfo exists $w]} {
158 bind $w <F1> { helpWindow CalVar }
163 foreach nag { "=" "+=" "+/-" "+-" "=+" "-/+" "-+" } {
164 ttk::button $f.nag$i -text $nag -command "::calvar::nag $nag" -width 3
165 pack $f.nag$i -side left
168 pack $f -expand 1 -fill both
172 text $f.t -height 12 -width 50
173 pack $f.t -expand 1 -fill both
174 pack $f -expand 1 -fill both
178 ttk::label $f.lPromo -text "Promotion"
179 pack $f.lPromo -side left
180 foreach piece { "q" "r" "b" "n" } {
181 ttk::button $f.p$piece -image w${piece}20 -command "::calvar::promo $piece"
182 pack $f.p$piece -side left
184 pack $f -expand 1 -fill both
188 ttk::button $f.bDone -text [
::tr "DoneWithPosition"] -command ::calvar::positionDone
190 pack $f -expand 1 -fill both
194 pack $f -expand 1 -fill both
195 ttk::button $w.fbuttons.stop -textvar ::tr(Stop) -command "::calvar::stop"
196 pack $w.fbuttons.stop -expand yes -side left -padx 20 -pady 2
198 bind $w <Escape> { .calvarWin.fbuttons.stop invoke }
200 bind $w <Configure> "recordWinSize $w"
206 set ::analysis(multiPVCount$n) 10
208 set ::calvar::suggestMoves_old $::suggestMoves
209 set ::calvar::hideNextMove_old $::gameInfo(hideNextMove)
212 set ::gameInfo(hideNextMove) 1
216 set ::calvar::working 1
219 set ::calvar::afterIdPosition [after [
expr $::calvar::thinkingTimePosition * 1000] { ::calvar::stopAnalyze "" "" "" ; ::calvar::addLineToCompute "" }]
225 proc stop { {n 4 } } {
226 after cancel $::calvar::afterIdPosition
227 after cancel $::calvar::afterIdLine
231 set ::suggestMoves $::calvar::suggestMoves_old
232 set ::gameInfo(hideNextMove) $::calvar::hideNextMove_old
239 proc pressSquare { sq } {
240 global ::calvar::midmove
243 if {$midmove == ""} {
246 lappend ::calvar::currentListMoves "$midmove$sansq"
250 if {$midmove == ""} {
253 .calvarWin.fText.t insert "$::calvar::currentLine.end" "$tmp$sansq"
258 proc promo { piece } {
259 if { [
llength $::calvar::currentListMoves] == 0 } {
return}
261 set tmp [
lindex $::calvar::currentListMoves end]
263 lset ::calvar::currentListMoves end $tmp
264 .calvarWin.fText.t insert end "$piece"
270 .calvarWin.fText.t insert "$::calvar::currentLine.end" " $n\n"
271 set newline [list $::calvar::currentListMoves $n [
sc_pos fen]]
272 lappend ::calvar::lines $newline
273 incr ::calvar::currentLine
275 set ::calvar::currentListMoves {}
280 proc addLineToCompute {line {n 4} } {
281 global ::calvar::analysisQueue
283 lappend analysisQueue $line
285 if { $::calvar::working } {
return}
287 while { [
llength $analysisQueue] != 0 } {
288 set line [
lindex $analysisQueue 0]
289 set analysisQueue [
lreplace analysisQueue 0 0]
296 proc computeLine {line {n 4} } {
297 set ::calvar::working 1
298 set moves [
lindex $line 0]
299 set nag [
lindex $line 1]
300 set fen [
lindex $line 2]
302 set ::calvar::afterIdLine [after [
expr $::calvar::thinkingTimePerLine * 1000] "::calvar::stopAnalyze [list $moves $nag $fen]"]
307 proc handleResult {moves nag fen {n 4} } {
311 set firstmove [
lindex $usermoves 0]
315 set ::analysis(multiPV$n) {}
316 for {
set i 0} {$i < [
llength $::analysis(multiPVraw$n)]} {
incr i} {
317 set elt [
lindex $::analysis(multiPVraw$n) $i]
319 set line "$firstmove $line"
320 lappend ::analysis(multiPV$n) [list [
lindex $elt 0] [
lindex $elt 1] $line [
lindex $elt 3]]
323 if { [
llength $moves] != [
llength $usermoves]} {
324 set comment " error in user moves [
lrange $moves [
llength $usermoves] end]"
328 set pv [
lindex $::analysis(multiPV$n) 0]
329 if { [
llength $pv] == 4 } {
330 set engmoves [
lindex $pv 2]
332 set engscore [
expr - 1.0 * [
lindex $pv 1]]
333 set engdepth [
lindex $pv 0]
334 addVar $usermoves $engmoves $nag $comment $engscore
336 puts "Error pv = $pv"
343 proc addVar {usermoves engmoves nag comment engscore} {
347 sc_move addSan [
lindex $engmoves 0]
354 set repeat_move [
sc_game info previousMoveNT]
360 if {$repeat_move != ""} {
sc_move addSan $repeat_move}
362 if {$comment != ""} {
363 sc_pos setComment $comment
370 if {$repeat_move != ""} {
sc_move forward}
372 sc_pos setComment "$::calvar::engineName : $engscore"
377 if {$repeat_move != ""} {
sc_move forward}
385 proc addMissedLine {moves score depth} {
389 sc_move addSan [
lindex $moves 0]
396 set repeat_move [
sc_game info previousMoveNT]
401 if {$repeat_move != ""} {
sc_move addSan $repeat_move}
402 sc_pos setComment "Missed line ($depth) $score"
405 if {$repeat_move != ""} {
sc_move forward}
414 proc positionDone {} {
415 global ::calvar::initPosAnalysis ::calvar::lines
418 proc isPresent { engmoves } {
419 global ::calvar::lines
421 set firsteng [
lindex $engmoves 0]
422 foreach userLine $::calvar::lines {
424 set firstuser [
lindex $usermoves 0]
425 if {$firstuser == $firsteng} {
return 1}
431 foreach pv $::calvar::initPosAnalysis {
432 set engmoves [
lindex $pv 2]
433 set engscore [
lindex $pv 1]
434 set engdepth [
lindex $pv 0]
449 proc startAnalyze {moves nag fen {n 4}} {
453 if {$analysis(analyzeMode$n)} {
return}
454 set analysis(analyzeMode$n) 1
455 set analysis(waitForReadyOk$n) 1
457 vwait analysis(waitForReadyOk$n)
458 set analysis(fen$n) $fen
459 if { [
llength $moves] > 0 } {
469 proc stopAnalyze { moves nag fen {n 4} } {
470 if {! $::analysis(analyzeMode$n)} {
return}
471 set ::analysis(analyzeMode$n) 0
474 if { [
llength $moves] > 0 } {
477 set ::calvar::initPosAnalysis $::analysis(multiPV$n)
479 set ::calvar::working 0