Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/Chess+in+Tcl?V=44
QUERY_STRINGV=44
CONTENT_TYPE
DOCUMENT_URI/revision/Chess+in+Tcl
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.71.254.217
REMOTE_PORT10852
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR18.227.190.93
HTTP_CF_RAY87e8f03b2c962249-ORD
HTTP_X_FORWARDED_PROTOhttps
HTTP_CF_VISITOR{"scheme":"https"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTMozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; [email protected])
HTTP_CF_CONNECTING_IP18.227.190.93
HTTP_CDN_LOOPcloudflare
HTTP_CF_IPCOUNTRYUS

Body


Error

Unknow state transition: LINE -> END

-code

1

-level

0

-errorstack

INNER {returnImm {Unknow state transition: LINE -> END} {}} CALL {my render_wikit {Chess in Tcl} \[WikiDbImage\ chess.jpg\]\ \[WikiDbImage\ chessfont.jpg\]\n\n**\ Summary\ **\n\n\[Richard\ Suchenwirth\]\ 2002-09-14:\ \ In\ this\ weekend\ fun\ project,\ I\ experimented\nhow\ to\ play\ \[chess\]\ with\ Tcl.\n\n**\ Changes\ **\n\nThis\ version\ 0.2\ supports\ dynamic\ resizing\n\n**\ Description\ **\n\nMy\ ambition\ was\ not\ (yet)\ to\ code\ winning\ strategies,\ but\ just\ to\ handle\ the\nbasics\ -\ how\ to\ administer\ the\ board\ data\ structure,\ how\ to\ validate\ a\ move,\netc.\ The\ first\ part\ is\ \[pure-Tcl\],\ no\ Tk\ involved.\ \"\[Everything\ is\ a\ string\]\",\nso\ first\ I\ designed\ a\ string\ format\ to\ represent\ the\ state\ of\ the\ chess\ board:\none\ character\ per\ square\ -\ \".\"\ if\ empty,\ else\ the\ piece's\ abbreviation\n(uppercase\ for\ White,\ lowercase\ for\ black):\n\n'''R(ook=castle)\ (k)N(ight)\ B(ishop)\ Q(ueen)\ K(ing)\ P(awn).'''\n\nRows\ are\ delimited\ by\ newlines,\ squares\ by\ blanks.\ See\ the\ ''chess::reset''\nfunction\ for\ the\ example\ of\ the\ initial\ setup.\ Such\ strings\ can\ be\ loaded,\ if\nyou'd\ like\ to\ reproduce\ chess\ problems,\ or\ the\ current\ state\ of\ the\ board\ can\nbe\ returned\ in\ the\ same\ format.\n\nInternally,\ the\ board\ is\ implemented\ as\ an\ array\ in\ caller's\ scope,\ one\ element\nper\ square.\ Squares\ are\ named\ conventionally,\ A1\ being\ bottom\ left,\ H8\ top\nright.\ Moves\ are\ written\ in\ the\ form\ \$from-\$to,\ e.g.\ A2-A4,\ and\ kept\ in\ a\nhistory\ list\ which\ can\ be\ recalled\ or\ undone,\ one\ move\ at\ a\ time.\ \ Taken\ men\nare\ recorded\ as\ a\ suffix\ to\ the\ move,\ e.g.\ A2-A4-Q,\ so\ they\ can\ be\ reinstated\non\ undo.\ You\ can\ have\ multiple\ chess\ boards\ in\ parallel,\ if\ you\ \[wish\],\ as\ the\nAPI\ is\ \"object-oriented\":\n\n\ \ \ *\ chess::new\ myGame\n\ \ \ *\ myGame\ move\ A2-A4\n\n======\nnamespace\ eval\ chess\ \{set\ version\ 0.2\ \;#\ resize\ on\ <Configure>\}\nproc\ chess::new\ board\ \{\n\ \ \ \ #\ create\ a\ new\ game\ (generic\ dispatcher)\ with\ the\ board\ name\n\ \ \ \ proc\ ::\$board\ \{\{cmd\ format\}\ args\}\ \\\n\ \ \ \ \ \ \ \ \"uplevel\ 1\ chess::\\\$cmd\ \$board\ \\\$args\"\n\ \ \ \ uplevel\ 1\ \$board\ reset\n\}\nproc\ chess::reset\ \{boardName\ \{setup\ \"\"\}\}\ \{\n\ \ \ \ upvar\ 1\ \$boardName\ board\n\ \ \ \ if\ \{\$setup\ ==\ \"\"\}\ \{set\ setup\ \\\n\ \ \ \ \ \ \ \ \"r\ n\ b\ q\ k\ b\ n\ r\n\ \ \ \ \ \ \ \ \ p\ p\ p\ p\ p\ p\ p\ p\n\ \ \ \ \ \ \ \ \ .\ .\ .\ .\ .\ .\ .\ .\n\ \ \ \ \ \ \ \ \ .\ .\ .\ .\ .\ .\ .\ .\n\ \ \ \ \ \ \ \ \ .\ .\ .\ .\ .\ .\ .\ .\n\ \ \ \ \ \ \ \ \ .\ .\ .\ .\ .\ .\ .\ .\n\ \ \ \ \ \ \ \ \ P\ P\ P\ P\ P\ P\ P\ P\n\ \ \ \ \ \ \ \ \ R\ N\ B\ Q\ K\ B\ N\ R\"\n\ \ \ \ \}\n\ \ \ \ foreach\ line\ \[split\ \[string\ trim\ \$setup\]\ \\n\]\ y\ \{8\ 7\ 6\ 5\ 4\ 3\ 2\ 1\}\ \{\n\ \ \ \ \ \ \ \ foreach\ word\ \$line\ x\ \{A\ B\ C\ D\ E\ F\ G\ H\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ board(\$x\$y)\ \$word\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ set\ board(toMove)\ white\n\ \ \ \ set\ board(history)\ \{\}\ \;#\ start\ a\ new\ history...\n\}\nproc\ chess::format\ boardName\ \{\n\ \ \ \ #\ render\ current\ board\ into\ a\ well-readable\ string\n\ \ \ \ upvar\ 1\ \$boardName\ board\n\ \ \ \ foreach\ row\ \{8\ 7\ 6\ 5\ 4\ 3\ 2\ 1\}\ \{\n\ \ \ \ \ \ \ \ foreach\ column\ \{A\ B\ C\ D\ E\ F\ G\ H\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ append\ res\ \"\ \"\ \$board(\$column\$row)\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ append\ res\ \\n\n\ \ \ \ \}\n\ \ \ \ set\ res\n\}\nproc\ chess::move\ \{boardName\ move\}\ \{\n\ \ \ \ upvar\ 1\ \$boardName\ board\n\ \ \ \ foreach\ \{from\ to\}\ \[split\ \$move\ -\]\ break\n\ \ \ \ set\ fromMan\ \$board(\$from)\n\ \ \ \ if\ \{\$fromMan\ ==\ \".\"\}\ \{error\ \"no\ man\ to\ move\ at\ \$from\"\}\n\ \ \ \ set\ toMan\ \ \ \$board(\$to)\n\ \ \ \ if\ !\[valid?\ board\ \$move\]\ \{error\ \"invalid\ move\ for\ a\ \[manName\ \$fromMan\]\"\}\n\ \ \ \ set\ board(\$from)\ .\n\ \ \ \ set\ board(\$to)\ \ \ \$fromMan\n\ \ \ \ if\ \{\$toMan\ !=\ \".\"\}\ \{append\ move\ -\$toMan\}\ \;#\ taken\ one\n\ \ \ \ lappend\ board(history)\ \$move\n\ \ \ \ set\ board(toMove)\ \[expr\ \{\$board(toMove)\ ==\ \"white\"?\ \"black\":\ \"white\"\}\]\n\ \ \ \ set\ toMan\ \;#\ report\ possible\ victim\n\}\nproc\ chess::color\ man\ \{expr\ \{\[string\ is\ upper\ \$man\]?\ \"white\"\ :\ \"black\"\}\}\n\ \nproc\ chess::valid?\ \{boardName\ move\}\ \{\n\ \ \ \ upvar\ 1\ \$boardName\ board\n\ \ \ \ foreach\ \{from\ to\}\ \[split\ \$move\ -\]\ break\n\ \ \ \ if\ \{\$to==\"\"\}\ \{return\ 0\}\n\ \ \ \ set\ fromMan\ \$board(\$from)\n\ \ \ \ if\ \{\[color\ \$fromMan\]\ !=\ \$board(toMove)\}\ \{return\ 0\}\n\ \ \ \ set\ toMan\ \ \ \$board(\$to)\n\ \ \ \ if\ \[sameSide\ \$fromMan\ \$toMan\]\ \{return\ 0\}\n\ \ \ \ foreach\ \{x0\ y0\}\ \[coords\ \$from\]\ \{x1\ y1\}\ \[coords\ \$to\]\ break\n\ \ \ \ set\ dx\ \ \[expr\ \{\$x1-\$x0\}\]\n\ \ \ \ set\ adx\ \[expr\ \{abs(\$dx)\}\]\n\ \ \ \ set\ dy\ \ \[expr\ \{\$y1-\$y0\}\]\n\ \ \ \ set\ ady\ \[expr\ \{abs(\$dy)\}\]\n\ \ \ \ if\ \{\[string\ tolower\ \$fromMan\]\ !=\ \"n\"\ &&\ (!\$adx\ ||\ !\$ady\ ||\ \$adx==\$ady)\}\ \{\n\ \ \ \ \ \ \ \ for\ \{set\ x\ \$x0\;\ set\ y\ \$y0\}\ \{(\$x!=\$x1\ ||\ \$y!=\$y1)\}\ \\\n\ \ \ \ \ \ \ \ \ \ \{incr\ x\ \[sgn\ \$dx\]\;\ incr\ y\ \[sgn\ \$dy\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{(\$x!=\$x0\ ||\ \$y!=\$y0)\ &&\ \$board(\[square\ \$x\ \$y\])!=\".\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ 0\n\ \ \ \ \ \ \ \ \ \ \ \ \}\ \;#\ planned\ path\ is\ blocked\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ switch\ --\ \$fromMan\ \{\n\ \ \ \ \ \ \ \ K\ -\ k\ \{expr\ \$adx<2\ &&\ \$ady<2\}\n\ \ \ \ \ \ \ \ Q\ -\ q\ \{expr\ \$adx==0\ ||\ \$ady==0\ ||\ \$adx==\$ady\}\n\ \ \ \ \ \ \ \ B\ -\ b\ \{expr\ \$adx==\$ady\}\n\ \ \ \ \ \ \ \ N\ -\ n\ \{expr\ (\$adx==1\ &&\ \$ady==2)||(\$adx==2\ &&\ \$ady==1)\}\n\ \ \ \ \ \ \ \ R\ -\ r\ \{expr\ \$adx==0\ ||\ \$ady==0\}\n\ \ \ \ \ \ \ \ P\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ expr\ \{((\$y0==2\ &&\ \$dy==2)\ ||\ \$dy==1)\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ &&\ ((\$dx==0\ &&\ \$toMan==\".\")\ ||\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (\$adx==1\ &&\ \$ady==1\ &&\ \[sameSide\ p\ \$toMan\]))\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ p\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ expr\ \{((\$y0==7\ &&\ \$dy==-2)\ ||\ \$dy==-1)\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ &&\ ((\$dx==0\ &&\ \$toMan==\".\")\ ||\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (\$adx==1\ &&\ \$ady==1\ &&\ \[sameSide\ P\ \$toMan\]))\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ default\ \{return\ 0\}\n\ \ \ \ \}\n\}\nproc\ chess::validMoves\ \{boardName\ from\}\ \{\n\ \ \ \ upvar\ 1\ \$boardName\ board\n\ \ \ \ set\ res\ \{\}\n\ \ \ \ foreach\ to\ \[array\ names\ board\ ??\]\ \{\n\ \ \ \ \ \ \ \ set\ move\ \$from-\$to\n\ \ \ \ \ \ \ \ if\ \[valid?\ board\ \$move\]\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$board(\$to)\ !=\ \".\"\}\ \{append\ move\ -\$board(\$to)\}\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ res\ \$move\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ lsort\ \$res\n\}\nproc\ chess::coords\ square\ \{\n\ \ \ \ #\ translate\ square\ name\ to\ numeric\ coords:\ C5\ ->\ \{3\ 5\}\n\ \ \ \ foreach\ \{c\ y\}\ \[split\ \$square\ \"\"\]\ break\n\ \ \ \ list\ \[lsearch\ \{-\ A\ B\ C\ D\ E\ F\ G\ H\}\ \$c\]\ \$y\n\}\nproc\ chess::square\ \{x\ y\}\ \{\n\ \ \ \ #\ translate\ numeric\ coords\ to\ sq\ uare\ name:\ \{3\ 5\}\ ->\ C5\n\ \ \ \ return\ \[string\ map\ \{1\ A\ 2\ B\ 3\ C\ 4\ D\ 5\ E\ 6\ F\ 7\ G\ 8\ H\}\ \$x\]\$y\n\}\nproc\ chess::undo\ boardName\ \{\n\ \ \ \ upvar\ 1\ \$boardName\ board\n\ \ \ \ if\ !\[llength\ \$board(history)\]\ \{error\ \"Nothing\ to\ undo\"\}\n\ \ \ \ set\ move\ \[lindex\ \$board(history)\ end\]\n\ \ \ \ foreach\ \{from\ to\ hit\}\ \[split\ \$move\ -\]\ \ break\n\ \ \ \ set\ board(history)\ \[lrange\ \$board(history)\ 0\ end-1\]\n\ \ \ \ set\ board(\$from)\ \ \ \$board(\$to)\n\ \ \ \ if\ \{\$hit==\"\"\}\ \{set\ hit\ .\}\n\ \ \ \ set\ board(\$to)\ \$hit\n\ \ \ \ set\ board(toMove)\ \[expr\ \{\$board(toMove)\ ==\ \"white\"?\ \"bl\ ack\":\ \"white\"\}\]\n\}\nproc\ chess::sameSide\ \{a\ b\}\ \{regexp\ \{\[a-z\]\[a-z\]|\[A-Z\]\[A-Z\]\}\ \$a\$b\]\}\n\ \nproc\ chess::history\ boardName\ \{uplevel\ 1\ set\ \$boardName\\(history)\}\n\ \nproc\ chess::manName\ man\ \{\n\ \ \ \ set\ table\ \{-\ k\ king\ q\ queen\ b\ bishop\ n\ knight\ r\ rook\ p\ pawn\}\n\ \ \ \ set\ i\ \[l\ search\ \$table\ \[string\ tolower\ \$man\]\]\n\ \ \ \ lindex\ \$table\ \[incr\ i\]\n\}\nproc\ chess::values\ boardName\ \{\n\ \ \ \ #\ returns\ the\ current\ numeric\ value\ of\ white\ and\ black\ crews\n\ \ \ \ upvar\ 1\ \$boardName\ board\n\ \ \ \ set\ white\ 0\;\ set\ black\ 0\n\ \ \ \ foreach\ square\ \[array\ names\ b\ oard\ ??\]\ \{\n\ \ \ \ \ \ \ \ set\ man\ \$board(\$square)\n\ \ \ \ \ \ \ \ switch\ -regexp\ --\ \$man\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \[A-Z\]\ \{set\ white\ \[expr\ \{\$white\ +\ \[manValue\ \$man\]\}\]\}\n\ \ \ \ \ \ \ \ \ \ \ \ \[a-z\]\ \{set\ black\ \[expr\ \{\$black\ +\ \[manValue\ \$man\]\}\]\}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ list\ \$white\ \$black\n\}\nproc\ chess::manValue\ man\ \{\n\ \ \ \ array\ set\ a\ \{k\ 0\ q\ 9\ b\ 3.2\ n\ 3\ r\ 5\ p\ 1\}\n\ \ \ \ set\ a(\[string\ tolower\ \$man\])\n\}\n\n#-----------------------------------------------------------\ Tk\ UI\n\nif\ 0\ \{Now\ we\ create\ a\ \"real\"\ chess\ board\ on\ a\ canvas.\ The\ shapes\ of\nmen\ are\ extremely\ simple\ (maybe\ good\ for\ the\ visually\ impaired).\ Clicking\ on\na\ man\ highlights\ the\ valid\ moves\ in\ green\ (possible\ takes\ in\ red)\ for\ a\nsecond.\ Only\ valid\ moves\ are\ accepted,\ else\ the\ man\ snaps\ back\ to\ where\nhe\ stood.\ As\ bindings\ execute\ in\ global\ scope,\ the\ board\ array\ has\ to\nbe\ global\ for\ the\ UI.\n\}\n\n======\nproc\ chess::drawBoard\ \{boardName\ w\ args\}\ \{\n\ \ \ \ upvar\ #0\ \$boardName\ board\n\ \ \ \ array\ set\ opt\ \{-width\ 300\ -colors\ \{bisque\ tan3\}\ -side\ white\ -usefont\ 0\}\n\ \ \ \ array\ set\ opt\ \$args\n\ \ \ \ if\ \{!\[winfo\ exists\ \$w\]\}\ \{\n\ \ \ \ \ \ \ \ canvas\ \$w\ -width\ \$opt(-width)\ -height\ \$opt(-width)\n\ \ \ \ \ \ \ \ bind\ \$w\ <Configure>\ \"chess::drawBoard\ \$boardName\ \$w\ \$args\"\n\ \ \ \ \ \ \ \ set\ board(usefont)\ \$opt(-usefont)\n\ \ \ \ \ \ \ \ \$w\ bind\ mv\ <1>\ \[list\ chess::click1\ \$boardName\ \$w\ %x\ %y\]\n\ \ \ \ \ \ \ \ \$w\ bind\ mv\ <B1-Motion>\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ %W\ move\ current\ \[expr\ \{%x-\$chess::x\}\]\ \[expr\ \{%y-\$chess::y\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ chess::x\ %x\;\ set\ chess::y\ %y\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \$w\ bind\ mv\ <ButtonRelease-1>\ \"chess::release1\ \$boardName\ \$w\ %x\ %y\"\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \$w\ delete\ all\n\ \ \ \ \}\n\ \ \ \ set\ board(side)\ \ \ \$opt(-side)\n\ \ \ \ set\ dim\ \[min\ \[winfo\ height\ \$w\]\ \[winfo\ width\ \$w\]\]\n\ \ \ \ if\ \{\$dim<2\}\ \{set\ dim\ \$opt(-width)\}\n\ \ \ \ set\ board(sqw)\ \[set\ sqw\ \[expr\ \{(\$dim\ -\ 20)\ /\ 8\}\]\]\n\ \ \ \ set\ x0\ 15\n\ \ \ \ set\ x\ \$x0\;\ set\ y\ 5\;\ set\ colorIndex\ 0\n\ \ \ \ set\ rows\ \{8\ 7\ 6\ 5\ 4\ 3\ 2\ 1\}\n\ \ \ \ set\ cols\ \{A\ B\ C\ D\ E\ F\ G\ H\}\n\ \ \ \ if\ \{\$board(side)\ !=\ \"white\"\}\ \{\n\ \ \ \ \ \ \ \ set\ rows\ \[lrevert\ \$rows\]\n\ \ \ \ \ \ \ \ set\ cols\ \[lrevert\ \$cols\]\n\ \ \ \ \}\n\ \ \ \ foreach\ row\ \$rows\ \{\n\ \ \ \ \ \ \ \ \$w\ create\ text\ 5\ \[expr\ \{\$y+\$sqw/2\}\]\ -text\ \$row\n\ \ \ \ \ \ \ \ foreach\ col\ \$cols\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \$w\ create\ rect\ \$x\ \$y\ \[incr\ x\ \$sqw\]\ \[expr\ \$y+\$sqw\]\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -fill\ \[lindex\ \$opt(-colors)\ \$colorIndex\]\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -tag\ \[list\ square\ \$col\$row\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ colorIndex\ \[expr\ \{1-\$colorIndex\}\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ set\ x\ \$x0\;\ incr\ y\ \$sqw\n\ \ \ \ \ \ \ \ set\ colorIndex\ \[expr\ \{1-\$colorIndex\}\]\n\ \ \ \ \}\n\ \ \ \ set\ x\ \[expr\ \{\$x0\ -\ \$sqw/2\}\]\n\ \ \ \ incr\ y\ 8\ \;#\ letters\ go\ below\ chess\ board\n\ \ \ \ foreach\ col\ \$cols\ \{\$w\ create\ text\ \[incr\ x\ \$sqw\]\ \$y\ -text\ \$col\}\n\ \ \ \ drawSetup\ \$boardName\ \$w\n\ \ \ \ set\ w\n\}\nproc\ chess::click1\ \{boardName\ w\ cx\ cy\}\ \{\n\ \ \ \ upvar\ #0\ \$boardName\ board\n\ \ \ \ variable\ x\ \$cx\ y\ \$cy\ from\n\ \ \ \ \$w\ raise\ current\n\ \ \ \ regexp\ \{@(..)\}\ \[\$w\ gettags\ current\]\ ->\ from\n\ \ \ \ foreach\ move\ \[validMoves\ board\ \$from\]\ \{\n\ \ \ \ \ \ \ \ foreach\ \{-\ to\ victim\}\ \[split\ \$move\ -\]\ break\n\ \ \ \ \ \ \ \ set\ fill\ \[\$w\ itemcget\ \$to\ -fill\]\n\ \ \ \ \ \ \ \ if\ \{\$fill\ !=\ \"green\"\ &&\ \$fill\ !=\ \"red\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ newfill\ \[expr\ \{\$victim==\"\"?\ \"green\"\ :\ \"red\"\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \$w\ itemconfig\ \$to\ -fill\ \$newfill\n\ \ \ \ \ \ \ \ \ \ \ \ after\ 1000\ \$w\ itemconfig\ \$to\ -fill\ \$fill\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\}\nproc\ chess::release1\ \{boardName\ w\ cx\ cy\}\ \{\n\ \ \ \ upvar\ #0\ \$boardName\ board\n\ \ \ \ variable\ from\n\ \ \ \ set\ to\ \"\"\n\ \ \ \ foreach\ i\ \[\$w\ find\ overlap\ \$cx\ \$cy\ \$cx\ \$cy\]\ \{\n\ \ \ \ \ \ \ \ set\ tags\ \[\$w\ gettags\ \$i\]\n\ \ \ \ \ \ \ \ if\ \{\[lsearch\ \$tags\ square\]>=0\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ to\ \[lindex\ \$tags\ end\]\n\ \ \ \ \ \ \ \ \ \ \ \ break\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ if\ \[valid?\ board\ \$from-\$to\]\ \{\n\ \ \ \ \ \ \ \ set\ victim\ \[move\ board\ \$from-\$to\]\n\ \ \ \ \ \ \ \ if\ \{\[string\ tolower\ \$victim\]==\"k\"\}\ \{set\ ::info\ Checkmate.\}\n\ \ \ \ \ \ \ \ \$w\ delete\ @\$to\n\ \ \ \ \ \ \ \ set\ target\ \$to\n\ \ \ \ \ \ \ \ \$w\ dtag\ current\ @\$from\n\ \ \ \ \ \ \ \ \$w\ addtag\ @\$to\ withtag\ current\n\ \ \ \ \}\ else\ \{set\ target\ \$from\}\ \;#\ go\ back\ on\ invalid\ move\n\ \ \ \ foreach\ \{x0\ y0\ x1\ y1\}\ \ \ \ \ \[\$w\ bbox\ \$target\]\ break\n\ \ \ \ foreach\ \{xm0\ ym0\ xm1\ ym1\}\ \[\$w\ bbox\ current\]\ break\n\ \ \ \ set\ dx\ \[expr\ \{(\$x0+\ \$x1-\$xm0-\$xm1)/2\}\]\n\ \ \ \ set\ dy\ \[expr\ \{(\$y0+\$y1-\$ym0-\$ym1)/2\}\]\n\ \ \ \ \$w\ move\ current\ \$dx\ \$dy\n\}\nproc\ chess::drawSetup\ \{boardName\ w\}\ \{\n\ \ \ \ upvar\ #0\ \$boardName\ board\n\ \ \ \ \$w\ delete\ mv\n\ \ \ \ foreach\ square\ \[array\ names\ board\ ??\]\ \{\n\ \ \ \ \ \ \ \ drawMan\ \$boardName\ \$w\ \$square\ \$board(\$square)\n\ \ \ \ \}\n\}\nproc\ chess::drawMan\ \{boardName\ w\ where\ what\}\ \{\n\ \ \ \ if\ \{\$what==\".\"\}\ return\n\ \ \ \ upvar\ #0\ \$boardName\ board\n\ \ \ \ set\ fill\ \[expr\ \{\[regexp\ \{\[A-Z\]\}\ \$what\]?\ \"white\":\ \"black\"\}\]\n\ \ \ \ if\ \$board(usefont)\ \{\n\ \ \ \ \ \ \ \ set\ unicode\ \[string\ map\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ k\ \\u265a\ q\ \\u265b\ r\ \\u265c\ b\ \\u265d\ n\ \\u265e\ p\ \\u265f\n\ \ \ \ \ \ \ \ \ \ k\ K\ q\ Q\ r\ R\ b\ B\ n\ N\ p\ P\n\ \ \ \ \ \ \ \ \}\ \[string\ tolower\ \$what\]\]\n\ \ \ \ \ \ \ \ set\ font\ \[list\ Helvetica\ \[expr\ \{\$board(sqw)/2\}\]\ bold\]\n\ \ \ \ \ \ \ \ \$w\ create\ text\ 0\ 0\ -text\ \$unicode\ -font\ \$font\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ -tag\ \[list\ mv\ @\$where\]\ -fill\ \$fill\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \$w\ create\ poly\ \[manPolygon\ \$what\]\ -fill\ \$fill\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ -tag\ \[list\ mv\ @\$where\]\ -outline\ gray\n\ \ \ \ \ \ \ \ set\ f\ \[expr\ \{\$board(sqw)*0.035\}\]\n\ \ \ \ \ \ \ \ \$w\ scale\ @\$where\ 0\ 0\ \$f\ \$f\n\ \ \ \ \}\n\ \ \ \ foreach\ \{x0\ y0\ x1\ y1\}\ \[\$w\ bbox\ \$where\]\ break\n\ \ \ \ \$w\ move\ \ @\$where\ \[expr\ \{(\$x0+\$x1)/2\}\]\ \[expr\ \{(\$y0+\$y1)/2\}\]\n\}\nproc\ chess::manPolygon\ what\ \{\n\ \ \ \ #\ very\ simple\ shapes\ of\ the\ chess\ men\ -\ feel\ free\ to\ improve!\n\ \ \ \ switch\ --\ \[string\ tolower\ \$what\]\ \{\n\ \ \ \ \ b\ \{list\ -10\ 8\ \ -5\ 5\ \ -9\ 0\ \ -6\ -6\ \ 0\ -10\ \ 6\ -6\ \ 9\ 0\ \ 5\ 5\ \ 10\ 8\\\n\ \ \ \ \ \ \ \ 6\ 10\ \ 0\ 6\ \ -6\ 10\}\n\ \ \ \ \ k\ \{list\ -8\ 10\ \ -10\ 1\ \ -3\ -1\ \ -3\ -3\ \ -6\ -3\ \ -6\ -7\ \ -3\ -7\ \ -3\ -10\\\n\ \ \ \ \ \ \ \ 3\ -10\ \ 3\ -7\ \ 6\ -7\ \ 6\ -3\ \ 3\ -3\ \ 3\ -1\ \ 10\ 1\ \ 8\ 10\}\n\ \ \ \ \ n\ \{list\ -8\ 10\ \ -1\ -1\ \ -7\ 0\ \ -10\ -4\ \ 0\ -10\ \ 6\ -10\ \ 10\ 10\}\n\ \ \ \ \ p\ \{list\ -8\ 10\ \ -8\ 7\ \ -5\ 7\ \ -2\ -1\ \ -4\ -5\ \ -2\ -10\ \ 2\ -10\ \ 4\ -5\ \\\n\ \ \ \ \ \ \ \ \ \ 2\ -1\ \ 5\ 7\ \ 8\ 7\ \ 8\ 10\}\n\ \ \ \ \ q\ \{list\ -6\ 10\ \ -10\ -10\ \ -3\ 0\ \ 0\ -10\ \ 3\ 0\ \ 10\ -10\ \ 6\ 10\}\n\ \ \ \ \ r\ \{list\ -10\ 10\ \ -7\ 1\ \ -10\ 0\ \ -10\ -10\ \ -5\ -10\ \ -5\ -6\ \ -3\ -6\ \ -3\ -10\\\n\ \ \ \ \ \ \ \ \ \ 3\ -10\ \ 3\ -6\ \ 5\ -6\ \ 5\ -10\ \ 10\ -10\ 10\ 0\ \ 7\ 1\ \ 10\ 10\}\n\ \ \ \ \}\n\}\nproc\ chess::flipSides\ \{boardName\ w\}\ \{\n\ \ \ \ upvar\ #0\ \$boardName\ board\n\ \ \ \ \$w\ delete\ all\n\ \ \ \ set\ side\ \[expr\ \{\$board(side)==\"white\"?\ \"black\":\ \"white\"\}\]\n\ \ \ \ \$boardName\ drawBoard\ \$w\ -side\ \$side\n\}\n#-------------------------------------\ some\ general\ utilities:\nproc\ lrevert\ list\ \{\n\ \ \ \ set\ res\ \{\}\n\ \ \ \ set\ i\ \[llength\ \$list\]\n\ \ \ \ while\ \{\$i\}\ \{lappend\ res\ \[lindex\ \$list\ \[incr\ i\ -1\]\]\}\n\ \ \ \ set\ res\n\}\nproc\ min\ args\ \{lindex\ \[lsort\ -real\ \$args\]\ 0\}\nproc\ sgn\ x\ \{expr\ \{\$x>0?\ 1:\ \$x<0?\ -1:\ 0\}\}\ \n#------------------------------------------------testing\ demo:\nif\ \{\[file\ tail\ \[info\ script\]\]==\[file\ tail\ \$argv0\]\}\ \{\n\ \ \ \ chess::new\ game\n\ \ \ \ frame\ .f\n\ \ \ \ label\ \ .f.e\ -width\ 30\ -anchor\ w\ -textvar\ info\ -relief\ sunken\n\ \ \ \ button\ .f.u\ -text\ Undo\ \ -command\ \{game\ undo\;\ \ game\ drawSetup\ .c\}\n\ \ \ \ button\ .f.r\ -text\ Reset\ -command\ \{game\ reset\;\ game\ drawSetup\ .c\}\n\ \ \ \ button\ .f.f\ -text\ Flip\ \ -command\ \{game\ flipSides\ .c\}\n\ \ \ \ eval\ pack\ \[winfo\ children\ .f\]\ -side\ left\ -fill\ both\n\ \ \ \ pack\ .f\ -fill\ x\ -side\ bottom\n\ \ \ \ pack\ \[game\ drawBoard\ .c\]\ -fill\ both\ -expand\ 1\ \ \ \ \n\ \ \ \ trace\ variable\ game(toMove)\ w\ MoveInfo\n\ \ \ \ proc\ MoveInfo\ \{-\ -\ -\}\ \{\n\ \ \ \ \ \ \ \ set\ ::info\ \"\$::game(toMove)\ to\ move\ -\ \[chess::values\ ::game\]\"\n\ \ \ \ \}\n\ \ \ \ set\ info\ \"white\ to\ move\"\n\ \ \ \ bind\ .\ <3>\ \{\n\ \ \ \ \ \ \ \ set\ game(usefont)\ \[expr\ 1-\$game(usefont)\]\n\ \ \ \ \ \ \ \ event\ generate\ .c\ <Configure>\n\ \ \ \ \}\n\ \ \ \ bind\ .\ ?\ \ \ \ \ \ \ \ \{console\ show\}\n\ \ \ \ bind\ .\ <Escape>\ \{exec\ wish\ \$argv0\ &\;\ exit\}\n\}\n======\n\n----\n\n\[KBK\]\ -\ I\ love\ it,\ except\ for\ the\ shapes\ of\ the\ chessmen.\ Are\ you\ aware\ that\nthe\ chessmen\ have\ Unicode\ symbols\ (\\u2654-\\u265f)?\n\n\[RS\]:\ No,\ I\ wasn't\ -\ thanks\ for\ the\ hint!\ I\ made\ this\ configurable\ (maybe\ not\neverybody\ has\ a\ font\ that\ supplies\ these...\ -\ Arial\ Unicode\ MS,\ as\ from\ Office\n2000,\ seems\ to\ have\ them).\ Use\ the\ ''-usefont\ 1''\ switch\ on\ the\ ''drawBoard''\ncommand\ to\ get\ an\ appearance\ like\ on\ the\ second\ screenshot.\ (The\ Unicodes\ I\nchose\ use\ only\ glyphs\ of\ black\ men,\ but\ repaint\ the\ white\ ones\ -\ the\ originals\nwere\ transparent\ internally\ and\ didn't\ come\ out\ well).\ You\ can\ toggle\ the\ two\nrepresentations\ with\ right\ mouseclick.\n\n\[MDD\]:\ \ Cool.\ \ You\ could\ use\ \[Tequila\]\ to\ make\ a\ simple\ two-player\ net\ version.\nIf\ you\ did\ that,\ it\ would\ be\ pretty\ straightforward\ to\ add\ a\ persistent\ game\ DB\ntoo.\n\n\[Lars\ H\]:\ Very\ nice\ (IMO\ even\ with\ the\ crude\ chessmen).\ A\ few\ of\ the\ basic\nmoves\ are\ however\ still\ missing:\n\n\ \ \ *\ '''En\ passant'''\ (a\ pawn\ that\ moved\ two\ squares\ in\ the\ previous\ move\ is\ taken\ by\ a\ pawn\ from\ the\ other\ side,\ as\ if\ the\ taken\ pawn\ had\ just\ moved\ one\ square).\ ''Implementation\ catch:''\ When\ undoing,\ the\ pawn\ is\ not\ put\ back\ on\ the\ square\ to\ which\ the\ taking\ pawn\ moved.\n\ \ \ *\ '''Check'''\ Currently,\ no\ notice\ is\ taken\ of\ whether\ there\ is\ currently\ a\ check.\ This\ is\ important,\ since\ it\ limits\ the\ number\ of\ allowed\ moves\;\ a\ player\ may\ not\ make\ a\ move\ that\ puts\ his\ own\ king\ in\ check,\ and\ a\ player\ whose\ king\ is\ in\ check\ must\ make\ a\ move\ that\ gets\ the\ king\ out\ of\ check.\ If\ the\ program\ took\ this\ into\ account\ when\ determining\ valid\ moves,\ I\ would\ definitely\ label\ it\ as\ child-safe.\n\ \ \ *\ '''Castling'''\ (king\ moves\ two\ squares\ towards\ a\ rook,\ the\ rook\ is\ placed\ on\ the\ square\ that\ the\ king\ passed).\ This\ is\ a\ serious\ restriction,\ since\ experienced\ chess-players\ usually\ seek\ to\ make\ this\ move.\ The\ king\ may\ not\ end\ up\ in\ check,\ nor\ pass\ through\ an\ intermediate\ position\ where\ it\ would\ be\ in\ check.\ This\ move\ is\ not\ allowed\ if\ either\ piece\ has\ already\ been\ moved.\ ''Implementation\ catch:''\ Requires\ that\ the\ history\ list\ is\ redesigned,\ since\ two\ men\ move\ in\ the\ same\ move.\n\nAlso,\ if\ there\ was\ an\ option\ to\ have\ a\ visible\ history\ list\ (perhaps\ as\ text\nwidget\ in\ a\ separate\ toplevel\ window),\ with\ a\ more\ \"chessy\"\ notation\ (like\nKe1-e2\ instead\ of\ E1-E2,\ Qd1xg4\ instead\ of\ D1-G4-p,\ etc.)\ then\ it\ would\ look\ a\nlot\ more\ professional.\n\n----\nJeeBee\ 2007-06:\ \ I\ used\ this\ code\ as\ a\ starting\ point\ for\ chess\ in\ my\ games\nplugin\ for\ aMSN.\ The\ source\ can\ be\ found\ here:\nhttp://amsn.svn.sourceforge.net/viewvc/amsn/trunk/amsn-extras/plugins/games/Chess.tcl?revision=8761&view=markup.\n----\n\n\[MNO\]:\ Are\ you\ aware\ of\ \[http://scid.sourceforge.net/%|%Scid\],\ a\ free\ chess\ database\ program\ written\ in\ Tcl/Tk,\ extended\ in\ C++?\n\n----\n\n\[MPJ\]\ has\ tweaked\ the\ above\ code\ so\ it\ fits\ well\ on\ a\ \[PocketPC\].\ \ I\ also\nfigured\ out\ how\ to\ add\ online\ play\ using\ \[TclSOAP\]\ and\ a\ Web\ Service\ listed\ on\nhttp://www.xmethods.net.\ \ Check\ it\ out\ at\ \[Play\ Chess\ With\ a\ WebService\].\n\n----\n\n\[MNO\]\ I've\ recently\ been\ working\ on\ an\ internet\ chess\ server\ client,\n\[PocketICS\],\ for\ PocketPC\ to\ connect\ to\ chessclub.com\ or\ freechess.org.\ \ It's\nnearly\ finished\ (still\ have\ some\ niggly\ things\ to\ fix\ such\ as\ queening\ of\npawns!)\ but\ corrently\ stuck\ owing\ to\ the\ problems\ described\ on\ the\ \[PocketPC\nsocket/fileevent\ strangeness\]\ page.\n\n----\n\n\[Michael\ Schlenker\]:\ \ Dumping\ the\ history\ as\ LaTeX\ file\ using\ chess.sty\ would\nbe\ nice.\ Or\ similar\ functionality.\n\n----\n\n\[MDD\]:\ \ I\ just\ noticed\ that\ it\ doesn't\ support\ queening\ of\ pawns.\ \ I\ should\nalso\ add\ that\ my\ 5-year-old\ daughter,\ who\ is\ in\ the\ process\ of\ learning\ chess,\nreally\ likes\ this\ app\ since\ it\ highlights\ both\ possible\ moves\ and\ potential\ncaptures\ for\ her.\n\n----\n\nCan\ someone\ update\ this\ page\ so\ that\ it\ is\ \[wish-reaper\]\ ready?\n\n\[escargo\]\ 2003-11-24:\ \ I\ changed\ the\ formatting\ of\ the\ abbreviations\ and\ncorrected\ an\ added\ space\;\ I\ used\ \[wish-reaper\]\ on\ it\ and\ ran\ it\ on\ my\ \[Windows\]\nXP\ laptop.\ \ I\ find\ that\ the\ white\ pieces\ don't\ show\ up\ all\ that\ well\ on\ my\nlaptop\ screen,\ but\ other\ than\ that\ it\ seems\ to\ work.\n\n\n\n<<categories>>\ Games\ |\ Application\ |\ Tcl/Tk\ games\ |\ Arts\ and\ crafts\ of\ Tcl-Tk\ programming regexp2} CALL {my render {Chess in Tcl} \[WikiDbImage\ chess.jpg\]\ \[WikiDbImage\ chessfont.jpg\]\n\n**\ Summary\ **\n\n\[Richard\ Suchenwirth\]\ 2002-09-14:\ \ In\ this\ weekend\ fun\ project,\ I\ experimented\nhow\ to\ play\ \[chess\]\ with\ Tcl.\n\n**\ Changes\ **\n\nThis\ version\ 0.2\ supports\ dynamic\ resizing\n\n**\ Description\ **\n\nMy\ ambition\ was\ not\ (yet)\ to\ code\ winning\ strategies,\ but\ just\ to\ handle\ the\nbasics\ -\ how\ to\ administer\ the\ board\ data\ structure,\ how\ to\ validate\ a\ move,\netc.\ The\ first\ part\ is\ \[pure-Tcl\],\ no\ Tk\ involved.\ \"\[Everything\ is\ a\ string\]\",\nso\ first\ I\ designed\ a\ string\ format\ to\ represent\ the\ state\ of\ the\ chess\ board:\none\ character\ per\ square\ -\ \".\"\ if\ empty,\ else\ the\ piece's\ abbreviation\n(uppercase\ for\ White,\ lowercase\ for\ black):\n\n'''R(ook=castle)\ (k)N(ight)\ B(ishop)\ Q(ueen)\ K(ing)\ P(awn).'''\n\nRows\ are\ delimited\ by\ newlines,\ squares\ by\ blanks.\ See\ the\ ''chess::reset''\nfunction\ for\ the\ example\ of\ the\ initial\ setup.\ Such\ strings\ can\ be\ loaded,\ if\nyou'd\ like\ to\ reproduce\ chess\ problems,\ or\ the\ current\ state\ of\ the\ board\ can\nbe\ returned\ in\ the\ same\ format.\n\nInternally,\ the\ board\ is\ implemented\ as\ an\ array\ in\ caller's\ scope,\ one\ element\nper\ square.\ Squares\ are\ named\ conventionally,\ A1\ being\ bottom\ left,\ H8\ top\nright.\ Moves\ are\ written\ in\ the\ form\ \$from-\$to,\ e.g.\ A2-A4,\ and\ kept\ in\ a\nhistory\ list\ which\ can\ be\ recalled\ or\ undone,\ one\ move\ at\ a\ time.\ \ Taken\ men\nare\ recorded\ as\ a\ suffix\ to\ the\ move,\ e.g.\ A2-A4-Q,\ so\ they\ can\ be\ reinstated\non\ undo.\ You\ can\ have\ multiple\ chess\ boards\ in\ parallel,\ if\ you\ \[wish\],\ as\ the\nAPI\ is\ \"object-oriented\":\n\n\ \ \ *\ chess::new\ myGame\n\ \ \ *\ myGame\ move\ A2-A4\n\n======\nnamespace\ eval\ chess\ \{set\ version\ 0.2\ \;#\ resize\ on\ <Configure>\}\nproc\ chess::new\ board\ \{\n\ \ \ \ #\ create\ a\ new\ game\ (generic\ dispatcher)\ with\ the\ board\ name\n\ \ \ \ proc\ ::\$board\ \{\{cmd\ format\}\ args\}\ \\\n\ \ \ \ \ \ \ \ \"uplevel\ 1\ chess::\\\$cmd\ \$board\ \\\$args\"\n\ \ \ \ uplevel\ 1\ \$board\ reset\n\}\nproc\ chess::reset\ \{boardName\ \{setup\ \"\"\}\}\ \{\n\ \ \ \ upvar\ 1\ \$boardName\ board\n\ \ \ \ if\ \{\$setup\ ==\ \"\"\}\ \{set\ setup\ \\\n\ \ \ \ \ \ \ \ \"r\ n\ b\ q\ k\ b\ n\ r\n\ \ \ \ \ \ \ \ \ p\ p\ p\ p\ p\ p\ p\ p\n\ \ \ \ \ \ \ \ \ .\ .\ .\ .\ .\ .\ .\ .\n\ \ \ \ \ \ \ \ \ .\ .\ .\ .\ .\ .\ .\ .\n\ \ \ \ \ \ \ \ \ .\ .\ .\ .\ .\ .\ .\ .\n\ \ \ \ \ \ \ \ \ .\ .\ .\ .\ .\ .\ .\ .\n\ \ \ \ \ \ \ \ \ P\ P\ P\ P\ P\ P\ P\ P\n\ \ \ \ \ \ \ \ \ R\ N\ B\ Q\ K\ B\ N\ R\"\n\ \ \ \ \}\n\ \ \ \ foreach\ line\ \[split\ \[string\ trim\ \$setup\]\ \\n\]\ y\ \{8\ 7\ 6\ 5\ 4\ 3\ 2\ 1\}\ \{\n\ \ \ \ \ \ \ \ foreach\ word\ \$line\ x\ \{A\ B\ C\ D\ E\ F\ G\ H\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ board(\$x\$y)\ \$word\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ set\ board(toMove)\ white\n\ \ \ \ set\ board(history)\ \{\}\ \;#\ start\ a\ new\ history...\n\}\nproc\ chess::format\ boardName\ \{\n\ \ \ \ #\ render\ current\ board\ into\ a\ well-readable\ string\n\ \ \ \ upvar\ 1\ \$boardName\ board\n\ \ \ \ foreach\ row\ \{8\ 7\ 6\ 5\ 4\ 3\ 2\ 1\}\ \{\n\ \ \ \ \ \ \ \ foreach\ column\ \{A\ B\ C\ D\ E\ F\ G\ H\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ append\ res\ \"\ \"\ \$board(\$column\$row)\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ append\ res\ \\n\n\ \ \ \ \}\n\ \ \ \ set\ res\n\}\nproc\ chess::move\ \{boardName\ move\}\ \{\n\ \ \ \ upvar\ 1\ \$boardName\ board\n\ \ \ \ foreach\ \{from\ to\}\ \[split\ \$move\ -\]\ break\n\ \ \ \ set\ fromMan\ \$board(\$from)\n\ \ \ \ if\ \{\$fromMan\ ==\ \".\"\}\ \{error\ \"no\ man\ to\ move\ at\ \$from\"\}\n\ \ \ \ set\ toMan\ \ \ \$board(\$to)\n\ \ \ \ if\ !\[valid?\ board\ \$move\]\ \{error\ \"invalid\ move\ for\ a\ \[manName\ \$fromMan\]\"\}\n\ \ \ \ set\ board(\$from)\ .\n\ \ \ \ set\ board(\$to)\ \ \ \$fromMan\n\ \ \ \ if\ \{\$toMan\ !=\ \".\"\}\ \{append\ move\ -\$toMan\}\ \;#\ taken\ one\n\ \ \ \ lappend\ board(history)\ \$move\n\ \ \ \ set\ board(toMove)\ \[expr\ \{\$board(toMove)\ ==\ \"white\"?\ \"black\":\ \"white\"\}\]\n\ \ \ \ set\ toMan\ \;#\ report\ possible\ victim\n\}\nproc\ chess::color\ man\ \{expr\ \{\[string\ is\ upper\ \$man\]?\ \"white\"\ :\ \"black\"\}\}\n\ \nproc\ chess::valid?\ \{boardName\ move\}\ \{\n\ \ \ \ upvar\ 1\ \$boardName\ board\n\ \ \ \ foreach\ \{from\ to\}\ \[split\ \$move\ -\]\ break\n\ \ \ \ if\ \{\$to==\"\"\}\ \{return\ 0\}\n\ \ \ \ set\ fromMan\ \$board(\$from)\n\ \ \ \ if\ \{\[color\ \$fromMan\]\ !=\ \$board(toMove)\}\ \{return\ 0\}\n\ \ \ \ set\ toMan\ \ \ \$board(\$to)\n\ \ \ \ if\ \[sameSide\ \$fromMan\ \$toMan\]\ \{return\ 0\}\n\ \ \ \ foreach\ \{x0\ y0\}\ \[coords\ \$from\]\ \{x1\ y1\}\ \[coords\ \$to\]\ break\n\ \ \ \ set\ dx\ \ \[expr\ \{\$x1-\$x0\}\]\n\ \ \ \ set\ adx\ \[expr\ \{abs(\$dx)\}\]\n\ \ \ \ set\ dy\ \ \[expr\ \{\$y1-\$y0\}\]\n\ \ \ \ set\ ady\ \[expr\ \{abs(\$dy)\}\]\n\ \ \ \ if\ \{\[string\ tolower\ \$fromMan\]\ !=\ \"n\"\ &&\ (!\$adx\ ||\ !\$ady\ ||\ \$adx==\$ady)\}\ \{\n\ \ \ \ \ \ \ \ for\ \{set\ x\ \$x0\;\ set\ y\ \$y0\}\ \{(\$x!=\$x1\ ||\ \$y!=\$y1)\}\ \\\n\ \ \ \ \ \ \ \ \ \ \{incr\ x\ \[sgn\ \$dx\]\;\ incr\ y\ \[sgn\ \$dy\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{(\$x!=\$x0\ ||\ \$y!=\$y0)\ &&\ \$board(\[square\ \$x\ \$y\])!=\".\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ 0\n\ \ \ \ \ \ \ \ \ \ \ \ \}\ \;#\ planned\ path\ is\ blocked\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ switch\ --\ \$fromMan\ \{\n\ \ \ \ \ \ \ \ K\ -\ k\ \{expr\ \$adx<2\ &&\ \$ady<2\}\n\ \ \ \ \ \ \ \ Q\ -\ q\ \{expr\ \$adx==0\ ||\ \$ady==0\ ||\ \$adx==\$ady\}\n\ \ \ \ \ \ \ \ B\ -\ b\ \{expr\ \$adx==\$ady\}\n\ \ \ \ \ \ \ \ N\ -\ n\ \{expr\ (\$adx==1\ &&\ \$ady==2)||(\$adx==2\ &&\ \$ady==1)\}\n\ \ \ \ \ \ \ \ R\ -\ r\ \{expr\ \$adx==0\ ||\ \$ady==0\}\n\ \ \ \ \ \ \ \ P\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ expr\ \{((\$y0==2\ &&\ \$dy==2)\ ||\ \$dy==1)\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ &&\ ((\$dx==0\ &&\ \$toMan==\".\")\ ||\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (\$adx==1\ &&\ \$ady==1\ &&\ \[sameSide\ p\ \$toMan\]))\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ p\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ expr\ \{((\$y0==7\ &&\ \$dy==-2)\ ||\ \$dy==-1)\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ &&\ ((\$dx==0\ &&\ \$toMan==\".\")\ ||\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (\$adx==1\ &&\ \$ady==1\ &&\ \[sameSide\ P\ \$toMan\]))\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ default\ \{return\ 0\}\n\ \ \ \ \}\n\}\nproc\ chess::validMoves\ \{boardName\ from\}\ \{\n\ \ \ \ upvar\ 1\ \$boardName\ board\n\ \ \ \ set\ res\ \{\}\n\ \ \ \ foreach\ to\ \[array\ names\ board\ ??\]\ \{\n\ \ \ \ \ \ \ \ set\ move\ \$from-\$to\n\ \ \ \ \ \ \ \ if\ \[valid?\ board\ \$move\]\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$board(\$to)\ !=\ \".\"\}\ \{append\ move\ -\$board(\$to)\}\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ res\ \$move\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ lsort\ \$res\n\}\nproc\ chess::coords\ square\ \{\n\ \ \ \ #\ translate\ square\ name\ to\ numeric\ coords:\ C5\ ->\ \{3\ 5\}\n\ \ \ \ foreach\ \{c\ y\}\ \[split\ \$square\ \"\"\]\ break\n\ \ \ \ list\ \[lsearch\ \{-\ A\ B\ C\ D\ E\ F\ G\ H\}\ \$c\]\ \$y\n\}\nproc\ chess::square\ \{x\ y\}\ \{\n\ \ \ \ #\ translate\ numeric\ coords\ to\ sq\ uare\ name:\ \{3\ 5\}\ ->\ C5\n\ \ \ \ return\ \[string\ map\ \{1\ A\ 2\ B\ 3\ C\ 4\ D\ 5\ E\ 6\ F\ 7\ G\ 8\ H\}\ \$x\]\$y\n\}\nproc\ chess::undo\ boardName\ \{\n\ \ \ \ upvar\ 1\ \$boardName\ board\n\ \ \ \ if\ !\[llength\ \$board(history)\]\ \{error\ \"Nothing\ to\ undo\"\}\n\ \ \ \ set\ move\ \[lindex\ \$board(history)\ end\]\n\ \ \ \ foreach\ \{from\ to\ hit\}\ \[split\ \$move\ -\]\ \ break\n\ \ \ \ set\ board(history)\ \[lrange\ \$board(history)\ 0\ end-1\]\n\ \ \ \ set\ board(\$from)\ \ \ \$board(\$to)\n\ \ \ \ if\ \{\$hit==\"\"\}\ \{set\ hit\ .\}\n\ \ \ \ set\ board(\$to)\ \$hit\n\ \ \ \ set\ board(toMove)\ \[expr\ \{\$board(toMove)\ ==\ \"white\"?\ \"bl\ ack\":\ \"white\"\}\]\n\}\nproc\ chess::sameSide\ \{a\ b\}\ \{regexp\ \{\[a-z\]\[a-z\]|\[A-Z\]\[A-Z\]\}\ \$a\$b\]\}\n\ \nproc\ chess::history\ boardName\ \{uplevel\ 1\ set\ \$boardName\\(history)\}\n\ \nproc\ chess::manName\ man\ \{\n\ \ \ \ set\ table\ \{-\ k\ king\ q\ queen\ b\ bishop\ n\ knight\ r\ rook\ p\ pawn\}\n\ \ \ \ set\ i\ \[l\ search\ \$table\ \[string\ tolower\ \$man\]\]\n\ \ \ \ lindex\ \$table\ \[incr\ i\]\n\}\nproc\ chess::values\ boardName\ \{\n\ \ \ \ #\ returns\ the\ current\ numeric\ value\ of\ white\ and\ black\ crews\n\ \ \ \ upvar\ 1\ \$boardName\ board\n\ \ \ \ set\ white\ 0\;\ set\ black\ 0\n\ \ \ \ foreach\ square\ \[array\ names\ b\ oard\ ??\]\ \{\n\ \ \ \ \ \ \ \ set\ man\ \$board(\$square)\n\ \ \ \ \ \ \ \ switch\ -regexp\ --\ \$man\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \[A-Z\]\ \{set\ white\ \[expr\ \{\$white\ +\ \[manValue\ \$man\]\}\]\}\n\ \ \ \ \ \ \ \ \ \ \ \ \[a-z\]\ \{set\ black\ \[expr\ \{\$black\ +\ \[manValue\ \$man\]\}\]\}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ list\ \$white\ \$black\n\}\nproc\ chess::manValue\ man\ \{\n\ \ \ \ array\ set\ a\ \{k\ 0\ q\ 9\ b\ 3.2\ n\ 3\ r\ 5\ p\ 1\}\n\ \ \ \ set\ a(\[string\ tolower\ \$man\])\n\}\n\n#-----------------------------------------------------------\ Tk\ UI\n\nif\ 0\ \{Now\ we\ create\ a\ \"real\"\ chess\ board\ on\ a\ canvas.\ The\ shapes\ of\nmen\ are\ extremely\ simple\ (maybe\ good\ for\ the\ visually\ impaired).\ Clicking\ on\na\ man\ highlights\ the\ valid\ moves\ in\ green\ (possible\ takes\ in\ red)\ for\ a\nsecond.\ Only\ valid\ moves\ are\ accepted,\ else\ the\ man\ snaps\ back\ to\ where\nhe\ stood.\ As\ bindings\ execute\ in\ global\ scope,\ the\ board\ array\ has\ to\nbe\ global\ for\ the\ UI.\n\}\n\n======\nproc\ chess::drawBoard\ \{boardName\ w\ args\}\ \{\n\ \ \ \ upvar\ #0\ \$boardName\ board\n\ \ \ \ array\ set\ opt\ \{-width\ 300\ -colors\ \{bisque\ tan3\}\ -side\ white\ -usefont\ 0\}\n\ \ \ \ array\ set\ opt\ \$args\n\ \ \ \ if\ \{!\[winfo\ exists\ \$w\]\}\ \{\n\ \ \ \ \ \ \ \ canvas\ \$w\ -width\ \$opt(-width)\ -height\ \$opt(-width)\n\ \ \ \ \ \ \ \ bind\ \$w\ <Configure>\ \"chess::drawBoard\ \$boardName\ \$w\ \$args\"\n\ \ \ \ \ \ \ \ set\ board(usefont)\ \$opt(-usefont)\n\ \ \ \ \ \ \ \ \$w\ bind\ mv\ <1>\ \[list\ chess::click1\ \$boardName\ \$w\ %x\ %y\]\n\ \ \ \ \ \ \ \ \$w\ bind\ mv\ <B1-Motion>\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ %W\ move\ current\ \[expr\ \{%x-\$chess::x\}\]\ \[expr\ \{%y-\$chess::y\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ chess::x\ %x\;\ set\ chess::y\ %y\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \$w\ bind\ mv\ <ButtonRelease-1>\ \"chess::release1\ \$boardName\ \$w\ %x\ %y\"\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \$w\ delete\ all\n\ \ \ \ \}\n\ \ \ \ set\ board(side)\ \ \ \$opt(-side)\n\ \ \ \ set\ dim\ \[min\ \[winfo\ height\ \$w\]\ \[winfo\ width\ \$w\]\]\n\ \ \ \ if\ \{\$dim<2\}\ \{set\ dim\ \$opt(-width)\}\n\ \ \ \ set\ board(sqw)\ \[set\ sqw\ \[expr\ \{(\$dim\ -\ 20)\ /\ 8\}\]\]\n\ \ \ \ set\ x0\ 15\n\ \ \ \ set\ x\ \$x0\;\ set\ y\ 5\;\ set\ colorIndex\ 0\n\ \ \ \ set\ rows\ \{8\ 7\ 6\ 5\ 4\ 3\ 2\ 1\}\n\ \ \ \ set\ cols\ \{A\ B\ C\ D\ E\ F\ G\ H\}\n\ \ \ \ if\ \{\$board(side)\ !=\ \"white\"\}\ \{\n\ \ \ \ \ \ \ \ set\ rows\ \[lrevert\ \$rows\]\n\ \ \ \ \ \ \ \ set\ cols\ \[lrevert\ \$cols\]\n\ \ \ \ \}\n\ \ \ \ foreach\ row\ \$rows\ \{\n\ \ \ \ \ \ \ \ \$w\ create\ text\ 5\ \[expr\ \{\$y+\$sqw/2\}\]\ -text\ \$row\n\ \ \ \ \ \ \ \ foreach\ col\ \$cols\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \$w\ create\ rect\ \$x\ \$y\ \[incr\ x\ \$sqw\]\ \[expr\ \$y+\$sqw\]\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -fill\ \[lindex\ \$opt(-colors)\ \$colorIndex\]\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -tag\ \[list\ square\ \$col\$row\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ colorIndex\ \[expr\ \{1-\$colorIndex\}\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ set\ x\ \$x0\;\ incr\ y\ \$sqw\n\ \ \ \ \ \ \ \ set\ colorIndex\ \[expr\ \{1-\$colorIndex\}\]\n\ \ \ \ \}\n\ \ \ \ set\ x\ \[expr\ \{\$x0\ -\ \$sqw/2\}\]\n\ \ \ \ incr\ y\ 8\ \;#\ letters\ go\ below\ chess\ board\n\ \ \ \ foreach\ col\ \$cols\ \{\$w\ create\ text\ \[incr\ x\ \$sqw\]\ \$y\ -text\ \$col\}\n\ \ \ \ drawSetup\ \$boardName\ \$w\n\ \ \ \ set\ w\n\}\nproc\ chess::click1\ \{boardName\ w\ cx\ cy\}\ \{\n\ \ \ \ upvar\ #0\ \$boardName\ board\n\ \ \ \ variable\ x\ \$cx\ y\ \$cy\ from\n\ \ \ \ \$w\ raise\ current\n\ \ \ \ regexp\ \{@(..)\}\ \[\$w\ gettags\ current\]\ ->\ from\n\ \ \ \ foreach\ move\ \[validMoves\ board\ \$from\]\ \{\n\ \ \ \ \ \ \ \ foreach\ \{-\ to\ victim\}\ \[split\ \$move\ -\]\ break\n\ \ \ \ \ \ \ \ set\ fill\ \[\$w\ itemcget\ \$to\ -fill\]\n\ \ \ \ \ \ \ \ if\ \{\$fill\ !=\ \"green\"\ &&\ \$fill\ !=\ \"red\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ newfill\ \[expr\ \{\$victim==\"\"?\ \"green\"\ :\ \"red\"\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \$w\ itemconfig\ \$to\ -fill\ \$newfill\n\ \ \ \ \ \ \ \ \ \ \ \ after\ 1000\ \$w\ itemconfig\ \$to\ -fill\ \$fill\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\}\nproc\ chess::release1\ \{boardName\ w\ cx\ cy\}\ \{\n\ \ \ \ upvar\ #0\ \$boardName\ board\n\ \ \ \ variable\ from\n\ \ \ \ set\ to\ \"\"\n\ \ \ \ foreach\ i\ \[\$w\ find\ overlap\ \$cx\ \$cy\ \$cx\ \$cy\]\ \{\n\ \ \ \ \ \ \ \ set\ tags\ \[\$w\ gettags\ \$i\]\n\ \ \ \ \ \ \ \ if\ \{\[lsearch\ \$tags\ square\]>=0\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ to\ \[lindex\ \$tags\ end\]\n\ \ \ \ \ \ \ \ \ \ \ \ break\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ if\ \[valid?\ board\ \$from-\$to\]\ \{\n\ \ \ \ \ \ \ \ set\ victim\ \[move\ board\ \$from-\$to\]\n\ \ \ \ \ \ \ \ if\ \{\[string\ tolower\ \$victim\]==\"k\"\}\ \{set\ ::info\ Checkmate.\}\n\ \ \ \ \ \ \ \ \$w\ delete\ @\$to\n\ \ \ \ \ \ \ \ set\ target\ \$to\n\ \ \ \ \ \ \ \ \$w\ dtag\ current\ @\$from\n\ \ \ \ \ \ \ \ \$w\ addtag\ @\$to\ withtag\ current\n\ \ \ \ \}\ else\ \{set\ target\ \$from\}\ \;#\ go\ back\ on\ invalid\ move\n\ \ \ \ foreach\ \{x0\ y0\ x1\ y1\}\ \ \ \ \ \[\$w\ bbox\ \$target\]\ break\n\ \ \ \ foreach\ \{xm0\ ym0\ xm1\ ym1\}\ \[\$w\ bbox\ current\]\ break\n\ \ \ \ set\ dx\ \[expr\ \{(\$x0+\ \$x1-\$xm0-\$xm1)/2\}\]\n\ \ \ \ set\ dy\ \[expr\ \{(\$y0+\$y1-\$ym0-\$ym1)/2\}\]\n\ \ \ \ \$w\ move\ current\ \$dx\ \$dy\n\}\nproc\ chess::drawSetup\ \{boardName\ w\}\ \{\n\ \ \ \ upvar\ #0\ \$boardName\ board\n\ \ \ \ \$w\ delete\ mv\n\ \ \ \ foreach\ square\ \[array\ names\ board\ ??\]\ \{\n\ \ \ \ \ \ \ \ drawMan\ \$boardName\ \$w\ \$square\ \$board(\$square)\n\ \ \ \ \}\n\}\nproc\ chess::drawMan\ \{boardName\ w\ where\ what\}\ \{\n\ \ \ \ if\ \{\$what==\".\"\}\ return\n\ \ \ \ upvar\ #0\ \$boardName\ board\n\ \ \ \ set\ fill\ \[expr\ \{\[regexp\ \{\[A-Z\]\}\ \$what\]?\ \"white\":\ \"black\"\}\]\n\ \ \ \ if\ \$board(usefont)\ \{\n\ \ \ \ \ \ \ \ set\ unicode\ \[string\ map\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ k\ \\u265a\ q\ \\u265b\ r\ \\u265c\ b\ \\u265d\ n\ \\u265e\ p\ \\u265f\n\ \ \ \ \ \ \ \ \ \ k\ K\ q\ Q\ r\ R\ b\ B\ n\ N\ p\ P\n\ \ \ \ \ \ \ \ \}\ \[string\ tolower\ \$what\]\]\n\ \ \ \ \ \ \ \ set\ font\ \[list\ Helvetica\ \[expr\ \{\$board(sqw)/2\}\]\ bold\]\n\ \ \ \ \ \ \ \ \$w\ create\ text\ 0\ 0\ -text\ \$unicode\ -font\ \$font\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ -tag\ \[list\ mv\ @\$where\]\ -fill\ \$fill\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \$w\ create\ poly\ \[manPolygon\ \$what\]\ -fill\ \$fill\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ -tag\ \[list\ mv\ @\$where\]\ -outline\ gray\n\ \ \ \ \ \ \ \ set\ f\ \[expr\ \{\$board(sqw)*0.035\}\]\n\ \ \ \ \ \ \ \ \$w\ scale\ @\$where\ 0\ 0\ \$f\ \$f\n\ \ \ \ \}\n\ \ \ \ foreach\ \{x0\ y0\ x1\ y1\}\ \[\$w\ bbox\ \$where\]\ break\n\ \ \ \ \$w\ move\ \ @\$where\ \[expr\ \{(\$x0+\$x1)/2\}\]\ \[expr\ \{(\$y0+\$y1)/2\}\]\n\}\nproc\ chess::manPolygon\ what\ \{\n\ \ \ \ #\ very\ simple\ shapes\ of\ the\ chess\ men\ -\ feel\ free\ to\ improve!\n\ \ \ \ switch\ --\ \[string\ tolower\ \$what\]\ \{\n\ \ \ \ \ b\ \{list\ -10\ 8\ \ -5\ 5\ \ -9\ 0\ \ -6\ -6\ \ 0\ -10\ \ 6\ -6\ \ 9\ 0\ \ 5\ 5\ \ 10\ 8\\\n\ \ \ \ \ \ \ \ 6\ 10\ \ 0\ 6\ \ -6\ 10\}\n\ \ \ \ \ k\ \{list\ -8\ 10\ \ -10\ 1\ \ -3\ -1\ \ -3\ -3\ \ -6\ -3\ \ -6\ -7\ \ -3\ -7\ \ -3\ -10\\\n\ \ \ \ \ \ \ \ 3\ -10\ \ 3\ -7\ \ 6\ -7\ \ 6\ -3\ \ 3\ -3\ \ 3\ -1\ \ 10\ 1\ \ 8\ 10\}\n\ \ \ \ \ n\ \{list\ -8\ 10\ \ -1\ -1\ \ -7\ 0\ \ -10\ -4\ \ 0\ -10\ \ 6\ -10\ \ 10\ 10\}\n\ \ \ \ \ p\ \{list\ -8\ 10\ \ -8\ 7\ \ -5\ 7\ \ -2\ -1\ \ -4\ -5\ \ -2\ -10\ \ 2\ -10\ \ 4\ -5\ \\\n\ \ \ \ \ \ \ \ \ \ 2\ -1\ \ 5\ 7\ \ 8\ 7\ \ 8\ 10\}\n\ \ \ \ \ q\ \{list\ -6\ 10\ \ -10\ -10\ \ -3\ 0\ \ 0\ -10\ \ 3\ 0\ \ 10\ -10\ \ 6\ 10\}\n\ \ \ \ \ r\ \{list\ -10\ 10\ \ -7\ 1\ \ -10\ 0\ \ -10\ -10\ \ -5\ -10\ \ -5\ -6\ \ -3\ -6\ \ -3\ -10\\\n\ \ \ \ \ \ \ \ \ \ 3\ -10\ \ 3\ -6\ \ 5\ -6\ \ 5\ -10\ \ 10\ -10\ 10\ 0\ \ 7\ 1\ \ 10\ 10\}\n\ \ \ \ \}\n\}\nproc\ chess::flipSides\ \{boardName\ w\}\ \{\n\ \ \ \ upvar\ #0\ \$boardName\ board\n\ \ \ \ \$w\ delete\ all\n\ \ \ \ set\ side\ \[expr\ \{\$board(side)==\"white\"?\ \"black\":\ \"white\"\}\]\n\ \ \ \ \$boardName\ drawBoard\ \$w\ -side\ \$side\n\}\n#-------------------------------------\ some\ general\ utilities:\nproc\ lrevert\ list\ \{\n\ \ \ \ set\ res\ \{\}\n\ \ \ \ set\ i\ \[llength\ \$list\]\n\ \ \ \ while\ \{\$i\}\ \{lappend\ res\ \[lindex\ \$list\ \[incr\ i\ -1\]\]\}\n\ \ \ \ set\ res\n\}\nproc\ min\ args\ \{lindex\ \[lsort\ -real\ \$args\]\ 0\}\nproc\ sgn\ x\ \{expr\ \{\$x>0?\ 1:\ \$x<0?\ -1:\ 0\}\}\ \n#------------------------------------------------testing\ demo:\nif\ \{\[file\ tail\ \[info\ script\]\]==\[file\ tail\ \$argv0\]\}\ \{\n\ \ \ \ chess::new\ game\n\ \ \ \ frame\ .f\n\ \ \ \ label\ \ .f.e\ -width\ 30\ -anchor\ w\ -textvar\ info\ -relief\ sunken\n\ \ \ \ button\ .f.u\ -text\ Undo\ \ -command\ \{game\ undo\;\ \ game\ drawSetup\ .c\}\n\ \ \ \ button\ .f.r\ -text\ Reset\ -command\ \{game\ reset\;\ game\ drawSetup\ .c\}\n\ \ \ \ button\ .f.f\ -text\ Flip\ \ -command\ \{game\ flipSides\ .c\}\n\ \ \ \ eval\ pack\ \[winfo\ children\ .f\]\ -side\ left\ -fill\ both\n\ \ \ \ pack\ .f\ -fill\ x\ -side\ bottom\n\ \ \ \ pack\ \[game\ drawBoard\ .c\]\ -fill\ both\ -expand\ 1\ \ \ \ \n\ \ \ \ trace\ variable\ game(toMove)\ w\ MoveInfo\n\ \ \ \ proc\ MoveInfo\ \{-\ -\ -\}\ \{\n\ \ \ \ \ \ \ \ set\ ::info\ \"\$::game(toMove)\ to\ move\ -\ \[chess::values\ ::game\]\"\n\ \ \ \ \}\n\ \ \ \ set\ info\ \"white\ to\ move\"\n\ \ \ \ bind\ .\ <3>\ \{\n\ \ \ \ \ \ \ \ set\ game(usefont)\ \[expr\ 1-\$game(usefont)\]\n\ \ \ \ \ \ \ \ event\ generate\ .c\ <Configure>\n\ \ \ \ \}\n\ \ \ \ bind\ .\ ?\ \ \ \ \ \ \ \ \{console\ show\}\n\ \ \ \ bind\ .\ <Escape>\ \{exec\ wish\ \$argv0\ &\;\ exit\}\n\}\n======\n\n----\n\n\[KBK\]\ -\ I\ love\ it,\ except\ for\ the\ shapes\ of\ the\ chessmen.\ Are\ you\ aware\ that\nthe\ chessmen\ have\ Unicode\ symbols\ (\\u2654-\\u265f)?\n\n\[RS\]:\ No,\ I\ wasn't\ -\ thanks\ for\ the\ hint!\ I\ made\ this\ configurable\ (maybe\ not\neverybody\ has\ a\ font\ that\ supplies\ these...\ -\ Arial\ Unicode\ MS,\ as\ from\ Office\n2000,\ seems\ to\ have\ them).\ Use\ the\ ''-usefont\ 1''\ switch\ on\ the\ ''drawBoard''\ncommand\ to\ get\ an\ appearance\ like\ on\ the\ second\ screenshot.\ (The\ Unicodes\ I\nchose\ use\ only\ glyphs\ of\ black\ men,\ but\ repaint\ the\ white\ ones\ -\ the\ originals\nwere\ transparent\ internally\ and\ didn't\ come\ out\ well).\ You\ can\ toggle\ the\ two\nrepresentations\ with\ right\ mouseclick.\n\n\[MDD\]:\ \ Cool.\ \ You\ could\ use\ \[Tequila\]\ to\ make\ a\ simple\ two-player\ net\ version.\nIf\ you\ did\ that,\ it\ would\ be\ pretty\ straightforward\ to\ add\ a\ persistent\ game\ DB\ntoo.\n\n\[Lars\ H\]:\ Very\ nice\ (IMO\ even\ with\ the\ crude\ chessmen).\ A\ few\ of\ the\ basic\nmoves\ are\ however\ still\ missing:\n\n\ \ \ *\ '''En\ passant'''\ (a\ pawn\ that\ moved\ two\ squares\ in\ the\ previous\ move\ is\ taken\ by\ a\ pawn\ from\ the\ other\ side,\ as\ if\ the\ taken\ pawn\ had\ just\ moved\ one\ square).\ ''Implementation\ catch:''\ When\ undoing,\ the\ pawn\ is\ not\ put\ back\ on\ the\ square\ to\ which\ the\ taking\ pawn\ moved.\n\ \ \ *\ '''Check'''\ Currently,\ no\ notice\ is\ taken\ of\ whether\ there\ is\ currently\ a\ check.\ This\ is\ important,\ since\ it\ limits\ the\ number\ of\ allowed\ moves\;\ a\ player\ may\ not\ make\ a\ move\ that\ puts\ his\ own\ king\ in\ check,\ and\ a\ player\ whose\ king\ is\ in\ check\ must\ make\ a\ move\ that\ gets\ the\ king\ out\ of\ check.\ If\ the\ program\ took\ this\ into\ account\ when\ determining\ valid\ moves,\ I\ would\ definitely\ label\ it\ as\ child-safe.\n\ \ \ *\ '''Castling'''\ (king\ moves\ two\ squares\ towards\ a\ rook,\ the\ rook\ is\ placed\ on\ the\ square\ that\ the\ king\ passed).\ This\ is\ a\ serious\ restriction,\ since\ experienced\ chess-players\ usually\ seek\ to\ make\ this\ move.\ The\ king\ may\ not\ end\ up\ in\ check,\ nor\ pass\ through\ an\ intermediate\ position\ where\ it\ would\ be\ in\ check.\ This\ move\ is\ not\ allowed\ if\ either\ piece\ has\ already\ been\ moved.\ ''Implementation\ catch:''\ Requires\ that\ the\ history\ list\ is\ redesigned,\ since\ two\ men\ move\ in\ the\ same\ move.\n\nAlso,\ if\ there\ was\ an\ option\ to\ have\ a\ visible\ history\ list\ (perhaps\ as\ text\nwidget\ in\ a\ separate\ toplevel\ window),\ with\ a\ more\ \"chessy\"\ notation\ (like\nKe1-e2\ instead\ of\ E1-E2,\ Qd1xg4\ instead\ of\ D1-G4-p,\ etc.)\ then\ it\ would\ look\ a\nlot\ more\ professional.\n\n----\nJeeBee\ 2007-06:\ \ I\ used\ this\ code\ as\ a\ starting\ point\ for\ chess\ in\ my\ games\nplugin\ for\ aMSN.\ The\ source\ can\ be\ found\ here:\nhttp://amsn.svn.sourceforge.net/viewvc/amsn/trunk/amsn-extras/plugins/games/Chess.tcl?revision=8761&view=markup.\n----\n\n\[MNO\]:\ Are\ you\ aware\ of\ \[http://scid.sourceforge.net/%|%Scid\],\ a\ free\ chess\ database\ program\ written\ in\ Tcl/Tk,\ extended\ in\ C++?\n\n----\n\n\[MPJ\]\ has\ tweaked\ the\ above\ code\ so\ it\ fits\ well\ on\ a\ \[PocketPC\].\ \ I\ also\nfigured\ out\ how\ to\ add\ online\ play\ using\ \[TclSOAP\]\ and\ a\ Web\ Service\ listed\ on\nhttp://www.xmethods.net.\ \ Check\ it\ out\ at\ \[Play\ Chess\ With\ a\ WebService\].\n\n----\n\n\[MNO\]\ I've\ recently\ been\ working\ on\ an\ internet\ chess\ server\ client,\n\[PocketICS\],\ for\ PocketPC\ to\ connect\ to\ chessclub.com\ or\ freechess.org.\ \ It's\nnearly\ finished\ (still\ have\ some\ niggly\ things\ to\ fix\ such\ as\ queening\ of\npawns!)\ but\ corrently\ stuck\ owing\ to\ the\ problems\ described\ on\ the\ \[PocketPC\nsocket/fileevent\ strangeness\]\ page.\n\n----\n\n\[Michael\ Schlenker\]:\ \ Dumping\ the\ history\ as\ LaTeX\ file\ using\ chess.sty\ would\nbe\ nice.\ Or\ similar\ functionality.\n\n----\n\n\[MDD\]:\ \ I\ just\ noticed\ that\ it\ doesn't\ support\ queening\ of\ pawns.\ \ I\ should\nalso\ add\ that\ my\ 5-year-old\ daughter,\ who\ is\ in\ the\ process\ of\ learning\ chess,\nreally\ likes\ this\ app\ since\ it\ highlights\ both\ possible\ moves\ and\ potential\ncaptures\ for\ her.\n\n----\n\nCan\ someone\ update\ this\ page\ so\ that\ it\ is\ \[wish-reaper\]\ ready?\n\n\[escargo\]\ 2003-11-24:\ \ I\ changed\ the\ formatting\ of\ the\ abbreviations\ and\ncorrected\ an\ added\ space\;\ I\ used\ \[wish-reaper\]\ on\ it\ and\ ran\ it\ on\ my\ \[Windows\]\nXP\ laptop.\ \ I\ find\ that\ the\ white\ pieces\ don't\ show\ up\ all\ that\ well\ on\ my\nlaptop\ screen,\ but\ other\ than\ that\ it\ seems\ to\ work.\n\n\n\n<<categories>>\ Games\ |\ Application\ |\ Tcl/Tk\ games\ |\ Arts\ and\ crafts\ of\ Tcl-Tk\ programming} CALL {my revision {Chess in Tcl}} CALL {::oo::Obj5394670 process revision/Chess+in+Tcl} CALL {::oo::Obj5394668 process}

-errorcode

NONE

-errorinfo

Unknow state transition: LINE -> END
    while executing
"error $msg"
    (class "::Wiki" method "render_wikit" line 6)
    invoked from within
"my render_$default_markup $N $C $mkup_rendering_engine"
    (class "::Wiki" method "render" line 8)
    invoked from within
"my render $name $C"
    (class "::Wiki" method "revision" line 31)
    invoked from within
"my revision $page"
    (class "::Wiki" method "process" line 56)
    invoked from within
"$server process [string trim $uri /]"

-errorline

4