8 array set ::board::letterToPiece [list \
9 "R" wr "r" br "N" wn "n" bn "B" wb "b" bb \
10 "Q" wq "q" bq "K" wk "k" bk "P" wp "p" bp "." e]
16 { "Blue-white" "#f3f3f3" "#7389b6" "#f3f484" "#b8cbf8" "#ffffff" "#000000" "#000000" "#ffffff" }
17 { "Green-Yellow" "#e0d070" "#70a070" "#b0d0e0" "#bebebe" }
18 { "Brown" "#d0c0a0" "#a08050" "#b0d0e0" "#bebebe" }
19 { "Blue-ish" "#d0e0d0" "#80a0a0" "#b0d0e0" "#f0f0a0" }
20 { "M. Thomas" "#e0d8b8" "#047c24" "#1c80e0" "#fe0000" }
21 { "KM. Skontorp" "#ffdb86" "#ffa200" "#b0d0e0" "#bebebe" }
23 array set newColors {}
25 proc SetBoardTextures {} {
26 global boardfile_dark boardfile_lite
28 image create photo bgl20 -height 20 -width 20
29 image create photo bgd20 -height 20 -width 20
30 if { [
catch { bgl20 copy $boardfile_lite -from 0 0 20 20 bgd20 copy $boardfile_dark -from 0 0 20 20}] } {
31 set boardfile_dark emptySquare
32 set boardfile_lite emptySquare
33 bgl20 copy $boardfile_lite -from 0 0 20 20
34 bgd20 copy $boardfile_dark -from 0 0 20 20
37 set textureSize "[
image height $boardfile_lite].0"
38 foreach size $::boardSizes {
40 image create photo bgl$size -width $size -height $size
41 image create photo bgd$size -width $size -height $size
42 set z [
expr int (ceil ($size / $textureSize))]
43 bgl$size copy $boardfile_lite -zoom $z
44 bgd$size copy $boardfile_dark -zoom $z
52 proc setPieceFont {font} {
54 set dname [
file join $::scidImgDir pieces $font]
55 set fnames [glob -nocomplain -directory $dname *.png]
56 append fnames " " [glob -nocomplain -directory $dname *.gif]
57 foreach {fname} $fnames {
58 if {! [
catch {
image create photo tmpPieces -file "$fname"}]} {
59 set size [
image height tmpPieces]
60 if {[lsearch -exact $::boardSizes $size] == -1} {
61 image create photo e$size -height $size -width $size
63 foreach p {wp wn wb wr wq wk bp bn bb br bq bk} {
64 image create photo $p$size -width $size -height $size
65 $p$size copy tmpPieces -from $x 0 [
expr {$x + $size}] $size
68 lappend ::boardSizes $size
70 image delete tmpPieces
73 if {[
llength $::boardSizes] == 0 && $::boardStyle != "Merida"} {
74 set ::boardStyle "Merida"
78 set ::boardSizes [lsort -integer $::boardSizes]
79 foreach size $::boardSizes {
80 if {$size >= $::boardSize} { break}
90 proc chooseBoardTextures {i} {
91 global boardfile_dark boardfile_lite
93 set prefix [
lindex $::textureSquare $i]
94 set boardfile_dark ${prefix}-d
95 set boardfile_lite ${prefix}-l
103 proc chooseBoardColors {{choice -1}} {
104 global lite dark highcolor bestcolor
105 global colorSchemes newColors
107 set colors {lite dark highcolor bestcolor}
109 set w .boardColorDialog
111 if {[
winfo exists $w]} {
114 set list [
lindex $colorSchemes $choice]
115 set newColors(lite) [
lindex $list 1]
116 set newColors(dark) [
lindex $list 2]
117 set newColors(highcolor) [
lindex $list 3]
118 set newColors(bestcolor) [
lindex $list 4]
120 set nlite $newColors(lite)
121 set ndark $newColors(dark)
123 foreach i {wr bn wb bq wk bp} {
124 $w.bd.$i configure -background $ndark
126 foreach i {br wn bb wq bk wp} {
127 $w.bd.$i configure -background $nlite
129 $w.bd.bb configure -background $newColors(highcolor)
130 $w.bd.wk configure -background $newColors(bestcolor)
132 $w.select.b$i configure -background $newColors($i)
135 foreach i {0 1 2 3} {
137 $c itemconfigure dark -fill $dark -outline $dark
138 $c itemconfigure lite -fill $lite -outline $lite
145 wm title $w "Scid: [
tr OptionsBoardColors]"
147 foreach i $colors {
set newColors($i) [
set $i]}
149 pack [ttk::frame $bd] -side top -expand 1
151 pack [ttk::frame $w.select] -side top -fill x -padx 5
153 pack [ttk::frame $w.preset] -side top -fill x
154 pack [ttk::frame $w.texture] -side top -fill x
156 pack [ttk::frame $w.border] -side top
158 pack [ttk::frame $w.buttons] -side top -fill x
160 foreach psize $::boardSizes {
161 if {$psize >= 40} { break}
164 foreach j {r n b q k p} {
165 ttk::label $bd.w$j -image w${j}$psize
166 ttk::label $bd.b$j -image b${j}$psize
167 grid $bd.b$j -row 0 -column $column
168 grid $bd.w$j -row 1 -column $column
173 foreach row {0 1 0 1} column {0 0 2 2} c {
174 lite dark highcolor bestcolor
176 LightSquares DarkSquares SelectedSquares SuggestedSquares
178 button $f.b$c -image e20 -background [
set $c] -command "
179 set x \[ tk_chooseColor -initialcolor \$newColors($c) -title Scid \]
180 if {\$x != \"\"} { set newColors($c) \$x; chooseBoardColors }
182 ttk::label $f.l$c -text "$::tr($n) "
183 grid $f.b$c -row $row -column $column
184 grid $f.l$c -row $row -column [
expr {$column + 1}] -sticky w
189 foreach i {0 1 2 3} {
190 if {$i != 0} {
pack [ttk::frame $f.gap$i -width 20] -side left -padx 1}
192 ttk::radiobutton $b -text "$i:" -variable newborderwidth -value $i
194 canvas $c -height $psize -width $psize -background black
195 $c create rectangle 0 0 [
expr {20 - $i}] [
expr {20 - $i}] -tag dark
196 $c create rectangle [
expr {20 + $i}] [
expr {20 + $i}] $psize $psize -tag dark
197 $c create rectangle 0 [
expr {20 + $i}] [
expr 20 - $i] $psize -tag lite
198 $c create rectangle [
expr {20 + $i}] 0 $psize [
expr {20 - $i}] -tag lite
199 pack $b $c -side left -padx 1
200 bind $c <Button-1> "set newborderwidth $i"
202 set ::newborderwidth $::borderwidth
205 foreach list $colorSchemes {
206 set f $w.preset.p$count
207 pack [ttk::frame $f] -side left -padx 5
208 ttk::label $f.blite -image bp$psize -background [
lindex $list 1]
209 ttk::label $f.bdark -image bp$psize -background [
lindex $list 2]
210 ttk::label $f.wlite -image wp$psize -background [
lindex $list 1]
211 ttk::label $f.wdark -image wp$psize -background [
lindex $list 2]
212 ttk::button $f.select -text [
expr {$count + 1}] -command "chooseBoardColors $count ; \
213 set ::boardfile_dark emptySquare ; \
214 set ::boardfile_lite emptySquare ; \
216 foreach i {blite bdark wlite wdark} {
217 bind $f.$i <1> "chooseBoardColors $count ; \
218 set ::boardfile_dark emptySquare ; \
219 set ::boardfile_lite emptySquare ; \
222 grid $f.blite -row 0 -column 0 -sticky e
223 grid $f.bdark -row 0 -column 1 -sticky w
224 grid $f.wlite -row 1 -column 1 -sticky w
225 grid $f.wdark -row 1 -column 0 -sticky e
226 grid $f.select -row 2 -column 0 -columnspan 2
235 foreach tex $::textureSquare {
236 set f $w.texture.p$count
237 grid [ ttk::frame $f] -row $row -column $col -padx 5
238 canvas $f.c -width [
expr $psize*2] -height [
expr $psize*2] -background red
239 $f.c create image 0 0 -image ${tex}-l -anchor nw
240 $f.c create image $psize 0 -image ${tex}-d -anchor nw
241 $f.c create image 0 $psize -image ${tex}-d -anchor nw
242 $f.c create image $psize $psize -image ${tex}-l -anchor nw
244 $f.c create image 0 0 -image bp$psize -anchor nw
245 $f.c create image $psize 0 -image wp$psize -anchor nw
246 $f.c create image 0 $psize -image wp$psize -anchor nw
247 $f.c create image $psize $psize -image bp$psize -anchor nw
248 ttk::button $f.select -text [
expr {$count + 1}] -command "chooseBoardTextures $count"
249 bind $f.c <1> "chooseBoardTextures $count"
250 pack $f.c $f.select -side top
254 if {$col > 4} {
set col 0
incr row}
258 foreach i {lite dark highcolor bestcolor} {
259 set \$i \$newColors(\$i)
261 set borderwidth \$newborderwidth
262 ::board::border .main.board \$borderwidth
267 -command "catch {grab release $w}; destroy $w"
268 bind $w <Escape> "catch {grab release $w}; destroy $w"
275 namespace eval ::board {
280 variable squareIndex [list a1 b1 c1 d1 e1 f1 g1 h1 a2 b2 c2 d2 e2 f2 g2 h2 \
281 a3 b3 c3 d3 e3 f3 g3 h3 a4 b4 c4 d4 e4 f4 g4 h4 \
282 a5 b5 c5 d5 e5 f5 g5 h5 a6 b6 c6 d6 e6 f6 g6 h6 \
283 a7 b7 c7 d7 e7 f7 g7 h7 a8 b8 c8 d8 e8 f8 g8 h8]
291 proc ::board::sq {sqname} {
293 return [lsearch -exact $squareIndex $sqname]
306 proc ::board::san {sqno} {
307 if {($sqno < 0) || ($sqno > 63)} {
return}
308 return [
format %c%c \
309 [
expr {($sqno % 8) + [scan a %c]}] \
310 [
expr {($sqno / 8) + [scan 1 %c]}]]
317 proc ::board::new {w {psize 40} } {
318 if {[
winfo exists $w]} {
return}
320 foreach size $::boardSizes {
321 if {$size >= $psize} { break}
325 set ::board::_size($w) $psize
326 set ::board::_border($w) $::borderwidth
327 set ::board::_coords($w) 2
328 set ::board::_flip($w) 0
329 set ::board::_data($w) [
sc_pos board]
330 set ::board::_showMarks($w) 0
331 set ::board::_mark($w) {}
332 set ::board::_drag($w) -1
333 set ::board::_showmat($w) 0
335 set border $::board::_border($w)
336 set bsize [
expr {$psize * 8 + $border * 9}]
338 ttk::frame $w -class Board
339 canvas $w.bd -width $bsize -height $bsize -cursor crosshair -borderwidth 0 -highlightthickness 0
341 catch {
grid anchor $w center}
344 grid $w.bd -row [
expr $startrow +1] -column 3 -rowspan 8 -columnspan 8
348 for {
set i 0} {$i < 64} {
incr i} {
349 set xi [
expr {$i % 8}]
350 set yi [
expr {int($i/8)}]
351 set x1 [
expr {$xi * ($psize + $border) + $border }]
352 set y1 [
expr {(7 - $yi) * ($psize + $border) + $border }]
353 set x2 [
expr {$x1 + $psize }]
354 set y2 [
expr {$y1 + $psize }]
356 $bd create rectangle $x1 $y1 $x2 $y2 -tag sq$i -outline ""
360 for {
set i 1} {$i <= 8} {
incr i} {
361 ttk::label $w.lrank$i -text [
expr {9 - $i}]
362 grid $w.lrank$i -row [
expr $startrow + $i] -column 2 -sticky e -padx 5
363 ttk::label $w.rrank$i -text [
expr {9 - $i}]
364 grid $w.rrank$i -row [
expr $startrow + $i] -column 11 -sticky w -padx 5
366 foreach i {1 2 3 4 5 6 7 8} file {a b c d e f g h} {
367 ttk::label $w.tfile$file -text $file
368 grid $w.tfile$file -row $startrow -column [
expr $i + 2] -sticky s
369 ttk::label $w.bfile$file -text $file
370 grid $w.bfile$file -row [
expr $startrow + 9] -column [
expr $i + 2] -sticky n
373 canvas $w.mat -width 20 -height $bsize -highlightthickness 0
375 grid $w.mat -row 6 -column 12 -rowspan 8 -pady 5 -padx 5
383 proc ::board::addNamesBar {w {varname}} {
385 frame $w.playerW -background $bgcolor
386 frame $w.playerW.color -background #EAE0C8 -width 6 -height 6
387 canvas $w.playerW.tomove -borderwidth 0 -background $bgcolor -highlightthickness 0 -width 9 -height 9
388 label $w.playerW.name -textvariable ${varname}(nameW) -background $bgcolor -font font_SmallBold
389 label $w.playerW.elo -textvariable ${varname}(eloW) -background $bgcolor -font font_Small
390 label $w.playerW.clock -textvariable ${varname}(clockW) -background $bgcolor -font font_Small
391 grid $w.playerW.color -row 0 -column 0 -sticky news -padx 2 -pady 2
392 grid $w.playerW.name -row 0 -column 1 -sticky w
393 grid $w.playerW.elo -row 0 -column 2 -sticky w
394 grid $w.playerW.clock -row 0 -column 3 -sticky e
395 grid $w.playerW.tomove -row 0 -column 4 -sticky w -padx 4
396 grid columnconfigure $w.playerW 3 -weight 1
397 grid $w.playerW -row 16 -column 3 -columnspan 8 -sticky news -pady 4
399 frame $w.playerB -background $bgcolor
400 frame $w.playerB.color -background black -width 6 -height 6
401 canvas $w.playerB.tomove -borderwidth 0 -background $bgcolor -highlightthickness 0 -width 9 -height 9
402 label $w.playerB.name -textvariable ${varname}(nameB) -background $bgcolor -font font_SmallBold
403 label $w.playerB.elo -textvariable ${varname}(eloB) -background $bgcolor -font font_Small
404 label $w.playerB.clock -textvariable ${varname}(clockB) -background $bgcolor -font font_Small
405 grid $w.playerB.color -row 0 -column 0 -sticky news -padx 2 -pady 2
406 grid $w.playerB.name -row 0 -column 1 -sticky w
407 grid $w.playerB.elo -row 0 -column 2 -sticky w
408 grid $w.playerB.clock -row 0 -column 3 -sticky e
409 grid $w.playerB.tomove -row 0 -column 4 -sticky w -padx 4
410 grid columnconfigure $w.playerB 3 -weight 1
411 grid $w.playerB -row 3 -column 3 -columnspan 8 -sticky news -pady 4
414 proc ::board::addInfoBar {w varname} {
417 $w.bar.info.t tag configure header -font font_Bold
418 $w.bar.info.t tag bind click <Any-Enter> "$w.bar.info.t configure -cursor hand2"
419 $w.bar.info.t tag bind click <Any-Leave> "$w.bar.info.t configure -cursor {}"
420 grid propagate $w.bar.info 0
421 ttk::button $w.bar.back -image tb_BD_Back -style Toolbutton
422 ttk::button $w.bar.forward -image tb_BD_Forward -style Toolbutton
424 ttk::button $w.bar.cmd -image tb_BD_ShowToolbar -style Toolbutton \
425 -command "::board::updateToolBar_ $menu $varname $w.bar.cmd"
426 grid $w.bar.back -row 0 -column 0 -sticky news
427 grid $w.bar.cmd -in $w.bar -row 0 -column 1 -sticky news -padx 8
428 grid $w.bar.info -in $w.bar -row 0 -column 2 -sticky news
429 grid $w.bar.forward -row 0 -column 4 -sticky news
430 grid columnconfigure $w.bar 2 -weight 1
431 grid $w.bar -row 20 -column 3 -columnspan 8 -sticky news -pady 4
434 proc ::board::addInfo {{w} {msg}} {
435 if {$msg eq ""} {
return}
436 $w.bar.info.t configure -state normal
437 $w.bar.info.t insert end "\n$msg"
438 $w.bar.info.t configure -state disabled
441 proc ::board::setInfo {{w} {msg}} {
442 $w.bar.info.t configure -state normal
443 $w.bar.info.t delete 1.0 end
444 $w.bar.info.t insert end "$msg"
445 $w.bar.info.t configure -state disabled
448 proc ::board::setInfoAlert {{w} {header} {msg} {msgcolor} {cmd}} {
449 $w.bar.info.t configure -state normal
450 $w.bar.info.t delete 1.0 end
451 $w.bar.info.t insert end "$header " {header click}
452 $w.bar.info.t insert end "$msg" {color click}
453 $w.bar.info.t configure -state disabled
454 $w.bar.info.t tag configure color -foreground $msgcolor
455 $w.bar.info.t tag bind click <ButtonRelease-1> "
456 if {[
winfo exists $cmd]} {
457 after idle \"tk_popup $cmd %X \[expr -10 + %Y - \[winfo reqheight $cmd\] \]\"
464 set ::board::repeatCmd 400
465 proc ::board::setButtonCmd {{w} {button} {cmd}} {
467 $w.bar.$button configure -state disabled
469 $w.bar.$button configure -state normal
470 ::bind $w.bar.$button <ButtonPress-1> "
472 set ::board::repeatCmd \[expr int(\$::board::repeatCmd *0.8)\]
473 after \$::board::repeatCmd \"event generate $w.bar.$button <ButtonPress-1>\"
475 ::bind $w.bar.$button <Any-Leave> "
476 after cancel \"event generate $w.bar.$button <ButtonPress-1>\"
477 set ::board::repeatCmd 400
479 ::bind $w.bar.$button <ButtonRelease-1> "
480 after cancel \"event generate $w.bar.$button <ButtonPress-1>\"
481 set ::board::repeatCmd 400
486 proc ::board::updateToolBar_ {{menu} {varname} {mb ""} } {
488 set i [$menu index end]
491 catch {
set idx [
lindex [$menu entryconfigure $i -image] 4]}
492 if {[
info exists "${varname}($idx)"] } {
493 $menu entryconfigure $i -foreground black -command "eval \$::${varname}($idx)"
495 catch { $menu entryconfigure $i -foreground gray -command ""}
500 set x [
winfo rootx $mb]
501 set y [
winfo rooty $mb]
502 set bh [
winfo height $mb]
503 set mh [
winfo reqheight $menu]
504 if {$y >= $mh} {
incr y -$mh} {
incr y $bh}
509 proc ::board::newToolBar_ {{w} {varname}} {
512 set m [
menu $w.menu_back -bg white -font font_Regular]
513 $m add command -label " [
tr BackToMainline]" -image tb_BD_BackToMainline -compound left
514 $m add command -label " [
tr EditDelete]" -image tb_BD_VarDelete -compound left
515 $m add command -label " [
tr LeaveVariant]" -image tb_BD_VarLeave -compound left
516 $m add command -label " [
tr GameStart]" -image tb_BD_Start -compound left -accelerator "<home>"
517 ::bind $w.bar.back <ButtonRelease-$::MB3> "::board::updateToolBar_ $m $varname %W"
519 set m [
menu $w.menu_forw -bg white -font font_Regular]
520 $m add command -label " [
tr Autoplay]" -image tb_BD_Autoplay -compound left
521 $m add command -label " [
tr GameEnd]" -image tb_BD_End -compound left -accelerator "<end>"
522 ::bind $w.bar.forward <ButtonRelease-$::MB3> "::board::updateToolBar_ $m $varname %W"
524 set m [
menu $w.menu -bg white -font font_Regular]
525 $m add command -label " [
tr EditSetup]" -image tb_BD_SetupBoard -compound left
526 $m add command -label " [
tr IERotate]" -image tb_BD_Flip -compound left
527 $m add command -label " [
tr ShowHideCoords]" -image tb_BD_Coords -compound left
528 $m add command -label " [
tr ShowHideMaterial]" -image tb_BD_Material -compound left
529 $m add command -label " [
tr FullScreen]" -image tb_BD_Fullscreen -compound left
530 set ${varname}(tb_BD_Flip) "::board::flip $w"
531 set ${varname}(tb_BD_Coords) "::board::coords $w"
532 set ${varname}(tb_BD_Material) "::board::toggleMaterial $w"
533 set ${varname}(tb_BD_Fullscreen) { wm attributes . -fullscreen [expr ![wm attributes . -fullscreen] ] }
538 proc ::board::flipNames_ { {w} {white_on_top} } {
539 if {![
winfo exist $w.playerW] } {
return}
541 grid $w.playerW -row 3
542 grid $w.playerB -row 16
544 grid configure $w.playerW -row 16
545 grid configure $w.playerB -row 3
549 proc ::board::sideToMove_ { {w} {side} } {
550 if {![
winfo exist $w.playerW] } {
return}
552 $w.playerB.tomove delete -tag tomove
553 $w.playerW.tomove create rectangle 0 0 100 100 -fill blue -tag tomove
554 }
elseif {$side == "b"} {
555 $w.playerW.tomove delete -tag tomove
556 $w.playerB.tomove create rectangle 0 0 100 100 -fill blue -tag tomove
566 proc ::board::defaultColor {sq} {
567 return [
expr {($sq + ($sq / 8)) % 2 ? "$::lite" : "$::dark"}]
573 proc ::board::size {w} {
574 return $::board::_size($w)
577 proc ::board::resizeAuto {w bbox} {
578 set availw [
lindex $bbox 2]
579 set availh [
lindex $bbox 3]
580 set extraw [
expr [
winfo reqwidth $w] - $::board::_size($w) * 8]
581 set extrah [
expr [
winfo reqheight $w] - $::board::_size($w) * 8]
582 set availw [
expr $availw - $extraw]
583 set availh [
expr $availh - $extrah]
584 set maxSize [
expr {$availh < $availw ? $availh : $availw}]
585 set maxSize [
expr $maxSize / 8]
588 foreach size $::boardSizes {
589 if {$size <= $maxSize && $size > $newSize} {
set newSize $size}
601 proc ::board::resize {w psize} {
604 set oldsize $::board::_size($w)
605 if {$psize == $oldsize} {
return $oldsize}
606 if {$psize == "redraw"} {
set psize $oldsize}
607 if {$psize == "-1"} {
608 set index [lsearch -exact $boardSizes $oldsize]
609 if {$index == 0} {
return $oldsize}
611 set psize [
lindex $boardSizes $index]
612 }
elseif {$psize == "+1"} {
613 set index [lsearch -exact $boardSizes $oldsize]
615 if {$index == [
llength $boardSizes]} {
return $oldsize}
616 set psize [
lindex $boardSizes $index]
620 if {[lsearch -exact $boardSizes $psize] < 0} {
return $oldsize}
622 set border $::board::_border($w)
623 set bsize [
expr {$psize * 8 + $border * 9}]
625 $w.bd configure -width $bsize -height $bsize
626 set ::board::_size($w) $psize
629 for {
set i 0} {$i < 64} {
incr i} {
630 set xi [
expr {$i % 8}]
631 set yi [
expr {int($i/8)}]
632 set x1 [
expr {$xi * ($psize + $border) + $border }]
633 set y1 [
expr {(7 - $yi) * ($psize + $border) + $border }]
634 set x2 [
expr {$x1 + $psize }]
635 set y2 [
expr {$y1 + $psize }]
637 if {$::board::_flip($w)} {
set pos [
expr {63 - $i}]}
638 $w.bd coords sq$pos $x1 $y1 $x2 $y2
642 $w.mat configure -height $bsize
655 proc ::board::border {w {border ""}} {
657 return $::board::_border($w)
659 set ::board::_border($w) $border
669 proc ::board::getSquare {w x y} {
670 if {[
winfo containing $x $y] != "$w.bd"} {
673 set x [
expr {$x - [winfo rootx $w.bd]}]
674 set y [
expr {$y - [winfo rooty $w.bd]}]
675 set psize $::board::_size($w)
676 set border $::board::_border($w)
677 set x [
expr {int($x / ($psize+$border))}]
678 set y [
expr {int($y / ($psize+$border))}]
680 if {$x < 0 || $y < 0 || $x > 7 || $y > 7} {
683 set sq [
expr {(7-$y)*8 + $x}]
684 if {$::board::_flip($w)} {
set sq [
expr {63 - $sq}]}
692 proc ::board::showMarks {w value} {
693 set ::board::_showMarks($w) $value
701 proc ::board::colorSquare {w i {color ""}} {
702 if {$i < 0 || $i > 63} {
return}
704 $w.bd itemconfigure br$i -state hidden
708 if { $::glossOfDanger } {
709 array set attacks [
sc_pos attacks]
710 if {[
info exists attacks($i)]} {
711 set color $attacks($i)
714 foreach mark $::board::_mark($w) {
715 if {[
lindex $mark 1] == $i && [
lindex $mark 0] == "full"} {
716 set color [
lindex $mark 3]
720 $w.bd itemconfigure br$i -state $brstate
722 $w.bd itemconfigure sq$i -fill $color -outline ""
729 proc ::board::midSquare {w sq} {
730 set c [$w.bd coords sq$sq]
734 set psize $::board::_size($w)
735 if { $psize % 2 } {
set psize [
expr {$psize - 1}]}
736 set x [
expr {[lindex $c 0] + $psize/2}]
737 set y [
expr {[lindex $c 1] + $psize/2}]
755 proc ::board::setmarks {w cmds} {
756 set ::board::_mark($w) {}
760 if {$dest != -1} {
lset cmd 2 $dest}
761 lappend ::board::_mark($w) $cmd
767 namespace eval ::board::mark {
768 namespace import [
namespace parent]::sq
773 variable StartTag {\[%}
774 variable ScidKey {mark|arrow}
775 variable Command {draw}
776 variable Type {full|square|arrow|circle|disk|tux}
777 variable Text {[-+=?!A-Za-z0-9]}
778 variable Square {[a-h][1-8]\M}
779 variable Color {[\w#][^]]*\M}
783 variable ScidCmdRegex \
784 "$StartTag # leading tag
785 ($ScidKey)\\\ + # (old) command name + space chars
786 ($Square) # mandatory square (e.g. 'a4')
787 (?:\\ +($Square))? # optional: another (destination) square
788 (?:\\ *($Color))? # optional: color name
789 $EndTag # closing tag
793 variable StdCmdRegex \
794 "${StartTag} # leading tag
795 ${Command} # command name
796 \\ # a space character
797 (?:(${Type}|$Text),)? # keyword, e.g. 'arrow' (may be omitted)
798 # or single char (indicating type 'text')
799 ($Square) # mandatory square (e.g. 'a4')
800 (?:,($Square))? # optional: (destination) square
801 (?:,($Color))? # optional: color name
802 $EndTag # closing tag
806 variable CBSquare {csl}
807 variable CBarrow {cal}
808 variable CBColor {[GRY]}
809 variable Square {[a-h][1-8]\M}
810 variable sqintern {[a-h][1-8]}
812 variable CBSquareRegex \
817 (?:,($CBColor)($Square))?
821 variable CBArrowRegex \
852 proc ::board::mark::getEmbeddedCmds {comment} {
853 if {$comment == ""} {
return}
854 variable ScidCmdRegex
856 variable CBSquareRegex
857 variable CBArrowRegex
862 foreach r [list $ScidCmdRegex $StdCmdRegex $CBSquareRegex $CBArrowRegex] {
863 if {[
string equal $regex ""]} {
set regex $r}
else {
append regex "|$r"}
865 set locateScript {regexp -expanded -indices -start $start \
866 $regex $comment indices}
870 for {
set start 0} {[
eval $locateScript]} {
incr start} {
871 foreach {first last} $indices {}
872 foreach re [list $ScidCmdRegex $StdCmdRegex $CBSquareRegex $CBArrowRegex] {
874 if {![regexp -expanded $re [
string range $comment $first $last] \
875 match type arg1 arg2 color]} {
879 if {[
string equal $type "csl"] || [
string equal $type "cal"]} {
886 if {[
string equal $type "csl"]} {
set type "full"}
887 if {[
string equal $type "cal"]} {
set type "arrow"}
888 if {[
string equal $color "R"]} {
set color "red"}
889 if {[
string equal $color "G"]} {
set color "green"}
890 if {[
string equal $color "Y"]} {
set color "yellow"}
893 if {[
string equal $color ""]} {
set color "red"}
894 switch -glob -- $type {
895 "" {
set type [
expr {[string length $arg2] ? "arrow" : "full"}]}
897 ? {
if {[
string length $arg2]} break
else {
898 set arg2 $type
set type "text"}
902 lappend result [list $type $arg1 $arg2 $color]
903 lappend result $indices
922 proc ::board::mark::remove {win args} {
923 if {[
llength $args] == 2} {
924 eval add $win arrow $args nocolor 1
926 add $win DEL [
lindex $args 0] "" nocolor 1
948 proc ::board::mark::add {win args} {
950 if {[
string length [
lindex $args 0]] == 1} {
952 set args [
linsert $args 1 "text"]
953 set args [
linsert [
lrange $args 1 end] 2 [
lindex $args 0]]
956 if {![regexp true|false|1|0 [
lindex $args end]]} {
959 if {[
llength $args] == 4} {
set args [
linsert $args 2 ""]}
962 foreach {type square dest color new} $args {break}
963 if {[
llength $args] != 5 } {
return}
966 set type [
lindex $args 0]
969 if {$type == "arrow"} {
970 $board delete "mark${square}:${dest}" "mark${dest}:${square}"
971 if {[
string equal $color "nocolor"]} {
set type DEL}
973 $board delete "mark${square}"
983 set drawingScript "Draw[
string totitle $type]"
984 if {![
llength [
info procs $drawingScript]]} {
return}
987 if {[
catch {
eval $drawingScript $board $square $dest $color}]} {
992 if {$new} {
lappend ::board::_mark($win) [
lrange $args 0 end-1]}
1014 proc ::board::mark::DrawCircle {pathName square color} {
1019 set box [
GetBox $pathName $square $size]
1020 lappend pathName create oval [
lrange $box 0 3] \
1021 -tag [list mark circle mark$square p$square]
1024 lappend pathName -fill $color
1026 set width [
expr {[lindex $box 4] * $width}]
1027 if {$width <= 0.0} {
set width 1.0}
1028 lappend pathName -fill "" -outline $color -width $width
1035 proc ::board::mark::DrawDisk {pathName square color} {
1039 set box [
GetBox $pathName $square $size]
1041 {create oval [lrange $box 0 3]} \
1043 {-tag [list mark disk mark$square p$square]}
1048 proc ::board::mark::DrawText {pathName square char color {size 0} {shadowColor ""}} {
1049 set box [
GetBox $pathName $square 0.8]
1050 set len [
expr {($size > 0) ? $size : int([lindex $box 4])}]
1051 set x [
lindex $box 5]
1052 set y [
lindex $box 6]
1053 $pathName delete text$square mark$square
1054 if {$shadowColor!=""} {
1056 create text [
expr $x+1] [
expr $y+1] -fill $shadowColor \
1057 {-font [list helvetica $len bold]} \
1058 {-text [string index $char 0]} \
1060 {-tag [list mark text text$square mark$square p$square]}
1064 create text $x $y -fill $color \
1065 {-font [list helvetica $len bold]} \
1066 {-text [string index $char 0]} \
1068 {-tag [list mark text text$square mark$square p$square]}
1073 proc ::board::mark::DrawArrow {pathName from to color} {
1074 if {$from < 0 || $from > 63} {
return}
1075 if {$to < 0 || $to > 63} {
return}
1078 {create line $coord} \
1079 -fill $color -arrow last -width 2 \
1080 {-tag [list mark arrows "mark${from}:${to}"]}
1085 proc ::board::mark::DrawRectangle { pathName square color pattern } {
1086 if {$square < 0 || $square > 63} {
return}
1088 $pathName create rectangle [
lindex $box 0] [
lindex $box 1] [
lindex $box 2] [
lindex $box 3] \
1089 -outline $color -width $::highlightLastMoveWidth -dash $pattern -tag highlightLastMove
1094 image create photo tux16x16 -data \
1095 {R0lGODlhEAAQAPUyAAAAABQVFiIcBi0tLTc0Kj4+PkQ3CU9ADVVFD1hJFV1X
1096 P2pXFWJUKHttLnttOERERVVWWWRjYWlqcYNsGJR5GrSUIK6fXsKdGMCdI8er
1097 ItCuNtm2KuS6KebAKufBOvjJIfnNM/3TLP/aMP/lM+/We//lQ//jfoGAgJaU
1098 jpiYmqKipczBmv/wk97e3v//3Ojo6f/96P7+/v///wAAAAAAAAAAAAAAAAAA
1099 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEBADIALAAAAAAQABAAAAbm
1100 QJlMJpMBAAAAQCaTyWQymUwmAwQAAQAAIJPJZDKZTCYDQCInCQAgk8lkMplM
1101 JgMwOBoHACCTyYAymUwmkwEao5IFAADIZDKZTCaTAVQu2GsAAMhkMplMJgMU
1102 YrFY7AQAAGQymUwmA6RisVjsFQAAATKZTCYDBF6xWCwWewAAAJlMJjMoYrFY
1103 LBaDAAAAmUwW+oBWsVgsxlokFgCZTBYChS6oWCxmAn5CHYNMJhOJQiFS7JXS
1104 iEQjCkAmw3BCow0hAMiMNggAQCYDAAyTAwAASEwEAABAJpPJAAAAAACUAQAA
1106 set ::board::mark::tux16x16 tux16x16
1108 image create photo tux32x32 -data \
1109 {R0lGODlhIAAgAPU0AAAAABANAxERESAaBiwkCDAnCSQkJEM2DEA3GVBBDllJ
1110 EFNKLG5aFHBbFHpkFnZoMkBAQFBQUGBgYHBwcIBpF4xyGZ+DHZ+GKqmKHq+T
1111 Lb+hNsynJNSuJtu0J9+6NeW8Kc+wQPnMLPTJMP7QLv/UO//aVf/dYv/ifIiI
1112 hp+fn6+vr7+/v//lif/ol//rpM/Pz9/f3//22O/u6v/55f///////wAAAAAA
1113 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEBADUALAAAAAAgACAAAAb+
1114 wFqtVqvVarVarQYAAAAAAABQq9VqtVqtVqvVarVarVar1Wq1Wg0AAAAAAAAA
1115 AKjVarVarVar1YC1Wq1Wq9VqtVqtBgAAAAAAAAAAAGq1Wq1Wq9VqtVqtVqvV
1116 arVaDQAAAAAAAAAAAABqtVqtVqsBa7VarVar1Wq1Wq0GMMgighdtAgAAALVa
1117 rVar1Wq1Wq1Wq9VqtVqtBphEUpCUQQUAAAC1Wq1WA9ZqtVqtVqvVarVarVYD
1118 RBYejwahAgAAgFqtVqvVarVarVar1Wq1Wq1WAxRIIdFolAEAAABArQas1Wq1
1119 Wq1Wq9VqtVqtVqvVGqPRaDTSAAAAAKBWq9VqtVr+rVar1Wq1Wq1Wq9UMp9Fo
1120 xJIJAAAAAFir1Wq1Wq1Wq9VqtVqtVqvVABGaqzWj0SYAAAAAqNVqtVqtVqvV
1121 arVarVarAQQyGo1Go9FgAAAQAAAAarVarVar1Wq1Wq1WqwEAExqNRqPRaDSD
1122 AAAAAGq1Wq1Wq9VqtVqtVqsBAC8ajUaj0Wg0oAoAAAAAgFqtVqvVarVarVar
1123 AQACGo1Go9FoNBpNAAAAAIBarVar1Wq1Wq1WqwEAKhqNRqPRaEAajYYCAAAA
1124 AKBWq9VqtVqtVqvVAAIajUaj0Wg0Go22AgAAAACgVqvVarVarVarAQARGo1G
1125 o9GANBqNRpMBAAAAAAD+qNVqtVqtVqvVAAAUjUaj0Wg0Go1GowkAAAAAAKjV
1126 arVarVar1QgUFI1GowFpNBqNRqPRDAZDAAAA1Gq1Wq1Wq9VGo1HpRaPRaDQa
1127 jUY7iQAAwUMBANRqtVqtVhuFRqPR6LIC0mg0Go1Go5lGiYBlVAEAarVarVar
1128 jUaj0Wg0KqRoNBqNRqOZRqPRaPQBAGq1Wq1Wq41Go9FoBBxtADIajUaj0Uyj
1129 0Wg0Gn0YgFqtVqvVRqPRaDQajVw0Go1Go6VGo9FoNBqNOABArVar1Uaj0Qg4
1130 Go1GoxiNRntFBqPRaDQajT4KAKBWq9Vqo9FoNBqNRiOHASIAAAqj0Wg0CmGW
1131 AAAAoFar1WoYDlAUGo1Go1FFAAAAAInRaDT6EAAAAABQq9VqNQAAAHB0QqNO
1132 AQAAAACA0Gi0AQAAAECtVqvVajUgAAAAAAAAAAAAAAAAAAAAAAAAAIBarVar
1133 1Wq1Wq1WqwEAAAAAAKjVarUaAAAAAAC1Wq1Wq9VqwFqtVqvVarVarVar1Wq1
1134 Wq1Wq9VqtVqtVqvVarUgADs=
1136 set ::board::mark::tux32x32 tux32x32
1138 proc ::board::mark::DrawTux {pathName square discard} {
1142 for {
set len [
expr {int([lindex $box 4])}]} {$len > 0} {
incr len -1} {
1143 if {[
info exists tux${len}x${len}]} break
1146 $pathName create image [
lrange $box 5 6] \
1147 -image tux${len}x${len} \
1148 -tag [list mark "mark$square" tux]
1168 proc ::board::mark::GetArrowCoords {board from to {shrink 0.6}} {
1169 if {$shrink < 0.0} {
set shrink 0.0}
1170 if {$shrink > 1.0} {
set shrink 1.0}
1173 set fromXY [
GetBox $board $from]
1174 set toXY [
GetBox $board $to]
1177 foreach {x0 y0} [
lrange $fromXY 5 6] {x1 y1} [
lrange $toXY 5 6] {break}
1178 set dX [
expr {$x1 - $x0}]
1179 set dY [
expr {$y1 - $y0}]
1182 if {($shrink == 0.0) || ($dX == 0.0 && $dY == 0.0)} {
1183 return [list $x0 $y0 $x1 $y1]
1187 if {abs($dX) > abs($dY)} {
1188 set edge [
expr {($dX > 0) ? [lindex $fromXY 2] : [lindex $fromXY 0]}]
1189 set lambda [
expr {($edge - $x0) / $dX}]
1191 set edge [
expr {($dY > 0) ? [lindex $fromXY 3] : [lindex $fromXY 1]}]
1192 set lambda [
expr {($edge - $y0) / $dY}]
1197 set maxShrinkForAdjacent 0.667
1198 if {$shrink > $maxShrinkForAdjacent} {
1199 set dFile [
expr {($to % 8) - ($from % 8)}]
1200 set dRank [
expr {($from / 8) - ($to / 8)}]
1201 if {(abs($dFile) <= 1) && (abs($dRank) <= 1)} {
1202 set shrink $maxShrinkForAdjacent
1207 set shrink [
expr {$shrink * $lambda}]
1208 return [list [
expr {$x0 + $shrink * $dX}] [
expr {$y0 + $shrink * $dY}]\
1209 [
expr {$x1 - $shrink * $dX}] [
expr {$y1 - $shrink * $dY}]]
1226 proc ::board::mark::GetBox {pathName square {portion 1.0}} {
1227 set coord [$pathName coords sq$square]
1228 set len [
expr {[lindex $coord 2] - [lindex $coord 0]}]
1229 if {$portion < 1.0} {
1230 set dif [
expr {$len * (1.0 -$portion) * 0.5}]
1231 foreach i {0 1} {
lappend box [
expr {[lindex $coord $i] + $dif}]}
1232 foreach i {2 3} {
lappend box [
expr {[lindex $coord $i] - $dif}]}
1236 lappend box [
expr { [lindex $box 2] - [lindex $box 0] }]
1237 lappend box [
expr {([lindex $box 0] + [lindex $box 2]) / 2}]
1238 lappend box [
expr {([lindex $box 1] + [lindex $box 3]) / 2}]
1247 proc ::board::piece {w sq} {
1248 set p [
string index $::board::_data($w) $sq]
1249 return $::board::letterToPiece($p)
1258 proc ::board::setDragSquare {w sq} {
1259 set oldSq $::board::_drag($w)
1260 if {$oldSq >= 0 && $oldSq <= 63} {
1264 set ::board::_drag($w) $sq
1268 proc ::board::getDragSquare {w} {
1269 return $::board::_drag($w)
1277 proc ::board::dragPiece {w x y} {
1278 set sq $::board::_drag($w)
1279 if {$sq < 0} {
return}
1280 set x [
expr {$x - [winfo rootx $w.bd]}]
1281 set y [
expr {$y - [winfo rooty $w.bd]}]
1282 $w.bd coords p$sq $x $y
1290 proc ::board::bind {w sq event action} {
1292 for {
set i 0} {$i < 64} {
incr i} {
1293 $w.bd bind p$i $event $action
1296 $w.bd bind p$sq $event $action
1303 proc ::board::drawPiece {w sq piece} {
1304 set psize $::board::_size($w)
1305 set flip $::board::_flip($w)
1308 set xc [
lindex $midpoint 0]
1309 set yc [
lindex $midpoint 1]
1312 $w.bd create image $xc $yc -image $::board::letterToPiece($piece)$psize -tag p$sq
1318 proc ::board::clearText {w} {
1326 proc ::board::drawText {w sq text color args {shadow ""} } {
1328 [
expr {[catch {font actual font_Bold -size} size] ? 11 : $size}] \
1336 proc ::board::lastMoveHighlight {w} {
1337 $w.bd delete highlightLastMove
1338 if { ! $::highlightLastMove } {
return}
1339 set moveuci [
sc_game info previousMoveUCI]
1340 if {[
string length $moveuci] >= 4} {
1341 set moveuci [
string range $moveuci 0 3]
1342 set square1 [
::board::sq [
string range $moveuci 0 1]]
1343 set square2 [
::board::sq [
string range $moveuci 2 3]]
1346 if { ! $::arrowLastMove } {
return}
1359 proc ::board::update {w {board ""} {animate 0}} {
1360 set oldboard $::board::_data($w)
1362 set board $::board::_data($w)
1364 set ::board::_data($w) $board
1366 set psize $::board::_size($w)
1369 after cancel "::board::_animate $w"
1375 for {
set sq 0} { $sq < 64 } {
incr sq} {
1376 set piece [
string index $board $sq]
1379 set xc [
lindex $midpoint 0]
1380 set yc [
lindex $midpoint 1]
1383 $w.bd itemconfigure sq$sq -fill $color -outline ""
1386 if { ($sq + ($sq / 8)) % 2 } {
set boc bgl$psize}
1388 $w.bd create image $xc $yc -image $boc -tag br$sq
1392 $w.bd create image $xc $yc -image $::board::letterToPiece($piece)$psize -tag p$sq
1399 if { $::glossOfDanger } {
1400 foreach {sq col} [
sc_pos attacks] {
1406 if {$::board::_showMarks($w)} {
1407 foreach mark $::board::_mark($w) {
1408 set type [
lindex $mark 0]
1409 if {$type == "full"} {
1413 set drawingScript "mark::Draw[
string totitle $type]"
1414 if {[
llength [
info procs $drawingScript]]} {
1415 catch {
eval $drawingScript $w.bd [
join [
lrange $mark 1 3]]}
1422 if { $w == ".main.board"} {
1427 if {$::board::_showmat($w)} {
1432 if {$animate && $board != $oldboard} {
1437 proc ::board::isFlipped {w} {
1438 return $::board::_flip($w)
1450 proc ::board::flipAuto {w {newstate -1}} {
1451 if {$newstate == -1} {
1452 if {[
info exists ::board::flipAuto_($w)]} {
::board::flip $w $::board::flipAuto_($w)}
1455 set tmp $::board::_flip($w)
1456 if {[
info exists ::board::flipAuto_($w)]} {
set tmp $::board::flipAuto_($w)}
1458 set ::board::flipAuto_($w) $tmp
1464 proc ::board::flip {w {newstate -1}} {
1465 if {! [
info exists ::board::_flip($w)]} {
return}
1466 catch {unset ::board::flipAuto_($w)}
1467 if {$newstate == $::board::_flip($w)} {
return}
1468 set flip [
expr {1 - $::board::_flip($w)}]
1469 set ::board::_flip($w) $flip
1472 for {
set i 0} {$i < 32} {
incr i} {
1473 set swap [
expr {63 - $i}]
1474 set coords(South) [$w.bd coords sq$i]
1475 set coords(North) [$w.bd coords sq$swap]
1476 $w.bd coords sq$i $coords(North)
1477 $w.bd coords sq$swap $coords(South)
1481 for {
set i 1} {$i <= 8} {
incr i} {
1482 set value [
expr {9 - [$w.lrank$i cget -text]}]
1483 $w.lrank$i configure -text $value
1484 $w.rrank$i configure -text $value
1487 foreach file {a b c d e f g h} newvalue {h g f e d c b a} {
1488 $w.tfile$file configure -text $newvalue
1489 $w.bfile$file configure -text $newvalue
1492 foreach file {a b c d e f g h} {
1493 $w.tfile$file configure -text $file
1494 $w.bfile$file configure -text $file
1505 proc ::board::material {w} {
1510 set fen [
lindex [
sc_pos fen] 0]
1516 for {
set i 0} {$i < [
string length $fen]} {
incr i} {
1517 set ch [
string index $fen $i]
1531 set sum [
expr abs($p) + abs($n) +abs($b) +abs($r) +abs($q)]
1534 foreach pType {q r b n p} {
1535 set count [
expr "\$$pType"]
1538 incr rank [
expr abs($count)]
1541 foreach pType {q r b n p} {
1542 set count [
expr "\$$pType"]
1545 incr rank [
expr abs($count)]
1549 proc ::board::addMaterial {count piece parent rank sum} {
1550 if {$count == 0} {
return}
1553 set count [
expr 0 - $count]
1557 set w [$parent cget -width]
1558 set h [$parent cget -height]
1559 set offset [
expr ($h - ($sum * 20)) / 2]
1560 if {$offset <0} {
set offset 0}
1562 for {
set i 0} {$i<$count} {
incr i} {
1563 set y [
expr $rank * 20 +10 + $offset + $i * 20]
1564 $parent create image $x $y -image $col${piece}20 -tag material
1567 proc ::board::toggleMaterial {w} {
1568 set ::board::_showmat($w) [
expr {1 - $::board::_showmat($w)}]
1569 if {$::board::_showmat($w)} {
1575 return $::board::_showmat($w)
1585 proc ::board::coords {w} {
1586 set coords [
expr {1 + $::board::_coords($w)}]
1587 if { $coords > 2 } {
set coords 0}
1588 set ::board::_coords($w) $coords
1590 if {$coords == 0 } {
1591 for {
set i 1} {$i <= 8} {
incr i} {
1592 grid remove $w.lrank$i
1593 grid remove $w.rrank$i
1595 foreach i {a b c d e f g h} {
1596 grid remove $w.tfile$i
1597 grid remove $w.bfile$i
1599 }
elseif {$coords == 1 } {
1600 for {
set i 1} {$i <= 8} {
incr i} {
1601 grid configure $w.lrank$i
1602 grid remove $w.rrank$i
1604 foreach i {a b c d e f g h} {
1605 grid remove $w.tfile$i
1606 grid configure $w.bfile$i
1609 for {
set i 1} {$i <= 8} {
incr i} {
1610 grid configure $w.lrank$i
1611 grid configure $w.rrank$i
1613 foreach i {a b c d e f g h} {
1614 grid configure $w.tfile$i
1615 grid configure $w.bfile$i
1626 proc ::board::animate {w oldboard newboard} {
1628 if {$animateDelay <= 0} {
return}
1633 for {
set i 0} {$i < 64} {
incr i} {
1634 if {[
string index $oldboard $i] != [
string index $newboard $i]} {
1641 if {$diffcount < 2 || $diffcount > 4} {
return}
1643 for {
set i 0} {$i < $diffcount} {
incr i} {
1644 set sq($i) [
lindex $difflist $i]
1645 set old($i) [
string index $oldboard $sq($i)]
1646 set new($i) [
string index $newboard $sq($i)]
1652 set capturedPiece "."
1654 if {$diffcount == 4} {
1656 set castlingList [list [
sq e1] [
sq g1] [
sq h1] [
sq f1] \
1661 foreach {kfrom kto rfrom rto} $castlingList {
1662 if {[lsort $difflist] == [lsort [list $kfrom $kto $rfrom $rto]]} {
1663 if {[
string tolower [
string index $oldboard $kfrom]] == "k" &&
1664 [
string tolower [
string index $oldboard $rfrom]] == "r" &&
1665 [
string tolower [
string index $newboard $kto]] == "k" &&
1666 [
string tolower [
string index $newboard $rto]] == "r"} {
1673 }
elseif {[
string tolower [
string index $newboard $kfrom]] == "k" &&
1674 [
string tolower [
string index $newboard $rfrom]] == "r" &&
1675 [
string tolower [
string index $oldboard $kto]] == "k" &&
1676 [
string tolower [
string index $oldboard $rto]] == "r"} {
1685 if {$diffcount == 3} {
1690 if {$i == $j || $i == $k || $j == $k} { continue}
1693 if {$old($i) == $new($j) && $old($j) == "." && $new($k) == "." &&
1694 (($old($i) == "p" && $old($k) == "P") ||
1695 ($old($i) == "P" && $old($k) == "p"))} {
1701 if {$old($i) == $new($j) && $old($k) == "." && $new($i) == "." &&
1702 (($old($i) == "p" && $new($k) == "P") ||
1703 ($old($i) == "P" && $new($k) == "p"))} {
1706 set captured $sq($k)
1707 set capturedPiece $new($k)
1714 if {$diffcount == 2} {
1719 if {$old(0) != "." && $old(1) != "." && $new(0) != "." && $new(1) != "."} {
1725 if {$i == $j} { continue}
1726 if {$old($i) == $new($j) && $old($i) != "."} {
1729 set captured $sq($j)
1730 set capturedPiece $old($j)
1734 if {($old($i) == "P" && [
string is upper $new($j)] &&
1735 $sq($j) >= [
sq a8] && $sq($j) <= [
sq h8]) ||
1736 ($old($i) == "p" && [
string is lower $new($j)] &&
1737 $sq($j) >= [
sq a1] && $sq($j) <= [
sq h1])} {
1743 if {($new($j) == "P" && [
string is upper $old($i)] &&
1744 $sq($i) >= [
sq a8] && $sq($i) <= [
sq h8]) ||
1745 ($new($j) == "p" && [
string is lower $old($i)] &&
1746 $sq($i) >= [
sq a1] && $sq($i) <= [
sq h1])} {
1749 set captured $sq($j)
1750 set capturedPiece $old($j)
1757 if {$from < 0 || $to < 0} {
return}
1760 if {$capturedPiece != "." && $captured >= 0} {
1770 set start [
clock clicks -milli]
1771 set ::board::_animate($w,start) $start
1772 set ::board::_animate($w,end) [
expr {$start + $::animateDelay}]
1773 set ::board::_animate($w,from) $from
1774 set ::board::_animate($w,to) $to
1781 proc ::board::_animate {w} {
1782 if {! [
winfo exists $w]} {
return}
1783 set from $::board::_animate($w,from)
1784 set to $::board::_animate($w,to)
1785 set start $::board::_animate($w,start)
1786 set end $::board::_animate($w,end)
1787 set now [
clock clicks -milli]
1794 set ratio [
expr {double($now - $start) / double($end - $start)}]
1797 set fromX [
lindex $fromMid 0]
1798 set fromY [
lindex $fromMid 1]
1799 set toX [
lindex $toMid 0]
1800 set toY [
lindex $toMid 1]
1801 set x [
expr {$fromX + round(($toX - $fromX) * $ratio)}]
1802 set y [
expr {$fromY + round(($toY - $fromY) * $ratio)}]
1803 $w.bd coords p$to $x $y
1807 after 5 "::board::_animate $w"
1812 if {[lsearch -exact "$::boardStyles" "$::boardStyle"] == -1} {
1813 set ::boardStyle [
lindex $::boardStyles 0]