Richard Suchenwirth 2000-08-04 -- Anne Lavergne wrote in news:comp.lang.tcl :
> I am looking for a spreadsheet-like Tk widget i.e. 2D array of canvases > (cells) to implement a chessboard.
Couldn't resist - here is a one-canvas solution, with movable checkers [BE: draughts] pieces:
set dx 50 set dy 50 #set colors {black white red blue} set colors {white black red blue} pack [canvas .c -width [expr $dx*8] -height [expr $dy*8]] -fill both -expand 1 .c bind all <1> {set c(X) [.c canvasx %x]; set c(Y) [.c canvasy %y]} .c bind mv <B1-Motion> {mv %x %y} proc mv {x y} { global c set x [.c canvasx $x] set y [.c canvasy $y] set id [.c find withtag current] .c move $id [expr {$x-$c(X)}] [expr {$y-$c(Y)}] .c raise $id set c(X) $x; set c(Y) $y } set color 0 proc makepiece {x y color args} { global dx dy .c create oval [expr {$x+2}] [expr {$y+2}] [expr {$x+$dx-3}] [expr {$y+$dy-3}] \ -fill $color -tags [concat $args mv] } proc makecheck {x y color args} { global dx dy .c create rectangle $x $y [expr {$x+$dx}] [expr {$y+$dy}] \ -fill $color -tags $args } for {set i 0; set y 0} {$i<8} {incr i; incr y $dy} { for {set j 0; set x 0} {$j<8} {incr j; incr x $dx} { makecheck $x $y [lindex $colors $color] if {$i<3 && $color} { makepiece $x $y [lindex $colors 2] player2 } if {$i>4 && $color} { makepiece $x $y [lindex $colors 3] player1 } set color [expr {1-$color}] } set color [expr {1-$color}] }
In C/Motif, I'd not even have thought of writing something like this.. With Tcl, I come home after a real long working day and think "Wouldn't it be nice to also have a Nine Men Morris? A little Go board?" and after a long evening, here they are!
Bryan Oakley writes...
I updated the above to draw the checkers a little bit inside the borders.
Also, the following binding will make the checkers snap to a particular square. I'm sure somebody can improve on the efficiency of the solution.
.c bind mv <ButtonRelease-1> {drop [.c find withtag current]} proc drop {id} { global c dx dy set cx0 [expr {int($c(X) / $dx) * $dx + 2}] set cy0 [expr {int($c(Y) / $dy) * $dy + 2}] set cx1 [expr {$cx0 + $dx - 3}] set cy1 [expr {$cy0 + $dy - 3}] .c coords $id $cx0 $cy0 $cx1 $cy1 }
DKF - I've improved the efficiency slightly, but there really isn't much point in doing much better, as it only has to deal with responses to bindings.
HJG I changed this checkerboard-layout to look more like I know this game... But how do you actually play this thing, e.g. how are stones removed or promoted to queen/king ?
MG It looks like you can't, right now. This seems to just implement the board and the pieces (which can be moved) with no rules at all. It probably wouldn't take a heck of a lot to develop on it, though.
uniquename 2013aug01
Here is an image so that readers can easily see what the code above creates.