6 namespace eval ::tree {
9 set scoreHighlight_MinGames 15
10 set scoreHighlight_WhiteExpectedScoreBonus 3.8
11 set scoreHighlight_Margin 3.0
14 proc ::tree::doConfigMenus { baseNumber { lang "" } } {
15 if {! [
winfo exists .treeWin$baseNumber]} {
return}
16 if {$lang == ""} {
set lang $::language}
17 set m .treeWin$baseNumber.menu
18 foreach idx {0 1 2 3 4} tag {File Mask Sort Opt Help} {
21 foreach idx {0 1 2 3 5 7 9} tag {FillWithBase FillWithGame SetCacheSize CacheInfo Graph Copy Close} {
24 foreach idx {0 1 2 3 4 5 6 7 8 9} tag {New Open OpenRecent Save Close FillWithGame FillWithBase Search Info Display} {
27 foreach idx {0 1 2 3} tag {Alpha ECO Freq Score } {
30 foreach idx {0 1} tag {Lock Training } {
33 foreach idx {0 1} tag {Tree Index} {
39 proc ::tree::ConfigMenus { { lang "" } } {
40 for {
set i [
sc_info limit bases]} {$i > 0} {
incr i -1} {
45 proc ::tree::menuCopyToSelection { baseNumber } {
47 clipboard append [ .treeWin$baseNumber.f.tl get 1.0 end]
50 proc ::tree::make { { baseNumber -1 } {locked 0} } {
51 global tree highcolor geometry helpMessage
53 if {$baseNumber == -1} {
set baseNumber [
sc_base current]}
55 if {[
winfo exists .treeWin$baseNumber]} {
60 if {$baseNumber == [
sc_base current]} {
set ::treeWin 1}
61 set w .treeWin$baseNumber
67 set ::treeWin$baseNumber 1
68 set tree(training$baseNumber) 0
69 set tree(autorefresh$baseNumber) 1
70 set tree(locked$baseNumber) $locked
71 set tree(base$baseNumber) $baseNumber
72 set tree(status$baseNumber) ""
73 set tree(order$baseNumber) "frequency"
74 set tree(allgames$baseNumber) 1
76 bind $w <Destroy> "::tree::closeTree $baseNumber"
77 bind $w <Escape> "::tree::hideCtxtMenu $baseNumber ; .treeWin$baseNumber.buttons.stop invoke "
80 bind $w <ButtonPress-1> "::tree::hideCtxtMenu $baseNumber"
84 $w.menu add cascade -label TreeFile -menu $w.menu.file
85 $w.menu add cascade -label TreeMask -menu $w.menu.mask
86 $w.menu add cascade -label TreeSort -menu $w.menu.sort
87 $w.menu add cascade -label TreeOpt -menu $w.menu.opt
88 $w.menu add cascade -label TreeHelp -menu $w.menu.helpmenu
89 foreach i {file mask sort opt helpmenu} {
90 menu $w.menu.$i -tearoff 0
94 $w.menu.file add command -label TreeFileFillWithBase
95 set helpMessage($w.menu.file,0) TreeFileFillWithBase
96 $w.menu.file add command -label TreeFileFillWithGame
97 set helpMessage($w.menu.file,1) TreeFileFillWithGame
99 menu $w.menu.file.size
100 foreach i { 250 500 1000 2000 5000 10000 } {
101 $w.menu.file.size add radiobutton -label "$i" -value $i -variable ::tree::cachesize($baseNumber) -command "::tree::setCacheSize $baseNumber $i"
104 $w.menu.file add cascade -menu $w.menu.file.size -label TreeFileSetCacheSize
105 set helpMessage($w.menu.file,2) TreeFileSetCacheSize
107 $w.menu.file add command -label TreeFileCacheInfo -command "::tree::getCacheInfo $baseNumber"
108 set helpMessage($w.menu.file,3) TreeFileCacheInfo
110 $w.menu.file add separator
111 $w.menu.file add command -label TreeFileGraph -command "::tree::graph $baseNumber 1"
112 set helpMessage($w.menu.file,5) TreeFileGraph
113 $w.menu.file add separator
114 $w.menu.file add command -label TreeFileCopy -command "::tree::menuCopyToSelection $baseNumber"
115 set helpMessage($w.menu.file,7) TreeFileCopy
116 $w.menu.file add separator
117 $w.menu.file add command -label TreeFileClose -command ".treeWin$baseNumber.buttons.close invoke"
118 set helpMessage($w.menu.file,9) TreeFileClose
120 $w.menu.mask add command -label TreeMaskNew -command "::tree::mask::new"
121 set helpMessage($w.menu.mask,0) TreeMaskNew
122 $w.menu.mask add command -label TreeMaskOpen -command "::tree::mask::open"
123 set helpMessage($w.menu.mask,1) TreeMaskOpen
125 menu $w.menu.mask.recent
126 foreach f $::tree::mask::recentMask {
127 $w.menu.mask.recent add command -label $f -command "::tree::mask::open $f"
129 $w.menu.mask add cascade -label TreeMaskOpenRecent -menu $w.menu.mask.recent
130 set helpMessage($w.menu.mask,2) TreeMaskOpenRecent
132 $w.menu.mask add command -label TreeMaskSave -command "::tree::mask::save"
133 set helpMessage($w.menu.mask,3) TreeMaskSave
134 $w.menu.mask add command -label TreeMaskClose -command "::tree::mask::close"
135 set helpMessage($w.menu.mask,4) TreeMaskClose
136 $w.menu.mask add command -label TreeMaskFillWithGame -command "::tree::mask::fillWithGame"
137 set helpMessage($w.menu.mask,5) TreeMaskFillWithGame
138 $w.menu.mask add command -label TreeMaskFillWithBase -command "::tree::mask::fillWithBase"
139 set helpMessage($w.menu.mask,6) TreeMaskFillWithBase
141 $w.menu.mask add command -label TreeMaskSearch -command "::tree::mask::searchMask $baseNumber"
142 set helpMessage($w.menu.mask,7) TreeMaskSearch
143 $w.menu.mask add command -label TreeMaskInfo -command "::tree::mask::infoMask"
144 set helpMessage($w.menu.mask,8) TreeMaskInfo
145 $w.menu.mask add command -label TreeMaskDisplay -command "::tree::mask::displayMask"
146 set helpMessage($w.menu.mask,9) TreeMaskDisplay
148 foreach label {Alpha ECO Freq Score} value {alpha eco frequency score} {
149 $w.menu.sort add radiobutton -label TreeSort$label \
150 -variable tree(order$baseNumber) -value $value -command " ::tree::refresh $baseNumber "
153 $w.menu.opt add checkbutton -label TreeOptLock -variable tree(locked$baseNumber) -command "::tree::toggleLock $baseNumber"
154 set helpMessage($w.menu.opt,0) TreeOptLock
156 $w.menu.opt add checkbutton -label TreeOptTraining -variable tree(training$baseNumber) -command "::tree::toggleTraining $baseNumber"
157 set helpMessage($w.menu.opt,1) TreeOptTraining
159 $w.menu.opt add separator
161 $w.menu.helpmenu add command -label TreeHelpTree -accelerator F1 -command {helpWindow Tree}
162 $w.menu.helpmenu add command -label TreeHelpIndex -command {helpWindow Index}
167 -wrap none -selectbackground lightgrey -selectforeground black \
168 -font font_Fixed -foreground black -background white -setgrid 1 -exportselection 1
170 $w.f.tl tag configure greybg -background gray95
171 $w.f.tl tag configure whitebg -background white
172 $w.f.tl tag configure bluefg -foreground blue
173 $w.f.tl tag configure greenfg -foreground SeaGreen
174 $w.f.tl tag configure redfg -foreground red
176 selection handle $w.f.tl "::tree::copyToSelection $baseNumber"
178 ttk::frame $w.statusframe
179 pack $w.statusframe -side bottom -fill x
180 grid rowconfigure $w.statusframe 0 -weight 1
181 grid columnconfigure $w.statusframe 0 -weight 1
182 ttk::label $w.status -anchor w -font font_Small -relief sunken
183 grid $w.status -in $w.statusframe -column 0 -row 0 -sticky nsew
184 canvas $w.progress -height 0 -bg white -relief solid -border 1
185 $w.progress create rectangle 0 0 0 0 -fill blue -outline blue -tags bar
187 pack [ttk::frame $w.buttons -relief sunken] -side bottom -fill x
188 pack $w.f -side top -expand 1 -fill both
190 ttk::button $w.buttons.best -image tb_list -style Pad0.Small.TButton -command "::tree::best $baseNumber"
191 ttk::button $w.buttons.graph -image tb_bargraph -style Pad0.Small.TButton -command "::tree::graph $baseNumber 1"
193 ttk::button $w.buttons.bStartStop -image tb_search_on -style Pad0.Small.TButton -command "::tree::toggleRefresh $baseNumber"
195 ttk::checkbutton $w.buttons.allgames -textvar ::tr(allGames) -variable tree(allgames$baseNumber) -command "::tree::refresh $baseNumber"
196 ttk::checkbutton $w.buttons.training -textvar ::tr(Training) -variable tree(training$baseNumber) -command "::tree::toggleTraining $baseNumber"
198 foreach {b t} { best TreeFileBest graph TreeFileGraph allgames TreeOptLock training TreeOptTraining bStartStop TreeOptStartStop } {
199 set helpMessage($w.buttons.$b) $t
202 dialogbutton $w.buttons.stop -textvar ::tr(Stop) -command { progressBarCancel }
203 dialogbutton $w.buttons.close -textvar ::tr(Close) -command "::tree::closeTree $baseNumber"
205 pack $w.buttons.best $w.buttons.graph $w.buttons.bStartStop $w.buttons.allgames $w.buttons.training \
206 -side left -padx 3 -pady 2
208 $w.buttons.stop configure -state disabled
213 wm protocol $w WM_DELETE_WINDOW " .treeWin$baseNumber.buttons.close invoke "
215 set ::tree::cachesize($baseNumber) [
lindex [
sc_tree cacheinfo $baseNumber] 1]
218 proc ::tree::hideCtxtMenu { baseNumber } {
219 set w .treeWin$baseNumber.f.tl.ctxtMenu
220 if {[
winfo exists $w]} {
222 focus .treeWin$baseNumber
226 proc ::tree::selectCallback { baseNumber move } {
228 if { $::tree(refresh) } {
232 if {$::tree(autorefresh$baseNumber)} {
239 proc ::tree::closeTree {baseNumber} {
246 set ::geometry(treeWin$baseNumber) [
wm geometry .treeWin$baseNumber]
249 if {[
winfo exists .treeGraph$baseNumber]} {
destroy .treeGraph$baseNumber}
250 destroy .treeBest$baseNumber
251 destroy .treeWin$baseNumber
253 set curr_base [
sc_base current]
254 set ::treeWin [
winfo exists .treeWin$curr_base]
257 proc ::tree::toggleTraining { baseNumber } {
260 for {
set i 1} {$i <= [
sc_info limit bases]} {
incr i} {
261 if {! [
winfo exists .treeWin$baseNumber] || $i == $baseNumber } { continue}
262 set tree(training$i) 0
265 set ::tree::trainingBase 0
266 if {$tree(training$baseNumber)} {
267 set ::tree::trainingBase $baseNumber
268 set ::tree::trainingColor [
sc_pos side]
274 proc ::tree::doTraining { { n 0 } } {
276 if {$n != 1 && [
winfo exists .analysisWin1] && $::analysis(automove1)} {
280 if {$n != 2 && [
winfo exists .analysisWin2] && $::analysis(automove2)} {
288 if {! [
winfo exists .treeWin$::tree::trainingBase]} {
return}
289 if { $::tree::trainingBase == 0 } {
return}
292 if { $::tree::mask::maskFile != "" } {
293 set move_done [
sc_game info previousMoveNT]
294 if {$move_done != ""} {
298 if { [
info exists ::tree::mask::mask($fen)] } {
299 set moves [
lindex $::tree::mask::mask($fen) 0]
303 if {[
llength $moves] != 0} {
306 append txt "[
::trans [
lindex $elt 0]][
lindex $elt 1] "
314 set nag_order { "??" " ?" "?!" $::tree::mask::emptyNag "!?" " !" "!!"}
317 set n [
lindex $elt 1]
318 if { [lsearch $nag_order $nag_played] < [lsearch $nag_order $n]} {
319 append txt "[
::trans [
lindex $elt 0]][
lindex $elt 1] "
323 sc_pos addNag [
string trim $nag_played]
330 sc_pos setComment "[
sc_pos getComment] Mask : excluded line"
336 set move [
sc_tree move $::tree::trainingBase random]
341 proc ::tree::toggleLock { baseNumber } {
346 proc ::tree::select { move baseNumber } {
349 if {! [
winfo exists .treeWin$baseNumber]} {
return}
357 proc ::tree::refresh { { baseNumber "" }} {
359 if {$baseNumber == "" } {
371 proc ::tree::dorefresh { baseNumber } {
373 set w .treeWin$baseNumber
375 if {![
winfo exists $w]} {
return}
376 if { ! $tree(autorefresh$baseNumber) } {
return}
378 grid $w.progress -in $w.statusframe -column 0 -row 0 -sticky nsew
381 foreach button {best graph training allgames close} {
382 $w.buttons.$button configure -state disabled
384 $w.buttons.stop configure -state normal
387 if { $tree(allgames$baseNumber) == 0 } {
391 set err [
catch {
sc_tree search -hide $tree(training$baseNumber) \
392 -sort $tree(order$baseNumber) \
394 -filtered $filtered} moves]
396 set tree(status$baseNumber) ""
399 catch {$w.f.tl itemconfigure 0 -foreground darkBlue}
401 foreach button {best graph training allgames close} {
402 $w.buttons.$button configure -state normal
404 $w.buttons.stop configure -state disabled
407 if {[
winfo exists .treeGraph$baseNumber]} {
::tree::graph $baseNumber}
409 if { $moves == "canceled" } {
return "canceled"}
412 grid forget $w.progress
413 if {$::tree::trainingBase != 0 && $::tree::trainingColor == [
sc_pos side]} {
421 proc ::tree::displayLines { baseNumber moves } {
422 global ::tree::mask::maskFile
427 set w .treeWin$baseNumber
429 $w.f.tl configure -state normal
431 set moves [
split $moves "\n"]
434 set ::tree::treeData$baseNumber $moves
436 set len [
llength $moves]
437 $w.f.tl delete 1.0 end
439 foreach t [$w.f.tl tag names] {
440 if { [
string match "tagclick*" $t] || [
string match "tagtooltip*" $t] } {
441 $w.f.tl tag delete $t
446 set hasPositionComment 0
447 if { $maskFile != "" } {
449 if {$posComment != ""} {
450 set hasPositionComment 1
451 set firstLine [
lindex [
split $posComment "\n"] 0]
452 $w.f.tl insert end "$firstLine\n" [ list bluefg tagtooltip_poscomment]
454 $w.f.tl tag bind tagtooltip_poscomment <Double-Button-1> "::tree::mask::addComment"
459 if { $maskFile != "" } {
460 $w.f.tl image create end -image tb_empty -align center
461 $w.f.tl image create end -image tb_empty -align center
462 $w.f.tl insert end " "
463 $w.f.tl tag bind tagclick0 <ButtonPress-$::MB3> "::tree::mask::contextMenu $w.f.tl dummy %x %y %X %Y ; break"
465 $w.f.tl insert end "[
lindex $moves 0]\n" tagclick0
467 for {
set i 1} { $i < [
expr $len - 3] } {
incr i} {
468 set line [
lindex $moves $i]
469 if {$line == ""} { continue}
470 set move [
lindex $line 1]
474 if { $move == "\[end\]" } {
set colorScore ""}
478 if { $maskFile != "" && $i > 0 && $i < [
expr $len - 3] } {
483 if { $maskFile != "" } {
484 if { $i > 0 && $i < [
expr $len - 3] && $move != "\[end\]" } {
488 $w.f.tl image create end -image $img -align center
492 $w.f.tl insert end " " color$i
496 $w.f.tl image create end -image tb_empty -align center
497 $w.f.tl image create end -image tb_empty -align center
498 $w.f.tl insert end " "
503 if {[
expr $i % 2] && $i < [
expr $len -3] } {
504 $w.f.tl insert end "$line" [list greybg $tagfg tagtooltip$i]
506 $w.f.tl insert end "$line" [list whitebg $tagfg tagtooltip$i]
508 if {$colorScore != ""} {
509 $w.f.tl tag add $colorScore end-31c end-26c
511 if {$move != "" && $move != "---" && $move != "\[end\]" && $i != [
expr $len -2] && $i != 0} {
512 $w.f.tl tag bind tagclick$i <Button-1> "[list ::tree::selectCallback $baseNumber $move] ; break"
515 if { $maskFile != "" } {
518 if {$comment != ""} {
519 set firstLine [
lindex [
split $comment "\n"] 0]
520 $w.f.tl insert end " $firstLine" tagtooltip$i
522 $w.f.tl tag bind tagtooltip$i <Double-Button-1> "::tree::mask::addComment $move"
526 if { $maskFile != "" } {
528 $w.f.tl tag bind tagclick$i <ButtonPress-$::MB3> "::tree::mask::contextMenu $w.f.tl $move %x %y %X %Y ; break"
530 $w.f.tl tag add tagclick$i [
expr $i +1 + $hasPositionComment].0 [
expr $i + 1 + $hasPositionComment].end
532 $w.f.tl insert end "\n"
537 for {
set i [
expr $len - 3]} { $i < [
expr $len - 1] } {
incr i} {
538 if { $maskFile != "" } {
539 $w.f.tl image create end -image tb_empty -align center
540 $w.f.tl image create end -image tb_empty -align center
541 $w.f.tl insert end " "
543 $w.f.tl insert end "[
lindex $moves $i]\n"
548 if { $maskFile != "" } {
550 foreach m $movesMask {
551 if { [
scan [$w.f.tl index end] "%d.%d" currentLine dummy] != 2 } {
552 puts "ERROR scan index end [$w.f.tl index end]"
555 if {[lsearch $lMoves [
lindex $m 0]] != -1 || [
lindex $m 0] == "null"} {
559 $w.f.tl tag bind tagclick$idx <Button-1> "[list ::tree::selectCallback $baseNumber [
lindex $m 0]] ; break"
562 if {[
lindex $m $j] == ""} {
563 $w.f.tl image create end -image tb_empty -align center
565 $w.f.tl image create end -image [
lindex $m $j] -align center
570 $w.f.tl tag configure color$idx -background [
lindex $m 2]
571 $w.f.tl insert end " " color$idx
575 $w.f.tl insert end "[
::trans [
lindex $m 0]]" bluefg
577 set comment [
lindex $m 3]
578 set firstLine [
lindex [
split $comment "\n"] 0]
579 $w.f.tl insert end " $firstLine\n" tagtooltip$idx
583 $w.f.tl tag bind tagclick$idx <ButtonPress-$::MB3> "::tree::mask::contextMenu $w.f.tl [
lindex $m 0] %x %y %X %Y ; break"
584 $w.f.tl tag add tagclick$idx [
expr $currentLine -1].0 [
expr $currentLine -1].end
589 $w.f.tl configure -state disabled
596 proc ::tree::getLineValues { l } {
598 if {[
scan [
string range $l 14 24] "%d:" ngames] != 1} {
604 if {[
scan [
string range $l 25 29] "%f%%" freq] != 1} {
610 if {[
scan [
string range $l 33 37] "%f%%" success] != 1} {
616 if {[
scan [
string range $l 40 44] "%d" eloavg] != 1} {
622 if {[
scan [
string range $l 46 50] "%d" perf] != 1} {
633 proc ::tree::getColorScore { line } {
635 if { $data == {} } {
return ""}
636 set ngames [
lindex $data 0]
637 set freq [
lindex $data 1]
638 set success [
lindex $data 2]
639 set eloavg [
lindex $data 3]
640 set perf [
lindex $data 4]
641 if { $ngames < $::tree::scoreHighlight_MinGames } {
644 set wavg [
expr 50 + $::tree::scoreHighlight_WhiteExpectedScoreBonus]
645 set bavg [
expr 50 - $::tree::scoreHighlight_WhiteExpectedScoreBonus]
646 if { [
sc_pos side] == "white" && $success > [
expr $wavg + $::tree::scoreHighlight_Margin] || \
647 [
sc_pos side] == "black" && $success < [
expr $wavg - $::tree::scoreHighlight_Margin] } {
650 if { [
sc_pos side] == "white" && $success < [
expr $wavg - $::tree::scoreHighlight_Margin] || \
651 [
sc_pos side] == "black" && $success > [
expr $wavg + $::tree::scoreHighlight_Margin] } {
657 proc ::tree::status { msg baseNumber } {
660 set w .treeWin$baseNumber
661 if { $tree(status$baseNumber) == "" } {
662 catch {
sc_base filename $baseNumber} tree(status$baseNumber)
663 set tree(status$baseNumber) [
file tail $tree(status$baseNumber)]
664 ::setTitle $w "Scid: [
tr WindowsTree] $baseNumber: $tree(status$baseNumber)"
670 set status " $::tr(Database) $baseNumber: $tree(status$baseNumber)"
671 if {$tree(locked$baseNumber)} {
append status " ($::tr(TreeLocked))"}
672 if {! $tree(allgames$baseNumber)} {
673 append status " $::tr(Filter)"
677 $w.status configure -text $status
681 set tree(standardLines) {
693 {1.d4 d5 2.c4 c6 3.Nf3}
694 {1.d4 d5 2.c4 c6 3.Nf3 Nf6}
695 {1.d4 d5 2.c4 c6 3.Nf3 Nf6 4.Nc3}
696 {1.d4 d5 2.c4 c6 3.Nf3 Nf6 4.Nc3 dxc4}
697 {1.d4 d5 2.c4 c6 3.Nf3 Nf6 4.Nc3 e6}
698 {1.d4 d5 2.c4 c6 3.Nf3 Nf6 4.Nc3 e6 5.e3}
700 {1.d4 d5 2.c4 e6 3.Nc3}
701 {1.d4 d5 2.c4 e6 3.Nc3 Nf6}
702 {1.d4 d5 2.c4 e6 3.Nf3}
704 {1.d4 d5 2.c4 dxc4 3.Nf3}
705 {1.d4 d5 2.c4 dxc4 3.Nf3 Nf6}
708 {1.d4 d5 2.Nf3 Nf6 3.c4}
716 {1.d4 Nf6 2.c4 e6 3.Nc3}
717 {1.d4 Nf6 2.c4 e6 3.Nc3 Bb4}
718 {1.d4 Nf6 2.c4 e6 3.Nf3}
720 {1.d4 Nf6 2.c4 g6 3.Nc3}
721 {1.d4 Nf6 2.c4 g6 3.Nc3 Bg7}
722 {1.d4 Nf6 2.c4 g6 3.Nc3 Bg7 4.e4}
723 {1.d4 Nf6 2.c4 g6 3.Nc3 Bg7 4.e4 d6}
724 {1.d4 Nf6 2.c4 g6 3.Nc3 Bg7 4.e4 d6 5.Nf3}
725 {1.d4 Nf6 2.c4 g6 3.Nc3 Bg7 4.e4 d6 5.Nf3 O-O}
726 {1.d4 Nf6 2.c4 g6 3.Nc3 Bg7 4.e4 d6 5.Nf3 O-O 6.Be2}
727 {1.d4 Nf6 2.c4 g6 3.Nf3}
742 {1.e4 c5 2.Nf3 d6 3.d4}
743 {1.e4 c5 2.Nf3 d6 3.d4 cxd4}
744 {1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4}
745 {1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6}
746 {1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3}
747 {1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 a6}
748 {1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 e6}
749 {1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 g6}
750 {1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 Nc6}
751 {1.e4 c5 2.Nf3 d6 3.Bb5+}
754 {1.e4 c5 2.Nf3 Nc6 3.d4}
755 {1.e4 c5 2.Nf3 Nc6 3.Bb5}
759 {1.e4 c6 2.d4 d5 3.e5}
760 {1.e4 c6 2.d4 d5 3.Nc3}
761 {1.e4 c6 2.d4 d5 3.Nd2}
766 {1.e4 d6 2.d4 Nf6 3.Nc3}
770 {1.e4 e5 2.Nf3 Nc6 3.d4}
771 {1.e4 e5 2.Nf3 Nc6 3.Bb5}
772 {1.e4 e5 2.Nf3 Nc6 3.Bb5 a6}
773 {1.e4 e5 2.Nf3 Nc6 3.Bb5 a6 4.Ba4}
774 {1.e4 e5 2.Nf3 Nc6 3.Bb5 a6 4.Ba4 Nf6}
775 {1.e4 e5 2.Nf3 Nc6 3.Bb5 a6 4.Ba4 Nf6 5.O-O}
776 {1.e4 e5 2.Nf3 Nc6 3.Bc4}
781 {1.e4 e6 2.d4 d5 3.Nc3}
782 {1.e4 e6 2.d4 d5 3.Nc3 Bb4}
783 {1.e4 e6 2.d4 d5 3.Nc3 Nf6}
784 {1.e4 e6 2.d4 d5 3.Nd2}
785 {1.e4 e6 2.d4 d5 3.Nd2 c5}
786 {1.e4 e6 2.d4 d5 3.Nd2 Nf6}
802 proc ::tree::best { baseNumber } {
803 set w .treeBest$baseNumber
804 if {[
winfo exists $w]} {
807 .treeWin$baseNumber.buttons.best state pressed
809 bind $w <Destroy> "+.treeWin$baseNumber.buttons.best state !pressed"
817 proc ::tree::graphRedraw { baseNumber } {
818 .treeGraph$baseNumber.c itemconfigure text -width [
expr {[winfo width .treeGraph$baseNumber.c] - 50}]
819 .treeGraph$baseNumber.c coords text [
expr {[winfo width .treeGraph$baseNumber.c] / 2}] 10
830 proc ::tree::graph { baseNumber {bpress 0}} {
831 set w .treeGraph$baseNumber
832 if {! [
winfo exists .treeWin$baseNumber]} {
return}
833 if {! [
winfo exists $w]} {
836 bind $w <Escape> "destroy $w"
837 bind $w <F1> {helpWindow Tree Graph}
841 $w.menu add cascade -label GraphFile -menu $w.menu.file
843 $w.menu.file add command -label GraphFileColor -command "::tools::graphs::Save color $w.c"
844 $w.menu.file add command -label GraphFileGrey -command "::tools::graphs::Save gray $w.c"
845 $w.menu.file add separator
846 $w.menu.file add command -label GraphFileClose -command "destroy $w"
848 canvas $w.c -width 500 -height 300 -selectforeground [ttk::style lookup . -foreground] -background [ttk::style lookup . -background]
849 pack $w.c -side top -fill both -expand yes
850 $w.c create text 25 10 -tag text -justify center -width 1 -font font_Regular -anchor n
852 bind $w <Configure> "::tree::graphRedraw $baseNumber"
853 bind $w.c <Button-1> "::tree::graph $baseNumber"
854 ::setTitle $w "Scid: Tree Graph $baseNumber: [
file tail [
sc_base filename $baseNumber]]"
858 }
elseif {$bpress == 1} {
863 $w.c itemconfigure text -width [
expr {[winfo width $w.c] - 50}]
864 $w.c coords text [
expr {[winfo width $w.c] / 2}] 10
865 set height [
expr {[winfo height $w.c] - 100}]
866 set width [
expr {[winfo width $w.c] - 50}]
868 -xmin 0.5 -xtick 1 -ytick 5 -font font_Small -canvas $w.c
879 set treeData [subst $[subst {::tree::treeData$baseNumber}]]
882 set numTreeLines [
llength $treeData]
883 set totalLineIndex [
expr $numTreeLines - 2]
885 for {
set i 0} {$i < [
llength $treeData]} {
incr i} {
888 set line [
lindex $treeData $i]
889 set mNum [
string trim [
string range $line 0 1]]
890 set freq [
string trim [
string range $line 17 23]]
891 set fpct [
string trim [
string range $line 25 29]]
892 regsub -all {,} $fpct . fpct
893 set move [
string trim [
string range $line 4 9]]
894 set score [
string trim [
string range $line 33 37]]
895 regsub -all {,} $score . score
896 if {$score > 99.9} {
set score 99.9}
898 if {$i == $totalLineIndex} {
903 if {[
string index $line 2] == ":" && [
string compare "<end>" $move]} {
904 if {$fpct < 1.0 || $freq < 5 || $i > 5} {
905 incr othersCount $freq
907 set othersScore [
expr {$othersScore + (double($freq) * $score)}]
909 if {$numOthers > 1} {
set m "..."}
914 lappend xlabels [list $count "$move ([
expr round($score)]%)\n$freq: [
expr round($fpct)]%"]
920 if {$numOthers > 0 && $totalGames > 0} {
922 set fpct [
expr {double($othersCount) * 100.0 / double($totalGames)}]
923 set sc [
expr {round($othersScore / double($othersCount))}]
924 set othersName "$m ($sc%)\n$othersCount: [
expr round($fpct)]%"
926 lappend data [
expr {$othersScore / double($othersCount)}]
927 lappend xlabels [list $count $othersName]
935 -barwidth 0.75 -outline black -coords $data
937 -hline [list {gray80 1 each 5} {gray50 1 each 10} {black 2 at 50} \
938 {black 1 at 55} [list red 2 at $mean]] \
939 -brect [list [list 0.5 55 [
expr {$count + 0.5}] 50 LightSkyBlue1]]
943 catch {
set moves [
sc_game firstMoves -1]}
944 if {[
string length $moves] == 0} {
set moves $::tr(StartPos)}
946 $w.c itemconfigure text -text $title
950 proc ::tree::configGraphMenus { lang baseNumber } {
951 if {! [
winfo exists .treeGraph$baseNumber]} {
return}
952 if {$lang == ""} {
set lang $::language}
953 set m .treeGraph$baseNumber.menu
954 foreach idx {0} tag {File} {
957 foreach idx {0 1 3} tag {Color Grey Close} {
963 proc ::tree::toggleRefresh { baseNumber } {
965 set b .treeWin$baseNumber.buttons.bStartStop
967 if {$tree(autorefresh$baseNumber)} {
968 $b configure -image tb_search_off
969 set tree(autorefresh$baseNumber) 0
971 $b configure -image tb_search_on
972 set tree(autorefresh$baseNumber) 1
979 proc ::tree::setCacheSize { base size } {
985 proc ::tree::getCacheInfo { base } {
986 set ci [
sc_tree cacheinfo $base]
987 tk_messageBox -title "Scid" -type ok -icon info \
988 -message "Cache used : [
lindex $ci 0] / [
lindex $ci 1]"
1000 namespace eval ::tree::mask {
1005 set maskSerialized {}
1007 set defaultColor white
1010 set cacheFenIndex -1
1013 set searchMask_usenag 0
1014 set searchMask_usemarker0 0
1015 set searchMask_usemarker1 0
1016 set searchMask_usecolor 0
1017 set searchMask_usemovecomment 0
1018 set searchMask_useposcomment 0
1019 set displayMask_showNag 1
1020 set displayMask_showComment 1
1022 array set marker2image { Include tb_tick Exclude tb_cross MainLine tb_mainline Bookmark tb_bkm \
1023 White tb_white Black tb_black \
1024 NewLine tb_new ToBeVerified tb_rfilter ToTrain tb_msearch Dubious tb_help_small ToRemove tb_cut }
1030 proc ::tree::mask::open { {filename ""} } {
1031 global ::tree::mask::maskSerialized ::tree::mask::mask ::tree::mask::recentMask
1033 if {$filename == ""} {
1035 {{Tree Mask Files} {.stm} }
1037 set filename [
tk_getOpenFile -initialdir $::initialDir(stm) -filetypes $types -defaultextension ".stm"]
1038 set ::initialDir(stm) [
file dirname $filename]
1041 if {$filename != ""} {
1043 array unset ::tree::mask::mask
1044 array set ::tree::mask::mask {}
1046 array set mask $maskSerialized
1047 set maskSerialized {}
1048 set ::tree::mask::maskFile $filename
1049 set ::tree::mask::dirty 0
1052 if { [lsearch $recentMask $filename] == -1 } {
1053 set recentMask [
linsert $recentMask 0 $filename]
1054 if {[
llength $recentMask] > $::tree::mask::maxRecent } {
1055 set recentMask [
lreplace $recentMask [
expr $::tree::mask::maxRecent -1] end]
1061 if { [
winfo exists $w] } {
1062 $w.menu.mask.recent delete 0 end
1063 foreach f $::tree::mask::recentMask {
1064 $w.menu.mask.recent add command -label $f -command "::tree::mask::open $f"
1076 proc ::tree::mask::askForSave {} {
1077 if {$::tree::mask::dirty} {
1078 set answer [
tk_messageBox -title Scid -icon warning -type yesno \
1079 -message "[
tr DoYouWantToSaveFirst]\n$::tree::mask::maskFile ?"]
1080 if {$answer == "yes"} {
1088 proc ::tree::mask::new {} {
1091 {{Tree Mask Files} {.stm} }
1093 set filename [
tk_getSaveFile -filetypes $types -defaultextension ".stm"]
1095 if {$filename != ""} {
1096 if {[
file extension $filename] != ".stm" } {
1097 append filename ".stm"
1100 set ::tree::mask::dirty 0
1101 set ::tree::mask::maskFile $filename
1102 array unset ::tree::mask::mask
1103 array set ::tree::mask::mask {}
1110 proc ::tree::mask::close {} {
1111 if { $::tree::mask::maskFile == "" } {
1115 set ::tree::mask::dirty 0
1116 array unset ::tree::mask::mask
1117 array set ::tree::mask::mask {}
1118 set ::tree::mask::maskFile ""
1124 proc ::tree::mask::save {} {
1125 set f [ ::open $::tree::mask::maskFile w]
1126 puts $f "set ::tree::mask::maskSerialized [list [
array get ::tree::mask::mask]]"
1128 set ::tree::mask::dirty 0
1133 proc ::tree::mask::contextMenu {win move x y xc yc} {
1136 set mctxt $win.ctxtMenu
1137 if { [
winfo exists $mctxt] } {
1141 if {$move == "dummy"} {
1142 set state "disabled"
1147 $mctxt add command -label [
tr AddToMask] -command "::tree::mask::addToMask $move" -state $state
1148 $mctxt add command -label [
tr RemoveFromMask] -command "::tree::mask::removeFromMask $move" -state $state
1149 $mctxt add separator
1152 $mctxt add cascade -label [
tr Nag] -menu $mctxt.nag -state $state
1154 foreach nag [ list "!!" " !" "!?" "?!" " ?" "??" " ~" [
::tr "None"]] {
1155 $mctxt.nag add command -label $nag -command "::tree::mask::setNag [list $move $nag]" -state $state
1160 $mctxt add cascade -label "[
tr Marker] [
expr $j +1]" -menu $mctxt.image$j -state $state
1161 foreach e { Include Exclude MainLine Bookmark White Black NewLine ToBeVerified ToTrain Dubious ToRemove } {
1162 set i $::tree::mask::marker2image($e)
1163 $mctxt.image$j add command -label [
tr $e] -image $i -compound left -command "::tree::mask::setImage $move $i $j"
1165 $mctxt.image$j add command -label [
tr NoMarker] -command "::tree::mask::setImage $move {} $j"
1168 $mctxt add cascade -label [
tr ColorMarker] -menu $mctxt.color -state $state
1169 foreach c { "White" "Green" "Yellow" "Blue" "Red"} {
1170 $mctxt.color add command -label [
tr "${c}Mark"] -background $c -command "::tree::mask::setColor $move $c"
1173 $mctxt add separator
1174 $mctxt add command -label [
tr CommentMove] -command "::tree::mask::addComment $move" -state $state
1175 $mctxt add command -label [
tr CommentPosition] -command "::tree::mask::addComment"
1177 $mctxt add separator
1178 set lMatchMoves [
sc_pos matchMoves ""]
1179 if {[
llength $lMatchMoves] > 16} {
1181 for {
set idxMenu 0} { $idxMenu <= [
expr int([
llength $lMatchMoves] / 16)]} {
incr idxMenu} {
1182 menu $mctxt.matchmoves$idxMenu
1183 $mctxt add cascade -label "[
tr AddThisMoveToMask] ([
expr $idxMenu + 1])" -menu $mctxt.matchmoves$idxMenu
1184 for {
set i 0} {$i < 16} {
incr i} {
1185 if {[
expr $i + $idxMenu * 16 +1] > [
llength $lMatchMoves] } {
1188 set m [
lindex $lMatchMoves [
expr $i + $idxMenu * 16]]
1189 if {$m == "OK"} {
set m "O-O"}
1190 if {$m == "OQ"} {
set m "O-O-O"}
1191 $mctxt.matchmoves$idxMenu add command -label [
::trans $m] -command "::tree::mask::addToMask $m"
1195 menu $mctxt.matchmoves
1196 $mctxt add cascade -label [
tr AddThisMoveToMask] -menu $mctxt.matchmoves
1197 foreach m [
sc_pos matchMoves ""] {
1198 if {$m == "OK"} {
set m "O-O"}
1199 if {$m == "OQ"} {
set m "O-O-O"}
1200 $mctxt.matchmoves add command -label [
::trans $m] -command "::tree::mask::addToMask $m"
1204 $mctxt post [
winfo pointerx .] [
winfo pointery .]
1209 proc ::tree::mask::addToMask { move {fen ""} } {
1210 global ::tree::mask::mask
1212 if {$fen == ""} {
set fen $::tree::mask::cacheFenIndex}
1214 if {![
info exists mask($fen)]} {
1215 set mask($fen) { {} {} }
1217 set ::tree::mask::dirty 1
1218 set moves [
lindex $mask($fen) 0]
1219 if {[lsearch $moves $move] == -1} {
1220 lappend moves [list $move {} $::tree::mask::defaultColor {} {} {}]
1221 set newpos [
lreplace $mask($fen) 0 0 $moves]
1222 set mask($fen) $newpos
1229 proc ::tree::mask::removeFromMask { move {fen ""} } {
1230 global ::tree::mask::mask
1232 if {$fen == ""} {
set fen $::tree::mask::cacheFenIndex}
1234 if {![
info exists mask($fen)]} {
1237 set ::tree::mask::dirty 1
1239 set moves [
lindex $mask($fen) 0]
1240 set idxm [lsearch -regexp $moves "^$move *"]
1242 set moves [
lreplace $moves $idxm $idxm]
1243 lset mask($fen) 0 $moves
1248 if { [
llength [
lindex $mask($fen) 0]] == 0 && [
lindex $mask($fen) 1] == "" } {
1249 array unset mask $fen
1255 proc ::tree::mask::moveExists { move {fen ""} } {
1256 global ::tree::mask::mask
1258 if {$fen == ""} {
set fen $::tree::mask::cacheFenIndex}
1260 if {![
info exists mask($fen)] || $move == "\[end\]" } {
1263 set moves [
lindex $mask($fen) 0]
1264 if {[lsearch -regexp $moves "^$move *"] == -1} {
1272 proc ::tree::mask::getAllMoves {} {
1273 global ::tree::mask::mask
1274 if {![
info exists mask($::tree::mask::cacheFenIndex)]} {
1277 set moves [
lindex $mask($::tree::mask::cacheFenIndex) 0]
1283 proc ::tree::mask::getColor { move {fen ""}} {
1284 global ::tree::mask::mask
1286 if {$fen == ""} {
set fen $::tree::mask::cacheFenIndex}
1288 if {![
info exists mask($fen)]} {
1289 return $::tree::mask::defaultColor
1292 set moves [
lindex $mask($fen) 0]
1293 set idxm [lsearch -regexp $moves "^$move *"]
1295 return $::tree::mask::defaultColor
1297 set col [
lindex $moves $idxm 2]
1304 proc ::tree::mask::setColor { move color {fen ""}} {
1305 global ::tree::mask::mask
1307 if {$fen == ""} {
set fen $::tree::mask::cacheFenIndex}
1309 if {![
info exists mask($fen)]} {
1310 tk_messageBox -title "Scid" -type ok -icon warning -message [
tr AddMoveToMaskFirst]
1313 set ::tree::mask::dirty 1
1314 set moves [
lindex $mask($fen) 0]
1315 set idxm [lsearch -regexp $moves "^$move *"]
1317 tk_messageBox -title "Scid" -type ok -icon warning -message [
tr AddMoveToMaskFirst]
1320 set newmove [
lreplace [
lindex $moves $idxm] 2 2 $color]
1321 set moves [
lreplace $moves $idxm $idxm $newmove]
1322 set mask($fen) [
lreplace $mask($fen) 0 0 $moves]
1328 proc ::tree::mask::getNag { move { fen "" }} {
1329 global ::tree::mask::mask ::tree::mask::emptyNag
1331 if {$fen == ""} {
set fen $::tree::mask::cacheFenIndex}
1333 if {![
info exists mask($fen)]} {
1336 set moves [
lindex $mask($fen) 0]
1337 set idxm [lsearch -regexp $moves "^$move *"]
1341 set nag [
lindex $moves $idxm 1]
1345 if { [
string length $nag] == 1} {
set nag " $nag"}
1351 proc ::tree::mask::setNag { move nag {fen ""} {refresh 1} } {
1352 global ::tree::mask::mask
1354 if { $nag == [
::tr "None"] } {
1358 if {$fen == ""} {
set fen $::tree::mask::cacheFenIndex}
1360 if {![
info exists mask($fen)]} {
1361 tk_messageBox -title "Scid" -type ok -icon warning -message [
tr AddMoveToMaskFirst]
1364 set ::tree::mask::dirty 1
1365 set moves [
lindex $mask($fen) 0]
1366 set idxm [lsearch -regexp $moves "^$move *"]
1368 tk_messageBox -title "Scid" -type ok -icon warning -message [
tr AddMoveToMaskFirst]
1371 set newmove [
lreplace [
lindex $moves $idxm] 1 1 $nag]
1372 set moves [
lreplace $moves $idxm $idxm $newmove]
1373 set mask($fen) [
lreplace $mask($fen) 0 0 $moves]
1379 proc ::tree::mask::getComment { move { fen "" } } {
1380 global ::tree::mask::mask
1382 if {$fen == ""} {
set fen $::tree::mask::cacheFenIndex}
1384 if {![
info exists mask($fen)] || $move == "" || $move == "\[end\]" } {
1388 set moves [
lindex $mask($fen) 0]
1389 set idxm [lsearch -regexp $moves "^$move *"]
1393 set comment [
lindex $moves $idxm 3]
1394 if {$comment == ""} {
1402 proc ::tree::mask::setComment { move comment { fen "" } } {
1403 global ::tree::mask::mask
1405 if {$fen == ""} {
set fen $::tree::mask::cacheFenIndex}
1407 set comment [
string trim $comment]
1409 if {![
info exists mask($fen)]} {
1410 tk_messageBox -title "Scid" -type ok -icon warning -message [
tr AddMoveToMaskFirst]
1413 set ::tree::mask::dirty 1
1414 set moves [
lindex $mask($fen) 0]
1415 set idxm [lsearch -regexp $moves "^$move *"]
1417 tk_messageBox -title "Scid" -type ok -icon warning -message [
tr AddMoveToMaskFirst]
1420 set newmove [
lreplace [
lindex $moves $idxm] 3 3 $comment]
1421 set moves [
lreplace $moves $idxm $idxm $newmove]
1422 set mask($fen) [
lreplace $mask($fen) 0 0 $moves]
1427 proc ::tree::mask::getPositionComment {{fen ""}} {
1428 global ::tree::mask::mask
1430 if {$fen == ""} {
set fen $::tree::mask::cacheFenIndex}
1432 if { ! [
info exists mask($fen)] } {
1436 set comment [
lindex $mask($fen) 1]
1437 set comment [
string trim $comment]
1444 proc ::tree::mask::setPositionComment { comment {fen ""} } {
1445 global ::tree::mask::mask
1447 if {$fen == ""} {
set fen $::tree::mask::cacheFenIndex}
1448 set comment [
string trim $comment]
1449 set ::tree::mask::dirty 1
1451 if {![
info exists mask($fen)]} {
1452 set mask($fen) { {} {} }
1455 set newpos [
lreplace $mask($fen) 1 1 $comment]
1456 set mask($fen) $newpos
1461 proc ::tree::mask::setImage { move img nmr } {
1462 global ::tree::mask::mask
1463 set fen $::tree::mask::cacheFenIndex
1464 if {![
info exists mask($fen)]} {
1465 tk_messageBox -title "Scid" -type ok -icon warning -message [
tr AddMoveToMaskFirst]
1468 set ::tree::mask::dirty 1
1469 set moves [
lindex $mask($fen) 0]
1470 set idxm [lsearch -regexp $moves "^$move *"]
1472 tk_messageBox -title "Scid" -type ok -icon warning -message [
tr AddMoveToMaskFirst]
1475 set loc [
expr 4 + $nmr]
1476 set newmove [
lreplace [
lindex $moves $idxm] $loc $loc $img]
1477 set moves [
lreplace $moves $idxm $idxm $newmove]
1478 set mask($fen) [
lreplace $mask($fen) 0 0 $moves]
1485 proc ::tree::mask::getImage { move nmr } {
1486 global ::tree::mask::mask
1488 set fen $::tree::mask::cacheFenIndex
1489 if {![
info exists mask($fen)]} {
1492 set moves [
lindex $mask($fen) 0]
1493 set idxm [lsearch -regexp $moves "^$move *"]
1497 set loc [
expr 4 + $nmr]
1498 set img [
lindex $moves $idxm $loc]
1499 if {$img == ""} {
set img tb_empty}
1506 proc ::tree::mask::addComment { { move "" } } {
1509 if { $move != "" } {
1511 tk_messageBox -title "Scid" -type ok -icon warning -message [
tr AddMoveToMaskFirst]
1515 set w .treeMaskAddComment
1516 toplevel .treeMaskAddComment
1524 set oldComment [
string trim $oldComment]
1525 autoscrollframe $w.f text $w.f.e -width 40 -height 5 -wrap word -setgrid 1
1526 $w.f.e insert end $oldComment
1527 ttk::button $w.ok -text OK -command "::tree::mask::updateComment $move ; destroy $w ; ::tree::refresh"
1528 pack $w.f -side top -expand 1 -fill both
1529 pack $w.ok -side bottom
1535 proc ::tree::mask::updateComment { { move "" } } {
1536 set e .treeMaskAddComment.f.e
1537 set newComment [$e get 1.0 end]
1538 set newComment [
string trim $newComment]
1539 set ::tree::mask::dirty 1
1550 proc ::tree::mask::fillWithBase {} {
1551 if {$::tree::mask::maskFile == ""} {
1552 tk_messageBox -title "Scid" -type ok -icon warning -message [
tr OpenAMaskFileFirst]
1556 set n [
sc_base numGames $::curr_db]
1558 for {
set gnum 1} { $gnum <= $n} {
incr gnum} {
1568 proc ::tree::mask::fillWithGame { {base ""} {gnum ""} {refresh 1} } {
1569 if {$::tree::mask::maskFile == ""} {
1570 tk_messageBox -title "Scid" -type ok -icon warning -message [
tr OpenAMaskFileFirst]
1583 set game [
sc_base getGame $base $gnum]
1584 set n [
llength $game]
1585 for {
set i 0} { $i < $n} {
incr i} {
1587 foreach {RAVd RAVn FEN NAGs comment lastMoveSAN} [
lindex $game $i] {}
1589 if { $RAVd > $lastRAVd || ($RAVd == $lastRAVd && $RAVn != $lastRAVn) } {
1591 set parent [
expr { $RAVd - 1 }]
1592 set iFEN($RAVd) $iFENrav($parent)
1595 set fromFEN [
lindex [
lindex $game $iFEN($RAVd)] 2]
1600 set iFENrav($RAVd) $iFEN($RAVd)
1604 set ::tree::mask::dirty 1
1610 proc ::tree::mask::feedMask { fen move nag comment } {
1611 global ::tree::mask::mask
1613 set stdNags { "!!" "!" "!?" "?!" "??" "~"}
1622 if {![
info exists mask($fen)]} {
1623 set mask($fen) { {} {} }
1625 set moves [
lindex $mask($fen) 0]
1626 if {[lsearch $moves $move] == -1} {
1627 lappend moves [list $move {} $::tree::mask::defaultColor {} {} {}]
1628 set newpos [
lreplace $mask($fen) 0 0 $moves]
1629 set mask($fen) $newpos
1633 if {$move == "null"} {
1640 if {$nag == 0} {
set nag ""}
1643 if {[lsearch $stdNags $nag] == -1 } {
1644 set comment "$nag $comment"
1647 set oldNag [
getNag $move]
1648 if {$oldNag != $::tree::mask::emptyNag && $oldNag != $nag} {
1649 set comment "<$oldNag>(?!?) $comment"
1657 if { $oldComment != "" && $oldComment != $comment } {
1658 set comment "$oldComment\n$comment"
1665 proc ::tree::mask::toShortFen {fen} {
1666 set ret [
lreplace $fen end-1 end]
1672 proc ::tree::mask::setCacheFenIndex {} {
1678 proc ::tree::mask::infoMask {} {
1679 global ::tree::mask::mask
1681 set npos [
array size mask]
1683 set nmoves [
lindex [
split [
array statistics mask] "\n"] end]
1687 tk_messageBox -title "Mask info" -type ok -icon info -message "Mask : $::tree::mask::maskFile\n[
tr Positions] : $npos\n[
tr Moves] : $nmoves"
1693 proc ::tree::mask::displayMask {} {
1694 global ::tree::mask::mask
1697 if { [
winfo exists $w] } {
1702 wm title $w [
::tr DisplayMask]
1707 pack $w.f -fill both -expand 1
1711 ttk::button $w.fcb.bupdate -text [
::tr "Update"] -command ::tree::mask::updateDisplayMask
1712 ttk::checkbutton $w.fcb.nag -text [
::tr "Nag"] -variable ::tree::mask::displayMask_showNag -command ::tree::mask::updateDisplayMask
1713 ttk::checkbutton $w.fcb.comment -text [
::tr "Comments"] -variable ::tree::mask::displayMask_showComment -command ::tree::mask::updateDisplayMask
1714 pack $w.fcb.bupdate $w.fcb.nag $w.fcb.comment -side right -padx 5 -pady "2 5"
1716 ttk::treeview $w.f.tree -yscrollcommand "$w.f.ybar set" -xscrollcommand "$w.f.xbar set" -show tree -selectmode browse
1718 $w.f.tree column #0 -minwidth 1200
1719 ttk::scrollbar $w.f.xbar -command "$w.f.tree xview" -orient horizontal
1720 ttk::scrollbar $w.f.ybar -command "$w.f.tree yview"
1722 pack $w.f.xbar -side bottom -fill x
1723 pack $w.f.ybar -side right -fill y
1724 pack $w.f.tree -side left -expand 1 -fill both
1728 bind $w <Escape> { destroy .displaymask }
1729 bind $w <Configure> {
1730 recordWinSize .displaymask
1733 $w.f.tree tag bind dblClickTree <Double-Button-1> {::tree::mask::maskTreeUnfold }
1738 proc ::tree::mask::updateDisplayMask {} {
1739 global ::tree::mask::mask
1741 set tree .displaymask.f.tree
1742 $tree delete [ $tree children {}]
1745 set currentbase [
sc_base current]
1749 if {[
catch {
sc_game startBoard $fen} err]} {
1750 puts "sc_game startBoard $fen => $err"
1752 if { [
info exists mask($fen)] } {
1753 set moves [
lindex $mask($fen) 0]
1763 proc ::tree::mask::createImage {marker1 marker2} {
1765 if {[lsearch [
image names] "$marker1$marker2"] != -1} {
1768 set img1 $::tree::mask::marker2image($marker1)
1769 set img2 $::tree::mask::marker2image($marker2)
1770 set w1 [
image width $img1]
1771 set w2 [
image width $img2]
1772 set h1 [
image height $img1]
1773 set h2 [
image height $img2]
1775 image create photo $marker1$marker2 -height $h1 -width [
expr $w1 + $w2 + $margin]
1776 $marker1$marker2 copy $img1 -from 0 0 -to 0 0
1777 $marker1$marker2 copy $img2 -from 0 0 -to [
expr $w1 +$margin] 0
1782 proc ::tree::mask::maskTreeUnfold {} {
1783 set t .displaymask.f.tree
1786 set t .displaymask.f.tree
1787 foreach c [$t children $id] {
1788 $t item $c -open true
1793 set id [$t selection]
1799 proc ::tree::mask::trimToFirstLine {s} {
1800 set s [
lindex [
split $s "\n"] 0]
1806 proc ::tree::mask::populateDisplayMask { moves parent fen fenSeen posComment} {
1807 global ::tree::mask::mask
1811 if { $posComment != ""} {
1812 set posComment "\[$posComment\] "
1815 set tree .displaymask.f.tree
1818 set move [
lindex $m 0]
1819 if {$move == "null"} { continue}
1821 if {[
lindex $m 4] != "" && [
lindex $m 5] == ""} {
1822 set img [
lindex $m 4]
1824 if {[
lindex $m 4] == "" && [
lindex $m 5] != ""} {
1825 set img [
lindex $m 5]
1827 if {[
lindex $m 4] != "" && [
lindex $m 5] != ""} {
1828 set l [
array get ::tree::mask::marker2image]
1829 set idx [ lsearch $l [
lindex $m 4]]
1830 set mark1 [
lindex $l [
expr $idx -1]]
1831 set idx [ lsearch $l [
lindex $m 5]]
1832 set mark2 [
lindex $l [
expr $idx -1]]
1834 set img $mark1$mark2
1838 if { $::tree::mask::displayMask_showNag } {
1839 set nag [
lindex $m 1]
1842 if {[
lindex $m 3] != "" && $::tree::mask::displayMask_showComment} {
1843 set move_comment " [
lindex $m 3]"
1848 if { ! $::tree::mask::displayMask_showComment} {
1851 set id [ $tree insert $parent end -text "$posComment[
::trans $move][
set nag]$move_comment" -image $img -tags dblClickTree]
1852 if {[
catch {
sc_game startBoard $fen} err]} {
1853 puts "ERROR sc_game startBoard $fen => $err"
1858 if {[lsearch $fenSeen $newfen] != -1} {
return}
1859 if { [
info exists mask($newfen)] } {
1860 set newmoves [
lindex $mask($newfen) 0]
1862 while { [
llength $newmoves] == 1 } {
1863 lappend fenSeen $newfen
1864 sc_move addSan [
lindex $newmoves { 0 0 }]
1866 if {[lsearch $fenSeen $newfen] != -1} {
return}
1867 lappend fenSeen $newfen
1868 if {[
lindex $newmoves 0 3] != "" && $::tree::mask::displayMask_showComment } {
1869 set move_comment " [
lindex $newmoves 0 3]"
1875 if {[
lindex $newmoves 1] != "" && $::tree::mask::displayMask_showComment } {
1876 set pos_comment " \[[
lindex $newmoves 1]\]"
1882 if { $::tree::mask::displayMask_showNag } {
1883 set nag [
lindex $newmoves { 0 1 }]
1885 $tree item $id -text "[ $tree item $id -text] $pos_comment[
::trans [
lindex $newmoves { 0 0 }]][
set nag]$move_comment"
1886 if { ! [
info exists mask($newfen)] } {
1889 set newmoves [
lindex $mask($newfen) 0]
1892 if { [
info exists mask($newfen)] } {
1893 set newmoves [
lindex $mask($newfen) 0]
1903 proc ::tree::mask::searchMask { baseNumber } {
1906 if { [
winfo exists $w] } {
1911 wm title $w [
::tr SearchMask]
1914 pack $w.f1 -side top -fill both -expand 1 -anchor e
1915 pack $w.f2 -side top -fill both -expand 1 -anchor e
1918 ttk::checkbutton $w.f1.nagl -text [
tr Nag] -variable ::tree::mask::searchMask_usenag
1920 ttk::menubutton $w.f1.nag -textvariable ::tree::mask::searchMask_nag -menu $w.f1.nagmenu -style pad0.TMenubutton
1921 set ::tree::mask::searchMask_nag [
::tr "None"]
1922 foreach nag [ list "!!" " !" "!?" "?!" " ?" "??" " ~" [
::tr "None"]] {
1923 $w.f1.nagmenu add command -label $nag -command "set ::tree::mask::searchMask_nag $nag"
1925 grid $w.f1.nagl -column 0 -row 0 -sticky w -padx 10
1926 grid $w.f1.nag -column 0 -row 1 -sticky w -padx 10
1930 ttk::checkbutton $w.f1.ml$j -text "[
tr Marker] [
expr $j +1]" -variable ::tree::mask::searchMask_usemarker$j
1932 ttk::menubutton $w.f1.m$j -textvariable ::tree::mask::searchMask_trm$j -menu $w.f1.menum$j -style pad0.TMenubutton
1933 set ::tree::mask::searchMask_trm$j [
tr "Include"]
1934 set ::tree::mask::searchMask_m$j $::tree::mask::marker2image(Include)
1935 foreach e { Include Exclude MainLine Bookmark White Black NewLine ToBeVerified ToTrain Dubious ToRemove } {
1936 set i $::tree::mask::marker2image($e)
1937 $w.f1.menum$j add command -label [
tr $e] -image $i -compound left \
1938 -command "set ::tree::mask::searchMask_trm$j \"[
tr $e]\" ; set ::tree::mask::searchMask_m$j $i"
1940 grid $w.f1.ml$j -column [
expr 1 + $j] -row 0 -sticky w -padx [
expr $j*10]
1941 grid $w.f1.m$j -column [
expr 1 + $j] -row 1 -sticky w -padx [
expr $j*10]
1945 ttk::checkbutton $w.f1.colorl -text [
tr ColorMarker] -variable ::tree::mask::searchMask_usecolor
1946 menu $w.f1.colormenu
1947 ttk::menubutton $w.f1.color -textvariable ::tree::mask::searchMask_trcolor -menu $w.f1.colormenu -style pad0.TMenubutton
1948 set ::tree::mask::searchMask_trcolor [
::tr "White"]
1949 set ::tree::mask::searchMask_color "White"
1950 foreach c { "White" "Green" "Yellow" "Blue" "Red"} {
1951 $w.f1.colormenu add command -label [
tr "${c}Mark"] \
1952 -command "set ::tree::mask::searchMask_trcolor [
tr ${c}Mark] ; set ::tree::mask::searchMask_color $c"
1954 grid $w.f1.colorl -column 3 -row 0 -sticky w
1955 grid $w.f1.color -column 3 -row 1 -sticky w
1958 ttk::checkbutton $w.f1.movecommentl -text "Move comment" -variable ::tree::mask::searchMask_usemovecomment
1959 ttk::entry $w.f1.movecomment -textvariable ::tree::mask::searchMask_movecomment -width 12
1960 grid $w.f1.movecommentl -column 4 -row 0 -sticky w -padx 10
1961 grid $w.f1.movecomment -column 4 -row 1 -sticky w -padx 10
1964 ttk::checkbutton $w.f1.poscommentl -text "Position comment" -variable ::tree::mask::searchMask_useposcomment
1965 ttk::entry $w.f1.poscomment -textvariable ::tree::mask::searchMask_poscomment -width 12
1966 grid $w.f1.poscommentl -column 5 -row 0 -sticky w
1967 grid $w.f1.poscomment -column 5 -row 1 -sticky w
1969 ttk::button $w.f1.search -text [
tr "Search"] -command " ::tree::mask::performSearch $baseNumber "
1970 grid $w.f1.search -column 5 -row 2 -sticky e -pady "2 5" -padx "0 5"
1973 text $w.f2.text -yscrollcommand "$w.f2.ybar set" -height 40
1974 ttk::scrollbar $w.f2.ybar -command "$w.f2.text yview"
1975 pack $w.f2.text -side left -fill both -expand yes
1976 pack $w.f2.ybar -side left -fill y
1981 bind $w.f2.text <ButtonPress-1> " ::tree::mask::searchClick %x %y %W $baseNumber "
1982 bind $w <Escape> { destroy .searchmask }
1983 bind $w <Configure> "recordWinSize $w"
1989 proc ::tree::mask::performSearch { baseNumber } {
1990 global ::tree::mask::mask
1991 set t .searchmask.f2.text
2003 foreach fen [
array names mask] {
2007 set poscomment [
lindex $mask($fen) 1]
2008 if { $::tree::mask::searchMask_useposcomment } {
2009 if { [
string match -nocase "*$::tree::mask::searchMask_poscomment*" $poscomment] } {
2010 lappend res "$fen $poscomment"
2017 set moves [
lindex $mask($fen) 0]
2022 if { $::tree::mask::searchMask_usenag } {
2023 set nag $::tree::mask::searchMask_nag
2024 if { $nag == [
::tr "None"] } {
set nag ""}
2025 if { [
string trim [
lindex $m 1]] != $nag } {
2031 if { $::tree::mask::searchMask_usemarker0 } {
2032 if { $::tree::mask::searchMask_m0 != [
lindex $m 4] } {
2036 if { $::tree::mask::searchMask_usemarker1 } {
2037 if { $::tree::mask::searchMask_m1 != [
lindex $m 5] } {
2043 if { $::tree::mask::searchMask_usecolor } {
2044 if { [
string compare -nocase $::tree::mask::searchMask_color [
lindex $m 2]] != 0 } {
2050 set movecomment [
lindex $m 3]
2051 if { $::tree::mask::searchMask_usemovecomment } {
2052 if { ! [
string match -nocase "*$::tree::mask::searchMask_movecomment*" $movecomment] } {
2057 lappend res "$fen [
::trans [
lindex $m 0]] $movecomment"
2064 $t insert end "$l\n"
2066 wm title .searchmask "[
::tr SearchMask] [
::tr Positions] $pos_count / $pos_total - [
::tr moves] $move_count / $move_total"
2071 proc ::tree::mask::searchClick {x y win baseNumber} {
2072 set idx [ $win index @$x,$y]
2073 if { [
scan $idx "%d.%d" l c] != 2 } {
2077 set elt [$win get $l.0 $l.end]
2079 if {[
llength $elt] < 4} {
2083 set fen [
lrange $elt 0 3]
2089 if {[
catch {
sc_game startBoard $fen} err]} {
2090 puts "sc_game startBoard $fen => $err"