6 namespace eval tacgame {
14 set openingMovesList {}
15 set openingMovesHash {}
25 set lastblundervalue 0.0
26 set prev_lastblundervalue 0.0
27 set blundermissed false
28 set blunderwarning false
29 set blunderwarningvalue 0.0
30 set blundermissedvalue 0.0
32 set blunderWarningLabel $::tr(Noblunder)
36 set prev_blunderpending 0
40 set analysisCoach(automove1) 0
48 set ::tacgame::blundermissed false
49 set ::tacgame::lastblundervalue 0.0
50 set ::tacgame::prev_lastblundervalue 0.0
51 set ::tacgame::prev_blunderpending 0
52 set ::tacgame::currentPosHash [
sc_pos hash]
53 set ::tacgame::lscore {}
54 set ::tacgame::resignCount 0
61 proc resetEngine {n} {
63 global ::tacgame::analysisCoach
64 set analysisCoach(pipe$n) ""
65 set analysisCoach(seen$n) 0
66 set analysisCoach(seenEval$n) 0
67 set analysisCoach(score$n) 0
68 set analysisCoach(moves$n) ""
69 set analysisCoach(movelist$n) {}
70 set analysisCoach(nonStdStart$n) 0
71 set analysisCoach(has_analyze$n) 0
72 set analysisCoach(has_setboard$n) 0
73 set analysisCoach(send_sigint$n) 0
74 set analysisCoach(wants_usermove$n) 0
75 set analysisCoach(wholeSeconds$n) 0
76 set analysisCoach(analyzeMode$n) 0
77 set analysisCoach(invertScore$n) 1
78 set analysisCoach(automove$n) 0
79 set analysisCoach(automoveThinking$n) 0
80 set analysisCoach(automoveTime$n) 2000
81 set analysisCoach(lastClicks$n) 0
82 set analysisCoach(after$n) ""
83 set analysisCoach(log$n) ""
84 set analysisCoach(logCount$n) 0
85 set analysisCoach(wbEngineDetected$n) 0
97 global ::tacgame::configWin ::tacgame::analysisCoachCommand ::tacgame::analysisCoach \
98 engineCoach1 engineCoach2 ::tacgame::level ::tacgame::levelFixed \
99 ::tacgame::isLimitedAnalysisTime ::tacgame::analysisTime ::tacgame::index1 ::tacgame::index2 ::tacgame::chosenOpening
102 if {[
winfo exists .coachWin]} {
113 foreach e $::engines(list) {
114 if { $index1 != -1 && $index2 != -1 } { break}
115 set name [
lindex $e 0]
116 if { [
string match -nocase "*phalanx*" $name] } {
117 set engineCoach1 $name
121 if {[
lindex $e 7] != 0} {
122 set engineCoach2 $name
129 if { $index1 == -1 || $index2 == -1 } {
130 tk_messageBox -title "Scid" -icon warning -type ok -message $::tr(PhalanxOrTogaMissing)
135 if {[
winfo exists $w]} {
142 wm title $w "$::tr(configurecoachgame)"
144 bind $w <F1> { helpWindow TacticalGame }
147 ttk::labelframe $w.flevel -text [
string toupper $::tr(difficulty) 0 0]
148 ttk::frame $w.flevel.diff_fixed
149 ttk::frame $w.flevel.diff_random
150 ttk::labelframe $w.fopening -text $::tr(Opening)
151 ttk::labelframe $w.flimit -text $::tr(Time)
152 ttk::frame $w.fbuttons
154 pack $w.flevel -side top -fill x
155 pack $w.flevel.diff_fixed -side top -anchor w
156 pack $w.flevel.diff_random -side top -anchor w
157 pack $w.fopening -side top -fill both -expand 1 -pady 10
158 pack $w.flimit $w.fbuttons -side top -fill x
160 ttk::radiobutton $w.flevel.diff_random.cb -text $::tr(RandomLevel) -variable ::tacgame::randomLevel -value 1 -width 15
161 ttk::scale $w.flevel.diff_random.lMin -orient horizontal -from 1200 -to 2200 -length 100 -variable ::tacgame::levelMin \
162 -command { ::utils::validate::roundScale ::tacgame::levelMin 50 }
163 ttk::label $w.flevel.diff_random.labelMin -textvariable ::tacgame::levelMin
164 ttk::scale $w.flevel.diff_random.lMax -orient horizontal -from 1200 -to 2200 -length 100 -variable ::tacgame::levelMax \
165 -command { ::utils::validate::roundScale ::tacgame::levelMax 50 }
166 ttk::label $w.flevel.diff_random.labelMax -textvariable ::tacgame::levelMax
167 ttk::radiobutton $w.flevel.diff_fixed.cb -text $::tr(FixedLevel) -variable ::tacgame::randomLevel -value 0 -width 15
168 ttk::label $w.flevel.diff_fixed.labelFixed -textvariable ::tacgame::levelFixed
169 ttk::scale $w.flevel.diff_fixed.scale -orient horizontal -from 1200 -to 2200 -length 200 \
170 -variable ::tacgame::levelFixed -command { ::utils::validate::roundScale ::tacgame::levelFixed 50 }
172 grid $w.flevel.diff_fixed.cb -row 0 -column 0 -rowspan 2
173 grid $w.flevel.diff_fixed.labelFixed -row 0 -column 1
174 grid $w.flevel.diff_fixed.scale -row 1 -column 1 -padx "10 0" -sticky e
175 grid $w.flevel.diff_random.cb -row 0 -column 0 -rowspan 2
176 grid $w.flevel.diff_random.labelMin -row 0 -column 1
177 grid $w.flevel.diff_random.lMin -row 1 -column 1 -padx "10 0" -sticky e
178 grid $w.flevel.diff_random.labelMax -row 0 -column 2
179 grid $w.flevel.diff_random.lMax -row 1 -column 2 -sticky e
182 ttk::radiobutton $w.fopening.cbNew -text $::tr(StartNewGame) -variable ::tacgame::openingType -value new
185 ttk::radiobutton $w.fopening.cbPosition -text $::tr(StartFromCurrentPosition) -variable ::tacgame::openingType -value current
188 ttk::radiobutton $w.fopening.cbSpecific -text $::tr(SpecificOpening) -variable ::tacgame::openingType -value specific
190 pack $w.fopening.cbNew -anchor w
191 pack $w.fopening.cbPosition -anchor w
192 pack $w.fopening.cbSpecific -anchor w
194 ttk::frame $w.fopening.fOpeningList
195 listbox $w.fopening.fOpeningList.lbOpening -yscrollcommand "$w.fopening.fOpeningList.ybar set" \
196 -height 5 -width 40 -list ::tacgame::openingList
197 $w.fopening.fOpeningList.lbOpening selection set $::tacgame::chosenOpening
198 $w.fopening.fOpeningList.lbOpening see $::tacgame::chosenOpening
200 ttk::scrollbar $w.fopening.fOpeningList.ybar -command "$w.fopening.fOpeningList.lbOpening yview"
201 pack $w.fopening.fOpeningList.lbOpening -side left -fill both -expand 1
202 pack $w.fopening.fOpeningList.ybar -side right -fill y
203 pack $w.fopening.fOpeningList -expand yes -fill both -side top -expand 1
206 ttk::checkbutton $w.flimit.blimit -text $::tr(limitanalysis) -variable ::tacgame::isLimitedAnalysisTime
207 ttk::label $w.flimit.labelsecval -textvariable ::tacgame::analysisTime
208 ttk::label $w.flimit.labelsec -text $::tr(seconds)
209 ttk::scale $w.flimit.analysisTime -orient horizontal -from 5 -to 60 -length 200 -variable ::tacgame::analysisTime \
210 -command { ::utils::validate::roundScale ::tacgame::analysisTime 1 }
211 grid $w.flimit.blimit -column 0 -row 0 -columnspan 2 -sticky we
212 grid $w.flimit.labelsecval -column 0 -row 1 -sticky e
213 grid $w.flimit.labelsec -column 1 -row 1 -sticky w -padx 5
214 grid $w.flimit.analysisTime -column 0 -row 2 -columnspan 2 -sticky we
217 ttk::button $w.fbuttons.close -text $::tr(Play) -command {
219 set ::tacgame::chosenOpening [.configWin.fopening.fOpeningList.lbOpening curselection]
223 ttk::button $w.fbuttons.cancel -textvar ::tr(Cancel) -command "focus .; destroy $w"
227 bind $w <Escape> { .configWin.fbuttons.cancel invoke }
228 bind $w <Return> { .configWin.fbuttons.close invoke }
229 bind $w <F1> { helpWindow TacticalGame }
231 bind $w <Configure> "recordWinSize $w"
240 global ::tacgame::analysisCoach ::tacgame::threshold ::tacgame::showblunder ::tacgame::showblundervalue \
241 ::tacgame::blunderfound ::tacgame::showmovevalue ::tacgame::level ::tacgame::levelFixed engineCoach1 \
242 engineCoach2 ::tacgame::index1 ::tacgame::index2 ::tacgame::chosenOpening \
243 ::tacgame::openingType ::tacgame::openingList ::tacgame::openingMovesList \
244 ::tacgame::openingMovesHash ::tacgame::openingMoves ::tacgame::outOfOpening
246 if {$::tacgame::openingType ne "current"} {
252 catch { unset ::uci::uciInfo(score2)}
254 set ::tacgame::lFen {}
257 if {[
winfo exists $w]} {
263 if {$::tacgame::randomLevel} {
264 if {$::tacgame::levelMax < $::tacgame::levelMin} {
265 set tmp $::tacgame::levelMax
266 set ::tacgame::levelMax $::tacgame::levelMin
267 set ::tacgame::levelMin $tmp
269 set level [
expr int(rand()*($::tacgame::levelMax - $::tacgame::levelMin)) + $::tacgame::levelMin]
271 set level $::tacgame::levelFixed
275 if {$openingType == "specific"} {
276 set fields [
split [
lindex $openingList $chosenOpening] ":"]
277 set openingName [
lindex $fields 0]
278 set openingMoves [
string trim [
lindex $fields 1]]
279 set openingMovesList ""
280 set openingMovesHash ""
282 foreach m [
split $openingMoves] {
287 set n [
string trim $m]
288 lappend openingMovesList [
string trim [regsub {^[1-9]+\.} $m ""]]
291 lappend openingMovesHash [
sc_pos hash]
292 foreach m $openingMovesList {
293 if {[
catch {
sc_move addSan $m}]} {
295 lappend openingMovesHash [
sc_pos hash]
300 if {$::tacgame::openingType != "current"} {
301 sc_game tags set -event "Tactical game"
303 sc_game tags set -white "Phalanx - $level ELO"
305 sc_game tags set -black "Phalanx - $level ELO"
314 setTitle $w "$::tr(coachgame) (Elo $level)"
316 ttk::frame $w.fdisplay
317 ttk::frame $w.fthreshold
318 ttk::frame $w.finformations
319 ttk::labelframe $w.fclockw -text "$::tr(Time) $::tr(Player)"
320 ttk::labelframe $w.fclockb -text "$::tr(Time) $::tr(Engine)"
321 ttk::frame $w.fbuttons
322 pack $w.fdisplay -side top -fill both -pady 5 -padx 10
323 pack [ttk::separator $w.line1 -orient horizontal] -side top -fill x -padx 10 -pady 5
324 pack $w.fthreshold -side top -fill both -pady 5 -padx 10
325 pack [ttk::separator $w.line2 -orient horizontal] -side top -fill x -padx 10 -pady 5
326 pack $w.finformations $w.fclockb $w.fclockw -side top -fill both -pady 5 -padx 10
327 pack $w.fbuttons -side top -pady "10 15"
329 ttk::checkbutton $w.fdisplay.b1 -text $::tr(showblunderexists) -variable ::tacgame::showblunder
330 ttk::checkbutton $w.fdisplay.b2 -text $::tr(showblundervalue) -variable ::tacgame::showblundervalue
331 ttk::checkbutton $w.fdisplay.b5 -text $::tr(showscore) -variable ::tacgame::showevaluation
332 pack $w.fdisplay.b1 $w.fdisplay.b2 $w.fdisplay.b5 -anchor w
334 ttk::label $w.fthreshold.l -text $::tr(moveblunderthreshold) -wraplength 300
336 ttk::scale $w.fthreshold.t -orient horizontal -from 0.0 -to 10.0 -length 200 \
337 -variable ::tacgame::threshold -command { ::utils::validate::floatScale ::tacgame::threshold 0.1 }
338 ttk::label $w.fthreshold.labelt -textvariable ::tacgame::threshold
339 pack $w.fthreshold.l $w.fthreshold.labelt $w.fthreshold.t -side top -anchor w
341 ttk::label $w.finformations.l1 -textvariable ::tacgame::blunderWarningLabel -background linen
342 ttk::label $w.finformations.l3 -textvariable ::tacgame::scoreLabel -foreground WhiteSmoke -background SlateGray
343 pack $w.finformations.l1 $w.finformations.l3 -padx 5 -pady 5 -side top -fill x
350 ttk::button $w.fbuttons.close -textvar ::tr(Abort) -command "destroy .coachWin"
351 pack $w.fbuttons.close -expand yes -fill both -padx 20 -pady 2
355 set ::uci::uciInfo(multipv2) 1
361 bind $w <F1> { helpWindow TacticalGame }
362 bind $w <Destroy> "if {\[string equal $w %W\]} {::tacgame::abortGame}"
363 bind $w <Escape> "destroy .coachWin"
367 set ::playMode "::tacgame::callback"
371 proc callback {cmd} {
373 stop {
destroy .coachWin}
378 proc toggleClocks {} {
393 proc abortGame { { destroyWin 1 } } {
394 catch { unset ::playMode}
395 after cancel ::tacgame::phalanxGo
412 proc launchengine {index n} {
413 global ::tacgame::analysisCoach ::tacgame::level
417 set engineData [
lindex $::engines(list) $index]
418 set analysisName [
lindex $engineData 0]
419 set analysisCommand [
::toAbsPath [
lindex $engineData 1]]
420 set analysisArgs [
lindex $engineData 2]
421 set analysisDir [
::toAbsPath [
lindex $engineData 3]]
426 set easylevel [
expr int(100-(100*($level-1200)/(2200-1200)))]
427 append analysisArgs " -b+ -p- -l- -e $easylevel "
432 if {$analysisDir != "."} {
434 catch {
cd $analysisDir}
438 if {[
catch {
set analysisCoach(pipe$n) [open "| [list $analysisCommand] $analysisArgs" "r+"]} result]} {
439 if {$oldpwd != ""} {
catch {
cd $oldpwd}}
440 tk_messageBox -title "Scid: error starting analysis" \
441 -icon warning -type ok \
442 -message "Unable to start the program:\n$analysisCommand"
448 if {$oldpwd != ""} {
catch {
cd $oldpwd}}
451 fconfigure $analysisCoach(pipe$n) -buffering line -blocking 0
454 fileevent $analysisCoach(pipe$n) readable "::tacgame::processInput"
455 after 1000 "::tacgame::checkAnalysisStarted $n"
464 proc closeEngine {n} {
465 global windowsOS ::tacgame::analysisCoach
469 if {$analysisCoach(pipe$n) == "" } {
479 if {(!$windowsOS) && $analysisCoach(send_sigint$n)} {
480 catch {
exec -- kill -s INT [
pid $analysisCoach(pipe$n)]}
487 catch {
flush $analysisCoach(pipe$n)}
496 catch {
close $analysisCoach(pipe$n)}
498 set analysisCoach(pipe$n) ""
504 proc sendToEngine {n text} {
505 catch {
puts $::tacgame::analysisCoach(pipe$n) $text}
514 proc checkAnalysisStarted {n} {
515 global ::tacgame::analysisCoach
516 if {$analysisCoach(seen$n)} {
return}
526 set analysisCoach(seen$n) 1
542 proc processInput {} {
543 global ::tacgame::analysisCoach ::tacgame::analysis
546 set line [
gets $analysisCoach(pipe1)]
549 if {[
eof $analysisCoach(pipe1)]} {
550 fileevent $analysisCoach(pipe1) readable {}
551 catch {
close $analysisCoach(pipe1)}
552 set analysisCoach(pipe1) ""
553 tk_messageBox -type ok -icon info -parent .main -title "Scid" \
554 -message "The analysis engine 1 terminated without warning; it probably crashed or had an internal error."
557 if {! $analysisCoach(seen1)} {
559 set analysisCoach(seen1) 1
572 proc startAnalyze { } {
573 global ::tacgame::analysisCoach ::tacgame::isLimitedAnalysisTime ::tacgame::analysisTime
575 set ::analysis(waitForReadyOk$n) 1
577 vwait ::analysis(waitForReadyOk$n)
581 if { $isLimitedAnalysisTime == 1 } {
582 after [
expr 1000 * $analysisTime] ::tacgame::stopAnalyze
590 proc stopAnalyze { } {
591 global ::tacgame::analysisCoach ::tacgame::isLimitedAnalysisTime ::tacgame::analysisTime
593 after cancel ::tacgame::stopAnalyze
600 if { [
string index [
sc_game info previousMove] end] == "#"} {
610 global ::tacgame::analysisCoach ::tacgame::openingType ::tacgame::openingMovesList \
611 ::tacgame::openingMovesHash ::tacgame::openingMoves ::tacgame::outOfOpening
613 after cancel ::tacgame::phalanxGo
621 if { $analysisCoach(automoveThinking1) == 1 } {
622 after 1000 ::tacgame::phalanxGo
629 after 1000 ::tacgame::phalanxGo
637 if {$openingType == "specific" && !$outOfOpening} {
640 if { !$outOfOpening } {
641 set ply [
expr [
sc_pos moveNumber] * 2 - 1]
642 if { [
sc_pos side] == "white" } {
643 set ply [
expr $ply - 1]
646 if { [lsearch $openingMovesHash [
sc_pos hash]] == -1 && [
llength $openingMovesList] >= $ply} {
647 set answer [
tk_messageBox -icon question -parent .main -title $::tr(OutOfOpening) -type yesno \
648 -message "$::tr(NotFollowedLine) $openingMoves\n $::tr(DoYouWantContinue)"]
652 after 1000 ::tacgame::phalanxGo
662 set length [
llength $openingMovesHash]
663 for {
set i 0} { $i < [
expr $length-1] } {
incr i} {
664 set h [
lindex $openingMovesHash $i]
666 set index [lsearch $openingMovesHash $h]
667 set move [
lindex $openingMovesList $index]
671 if {$action == "replace"} {
672 if {[
catch {
sc_move addSan $move}]} {}
673 }
elseif {$action == "var"} {
675 if {[
catch {
sc_move addSan $move}]} {}
676 }
elseif {$action == "mainline"} {
678 if {[
catch {
sc_move addSan $move}]} {}
687 after 1000 ::tacgame::phalanxGo
695 set analysisCoach(automoveThinking1) 1
698 after 1000 ::tacgame::phalanxGo
705 set elt [
lrange [
split [
sc_pos fen]] 0 2]
707 if { $elt != [
lindex $::tacgame::lFen end] } {
708 lappend ::tacgame::lFen $elt
710 if { [
llength [lsearch -all $::tacgame::lFen $elt]] >=3 } {
711 tk_messageBox -type ok -message $::tr(Draw) -parent .main -icon info
720 proc makePhalanxMove { input } {
721 global ::tacgame::lscore ::tacgame::analysisCoach ::tacgame::currentPosHash ::tacgame::resignCount
724 if {[
scan $input "my move is %s" move] != 1} {
return 0}
729 if {[
info exists ::tacgame::sc1]} {
730 lappend lscore $::tacgame::sc1
734 if { ( [
getPhalanxColor] == "black" && [
lindex $lscore end] > $::informant("++-") ) || \
735 ( [
getPhalanxColor] == "white" && [
lindex $lscore end] < [
expr 0.0 - $::informant("++-")] ) } {
745 if { [
sc_pos hash] != $currentPosHash} {
751 if { [
sc_pos hash] != $currentPosHash} {
760 if {$action == "replace"} {
761 if {[
catch {
sc_move addSan $move}]} {
763 set lscore [
lreplace $lscore end end]
766 }
elseif {$action == "var"} {
768 if {[
catch {
sc_move addSan $move}]} {
770 set lscore [
lreplace $lscore end end]
773 }
elseif {$action == "mainline"} {
775 if {[
catch {
sc_move addSan $move}]} {
777 set lscore [
lreplace $lscore end end]
783 if { $::tacgame::showevaluation == 1 && [
info exists ::uci::uciInfo(score2)] } {
787 set analysisCoach(automoveThinking1) 0
788 set currentPosHash [
sc_pos hash]
796 if { $resignCount > 3 } {
797 tk_messageBox -type ok -message $::tr(Iresign) -parent .main -icon info
807 proc updateScore { } {
808 if { ! $::tacgame::showevaluation } {
return}
809 if {![
info exists ::uci::uciInfo(score2)]} {
810 set ::tacgame::scoreLabel ""
813 set ::tacgame::scoreLabel "Score: $::uci::uciInfo(score2)"
822 proc updateAnalysisText { } {
823 global ::tacgame::analysisCoach ::tacgame::showblunder ::tacgame::blunderWarningLabel \
824 ::tacgame::showblunder ::tacgame::showblundervalue ::tacgame::showblunderfound ::tacgame::showmovevalue \
825 ::tacgame::showevaluation ::tacgame::lscore ::tacgame::threshold \
826 ::tacgame::lastblundervalue ::tacgame::prev_lastblundervalue ::tacgame::scoreLabel \
827 ::tacgame::blunderpending ::tacgame::prev_blunderpending ::tacgame::sc1
833 set sc1 $::uci::uciInfo(score2)
834 set sc2 [
lindex $lscore end]
838 if {[
llength $lscore] < 2} {
839 set blunderWarningLabel $::tr(Noinfo)
841 if {[
llength $lscore] == 1 && $showevaluation } {
842 set scoreLabel "Score : [
lindex $lscore end]"
850 if { $analysisCoach(automoveThinking1) } {
851 set blunderWarningLabel $::tr(Noinfo)
857 if {[
llength $lscore] >=2} {
860 set lastblundervalue [
expr $sc1-$sc2]
863 if { [
expr abs($sc2)] < $::informant("++-") } {
865 set b [
expr abs($lastblundervalue)]
866 if { $b >= $::informant("?!") && $b < $::informant("?") } {
868 }
elseif { $b >= $::informant("?") && $b < $::informant("??") } {
870 }
elseif { $b >= $::informant("??") } {
875 .coachWin.finformations.l1 configure -background LightCoral
876 if { $showblundervalue } {
877 set tmp $::tr(blunder)
878 append tmp [
format " %+8.2f" [
expr abs($sc1-$sc2)]]
879 set blunderWarningLabel $tmp
882 set blunderWarningLabel "$::tr(blunder) !"
886 .coachWin.finformations.l1 configure -background linen
887 set blunderWarningLabel $::tr(Noblunder)
892 set blunderWarningLabel "---"
895 if { !$showblunder || $analysisCoach(automoveThinking1) } {
896 set blunderWarningLabel "---"
900 if { $showevaluation } {
901 set scoreLabel "Score : $sc1"
911 proc getPhalanxColor {} {
923 set openingList [ list \
924 "$::tr(Reti): 1.Nf3" \
925 "$::tr(English): 1.c4" \
926 "$::tr(d4Nf6Miscellaneous): 1.d4 Nf6" \
927 "$::tr(Trompowsky): 1.d4 Nf6 2.Bg5" \
928 "$::tr(Budapest): 1.d4 Nf6 2.c4 e5" \
929 "$::tr(OldIndian): 1.d4 Nf6 2.c4 d6" \
930 "$::tr(BenkoGambit): 1.d4 Nf6 2.c4 c5 3.d5 b5" \
931 "$::tr(ModernBenoni): 1.d4 Nf6 2.c4 c5 3.d5 e6" \
932 "$::tr(DutchDefence): 1.d4 f5" \
934 "$::tr(Scandinavian): 1.e4 d5" \
935 "$::tr(AlekhineDefence): 1.e4 Nf6" \
936 "$::tr(Pirc): 1.e4 d6" \
937 "$::tr(CaroKann): 1.e4 c6" \
938 "$::tr(CaroKannAdvance): 1.e4 c6 2.d4 d5 3.e5" \
939 "$::tr(Sicilian): 1.e4 c5" \
940 "$::tr(SicilianAlapin): 1.e4 c5 2.c3" \
941 "$::tr(SicilianClosed): 1.e4 c5 2.Nc3" \
942 "$::tr(Sicilian): 1.e4 c5 2.Nf3 Nc6" \
943 "$::tr(Sicilian): 1.e4 c5 2.Nf3 e6" \
944 "$::tr(SicilianRauzer): 1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 Nc6" \
945 "$::tr(SicilianDragon): 1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 g6 " \
946 "$::tr(SicilianScheveningen): 1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 e6" \
947 "$::tr(SicilianNajdorf): 1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 a6" \
948 "$::tr(OpenGame): 1.e4 e5" \
949 "$::tr(Vienna): 1.e4 e5 2.Nc3" \
950 "$::tr(KingsGambit): 1.e4 e5 2.f4" \
951 "$::tr(RussianGame): 1.e4 e5 2.Nf3 Nf6" \
952 "$::tr(OpenGame): 1.e4 e5 2.Nf3 Nc6" \
953 "$::tr(ItalianTwoKnights): 1.e4 e5 2.Nf3 Nc6 3.Bc4" \
954 "$::tr(Spanish): 1.e4 e5 2.Nf3 Nc6 3.Bb5" \
955 "$::tr(SpanishExchange): 1.e4 e5 2.Nf3 Nc6 3.Bb5 a6 4.Bxc6" \
956 "$::tr(SpanishOpen): 1.e4 e5 2.Nf3 Nc6 3.Bb5 a6 4.Ba4 Nf6 5.O-O Nxe4" \
957 "$::tr(SpanishClosed): 1.e4 e5 2.Nf3 Nc6 3.Bb5 a6 4.Ba4 Nf6 5.O-O Be7" \
958 "$::tr(FrenchDefence): 1.e4 e6" \
959 "$::tr(FrenchAdvance): 1.e4 e6 2.d4 d5 3.e5" \
960 "$::tr(FrenchTarrasch): 1.e4 e6 2.d4 d5 3.Nd2" \
961 "$::tr(FrenchWinawer): 1.e4 e6 2.d4 d5 3.Nc3 Bb4" \
962 "$::tr(FrenchExchange): 1.e4 e6 2.d4 d5 3.exd5 exd5" \
963 "$::tr(QueensPawn): 1.d4 d5" \
964 "$::tr(Slav): 1.d4 d5 2.c4 c6" \
965 "$::tr(QGA): 1.d4 d5 2.c4 dxc4" \
966 "$::tr(QGD): 1.d4 d5 2.c4 e6" \
967 "$::tr(QGDExchange): 1.d4 d5 2.c4 e6 3.cxd5 exd5" \
968 "$::tr(SemiSlav): 1.d4 d5 2.c4 e6 3.Nc3 Nf6 4.Nf3 c6" \
969 "$::tr(QGDwithBg5): 1.d4 d5 2.c4 e6 3.Nc3 Nf6 4.Bg5" \
970 "$::tr(QGDOrthodox): 1.d4 d5 2.c4 e6 3.Nc3 Nf6 4.Bg5 Be7 5.e3 O-O 6.Nf3 Nbd7" \
971 "$::tr(Grunfeld): 1.d4 Nf6 2.c4 g6 3.Nc3 d5" \
972 "$::tr(GrunfeldExchange): 1.d4 Nf6 2.c4 g6 3.Nc3 d5 4.cxd5" \
973 "$::tr(GrunfeldRussian): 1.d4 Nf6 2.c4 g6 3.Nc3 d5 4.Nf3 Bg7 5.Qb3" \
974 "$::tr(Catalan): 1.d4 Nf6 2.c4 e6 3.g3 " \
975 "$::tr(CatalanOpen): 1.d4 Nf6 2.c4 e6 3.g3 d5 4.Bg2 dxc4" \
976 "$::tr(CatalanClosed): 1.d4 Nf6 2.c4 e6 3.g3 d5 4.Bg2 Be7" \
977 "$::tr(QueensIndian): 1.d4 Nf6 2.c4 e6 3.Nf3 b6" \
978 "$::tr(NimzoIndian): 1.d4 Nf6 2.c4 e6 3.Nc3 Bb4" \
979 "$::tr(NimzoIndianClassical): 1.d4 Nf6 2.c4 e6 3.Nc3 Bb4 4.Qc2" \
980 "$::tr(NimzoIndianRubinstein): 1.d4 Nf6 2.c4 e6 3.Nc3 Bb4 4.e3" \
981 "$::tr(KingsIndian): 1.d4 Nf6 2.c4 g6" \
982 "$::tr(KingsIndianSamisch): 1.d4 Nf6 2.c4 g6 4.e4 d6 5.f3" \
983 "$::tr(KingsIndianMainLine): 1.d4 Nf6 2.c4 g6 4.e4 d6 5.Nf3"]