Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/Lights+Out?V=9
QUERY_STRINGV=9
CONTENT_TYPE
DOCUMENT_URI/revision/Lights+Out
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.70.127.34
REMOTE_PORT19474
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR3.144.243.184
HTTP_CF_RAY87f5c2c55b7c2b1c-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_IP3.144.243.184
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 {Lights Out} \[Keith\ Vetter\]\ 2004-09-10\ :\ This\ is\ a\ one-person\ puzzle\ in\ which\ you\ try\nto\ turn\ off\ all\ the\ lights.\ The\ board\ consists\ of\ a\ lattice\ of\ lights\ which\ncan\ be\ turned\ on\ and\ off.\ Clicking\ on\ any\ light\ toggles\ the\ on/off\ state\nof\ that\ light\ and\ its\ four\ vertically\ and\ horizontally\ adjacent\ neighbors.\n\nDetermining\ if\ a\ given\ random\ arrangement\ of\ on/off\ lights\ can\ be\ all\ turned\noff\ is\ known\ as\ the\ ''All-Ones\ Problem''.\n\nOne\ interesting\ quirk\ is\ that\ it\ doesn't\ matter\ the\ order\ of\ toggling\ lights\nneeded\ to\ reach\ the\ solution--the\ solution\ is\ communative.\ \n\n\[KPV\]\ 2004-09-11\ :\ Added\ a\ \"Hint\"\ button\ which\ first\ does\ a\ search\ find\nthe\ solution\ then\ displays\ one\ of\ the\ lights\ which\ needs\ to\ be\ toggled.\nThe\ solver\ does\ a\ BFS\ and\ can\ be\ time\ consuming\ for\ large\ size\ boards.\n\n----\n\ ##+##########################################################################\n\ #\n\ #\ LightsOut.tcl\ -\ description\n\ #\ by\ Keith\ Vetter\ --\ Sept\ 10,\ 2004\n\ #\ http://mathworld.wolfram.com/LightsOutPuzzle.html\n\ #\n\ package\ require\ Tk\n\ \n\ array\ set\ S\ \{title\ \"Lights\ Out\"\ w\ 500\ h\ 500\}\n\ array\ set\ G\ \{rows\ 3\ cols\ 3\}\n\ \n\ proc\ DoDisplay\ \{\}\ \{\n\ \ \ \ wm\ title\ .\ \$::S(title)\n\ \ \ \ frame\ .ctrl\ -relief\ ridge\ -bd\ 2\ -padx\ 5\ -pady\ 5\n\ \ \ \ canvas\ .c\ -relief\ raised\ -height\ \$::S(h)\ -width\ \$::S(w)\ -bd\ 2\ \\\n\ \ \ \ \ \ \ \ -highlightthickness\ 0\ -relief\ raised\n\ \ \ \ pack\ .ctrl\ -side\ right\ -fill\ both\ -ipady\ 5\n\ \ \ \ pack\ .c\ -side\ top\ -fill\ both\ -expand\ 1\n\ \n\ \ \ \ bind\ all\ <Key-F2>\ \{console\ show\}\n\ \ \ \ bind\ .c\ <Configure>\ \{ReCenter\ %W\ %h\ %w\}\n\ \n\ \ \ \ DoCtrlFrame\n\ \}\n\ proc\ ReCenter\ \{W\ h\ w\}\ \{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Called\ by\ configure\ event\n\ \ \ \ set\ h2\ \[expr\ \{\$h\ /\ 2\}\]\n\ \ \ \ set\ w2\ \[expr\ \{\$w\ /\ 2\}\]\n\ \ \ \ \$W\ config\ -scrollregion\ \[list\ -\$w2\ -\$h2\ \$w2\ \$h2\]\n\ \ \ \ DrawBoard\ 1\n\ \}\n\ \n\ proc\ DoCtrlFrame\ \{\}\ \{\n\ \ \ \ button\ .restart\ \ -text\ \"Restart\ Game\"\ -command\ \[list\ NewBoard\ last\]\ -bd\ 4\n\ \ \ \ .restart\ configure\ \ -font\ \"\[font\ actual\ \[.restart\ cget\ -font\]\]\ -weight\ bold\"\n\ \ \ \ option\ add\ *font\ \[.restart\ cget\ -font\]\n\ \ \ \ button\ .new\ -text\ \"New\ Game\"\ -bd\ 4\ -command\ \[list\ NewBoard\ rand\]\n\ \ \ \ button\ .hint\ -text\ Hint\ -bd\ 4\ -command\ ::Solve::Hint\n\ \ \ \ button\ .solution\ -text\ Solution\ -bd\ 4\ -command\ \{::Solve::Hint\ 1\}\n\ \ \ \ scale\ .rows\ -from\ 1\ -to\ 10\ -label\ Rows\ -orient\ h\ -relief\ ridge\ \\\n\ \ \ \ \ \ \ \ -variable\ G(rows)\ -command\ \[list\ NewBoard\ rand\]\n\ \ \ \ scale\ .cols\ -from\ 1\ -to\ 10\ -label\ Columns\ -orient\ h\ -relief\ ridge\ \\\n\ \ \ \ \ \ \ \ -variable\ G(cols)\ -command\ \[list\ NewBoard\ rand\]\n\ \ \ \ label\ .moves\ -textvariable\ G(tmoves)\ -relief\ sunken\n\ \ \ \ button\ .help\ -text\ Help\ -command\ Help\n\ \ \ \ \n\ \ \ \ grid\ .restart\ -in\ .ctrl\ -row\ 0\ -sticky\ ew\n\ \ \ \ grid\ .new\ -in\ .ctrl\ -sticky\ ew\n\ \ \ \ grid\ rowconfigure\ .ctrl\ 5\ -minsize\ 20\n\ \ \ \ grid\ .hint\ -in\ .ctrl\ -sticky\ ew\ -row\ 6\n\ \ \ \ grid\ .solution\ -in\ .ctrl\ -sticky\ ew\n\ \ \ \ grid\ rowconfigure\ .ctrl\ 10\ -minsize\ 50\n\ \ \ \ grid\ .rows\ -in\ .ctrl\ -sticky\ ew\ -row\ 11\n\ \ \ \ grid\ .cols\ -in\ .ctrl\ -sticky\ ew\n\ \ \ \ grid\ rowconfigure\ .ctrl\ 20\ -minsize\ 80\n\ \ \ \ grid\ .moves\ -in\ .ctrl\ -sticky\ ew\ -rows\ 21\n\ \ \ \ grid\ rowconfigure\ .ctrl\ 50\ -weight\ 1\n\ \ \ \ grid\ .help\ \ \ -in\ .ctrl\ -sticky\ ew\ -row\ 100\n\ \}\n\ proc\ DrawBoard\ \{\{redraw\ 0\}\}\ \{\n\ \ \ \ global\ S\ G\ NEIGHBORS\n\ \n\ \ \ \ .c\ delete\ msg\ hint\n\ \ \ \ if\ \{\$redraw\}\ \{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Redraw\ everything\n\ \ \ \ \ \ \ \ unset\ -nocomplain\ NEIGHBORS\ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Memoize\ array\n\ \ \ \ \ \ \ \ .c\ delete\ all\n\ \ \ \ \ \ \ \ set\ S(w)\ \[winfo\ width\ .c\]\n\ \ \ \ \ \ \ \ set\ S(h)\ \[winfo\ height\ .c\]\n\ \ \ \ \ \ \ \ set\ S(dx)\ \[expr\ \{double(\$S(w)\ -\ 10)\ /\ \$G(cols)\}\]\n\ \ \ \ \ \ \ \ set\ S(dy)\ \[expr\ \{double(\$S(h)\ -\ 10)\ /\ \$G(rows)\}\]\n\ \ \ \ \ \ \ \ if\ \{\$S(dx)\ <\ \$S(dy)\}\ \{set\ S(dy)\ \$S(dx)\}\ else\ \{set\ S(dx)\ \$S(dy)\}\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ set\ S(x0)\ \[expr\ \{-\ \$S(dx)\ *\ \$G(cols)\ /\ 2\}\]\n\ \ \ \ \ \ \ \ set\ S(y0)\ \[expr\ \{-\ \$S(dy)\ *\ \$G(rows)\ /\ 2\}\]\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ for\ \{set\ row\ 0\}\ \{\$row\ <\ \$G(rows)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ for\ \{set\ col\ 0\}\ \{\$col\ <\ \$G(cols)\}\ \{incr\ col\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ xy\ \[GetBox\ \$row\ \$col\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .c\ create\ rect\ \$xy\ -tag\ \[list\ c\ c\$row,\$col\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .c\ bind\ c\$row,\$col\ <Button-1>\ \[list\ DoClick\ \$row\ \$col\]\n\ \n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ set\ xy0\ \[GetBox\ 0\ 0\]\n\ \ \ \ \ \ \ \ set\ xy1\ \[GetBox\ \$G(rows)\ \$G(cols)\]\n\ \ \ \ \ \ \ \ set\ xy\ \[concat\ \[lrange\ \$xy0\ 0\ 1\]\ \[lrange\ \$xy1\ 0\ 1\]\]\n\ \ \ \ \ \ \ \ .c\ create\ rect\ \$xy\ -width\ 3\n\ \ \ \ \}\n\ \n\ \ \ \ #\ Draw\ the\ light\ lattice\n\ \ \ \ for\ \{set\ row\ 0\}\ \{\$row\ <\ \$G(rows)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ for\ \{set\ col\ 0\}\ \{\$col\ <\ \$G(cols)\}\ \{incr\ col\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ fill\ \[.c\ cget\ -bg\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$G(board,\$row,\$col)\ >\ 0\}\ \{set\ fill\ yellow\}\n\ \ \ \ \ \ \ \ \ \ \ \ .c\ itemconfig\ c\$row,\$col\ -fill\ \$fill\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ if\ \{\$G(msg)\ ne\ \"\"\}\ \{\n\ \ \ \ \ \ \ \ .c\ create\ text\ 0\ 0\ -tag\ msg\ -text\ \$G(msg)\ -font\ \{Times\ 36\ bold\}\n\ \ \ \ \}\n\ \}\n\ proc\ ShowHint\ \{row\ col\}\ \{\n\ \ \ \ set\ xy\ \[GetOval\ \$row\ \$col\]\n\ \ \ \ .c\ create\ oval\ \$xy\ -tag\ \[list\ hint\ h\$row,\$col\]\ -fill\ red\n\ \ \ \ .c\ bind\ h\$row,\$col\ <Button-1>\ \[list\ DoClick\ \$row\ \$col\]\n\ \}\n\ proc\ GetBox\ \{row\ col\}\ \{\n\ \ \ \ global\ S\n\ \n\ \ \ \ set\ x0\ \[expr\ \{\$S(x0)\ +\ \$col\ *\ \$S(dx)\}\]\n\ \ \ \ set\ y0\ \[expr\ \{\$S(y0)\ +\ \$row\ *\ \$S(dy)\}\]\n\ \ \ \ set\ x1\ \[expr\ \{\$x0\ +\ \$S(dx)\}\]\n\ \ \ \ set\ y1\ \[expr\ \{\$y0\ +\ \$S(dy)\}\]\n\ \ \ \ return\ \[list\ \$x0\ \$y0\ \$x1\ \$y1\]\n\ \}\n\ proc\ GetOval\ \{row\ col\}\ \{\n\ \ \ \ global\ S\n\ \n\ \ \ \ set\ x0\ \[expr\ \{\$S(x0)\ +\ (\$col\ +\ .33)\ *\ \$S(dx)\}\]\n\ \ \ \ set\ y0\ \[expr\ \{\$S(y0)\ +\ (\$row\ +\ .33)\ *\ \$S(dy)\}\]\n\ \ \ \ set\ x1\ \[expr\ \{\$S(x0)\ +\ (\$col\ +\ .66)\ *\ \$S(dx)\}\]\n\ \ \ \ set\ y1\ \[expr\ \{\$S(y0)\ +\ (\$row\ +\ .66)\ *\ \$S(dy)\}\]\n\ \ \ \ return\ \[list\ \$x0\ \$y0\ \$x1\ \$y1\]\n\ \}\n\ proc\ Neighbors\ \{row\ col\}\ \{\n\ \ \ \ global\ NEIGHBORS\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Memoize\n\ \n\ \ \ \ if\ \{\[info\ exists\ NEIGHBORS(\$row,\$col)\]\}\ \{\ return\ \$NEIGHBORS(\$row,\$col)\ \}\n\ \ \ \ set\ who\ \{\}\n\ \ \ \ foreach\ \{dr\ dc\}\ \{-1\ 0\ \ \ 0\ 0\ \ 1\ 0\ \ \ 0\ -1\ 0\ 1\}\ \{\n\ \ \ \ \ \ \ \ set\ r\ \[expr\ \{\$row\ +\ \$dr\}\]\n\ \ \ \ \ \ \ \ set\ c\ \[expr\ \{\$col\ +\ \$dc\}\]\n\ \ \ \ \ \ \ \ if\ \{\$r\ <\ 0\ ||\ \$c\ <\ 0\ ||\ \$r\ >=\ \$::G(rows)\ ||\ \$c\ >=\ \$::G(cols)\}\ continue\n\ \ \ \ \ \ \ \ lappend\ who\ \$r\ \$c\n\ \ \ \ \}\n\ \ \ \ set\ NEIGHBORS(\$row,\$col)\ \$who\n\ \ \ \ return\ \$who\n\ \}\n\ proc\ NewBoard\ \{\{how\ rand\}\ args\}\ \{\n\ \ \ \ InitBoard\ \$how\n\ \ \ \ DrawBoard\ 1\n\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \n\ proc\ InitBoard\ \{how\}\ \{\n\ \ \ \ global\ G\ LAST\n\ \n\ \ \ \ set\ G(state)\ play\n\ \ \ \ set\ G(msg)\ \"\"\n\ \ \ \ set\ G(moves)\ 0\n\ \ \ \ set\ G(tmoves)\ \"Moves:\ 0\"\n\ \ \ \ set\ G(path)\ \{\}\n\ \ \ \ array\ unset\ G\ board,*\n\ \ \ \ if\ \{\$how\ eq\ \"last\"\}\ \{\n\ \ \ \ \ \ \ \ array\ set\ G\ \[array\ get\ LAST\]\n\ \ \ \ \ \ \ \ return\n\ \ \ \ \}\n\ \n\ \ \ \ while\ \{1\}\ \{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Fill\ in\ the\ board\n\ \ \ \ \ \ \ \ for\ \{set\ row\ 0\}\ \{\$row\ <\ \$G(rows)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ for\ \{set\ col\ 0\}\ \{\$col\ <\ \$G(cols)\}\ \{incr\ col\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ G(board,\$row,\$col)\ \[expr\ \{int(rand()\ *\ 2)\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ if\ \{!\ \[IsWinner\]\}\ break\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Must\ have\ 1\ light\ on\n\ \ \ \ \}\n\ \ \ \ array\ set\ LAST\ \[array\ get\ G\ board,*\]\ \ \ \ \ \ \ \ \;#\ Remember\ for\ restart\n\ \}\n\ proc\ DoClick\ \{row\ col\}\ \{\n\ \ \ \ if\ \{\$::G(state)\ ne\ \"play\"\}\ return\n\ \ \ \ \n\ \ \ \ foreach\ \{r\ c\}\ \[Neighbors\ \$row\ \$col\]\ \{\n\ \ \ \ \ \ \ \ set\ ::G(board,\$r,\$c)\ \[expr\ \{1\ -\ \$::G(board,\$r,\$c)\}\]\n\ \ \ \ \}\n\ \ \ \ set\ ::G(tmoves)\ \"Moves:\ \[incr\ ::G(moves)\]\"\n\ \ \ \ lappend\ ::G(path)\ \$row\ \$col\n\ \n\ \ \ \ if\ \{\[IsWinner\]\}\ \{\n\ \ \ \ \ \ \ \ set\ ::G(msg)\ \"You\ Won!\"\n\ \ \ \ \ \ \ \ set\ ::G(state)\ won\n\ \ \ \ \}\n\ \ \ \ DrawBoard\n\ \}\n\ proc\ IsWinner\ \{\}\ \{\n\ \ \ \ foreach\ arr\ \[array\ names\ ::G\ board,*\]\ \{\n\ \ \ \ \ \ \ \ if\ \{\$::G(\$arr)\ ==\ 1\}\ \{return\ 0\}\n\ \ \ \ \}\n\ \ \ \ return\ 1\n\ \}\n\ proc\ Help\ \{\}\ \{\n\ \ \ \ set\ msg\ \"\$::S(title)\\nby\ Keith\ Vetter,\ September\ 2004\\n\\n\"\n\ \n\ \ \ \ append\ msg\ \"This\ is\ one-person\ puzzle\ in\ which\ you\ try\ to\ turn\ off\\n\"\n\ \ \ \ append\ msg\ \"all\ the\ lights.\ The\ board\ consists\ of\ a\ lattice\ of\ lights\\n\"\n\ \ \ \ append\ msg\ \"which\ can\ be\ turned\ on\ and\ off.\ Clicking\ on\ any\ light\\n\"\n\ \ \ \ append\ msg\ \"toggles\ the\ on/off\ state\ of\ this\ and\ its\ four\ vertically\\n\"\n\ \ \ \ append\ msg\ \"and\ horizontally\ adjacent\ neighbors.\\n\\n\"\n\ \n\ \ \ \ append\ msg\ \"Determining\ if\ a\ given\ random\ arrangement\ of\ on/off\\n\"\n\ \ \ \ append\ msg\ \"lights\ can\ be\ all\ turned\ off\ is\ known\ as\ the\\n\"\n\ \ \ \ append\ msg\ \"\\\"All-Ones\ Problem\\\"\\n\\n\"\n\ \n\ \ \ \ tk_messageBox\ -message\ \$msg\ -title\ \"\$::S(title)\ Help\"\n\ \}\n\ InitBoard\ rand\n\ DoDisplay\n\ \n\ \n\ namespace\ eval\ ::Solve\ \{\n\ \ \ \ variable\ b\n\ \}\n\ proc\ ::Solve::Hint\ \{\{all\ 0\}\}\ \{\n\ \ \ \ .c\ delete\ hint\n\ \ \ \ if\ \{\[::IsWinner\]\}\ return\n\ \ \ \ set\ path\ \[::Solve::Solver\]\n\ \ \ \ \n\ \ \ \ if\ \{\$path\ ==\ \{\}\}\ \{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ No\ solution\n\ \ \ \ \ \ \ \ set\ msg\ \"Can't\ be\ solved\"\n\ \ \ \ \ \ \ \ .c\ create\ text\ 0\ 0\ -tag\ msg\ -text\ \$msg\ -font\ \{Times\ 36\ bold\}\n\ \ \ \ \ \ \ \ return\n\ \ \ \ \}\n\ \ \ \ if\ \{!\ \$all\}\ \{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Just\ one\ hint\n\ \ \ \ \ \ \ \ set\ path\ \[lindex\ \$path\ \[expr\ \{int(rand()\ *\ \[llength\ \$path\])\}\]\]\n\ \ \ \ \}\n\ \ \ \ foreach\ step\ \$path\ \{\n\ \ \ \ \ \ \ \ scan\ \$step\ \"%d,%d\"\ row\ col\n\ \ \ \ \ \ \ \ ShowHint\ \$row\ \$col\n\ \ \ \ \}\n\ \}\n\ proc\ ::Solve::Solve\ \{\}\ \{\n\ \ \ \ global\ path\n\ \ \ \ \n\ \ \ \ set\ path\ \[::Solve::Solver\]\n\ \ \ \ puts\ \"\[llength\ \$path\]\ =>\ \$path\"\n\ \}\n\ proc\ ::Solve::Solver\ \{\}\ \{\n\ \ \ \ variable\ b\n\ \ \ \ global\ G\n\ \n\ \ \ \ array\ unset\ b\n\ \ \ \ set\ moves\ \{\}\n\ \ \ \ for\ \{set\ row\ 0\}\ \{\$row\ <\ \$G(rows)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ for\ \{set\ col\ 0\}\ \{\$col\ <\ \$G(cols)\}\ \{incr\ col\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ moves\ \"\$row,\$col\"\n\ \ \ \ \ \ \ \ \ \ \ \ set\ b(\$row,\$col)\ \$G(board,\$row,\$col)\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ set\ max\ \[llength\ \$moves\]\n\ \ \ \ \n\ \ \ \ array\ set\ save\ \[array\ get\ b\]\n\ \ \ \ for\ \{set\ n\ 1\}\ \{\$n\ <=\ \$max\}\ \{incr\ n\}\ \{\n\ \ \ \ \ \ \ \ set\ all\ \[::Solve::Combinations\ \$moves\ \$n\]\n\ \ \ \ \ \ \ \ foreach\ path\ \$all\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ array\ set\ b\ \[array\ get\ save\]\n\ \ \ \ \ \ \ \ \ \ \ \ foreach\ step\ \$path\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ scan\ \$step\ \"%d,%d\"\ row\ col\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::Solve::DoMove\ \$row\ \$col\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[::Solve::IsWinner\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ \$path\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ return\ \{\}\n\ \}\n\ proc\ ::Solve::IsWinner\ \{\}\ \{\n\ \ \ \ variable\ b\n\ \ \ \ foreach\ arr\ \[array\ names\ b\]\ \{\n\ \ \ \ \ \ \ \ if\ \{\$b(\$arr)\ !=\ 0\}\ \{return\ 0\}\n\ \ \ \ \}\n\ \ \ \ return\ 1\n\ \}\n\ proc\ ::Solve::DoMove\ \{row\ col\}\ \{\n\ \ \ \ variable\ b\n\ \ \ \ set\ nb\ \[Neighbors\ \$row\ \$col\]\n\ \ \ \ foreach\ \{row\ col\}\ \$nb\ \{\n\ \ \ \ \ \ \ \ set\ b(\$row,\$col)\ \[expr\ \{1\ -\ \$b(\$row,\$col)\}\]\n\ \ \ \ \}\n\ \}\n\ proc\ ::Solve::Combinations\ \{myList\ size\ \{prefix\ \{\}\}\}\ \{\n\ \ \ \ \;#\ End\ recursion\ when\ size\ is\ 0\ or\ equals\ our\ list\ size\n\ \ \ \ if\ \{\$size\ ==\ 0\}\ \{return\ \[list\ \$prefix\]\}\n\ \ \ \ if\ \{\$size\ ==\ \[llength\ \$myList\]\}\ \{return\ \[list\ \[concat\ \$prefix\ \$myList\]\]\}\n\ \ \ \ \n\ \ \ \ set\ first\ \[lindex\ \$myList\ 0\]\n\ \ \ \ set\ rest\ \[lrange\ \$myList\ 1\ end\]\n\ \ \ \ \n\ \ \ \ \;#\ Combine\ solutions\ w/\ first\ element\ and\ solutions\ w/o\ first\ element\n\ \ \ \ set\ ans1\ \[::Solve::Combinations\ \$rest\ \[expr\ \{\$size-1\}\]\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \[concat\ \$prefix\ \$first\]\]\n\ \ \ \ set\ ans2\ \[::Solve::Combinations\ \$rest\ \$size\ \$prefix\]\n\ \ \ \ return\ \[concat\ \$ans1\ \$ans2\]\n\ \}\n\n----\n\[GS\]\ (040911)\ A\ few\ years\ ago,\ there\ was\ an\ interesting\ discussion\ on\ sci.math\ about\ this\ puzzle\ \n\[http://www.math.niu.edu/~rusin/papers/uses-math/games/other/lights\]\ \nand\ also\ a\ published\ article:\ Óscar\ Martín-Sánchez\ and\ Cristóbal\ Pareja-Flores,\ ''Two\ Reflected\ Analyses\ of\ Lights\ Out'',\ Mathematics\ Magazine\ 74:4\ (2001),\ 295-304.\ \[http://dalila.sip.ucm.es/miembros/cpareja/lo/paper.ps\]\n----\n\n\n\n\n\n======\n----\n***Screenshots***\n\n\n\n\n\[http://farm5.static.flickr.com/4063/4685112957_bba73da26a_m.jpg\]\n\ \ \ \ \ \ \ \ \n\n\n\n\n\n\n\n<alt=TCL_WIKI_lightsoutboasrdgametestpixversion2.png>\n\[gold\]\ added\ pix\ \n\n\ \ \ \ \n----\n**References**\n\n\n\n\n\n\n----\n\n\[Category\ Games\]\ |\ \[Category\ Application\]\ |\ \[Tcl/Tk\ Games\] regexp2} CALL {my render {Lights Out} \[Keith\ Vetter\]\ 2004-09-10\ :\ This\ is\ a\ one-person\ puzzle\ in\ which\ you\ try\nto\ turn\ off\ all\ the\ lights.\ The\ board\ consists\ of\ a\ lattice\ of\ lights\ which\ncan\ be\ turned\ on\ and\ off.\ Clicking\ on\ any\ light\ toggles\ the\ on/off\ state\nof\ that\ light\ and\ its\ four\ vertically\ and\ horizontally\ adjacent\ neighbors.\n\nDetermining\ if\ a\ given\ random\ arrangement\ of\ on/off\ lights\ can\ be\ all\ turned\noff\ is\ known\ as\ the\ ''All-Ones\ Problem''.\n\nOne\ interesting\ quirk\ is\ that\ it\ doesn't\ matter\ the\ order\ of\ toggling\ lights\nneeded\ to\ reach\ the\ solution--the\ solution\ is\ communative.\ \n\n\[KPV\]\ 2004-09-11\ :\ Added\ a\ \"Hint\"\ button\ which\ first\ does\ a\ search\ find\nthe\ solution\ then\ displays\ one\ of\ the\ lights\ which\ needs\ to\ be\ toggled.\nThe\ solver\ does\ a\ BFS\ and\ can\ be\ time\ consuming\ for\ large\ size\ boards.\n\n----\n\ ##+##########################################################################\n\ #\n\ #\ LightsOut.tcl\ -\ description\n\ #\ by\ Keith\ Vetter\ --\ Sept\ 10,\ 2004\n\ #\ http://mathworld.wolfram.com/LightsOutPuzzle.html\n\ #\n\ package\ require\ Tk\n\ \n\ array\ set\ S\ \{title\ \"Lights\ Out\"\ w\ 500\ h\ 500\}\n\ array\ set\ G\ \{rows\ 3\ cols\ 3\}\n\ \n\ proc\ DoDisplay\ \{\}\ \{\n\ \ \ \ wm\ title\ .\ \$::S(title)\n\ \ \ \ frame\ .ctrl\ -relief\ ridge\ -bd\ 2\ -padx\ 5\ -pady\ 5\n\ \ \ \ canvas\ .c\ -relief\ raised\ -height\ \$::S(h)\ -width\ \$::S(w)\ -bd\ 2\ \\\n\ \ \ \ \ \ \ \ -highlightthickness\ 0\ -relief\ raised\n\ \ \ \ pack\ .ctrl\ -side\ right\ -fill\ both\ -ipady\ 5\n\ \ \ \ pack\ .c\ -side\ top\ -fill\ both\ -expand\ 1\n\ \n\ \ \ \ bind\ all\ <Key-F2>\ \{console\ show\}\n\ \ \ \ bind\ .c\ <Configure>\ \{ReCenter\ %W\ %h\ %w\}\n\ \n\ \ \ \ DoCtrlFrame\n\ \}\n\ proc\ ReCenter\ \{W\ h\ w\}\ \{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Called\ by\ configure\ event\n\ \ \ \ set\ h2\ \[expr\ \{\$h\ /\ 2\}\]\n\ \ \ \ set\ w2\ \[expr\ \{\$w\ /\ 2\}\]\n\ \ \ \ \$W\ config\ -scrollregion\ \[list\ -\$w2\ -\$h2\ \$w2\ \$h2\]\n\ \ \ \ DrawBoard\ 1\n\ \}\n\ \n\ proc\ DoCtrlFrame\ \{\}\ \{\n\ \ \ \ button\ .restart\ \ -text\ \"Restart\ Game\"\ -command\ \[list\ NewBoard\ last\]\ -bd\ 4\n\ \ \ \ .restart\ configure\ \ -font\ \"\[font\ actual\ \[.restart\ cget\ -font\]\]\ -weight\ bold\"\n\ \ \ \ option\ add\ *font\ \[.restart\ cget\ -font\]\n\ \ \ \ button\ .new\ -text\ \"New\ Game\"\ -bd\ 4\ -command\ \[list\ NewBoard\ rand\]\n\ \ \ \ button\ .hint\ -text\ Hint\ -bd\ 4\ -command\ ::Solve::Hint\n\ \ \ \ button\ .solution\ -text\ Solution\ -bd\ 4\ -command\ \{::Solve::Hint\ 1\}\n\ \ \ \ scale\ .rows\ -from\ 1\ -to\ 10\ -label\ Rows\ -orient\ h\ -relief\ ridge\ \\\n\ \ \ \ \ \ \ \ -variable\ G(rows)\ -command\ \[list\ NewBoard\ rand\]\n\ \ \ \ scale\ .cols\ -from\ 1\ -to\ 10\ -label\ Columns\ -orient\ h\ -relief\ ridge\ \\\n\ \ \ \ \ \ \ \ -variable\ G(cols)\ -command\ \[list\ NewBoard\ rand\]\n\ \ \ \ label\ .moves\ -textvariable\ G(tmoves)\ -relief\ sunken\n\ \ \ \ button\ .help\ -text\ Help\ -command\ Help\n\ \ \ \ \n\ \ \ \ grid\ .restart\ -in\ .ctrl\ -row\ 0\ -sticky\ ew\n\ \ \ \ grid\ .new\ -in\ .ctrl\ -sticky\ ew\n\ \ \ \ grid\ rowconfigure\ .ctrl\ 5\ -minsize\ 20\n\ \ \ \ grid\ .hint\ -in\ .ctrl\ -sticky\ ew\ -row\ 6\n\ \ \ \ grid\ .solution\ -in\ .ctrl\ -sticky\ ew\n\ \ \ \ grid\ rowconfigure\ .ctrl\ 10\ -minsize\ 50\n\ \ \ \ grid\ .rows\ -in\ .ctrl\ -sticky\ ew\ -row\ 11\n\ \ \ \ grid\ .cols\ -in\ .ctrl\ -sticky\ ew\n\ \ \ \ grid\ rowconfigure\ .ctrl\ 20\ -minsize\ 80\n\ \ \ \ grid\ .moves\ -in\ .ctrl\ -sticky\ ew\ -rows\ 21\n\ \ \ \ grid\ rowconfigure\ .ctrl\ 50\ -weight\ 1\n\ \ \ \ grid\ .help\ \ \ -in\ .ctrl\ -sticky\ ew\ -row\ 100\n\ \}\n\ proc\ DrawBoard\ \{\{redraw\ 0\}\}\ \{\n\ \ \ \ global\ S\ G\ NEIGHBORS\n\ \n\ \ \ \ .c\ delete\ msg\ hint\n\ \ \ \ if\ \{\$redraw\}\ \{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Redraw\ everything\n\ \ \ \ \ \ \ \ unset\ -nocomplain\ NEIGHBORS\ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Memoize\ array\n\ \ \ \ \ \ \ \ .c\ delete\ all\n\ \ \ \ \ \ \ \ set\ S(w)\ \[winfo\ width\ .c\]\n\ \ \ \ \ \ \ \ set\ S(h)\ \[winfo\ height\ .c\]\n\ \ \ \ \ \ \ \ set\ S(dx)\ \[expr\ \{double(\$S(w)\ -\ 10)\ /\ \$G(cols)\}\]\n\ \ \ \ \ \ \ \ set\ S(dy)\ \[expr\ \{double(\$S(h)\ -\ 10)\ /\ \$G(rows)\}\]\n\ \ \ \ \ \ \ \ if\ \{\$S(dx)\ <\ \$S(dy)\}\ \{set\ S(dy)\ \$S(dx)\}\ else\ \{set\ S(dx)\ \$S(dy)\}\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ set\ S(x0)\ \[expr\ \{-\ \$S(dx)\ *\ \$G(cols)\ /\ 2\}\]\n\ \ \ \ \ \ \ \ set\ S(y0)\ \[expr\ \{-\ \$S(dy)\ *\ \$G(rows)\ /\ 2\}\]\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ for\ \{set\ row\ 0\}\ \{\$row\ <\ \$G(rows)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ for\ \{set\ col\ 0\}\ \{\$col\ <\ \$G(cols)\}\ \{incr\ col\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ xy\ \[GetBox\ \$row\ \$col\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .c\ create\ rect\ \$xy\ -tag\ \[list\ c\ c\$row,\$col\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .c\ bind\ c\$row,\$col\ <Button-1>\ \[list\ DoClick\ \$row\ \$col\]\n\ \n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ set\ xy0\ \[GetBox\ 0\ 0\]\n\ \ \ \ \ \ \ \ set\ xy1\ \[GetBox\ \$G(rows)\ \$G(cols)\]\n\ \ \ \ \ \ \ \ set\ xy\ \[concat\ \[lrange\ \$xy0\ 0\ 1\]\ \[lrange\ \$xy1\ 0\ 1\]\]\n\ \ \ \ \ \ \ \ .c\ create\ rect\ \$xy\ -width\ 3\n\ \ \ \ \}\n\ \n\ \ \ \ #\ Draw\ the\ light\ lattice\n\ \ \ \ for\ \{set\ row\ 0\}\ \{\$row\ <\ \$G(rows)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ for\ \{set\ col\ 0\}\ \{\$col\ <\ \$G(cols)\}\ \{incr\ col\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ fill\ \[.c\ cget\ -bg\]\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$G(board,\$row,\$col)\ >\ 0\}\ \{set\ fill\ yellow\}\n\ \ \ \ \ \ \ \ \ \ \ \ .c\ itemconfig\ c\$row,\$col\ -fill\ \$fill\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ if\ \{\$G(msg)\ ne\ \"\"\}\ \{\n\ \ \ \ \ \ \ \ .c\ create\ text\ 0\ 0\ -tag\ msg\ -text\ \$G(msg)\ -font\ \{Times\ 36\ bold\}\n\ \ \ \ \}\n\ \}\n\ proc\ ShowHint\ \{row\ col\}\ \{\n\ \ \ \ set\ xy\ \[GetOval\ \$row\ \$col\]\n\ \ \ \ .c\ create\ oval\ \$xy\ -tag\ \[list\ hint\ h\$row,\$col\]\ -fill\ red\n\ \ \ \ .c\ bind\ h\$row,\$col\ <Button-1>\ \[list\ DoClick\ \$row\ \$col\]\n\ \}\n\ proc\ GetBox\ \{row\ col\}\ \{\n\ \ \ \ global\ S\n\ \n\ \ \ \ set\ x0\ \[expr\ \{\$S(x0)\ +\ \$col\ *\ \$S(dx)\}\]\n\ \ \ \ set\ y0\ \[expr\ \{\$S(y0)\ +\ \$row\ *\ \$S(dy)\}\]\n\ \ \ \ set\ x1\ \[expr\ \{\$x0\ +\ \$S(dx)\}\]\n\ \ \ \ set\ y1\ \[expr\ \{\$y0\ +\ \$S(dy)\}\]\n\ \ \ \ return\ \[list\ \$x0\ \$y0\ \$x1\ \$y1\]\n\ \}\n\ proc\ GetOval\ \{row\ col\}\ \{\n\ \ \ \ global\ S\n\ \n\ \ \ \ set\ x0\ \[expr\ \{\$S(x0)\ +\ (\$col\ +\ .33)\ *\ \$S(dx)\}\]\n\ \ \ \ set\ y0\ \[expr\ \{\$S(y0)\ +\ (\$row\ +\ .33)\ *\ \$S(dy)\}\]\n\ \ \ \ set\ x1\ \[expr\ \{\$S(x0)\ +\ (\$col\ +\ .66)\ *\ \$S(dx)\}\]\n\ \ \ \ set\ y1\ \[expr\ \{\$S(y0)\ +\ (\$row\ +\ .66)\ *\ \$S(dy)\}\]\n\ \ \ \ return\ \[list\ \$x0\ \$y0\ \$x1\ \$y1\]\n\ \}\n\ proc\ Neighbors\ \{row\ col\}\ \{\n\ \ \ \ global\ NEIGHBORS\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Memoize\n\ \n\ \ \ \ if\ \{\[info\ exists\ NEIGHBORS(\$row,\$col)\]\}\ \{\ return\ \$NEIGHBORS(\$row,\$col)\ \}\n\ \ \ \ set\ who\ \{\}\n\ \ \ \ foreach\ \{dr\ dc\}\ \{-1\ 0\ \ \ 0\ 0\ \ 1\ 0\ \ \ 0\ -1\ 0\ 1\}\ \{\n\ \ \ \ \ \ \ \ set\ r\ \[expr\ \{\$row\ +\ \$dr\}\]\n\ \ \ \ \ \ \ \ set\ c\ \[expr\ \{\$col\ +\ \$dc\}\]\n\ \ \ \ \ \ \ \ if\ \{\$r\ <\ 0\ ||\ \$c\ <\ 0\ ||\ \$r\ >=\ \$::G(rows)\ ||\ \$c\ >=\ \$::G(cols)\}\ continue\n\ \ \ \ \ \ \ \ lappend\ who\ \$r\ \$c\n\ \ \ \ \}\n\ \ \ \ set\ NEIGHBORS(\$row,\$col)\ \$who\n\ \ \ \ return\ \$who\n\ \}\n\ proc\ NewBoard\ \{\{how\ rand\}\ args\}\ \{\n\ \ \ \ InitBoard\ \$how\n\ \ \ \ DrawBoard\ 1\n\ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \n\ proc\ InitBoard\ \{how\}\ \{\n\ \ \ \ global\ G\ LAST\n\ \n\ \ \ \ set\ G(state)\ play\n\ \ \ \ set\ G(msg)\ \"\"\n\ \ \ \ set\ G(moves)\ 0\n\ \ \ \ set\ G(tmoves)\ \"Moves:\ 0\"\n\ \ \ \ set\ G(path)\ \{\}\n\ \ \ \ array\ unset\ G\ board,*\n\ \ \ \ if\ \{\$how\ eq\ \"last\"\}\ \{\n\ \ \ \ \ \ \ \ array\ set\ G\ \[array\ get\ LAST\]\n\ \ \ \ \ \ \ \ return\n\ \ \ \ \}\n\ \n\ \ \ \ while\ \{1\}\ \{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Fill\ in\ the\ board\n\ \ \ \ \ \ \ \ for\ \{set\ row\ 0\}\ \{\$row\ <\ \$G(rows)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ for\ \{set\ col\ 0\}\ \{\$col\ <\ \$G(cols)\}\ \{incr\ col\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ G(board,\$row,\$col)\ \[expr\ \{int(rand()\ *\ 2)\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ if\ \{!\ \[IsWinner\]\}\ break\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Must\ have\ 1\ light\ on\n\ \ \ \ \}\n\ \ \ \ array\ set\ LAST\ \[array\ get\ G\ board,*\]\ \ \ \ \ \ \ \ \;#\ Remember\ for\ restart\n\ \}\n\ proc\ DoClick\ \{row\ col\}\ \{\n\ \ \ \ if\ \{\$::G(state)\ ne\ \"play\"\}\ return\n\ \ \ \ \n\ \ \ \ foreach\ \{r\ c\}\ \[Neighbors\ \$row\ \$col\]\ \{\n\ \ \ \ \ \ \ \ set\ ::G(board,\$r,\$c)\ \[expr\ \{1\ -\ \$::G(board,\$r,\$c)\}\]\n\ \ \ \ \}\n\ \ \ \ set\ ::G(tmoves)\ \"Moves:\ \[incr\ ::G(moves)\]\"\n\ \ \ \ lappend\ ::G(path)\ \$row\ \$col\n\ \n\ \ \ \ if\ \{\[IsWinner\]\}\ \{\n\ \ \ \ \ \ \ \ set\ ::G(msg)\ \"You\ Won!\"\n\ \ \ \ \ \ \ \ set\ ::G(state)\ won\n\ \ \ \ \}\n\ \ \ \ DrawBoard\n\ \}\n\ proc\ IsWinner\ \{\}\ \{\n\ \ \ \ foreach\ arr\ \[array\ names\ ::G\ board,*\]\ \{\n\ \ \ \ \ \ \ \ if\ \{\$::G(\$arr)\ ==\ 1\}\ \{return\ 0\}\n\ \ \ \ \}\n\ \ \ \ return\ 1\n\ \}\n\ proc\ Help\ \{\}\ \{\n\ \ \ \ set\ msg\ \"\$::S(title)\\nby\ Keith\ Vetter,\ September\ 2004\\n\\n\"\n\ \n\ \ \ \ append\ msg\ \"This\ is\ one-person\ puzzle\ in\ which\ you\ try\ to\ turn\ off\\n\"\n\ \ \ \ append\ msg\ \"all\ the\ lights.\ The\ board\ consists\ of\ a\ lattice\ of\ lights\\n\"\n\ \ \ \ append\ msg\ \"which\ can\ be\ turned\ on\ and\ off.\ Clicking\ on\ any\ light\\n\"\n\ \ \ \ append\ msg\ \"toggles\ the\ on/off\ state\ of\ this\ and\ its\ four\ vertically\\n\"\n\ \ \ \ append\ msg\ \"and\ horizontally\ adjacent\ neighbors.\\n\\n\"\n\ \n\ \ \ \ append\ msg\ \"Determining\ if\ a\ given\ random\ arrangement\ of\ on/off\\n\"\n\ \ \ \ append\ msg\ \"lights\ can\ be\ all\ turned\ off\ is\ known\ as\ the\\n\"\n\ \ \ \ append\ msg\ \"\\\"All-Ones\ Problem\\\"\\n\\n\"\n\ \n\ \ \ \ tk_messageBox\ -message\ \$msg\ -title\ \"\$::S(title)\ Help\"\n\ \}\n\ InitBoard\ rand\n\ DoDisplay\n\ \n\ \n\ namespace\ eval\ ::Solve\ \{\n\ \ \ \ variable\ b\n\ \}\n\ proc\ ::Solve::Hint\ \{\{all\ 0\}\}\ \{\n\ \ \ \ .c\ delete\ hint\n\ \ \ \ if\ \{\[::IsWinner\]\}\ return\n\ \ \ \ set\ path\ \[::Solve::Solver\]\n\ \ \ \ \n\ \ \ \ if\ \{\$path\ ==\ \{\}\}\ \{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ No\ solution\n\ \ \ \ \ \ \ \ set\ msg\ \"Can't\ be\ solved\"\n\ \ \ \ \ \ \ \ .c\ create\ text\ 0\ 0\ -tag\ msg\ -text\ \$msg\ -font\ \{Times\ 36\ bold\}\n\ \ \ \ \ \ \ \ return\n\ \ \ \ \}\n\ \ \ \ if\ \{!\ \$all\}\ \{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Just\ one\ hint\n\ \ \ \ \ \ \ \ set\ path\ \[lindex\ \$path\ \[expr\ \{int(rand()\ *\ \[llength\ \$path\])\}\]\]\n\ \ \ \ \}\n\ \ \ \ foreach\ step\ \$path\ \{\n\ \ \ \ \ \ \ \ scan\ \$step\ \"%d,%d\"\ row\ col\n\ \ \ \ \ \ \ \ ShowHint\ \$row\ \$col\n\ \ \ \ \}\n\ \}\n\ proc\ ::Solve::Solve\ \{\}\ \{\n\ \ \ \ global\ path\n\ \ \ \ \n\ \ \ \ set\ path\ \[::Solve::Solver\]\n\ \ \ \ puts\ \"\[llength\ \$path\]\ =>\ \$path\"\n\ \}\n\ proc\ ::Solve::Solver\ \{\}\ \{\n\ \ \ \ variable\ b\n\ \ \ \ global\ G\n\ \n\ \ \ \ array\ unset\ b\n\ \ \ \ set\ moves\ \{\}\n\ \ \ \ for\ \{set\ row\ 0\}\ \{\$row\ <\ \$G(rows)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ for\ \{set\ col\ 0\}\ \{\$col\ <\ \$G(cols)\}\ \{incr\ col\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ moves\ \"\$row,\$col\"\n\ \ \ \ \ \ \ \ \ \ \ \ set\ b(\$row,\$col)\ \$G(board,\$row,\$col)\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ set\ max\ \[llength\ \$moves\]\n\ \ \ \ \n\ \ \ \ array\ set\ save\ \[array\ get\ b\]\n\ \ \ \ for\ \{set\ n\ 1\}\ \{\$n\ <=\ \$max\}\ \{incr\ n\}\ \{\n\ \ \ \ \ \ \ \ set\ all\ \[::Solve::Combinations\ \$moves\ \$n\]\n\ \ \ \ \ \ \ \ foreach\ path\ \$all\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ array\ set\ b\ \[array\ get\ save\]\n\ \ \ \ \ \ \ \ \ \ \ \ foreach\ step\ \$path\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ scan\ \$step\ \"%d,%d\"\ row\ col\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::Solve::DoMove\ \$row\ \$col\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[::Solve::IsWinner\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ \$path\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ return\ \{\}\n\ \}\n\ proc\ ::Solve::IsWinner\ \{\}\ \{\n\ \ \ \ variable\ b\n\ \ \ \ foreach\ arr\ \[array\ names\ b\]\ \{\n\ \ \ \ \ \ \ \ if\ \{\$b(\$arr)\ !=\ 0\}\ \{return\ 0\}\n\ \ \ \ \}\n\ \ \ \ return\ 1\n\ \}\n\ proc\ ::Solve::DoMove\ \{row\ col\}\ \{\n\ \ \ \ variable\ b\n\ \ \ \ set\ nb\ \[Neighbors\ \$row\ \$col\]\n\ \ \ \ foreach\ \{row\ col\}\ \$nb\ \{\n\ \ \ \ \ \ \ \ set\ b(\$row,\$col)\ \[expr\ \{1\ -\ \$b(\$row,\$col)\}\]\n\ \ \ \ \}\n\ \}\n\ proc\ ::Solve::Combinations\ \{myList\ size\ \{prefix\ \{\}\}\}\ \{\n\ \ \ \ \;#\ End\ recursion\ when\ size\ is\ 0\ or\ equals\ our\ list\ size\n\ \ \ \ if\ \{\$size\ ==\ 0\}\ \{return\ \[list\ \$prefix\]\}\n\ \ \ \ if\ \{\$size\ ==\ \[llength\ \$myList\]\}\ \{return\ \[list\ \[concat\ \$prefix\ \$myList\]\]\}\n\ \ \ \ \n\ \ \ \ set\ first\ \[lindex\ \$myList\ 0\]\n\ \ \ \ set\ rest\ \[lrange\ \$myList\ 1\ end\]\n\ \ \ \ \n\ \ \ \ \;#\ Combine\ solutions\ w/\ first\ element\ and\ solutions\ w/o\ first\ element\n\ \ \ \ set\ ans1\ \[::Solve::Combinations\ \$rest\ \[expr\ \{\$size-1\}\]\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \[concat\ \$prefix\ \$first\]\]\n\ \ \ \ set\ ans2\ \[::Solve::Combinations\ \$rest\ \$size\ \$prefix\]\n\ \ \ \ return\ \[concat\ \$ans1\ \$ans2\]\n\ \}\n\n----\n\[GS\]\ (040911)\ A\ few\ years\ ago,\ there\ was\ an\ interesting\ discussion\ on\ sci.math\ about\ this\ puzzle\ \n\[http://www.math.niu.edu/~rusin/papers/uses-math/games/other/lights\]\ \nand\ also\ a\ published\ article:\ Óscar\ Martín-Sánchez\ and\ Cristóbal\ Pareja-Flores,\ ''Two\ Reflected\ Analyses\ of\ Lights\ Out'',\ Mathematics\ Magazine\ 74:4\ (2001),\ 295-304.\ \[http://dalila.sip.ucm.es/miembros/cpareja/lo/paper.ps\]\n----\n\n\n\n\n\n======\n----\n***Screenshots***\n\n\n\n\n\[http://farm5.static.flickr.com/4063/4685112957_bba73da26a_m.jpg\]\n\ \ \ \ \ \ \ \ \n\n\n\n\n\n\n\n<alt=TCL_WIKI_lightsoutboasrdgametestpixversion2.png>\n\[gold\]\ added\ pix\ \n\n\ \ \ \ \n----\n**References**\n\n\n\n\n\n\n----\n\n\[Category\ Games\]\ |\ \[Category\ Application\]\ |\ \[Tcl/Tk\ Games\]} CALL {my revision {Lights Out}} CALL {::oo::Obj6451371 process revision/Lights+Out} CALL {::oo::Obj6451369 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