11 namespace eval reviewgame {
18 set window ".reviewgame"
22 set moveOfGameIsBest 0
32 array set analysisEngine {}
35 set progressBarTimer 0
42 proc ::reviewgame::start {} {
44 tk_messageBox -type ok -icon warning -title "Scid" -message "This feature require at least one UCI engine"
48 set w $::reviewgame::window
53 ttk::frame $w.fgameinfo
54 set welo [
sc_game tags get WhiteElo]
55 set belo [
sc_game tags get BlackElo]
56 if { $welo == "0"} {
set welo "-"}
57 if { $belo == "0"} {
set belo "-"}
58 ttk::label $w.fgameinfo.l1 -text "[
sc_game tags get White] ($welo) - [
sc_game tags get Black] ($belo)"
59 set result [
sc_game tags get Result]
60 if { $result == "1" } {
set result "1-0"}
61 if { $result == "0" } {
set result "0-1"}
62 if { $result == "=" } {
set result "1/2 - 1/2"}
63 ttk::label $w.fgameinfo.l2 -text "$result"
64 pack $w.fgameinfo.l1 $w.fgameinfo.l2
65 pack $w.fgameinfo -expand 1 -fill both
68 ttk::label $w.fparam.ltime1 -text "[
::tr Time] ([
::tr sec])"
69 ttk::spinbox $w.fparam.time1 -values { 5 10 15 30 45 60 90 120 } -command { set ::reviewgame::timeShort [$::reviewgame::window.fparam.time1 get] } -width 7
70 $w.fparam.time1 set $::reviewgame::timeShort
71 ttk::label $w.fparam.ltime2 -text "[
::tr GameReviewTimeExtended] ([
::tr min])"
72 ttk::spinbox $w.fparam.time2 -values { 1 2 3 4 5} -command { set ::reviewgame::timeExtended [$::reviewgame::window.fparam.time1 get] } -width 7
73 $w.fparam.time2 set $::reviewgame::timeExtended
74 ttk::label $w.fparam.lmargin -text "[
::tr GameReviewMargin]"
75 ttk::spinbox $w.fparam.margin -from 0.1 -to 1.0 -increment 0.1 -command { set ::reviewgame::margin [$::reviewgame::window.fparam.time1 get] } -width 7
76 $w.fparam.margin set $::reviewgame::margin
79 grid $w.fparam.ltime1 -column 0 -row $row -sticky nw
80 grid $w.fparam.time1 -column 1 -row $row -sticky nw
82 grid $w.fparam.ltime2 -column 0 -row $row -sticky nw
83 grid $w.fparam.time2 -column 1 -row $row -sticky nw
85 grid $w.fparam.lmargin -column 0 -row $row -sticky nw
86 grid $w.fparam.margin -column 1 -row $row -sticky nw
89 ttk::checkbutton $w.fparam.cbproceed -text "[
::tr GameReviewAutoContinue]" -variable ::reviewgame::autoProceed
90 grid $w.fparam.cbproceed -column 0 -row $row -columnspan 2 -sticky nw
92 pack $w.fparam -expand 1 -fill both
95 pack $w.finfo -expand 1 -fill both
96 ttk::progressbar $w.finfo.pb -orient horizontal -length 100 -value 0 -mode determinate
97 ttk::label $w.finfo.pblabel -image tb_stop -compound left
98 ttk::label $w.finfo.sc1 -text "-"
99 ttk::label $w.finfo.sc2 -text "-"
100 ttk::label $w.finfo.sc3 -foreground blue -text "-"
101 ttk::button $w.finfo.proceed -textvar ::tr(Continue) -command ::reviewgame::proceed
102 ttk::button $w.finfo.extended -text "[
::tr GameReviewReCalculate]" -command ::reviewgame::extendedTime
105 grid $w.finfo.pb -column 0 -row $row -sticky nw
107 grid $w.finfo.pblabel -column 0 -row $row -sticky nw
109 grid $w.finfo.proceed -column 0 -row $row -sticky nw
110 grid $w.finfo.extended -column 1 -row $row -sticky nw
112 grid $w.finfo.sc1 -column 0 -row $row -columnspan 2 -sticky nw
114 grid $w.finfo.sc2 -column 0 -row $row -columnspan 2 -sticky nw
116 grid $w.finfo.sc3 -column 0 -row $row -columnspan 2 -sticky nw
119 ttk::button $w.finfo.sol -text [
::tr ShowSolution] -command ::reviewgame::showSolution
120 grid $w.finfo.sol -column 0 -row $row -sticky nw
124 ttk::label $w.finfo.stats -text ""
125 grid $w.finfo.stats -column 0 -row $row -sticky nw -columnspan 3
127 ttk::frame $w.fbuttons
128 pack $w.fbuttons -fill x
129 ttk::button $w.fbuttons.close -textvar ::tr(Abort) -command ::reviewgame::endTraining
130 pack $w.fbuttons.close -expand 1 -fill x
134 bind $w <Destroy> "if {\[string equal $w %W\]} {::reviewgame::endTraining}"
135 bind $w <F1> { helpWindow ReviewGame }
137 set ::reviewgame::prevFen [
sc_pos fen]
138 set ::reviewgame::movesLikePlayer 0
139 set ::reviewgame::movesLikeEngine 0
140 set ::reviewgame::numberMovesPlayed 0
147 proc ::reviewgame::callback {cmd} {
149 stop {
destroy $::reviewgame::window}
157 proc ::reviewgame::showSolution {} {
158 set w $::reviewgame::window
159 $w.finfo.sol configure -text "[
sc_game info nextMove]"
160 set ::reviewgame::solutionDisplayed 1
165 proc ::reviewgame::endTraining {} {
166 set w $::reviewgame::window
168 after cancel ::reviewgame::mainLoop
169 set ::reviewgame::bailout 1
170 set ::reviewgame::sequence 0
171 after cancel ::reviewgame::stopAnalyze
183 proc ::reviewgame::isPlayerTurn {} {
193 proc ::reviewgame::abnormalContinuation {} {
201 set ::reviewgame::prevFen [
sc_pos fen]
208 proc ::reviewgame::mainLoop {} {
209 global ::reviewgame::prevScore ::reviewgame::prevLine ::reviewgame::analysisEngine ::reviewgame::nextEngineMove
210 global ::reviewgame::sequence ::reviewgame::useExtendedTime
211 set w $::reviewgame::window
213 after cancel ::reviewgame::mainLoop
215 if { ! [
checkConsistency] } {
puts "ERROR checkConsistency returns false"
return}
217 if { $useExtendedTime } {
218 set ::reviewgame::thinkingTime [
expr $::reviewgame::timeExtended * 60]
220 set ::reviewgame::thinkingTime $::reviewgame::timeShort
225 if { [
sc_game info nextMoveNT] != ""} {
230 $w.finfo.proceed configure -state disabled
231 $w.finfo.sol configure -state disabled
234 if {$sequence == 0} {
235 $w.finfo.sc1 configure -text ""
236 $w.finfo.sc2 configure -text ""
237 set ::reviewgame::movePlayed [
sc_game info nextMoveNT]
238 if {$::reviewgame::movePlayed == ""} {
241 $w.finfo.pblabel configure -image tb_stop -text "[
::tr GameReviewAnalyzingMovePlayedDuringTheGame]"
243 vwait ::reviewgame::sequence
244 if { $::reviewgame::bailout } {
return}
248 if { $sequence == 1 } {
249 $w.finfo.pblabel configure -image tb_stop -text "[
::tr GameReviewAnalyzingThePosition]"
251 vwait ::reviewgame::sequence
252 if { $::reviewgame::bailout } {
return}
255 $w.finfo.pblabel configure -image tb_play -text "[
::tr GameReviewEnterYourMove]"
256 $w.finfo.sol configure -state normal
260 after 1000 ::reviewgame::mainLoop
264 $w.finfo.sol configure -text "[
::tr ShowSolution]"
268 $w.finfo.proceed configure -state normal
269 $w.finfo.extended configure -state normal
271 set ::reviewgame::useExtendedTime 0
272 after 1000 ::reviewgame::mainLoop
277 proc ::reviewgame::checkPlayerMove {} {
278 global ::reviewgame::prevScore ::reviewgame::prevLine ::reviewgame::analysisEngine ::reviewgame::nextEngineMove
279 global ::reviewgame::sequence ::reviewgame::useExtendedTime
280 set w $::reviewgame::window
282 incr ::reviewgame::numberMovesPlayed
286 set user_move [
sc_game info previousMoveNT]
289 if {$user_move != $::reviewgame::movePlayed} {
290 $w.finfo.pblabel configure -image tb_stop -text "[
::tr GameReviewCheckingYourMove]"
291 $w.finfo.sc3 configure -text ""
293 vwait ::reviewgame::sequence
294 if { $::reviewgame::bailout } {
return}
295 $w.finfo.pblabel configure -image tb_stop -text "[
::tr GameReviewYourMoveWasAnalyzed]"
297 $w.finfo.sc3 configure -text "[
::tr GameReviewScoreOfYourMove] : $analysisEngine(score,2)"
301 if {$user_move == $::reviewgame::movePlayed } {
303 set ::reviewgame::sequence 0
305 $w.finfo.sc3 configure -text "[
::tr GameReviewYouPlayedSameMove]" -foreground "sea green"
306 if { ! $::reviewgame::solutionDisplayed } {
307 incr ::reviewgame::movesLikePlayer
317 $w.finfo.sc2 configure -text "[
::tr GameReviewGameMoveScore] : $analysisEngine(score,1) [
::trans $::reviewgame::movePlayed]"
319 $w.finfo.sc1 configure -text "[
::tr GameReviewEngineScore] : $analysisEngine(score,2) [
::trans [
lindex $analysisEngine(moves,2) 0]]"
320 if { $::reviewgame::autoProceed } {
324 $w.finfo.pblabel configure -image tb_play -text ""
326 }
elseif { $user_move == [
lindex $analysisEngine(moves,2) 0] || [
isGoodScore $analysisEngine(score,2) $analysisEngine(score,3)] } {
328 set ::reviewgame::sequence 0
331 if {$user_move == [
lindex $analysisEngine(moves,2) 0]} {
332 $w.finfo.sc3 configure -text "[
::tr GameReviewYouPlayedLikeTheEngine]" -foreground "sea green"
333 incr ::reviewgame::movesLikeEngine
336 $w.finfo.sc3 configure -text "[
::tr GameReviewNotEngineMoveButGoodMove] : [
::trans $user_move] ($analysisEngine(score,3))" -foreground blue
342 $w.finfo.sc2 configure -text "[
::tr GameReviewGameMoveScore] : $analysisEngine(score,1) [
::trans $::reviewgame::movePlayed]"
344 $w.finfo.sc1 configure -text "[
::tr GameReviewEngineScore] $analysisEngine(score,2) [
::trans [
lindex $analysisEngine(moves,2) 0]]"
349 set ::reviewgame::sequence 2
351 $w.finfo.sc3 configure -text "[
::tr GameReviewMoveNotGood] $analysisEngine(score,3) \n([
::trans $analysisEngine(moves,3)])" -foreground red
356 sc_pos setComment "($analysisEngine(score,3))"
357 sc_move addSan $analysisEngine(moves,3)
360 sc_pos setComment "Engine : ($analysisEngine(score,2))"
361 sc_move addSan $analysisEngine(moves,2)
366 $w.finfo.extended configure -state normal
369 $w.finfo.sc2 configure -text "[
::tr GameReviewGameMoveScore] : $analysisEngine(score,1)"
371 $w.finfo.sc1 configure -text "[
::tr GameReviewEngineScore] $analysisEngine(score,2)"
372 set ::reviewgame::sequence 2
381 proc ::reviewgame::updateStats {} {
383 set l $::reviewgame::window.finfo.stats
385 set player [
sc_game info white]
387 set player [
sc_game info black]
390 $l configure -text "[
::tr GameReviewMovesPlayedLike] $player : $::reviewgame::movesLikePlayer / $::reviewgame::numberMovesPlayed\n[
::tr GameReviewMovesPlayedEngine] : $::reviewgame::movesLikeEngine / $::reviewgame::numberMovesPlayed"
395 proc ::reviewgame::isGoodScore {engine player} {
396 global ::reviewgame::margin
399 if {$player >= [
expr $engine - $margin]} {
403 if {$player <= [
expr $engine + $margin]} {
413 proc ::reviewgame::resetValues {} {
414 set ::reviewgame::prevScore 0
415 set ::reviewgame::prevLine ""
416 set ::reviewgame::nextEngineMove ""
417 set ::reviewgame::prevFen ""
418 set ::reviewgame::sequence 0
419 set ::reviewgame::analysisEngine(analyzeMode) 0
420 set ::reviewgame::bailout 0
421 set ::reviewgame::useExtendedTime 0
422 set ::reviewgame::solutionDisplayed 0
429 proc ::reviewgame::launchengine {} {
430 global ::reviewgame::analysisEngine
434 set analysisEngine(analyzeMode) 0
439 foreach e $::engines(list) {
440 if {[
lindex $e 7] != 0} {
446 if { ! $engineFound } {
458 proc ::reviewgame::sendToEngine {text} {
466 proc ::reviewgame::startAnalyze { analysisTime { move "" } } {
467 global ::reviewgame::analysisEngine ::reviewgame::engineSlot
469 set pb $::reviewgame::window.finfo.pb
470 set length [$pb cget -maximum]
471 set ::reviewgame::progressBarTimer [
expr ( $analysisTime * 1000 * $::reviewgame::progressBarStep ) / $length]
472 after $::reviewgame::progressBarTimer ::reviewgame::updateProgressBar
475 if {$analysisEngine(analyzeMode)} {
478 set analysisEngine(analyzeMode) 1
479 after cancel ::reviewgame::stopAnalyze
486 set ::analysis(fen$engineSlot) [
sc_pos fen]
489 set ::analysis(fen$engineSlot) [
sc_pos fen]
494 after [
expr 1000 * $analysisTime] "::reviewgame::stopAnalyze $move"
500 proc ::reviewgame::stopAnalyze { { move "" } } {
501 global ::reviewgame::analysisEngine ::reviewgame::sequence
504 if { ! $analysisEngine(analyzeMode) } {
return}
506 after cancel ::reviewgame::updateProgressBar
507 if { [
winfo exists $::reviewgame::window.finfo.pb]} {
508 $::reviewgame::window.finfo.pb configure -value 0
511 incr ::reviewgame::sequence
512 set pv [
lindex $::analysis(multiPV$::reviewgame::engineSlot) 0]
513 set analysisEngine(score,$sequence) [
lindex $pv 1]
514 set analysisEngine(moves,$sequence) [
lindex $pv 2]
516 set analysisEngine(analyzeMode) 0
522 proc ::reviewgame::proceed {} {
526 set ::reviewgame::prevFen [
sc_pos fen]
527 after 1000 ::reviewgame::mainLoop
532 proc ::reviewgame::extendedTime {} {
535 if { $::reviewgame::analysisEngine(analyzeMode)} {
543 set ::reviewgame::useExtendedTime 1
544 set ::reviewgame::sequence 0
551 proc ::reviewgame::updateProgressBar {} {
552 $::reviewgame::window.finfo.pb step $::reviewgame::progressBarStep
553 after $::reviewgame::progressBarTimer ::reviewgame::updateProgressBar
558 proc ::reviewgame::checkConsistency {} {
560 tk_messageBox -type ok -icon warning -title "Scid" -message "Choose the side BEFORE starting the exercise"
569 proc ::reviewgame::playerCanMove {} {
570 if { ! [
winfo exists $::reviewgame::window] } {
return 1}
574 }
elseif { $::reviewgame::sequence == 2 } {