Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/Lights+On?V=17
QUERY_STRINGV=17
CONTENT_TYPE
DOCUMENT_URI/revision/Lights+On
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.70.130.65
REMOTE_PORT57522
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR18.218.234.83
HTTP_CF_RAY87ad53120a5b86f3-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.218.234.83
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 On} \[Keith\ Vetter\]\ 2006-02-09\ :\ Here's\ a\ fun\ litle\ game\ where\ you\ have\ to\ rotate\ nodes\ \nto\ connect\ up\ wires\ to\ light\ up\ every\ node.\ I\ wrote\ a\ somewhat\ similar\ game\nearlier\ called\ \[Lights\ Out\].\n\nFun\ project\ for\ several\ reasons:\ 1)\ implemented\ a\ minimum\ spanning\ntree\ algorithm\ (Prim's)\ 2)\ implemented\ a\ depth-first\ search\ \nand\ 3)\ did\ a\ poor\ man's\ anti-aliasing\ to\ get\ nicer\ looking\ lines.\n\n----\n\[ABU\]\ Really\ nice.\ Just\ for\ the\ blockheads\ like\ me,\ could\ you\ provide\ a\ \"solve\"\ command\ with\ a\ slow\ animation\ ?\n\n\[KPV\]\ There's\ already\ a\ built\ it\ cheat\ command.\ \nJust\ hold\ the\ control\ key\ down\ and\ click\ on\ a\ node.\ That\ will\ncause\ that\ node\ to\ orient\ itself\ correctly.\n\n----\n\[GS\]\ 2010-10-23\ :\ A\ slightly\ modified\ version\ \[http://wfr.tcl.tk/fichiers/pub/lightson-winmo.tcl\]\ for\ touchscreen\ Windows\ Mobile\ device\ with\ \[eTcl\].\ Lights\ bulbs\ are\ larger\ and\ expert\ mod\ has\ been\ disabled\ because\ it\ is\ too\ larger\ to\ fit\ in\ smartphone\ screen\ resolution.\n\n\[http://wfr.tcl.tk/fichiers/images/lightson.gif\]\n\n\[uniquename\]\ 2013aug01\n\nHere\ is\ a\ right-clipped\ image\ of\ the\ 'desktop'\ version\ ---\ along\ with\ a\ (partly-clipped)\ image\ of\ the\ help\ popup.\n\n\[vetter_LightsOn_screenshot_647x461.jpg\]\n\nThis\ is\ the\ initial\ setting\ of\ the\ GUI.\ The\ little\ rods\ rotate\ to\ 'hexagonal-angles'\ ---\ and\ lights\ come\ on\ as\ more\ segments\ are\ attached,\nto\ complete\ the\ circuit\ to\ the\ central\ light.\n\n======\n\ ##+##########################################################################\n\ #\n\ #\ lightsOn.tcl\ --\ based\ on\ http://pyva.net/eng/pc/lights.html\n\ #\ by\ Keith\ Vetter\n\ #\n\ package\ require\ Tk\n\ \n\ set\ G(n)\ 7\n\ array\ set\ S\ \{title\ \"Lights\ On\"\ w\ 600\ h\ 600\ vdist\ 50\ hdist\ 28\}\n\ array\ set\ DRC\ \{0\ \{0\ 2\}\ 1\ \{-1\ 1\}\ 2\ \{-1\ -1\}\ 3\ \{0\ -2\}\ 4\ \{1\ -1\}\ 5\ \{1\ 1\}\}\n\ array\ set\ COLORS\ \{ray1\ \\#4C526C\ ray2\ \\#8C96B4\}\n\ \n\ proc\ DoDisplay\ \{\}\ \{\n\ \ \ \ global\ S\n\ \n\ \ \ \ wm\ title\ .\ \$S(title)\n\ \ \ \ canvas\ .c\ -bg\ black\ -width\ \$S(w)\ -height\ \$S(h)\ -highlightthickness\ 0\n\ \ \ \ label\ .t\ -textvariable\ ::G(tmsg)\ -font\ \{Times\ 18\ bold\}\ \\\n\ \ \ \ \ \ \ \ -fg\ cyan\ -bg\ black\ -anchor\ w\ -padx\ 10\n\ \ \ \ pack\ .t\ -side\ top\ -fill\ x\n\ \ \ \ pack\ .c\ -side\ top\ -fill\ both\ -expand\ 1\n\ \ \ \ bind\ all\ <F2>\ NewGame\n\ \ \ \ bind\ all\ <F3>\ \{console\ show\}\n\ \ \ \ DoMenus\n\ \n\ \ \ \ bind\ .c\ <Configure>\ \{ReCenter\ %W\ %h\ %w\}\ \ \ \ \ \;#\ Force\ 0,0\ to\ be\ in\ center\n\ \ \ \ update\n\ \}\n\ proc\ DoMenus\ \{\}\ \{\n\ \ \ \ menu\ .m\ -tearoff\ 0\n\ \ \ \ .\ configure\ -menu\ .m\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Attach\ menu\ to\ main\ window\n\ \n\ \ \ \ .m\ add\ cascade\ -menu\ .m.game\ -label\ \"Game\"\ -underline\ 0\n\ \ \ \ .m\ add\ cascade\ -menu\ .m.help\ -label\ \"Help\"\ -underline\ 0\n\ \n\ \ \ \ menu\ .m.game\ -tearoff\ 0\n\ \ \ \ .m.game\ add\ command\ -label\ \"New\ Game\"\ -under\ 0\ -command\ NewGame\ -acc\ \"F2\"\n\ \ \ \ .m.game\ add\ separator\n\ \ \ \ .m.game\ add\ radiobutton\ -label\ \"Easy\"\ \ \ -under\ 0\ -variable\ ::G(n)\ -value\ 5\ \ -command\ NewGame\n\ \ \ \ .m.game\ add\ radiobutton\ -label\ \"Normal\"\ -under\ 0\ -variable\ ::G(n)\ -value\ 7\ \ -command\ NewGame\n\ \ \ \ .m.game\ add\ radiobutton\ -label\ \"Hard\"\ \ \ -under\ 0\ -variable\ ::G(n)\ -value\ 9\ \ -command\ NewGame\n\ \ \ \ .m.game\ add\ radiobutton\ -label\ \"Expert\"\ -under\ 0\ -variable\ ::G(n)\ -value\ 11\ -command\ NewGame\n\ \ \ \ .m.game\ add\ separator\n\ \ \ \ .m.game\ add\ command\ -label\ \"Exit\"\ -under\ 1\ -command\ exit\n\ \n\ \ \ \ menu\ .m.help\ -tearoff\ 0\n\ \ \ \ .m.help\ add\ command\ -label\ \"About\"\ -under\ 0\ -command\ About\n\ \}\n\ proc\ DrawBoard\ \{\}\ \{\n\ \ \ \ global\ B\n\ \n\ \ \ \ .c\ delete\ all\n\ \ \ \ for\ \{set\ row\ \$::G(-n2)\}\ \{\$row\ <\ \$::G(n2)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ set\ cmax\ \[expr\ \{\$::G(n)-1-abs(\$row)\}\]\n\ \ \ \ \ \ \ \ for\ \{set\ col\ -\$cmax\}\ \{\$col\ <=\ \$cmax\}\ \{incr\ col\ 2\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ DrawCellRays\ \$row\ \$col\n\ \ \ \ \ \ \ \ \ \ \ \ .c\ create\ image\ \[Cell2XY\ \$row\ \$col\]\ -image\ ::img::ball\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -tag\ b\$row,\$col\n\ \ \ \ \ \ \ \ \ \ \ \ .c\ bind\ b\$row,\$col\ <1>\ \[list\ Click\ \$row\ \$col\ 1\]\n\ \ \ \ \ \ \ \ \ \ \ \ .c\ bind\ r\$row,\$col\ <1>\ \[list\ Click\ \$row\ \$col\ 1\]\n\ \ \ \ \ \ \ \ \ \ \ \ .c\ bind\ b\$row,\$col\ <3>\ \[list\ Click\ \$row\ \$col\ -1\]\n\ \ \ \ \ \ \ \ \ \ \ \ .c\ bind\ r\$row,\$col\ <3>\ \[list\ Click\ \$row\ \$col\ -1\]\n\ \ \ \ \ \ \ \ \ \ \ \ .c\ bind\ b\$row,\$col\ <Control-1>\ \[list\ Cheat\ \$row\ \$col\]\n\ \ \ \ \ \ \ \ \ \ \ \ .c\ bind\ r\$row,\$col\ <Control-1>\ \[list\ Cheat\ \$row\ \$col\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ LightUp\n\ \}\n\ proc\ DrawRay\ \{row\ col\ dir\}\ \{\n\ \ \ \ foreach\ \{r1\ c1\}\ \[MoveDir\ \$row\ \$col\ \$dir\]\ break\n\ \n\ \ \ \ foreach\ \{x0\ y0\}\ \[Cell2XY\ \$row\ \$col\]\ break\n\ \ \ \ foreach\ \{x1\ y1\}\ \[Cell2XY\ \$r1\ \$c1\]\ break\n\ \n\ \ \ \ set\ x2\ \[expr\ \{\$x0\ +\ (\$x1-\$x0)/2\}\]\ \ \ \ \ \ \ \ \ \ \ \;#\ Halfway\ point\n\ \ \ \ set\ y2\ \[expr\ \{\$y0\ +\ (\$y1-\$y0)/2\}\]\n\ \ \ \ set\ tag\ r\$row,\$col\n\ \ \ \ .c\ create\ line\ \$x0\ \$y0\ \$x2\ \$y2\ -tag\ \[list\ r1\ \$tag\]\ -width\ 4\ -fil\ \$::COLORS(ray1)\n\ \ \ \ .c\ create\ line\ \$x0\ \$y0\ \$x2\ \$y2\ -tag\ \[list\ r2\ \$tag\]\ -width\ 2\ -fil\ \$::COLORS(ray2)\n\ \ \ \ .c\ lower\ r\$row,\$col\n\ \}\n\ proc\ DrawCellRays\ \{row\ col\}\ \{\n\ \ \ \ .c\ delete\ r\$row,\$col\n\ \ \ \ foreach\ dir\ \$::B(r,\$row,\$col)\ \{\n\ \ \ \ \ \ \ \ DrawRay\ \$row\ \$col\ \$dir\n\ \ \ \ \}\n\ \}\n\ proc\ Cell2XY\ \{row\ col\}\ \{\n\ \ \ \ set\ x\ \[expr\ \{\$col\ *\ \$::S(hdist)\}\]\n\ \ \ \ set\ y\ \[expr\ \{-\$row\ *\ \$::S(vdist)\}\]\n\ \ \ \ return\ \[list\ \$x\ \$y\]\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ Recenter\ --\ keeps\ 0,0\ at\ the\ center\ of\ the\ canvas\ during\ resizing\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\ \}\n\ \n\ proc\ Timer\ \{\{restart\ 0\}\}\ \{\n\ \ \ \ global\ G\n\ \n\ \ \ \ foreach\ aid\ \[after\ info\]\ \{\ after\ cancel\ \$aid\ \}\n\ \ \ \ if\ \{\$restart\}\ \{\n\ \ \ \ \ \ \ \ set\ G(start)\ \[clock\ seconds\]\n\ \ \ \ \}\n\ \ \ \ if\ \{\$G(state)\ ne\ \"play\"\}\ return\n\ \ \ \ set\ tlen\ \[expr\ \{\[clock\ seconds\]\ -\ \$G(start)\}\]\n\ \ \ \ set\ G(tmsg)\ \[clock\ format\ \$tlen\ -format\ \"%M:%S\"\]\n\ \ \ \ after\ 1000\ Timer\n\ \}\n\ proc\ NewGame\ \{\}\ \{\n\ \ \ \ MakeBoard\n\ \ \ \ DrawBoard\n\ \ \ \ set\ ::G(state)\ play\n\ \ \ \ Timer\ 1\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ MakeBoard\ --\ figures\ out\ all\ the\ nodes\ and\ all\ edges,\ then\ deletes\n\ #\ edges\ leaving\ a\ minimum\ spanning\ tree\ and\ finally\ randomly\ rotates\n\ #\ all\ nodes.\n\ #\n\ proc\ MakeBoard\ \{\}\ \{\n\ \ \ \ global\ B\ G\ EDGES\n\ \n\ \ \ \ unset\ -nocomplain\ B\n\ \ \ \ set\ EDGES\ \{\}\n\ \n\ \ \ \ set\ G(n2)\ \[expr\ \{(\$G(n)+1)/2\}\]\ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Handy\ constants\n\ \ \ \ set\ G(-n2)\ \[expr\ \{1-\$G(n2)\}\]\n\ \n\ \ \ \ for\ \{set\ row\ \$::G(-n2)\}\ \{\$row\ <\ \$::G(n2)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ set\ cmax\ \[expr\ \{\$::G(n)-1-abs(\$row)\}\]\n\ \ \ \ \ \ \ \ for\ \{set\ col\ -\$cmax\}\ \{\$col\ <=\ \$cmax\}\ \{incr\ col\ 2\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ B(c,\$row,\$col)\ 1\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \n\ \ \ \ #\ Compute\ all\ legal\ edges\n\ \ \ \ for\ \{set\ row\ \$::G(-n2)\}\ \{\$row\ <\ \$::G(n2)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ set\ cmax\ \[expr\ \{\$::G(n)-1-abs(\$row)\}\]\n\ \ \ \ \ \ \ \ for\ \{set\ col\ -\$cmax\}\ \{\$col\ <=\ \$cmax\}\ \{incr\ col\ 2\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ B(r,\$row,\$col)\ \[FindNeighbors\ \$row\ \$col\]\n\ \ \ \ \ \ \ \ \ \ \ \ foreach\ dir\ \{0\ 1\ 2\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[lsearch\ \$B(r,\$row,\$col)\ \$dir\]\ >\ -1\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ EDGES\ \[list\ \$row\ \$col\ \$dir\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ set\ G(cnt)\ \[llength\ \[array\ names\ B\ c*\]\]\n\ \n\ \ \ \ #\ Now\ convert\ full\ graph\ into\ minimum\ spanning\ tree\n\ \ \ \ set\ mst\ \[MST\]\n\ \ \ \ foreach\ e\ \$EDGES\ \{\n\ \ \ \ \ \ \ \ if\ \{\[lsearch\ \$mst\ \$e\]\ ==\ -1\}\ \{\ \ \ \ \ \ \ \ \ \ \;#\ Is\ edge\ not\ in\ MST???\n\ \ \ \ \ \ \ \ \ \ \ \ eval\ RemoveEdge\ \$e\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ ...then\ remove\ it\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \n\ \ \ \ #\ Now\ rotate\ randomly\ every\ node\n\ \ \ \ for\ \{set\ row\ \$::G(-n2)\}\ \{\$row\ <\ \$::G(n2)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ set\ cmax\ \[expr\ \{\$::G(n)-1-abs(\$row)\}\]\n\ \ \ \ \ \ \ \ for\ \{set\ col\ -\$cmax\}\ \{\$col\ <=\ \$cmax\}\ \{incr\ col\ 2\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ B(rr,\$row,\$col)\ \$B(r,\$row,\$col)\n\ \ \ \ \ \ \ \ \ \ \ \ RotateCell\ \$row\ \$col\ \[expr\ \{int(rand()*6)\}\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ FindNeighbors\ --\ returns\ list\ of\ all\ legal\ directions\ from\ this\ node\n\ #\n\ proc\ FindNeighbors\ \{row\ col\}\ \{\n\ \ \ \ global\ B\n\ \n\ \ \ \ set\ dirs\ \{\}\n\ \ \ \ foreach\ dir\ \{0\ 1\ 2\ 3\ 4\ 5\}\ \{\n\ \ \ \ \ \ \ \ foreach\ \{r\ c\}\ \[MoveDir\ \$row\ \$col\ \$dir\]\ break\n\ \ \ \ \ \ \ \ if\ \{\[info\ exists\ B(c,\$r,\$c)\]\}\ \{\ lappend\ dirs\ \$dir\ \}\n\ \ \ \ \}\n\ \ \ \ return\ \$dirs\n\ \}\n\ proc\ MoveDir\ \{row\ col\ dir\}\ \{\n\ \ \ \ foreach\ \{dr\ dc\}\ \$::DRC(\$dir)\ break\n\ \ \ \ set\ r1\ \[expr\ \{\$row\ +\ \$dr\}\]\n\ \ \ \ set\ c1\ \[expr\ \{\$col\ +\ \$dc\}\]\n\ \ \ \ return\ \[list\ \$r1\ \$c1\]\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ Click\ --\ handles\ clicking\ on\ a\ node\n\ #\n\ proc\ Click\ \{row\ col\ rdir\}\ \{\n\ \ \ \ RotateCell\ \$row\ \$col\ \$rdir\n\ \ \ \ DrawCellRays\ \$row\ \$col\n\ \ \ \ LightUp\n\ \}\n\ proc\ Cheat\ \{row\ col\}\ \{\n\ \ \ \ set\ ::B(r,\$row,\$col)\ \$::B(rr,\$row,\$col)\n\ \ \ \ DrawCellRays\ \$row\ \$col\n\ \ \ \ LightUp\n\ \}\n\ \n\ proc\ RotateCell\ \{row\ col\ rdir\}\ \{\n\ \ \ \ global\ B\n\ \ \ \ set\ dirs\ \{\}\n\ \ \ \ foreach\ dir\ \$B(r,\$row,\$col)\ \{\n\ \ \ \ \ \ \ \ lappend\ dirs\ \[expr\ \{(\$dir\ +\ \$rdir)\ %\ 6\}\]\n\ \ \ \ \}\n\ \ \ \ set\ B(r,\$row,\$col)\ \$dirs\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ LightUp\ --\ does\ a\ depth-first-search\ to\ find\ all\ connected\ components\n\ #\n\ proc\ LightUp\ \{\}\ \{\n\ \ \ \ global\ DFS\n\ \n\ \ \ \ DFS\n\ \ \ \ set\ solved\ 1\n\ \ \ \ for\ \{set\ row\ \$::G(-n2)\}\ \{\$row\ <\ \$::G(n2)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ set\ cmax\ \[expr\ \{\$::G(n)-1-abs(\$row)\}\]\n\ \ \ \ \ \ \ \ for\ \{set\ col\ -\$cmax\}\ \{\$col\ <=\ \$cmax\}\ \{incr\ col\ 2\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ img\ \"::img::ball2\"\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{!\ \$DFS(\$row,\$col)\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ solved\ 0\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ img\ \"::img::ball\"\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ .c\ itemconfig\ b\$row,\$col\ -image\ \$img\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \n\ \ \ \ if\ \{\$solved\}\ Victory\n\ \}\n\ \n\ proc\ Victory\ \{\}\ \{\n\ \ \ \ global\ G\n\ \n\ \ \ \ if\ \{\$G(state)\ ne\ \"play\"\}\ return\n\ \ \ \ set\ G(state)\ solved\n\ \ \ \ Flash\n\ \}\n\ proc\ Flash\ \{\{cnt\ 3\}\ \{delay\ 200\}\}\ \{\n\ \ \ \ for\ \{set\ i\ 0\}\ \{\$i\ <\ \$cnt\}\ \{incr\ i\}\ \{\n\ \ \ \ \ \ \ \ .c\ config\ -bg\ red\n\ \ \ \ \ \ \ \ .t\ config\ -bg\ red\n\ \ \ \ \ \ \ \ update\n\ \ \ \ \ \ \ \ after\ \$delay\n\ \ \ \ \ \ \ \ .c\ config\ -bg\ black\n\ \ \ \ \ \ \ \ .t\ config\ -bg\ black\n\ \ \ \ \ \ \ \ update\n\ \ \ \ \ \ \ \ after\ \$delay\n\ \ \ \ \}\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ RemoveEdge\ --\ removes\ an\ edge\ for\ a\ given\ node\ and\ the\ reverse\ node\n\ #\n\ proc\ RemoveEdge\ \{row\ col\ dir\}\ \{\n\ \ \ \ global\ B\n\ \n\ \ \ \ foreach\ \{r\ c\}\ \[MoveDir\ \$row\ \$col\ \$dir\]\ break\n\ \ \ \ set\ opp\ \[expr\ \{(\$dir\ +\ 3)\ %\ 6\}\]\n\ \n\ \ \ \ set\ n\ \[lsearch\ \$B(r,\$row,\$col)\ \$dir\]\n\ \ \ \ set\ B(r,\$row,\$col)\ \[lreplace\ \$B(r,\$row,\$col)\ \$n\ \$n\]\n\ \n\ \ \ \ set\ n\ \[lsearch\ \$B(r,\$r,\$c)\ \$opp\]\n\ \ \ \ set\ B(r,\$r,\$c)\ \[lreplace\ \$B(r,\$r,\$c)\ \$n\ \$n\]\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ DFS\ --\ does\ a\ depth-first-search\ from\ the\ origin.\ This\ can\ blow\ out\n\ #\ the\ recursion\ limit\ for\ big\ board\ sizes.\n\ #\n\ proc\ DFS\ \{\}\ \{\n\ \ \ \ global\ DFS\n\ \n\ \ \ \ unset\ -nocomplain\ DFS\n\ \ \ \ set\ DFS(cnt)\ 0\n\ \ \ \ for\ \{set\ row\ \$::G(-n2)\}\ \{\$row\ <\ \$::G(n2)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ set\ cmax\ \[expr\ \{\$::G(n)-1-abs(\$row)\}\]\n\ \ \ \ \ \ \ \ for\ \{set\ col\ -\$cmax\}\ \{\$col\ <=\ \$cmax\}\ \{incr\ col\ 2\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ DFS(\$row,\$col)\ 0\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \n\ \ \ \ _DFS\ 0\ 0\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ _DFS\ --\ recursive\ caller\ for\ DFS\n\ #\n\ proc\ _DFS\ \{row\ col\}\ \{\n\ \ \ \ global\ B\ DFS\n\ \n\ \ \ \ set\ DFS(\$row,\$col)\ 1\n\ \ \ \ incr\ DFS(cnt)\n\ \ \ \ foreach\ dir\ \$B(r,\$row,\$col)\ \{\n\ \ \ \ \ \ \ \ if\ \{!\ \[IsPath\ \$row\ \$col\ \$dir\]\}\ continue\n\ \ \ \ \ \ \ \ foreach\ \{r\ c\}\ \[MoveDir\ \$row\ \$col\ \$dir\]\ break\n\ \ \ \ \ \ \ \ if\ \{\$DFS(\$r,\$c)\ !=\ 0\}\ continue\n\ \ \ \ \ \ \ \ _DFS\ \$r\ \$c\n\ \ \ \ \}\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ IsPath\ --\ return\ true\ if\ there\ is\ a\ path\ from\ row,col\ in\ direction\ dir\n\ #\ \ \ \ \ assumes\ path\ exists\ out\ of\ row,col\ so\ it\ checks\ for\ off\ the\ board\n\ #\ \ \ \ \ and\ is\ there\ a\ matching\ opposite\ path\ from\ destination\n\ #\n\ proc\ IsPath\ \{row\ col\ dir\}\ \{\n\ \ \ \ global\ B\n\ \n\ \ \ \ foreach\ \{r\ c\}\ \[MoveDir\ \$row\ \$col\ \$dir\]\ break\n\ \ \ \ if\ \{!\ \[info\ exists\ B(c,\$r,\$c)\]\}\ \{\ return\ 0\ \}\;#\ Destination\ off\ the\ board\n\ \ \ \ set\ opp\ \[expr\ \{(\$dir\ +\ 3)\ %\ 6\}\]\n\ \ \ \ set\ n\ \[lsearch\ \$B(r,\$r,\$c)\ \$opp\]\n\ \ \ \ return\ \[expr\ \{\$n\ >\ -1\ ?\ 1\ :\ 0\}\]\n\ \}\n\ \n\ proc\ Shuffle\ \{l\}\ \{\n\ \ \ \ set\ len\ \[llength\ \$l\]\n\ \ \ \ set\ len2\ \$len\n\ \ \ \ for\ \{set\ i\ 0\}\ \{\$i\ <\ \$len-1\}\ \{incr\ i\}\ \{\n\ \ \ \ \ \ \ \ set\ n\ \[expr\ \{int(\$i\ +\ \$len2\ *\ rand())\}\]\n\ \ \ \ \ \ \ \ incr\ len2\ -1\n\ \n\ \ \ \ \ \ \ \ #\ Swap\ elements\ at\ i\ &\ n\n\ \ \ \ \ \ \ \ set\ temp\ \[lindex\ \$l\ \$i\]\n\ \ \ \ \ \ \ \ lset\ l\ \$i\ \[lindex\ \$l\ \$n\]\n\ \ \ \ \ \ \ \ lset\ l\ \$n\ \$temp\n\ \ \ \ \}\n\ \ \ \ return\ \$l\n\ \}\n\ proc\ About\ \{\}\ \{\n\ \ \ \ set\ txt\ \"\$::S(title)\\nby\ Keith\ Vetter,\ February\ 2006\\n\\n\"\n\ \ \ \ append\ txt\ \"Turn\ on\ all\ the\ lights!\\n\\n\"\n\ \ \ \ append\ txt\ \"Left\ click:\ rotate\ clockwise\\n\"\n\ \ \ \ append\ txt\ \"Right\ click:\ rotate\ counter-clockwise\\n\"\n\ \ \ \ tk_messageBox\ -message\ \$txt\ -title\ About\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ MST\ --\ computes\ a\ random\ minimum\ spanning\ tree\ using\ Prim's\ algorithm\n\ #\n\ proc\ MST\ \{\}\ \{\n\ \ \ \ global\ B\ EDGES\n\ \n\ \ \ \ set\ mst\ \{\}\n\ \n\ \ \ \ #\ Mark\ all\ nodes\ as\ unvisited\n\ \ \ \ for\ \{set\ row\ \$::G(-n2)\}\ \{\$row\ <\ \$::G(n2)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ set\ cmax\ \[expr\ \{\$::G(n)-1-abs(\$row)\}\]\n\ \ \ \ \ \ \ \ for\ \{set\ col\ -\$cmax\}\ \{\$col\ <=\ \$cmax\}\ \{incr\ col\ 2\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ visited(\$row,\$col)\ 0\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \n\ \ \ \ set\ edges\ \[Shuffle\ \$EDGES\]\n\ \n\ \ \ \ foreach\ \{r\ c\}\ \[lindex\ \$edges\ 0\]\ break\ \ \ \ \ \ \ \;#\ Start\ with\ random\ node\n\ \ \ \ set\ visited(\$r,\$c)\ 1\n\ \ \ \ while\ \{\[llength\ \$mst\]\ <\ \$::G(cnt)-1\}\ \{\n\ \ \ \ \ \ \ \ #\ Find\ edge\ out\ of\ visited\ nodes\ (inefficient\ but\ who\ cares)\n\ \ \ \ \ \ \ \ for\ \{set\ i\ 0\}\ \{\$i\ <\ \[llength\ \$edges\]\}\ \{incr\ i\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ foreach\ \{r0\ c0\ dir\}\ \[lindex\ \$edges\ \$i\]\ break\ \;#\ Start\ point\n\ \ \ \ \ \ \ \ \ \ \ \ foreach\ \{r1\ c1\}\ \[MoveDir\ \$r0\ \$c0\ \$dir\]\ break\ \;#\ End\ point\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$visited(\$r0,\$c0)\ !=\ \$visited(\$r1,\$c1)\}\ break\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ set\ edges\ \[lreplace\ \$edges\ \$i\ \$i\]\ \ \ \ \ \ \ \;#\ Remove\ from\ edge\ list\n\ \ \ \ \ \ \ \ lappend\ mst\ \[list\ \$r0\ \$c0\ \$dir\]\ \ \ \ \ \ \ \ \ \;#\ Add\ to\ our\ mst\n\ \ \ \ \ \ \ \ set\ visited(\$r0,\$c0)\ 1\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Mark\ nodes\ as\ visited\n\ \ \ \ \ \ \ \ set\ visited(\$r1,\$c1)\ 1\n\ \ \ \ \}\n\ \n\ \ \ \ return\ \$mst\n\ \}\n\ \n\ ################################################################\n\ \n\ image\ create\ photo\ ::img::ball\ -data\ \{\n\ \ \ \ R0lGODlhCgAKALMAACQmJHd3d6SmpAQC/ExKTJGRkcTCxFxeXDk3Oby6vISGhJyenNDQ0GZnZlRW\n\ \ \ \ VKyurCH5BAEAAAMALAAAAAAKAAoAAwQ5cIyWGHtOjmJNekszHN4jLIUSIAWYBkHTEEUBN0d+ODHu\n\ \ \ \ /I4dIQgMHggAo3EHGCB+uR9CAxg6kJIIADs=\}\n\ image\ create\ photo\ ::img::ball2\ -data\ \{\n\ \ \ \ R0lGODlhCgAKALMAAGRXBJSKBN7MBOzYXLyyBOjkBMq/BN3XBAQC/Pz2fJR6BJSWBPPwBL6aBGRm\n\ \ \ \ BN23BCH5BAEAAAgALAAAAAAKAAoAAwQzECFnzjFAomWtEMFkFQxTCBghkKX5NMaQzPTwPDI9283D\n\ \ \ \ loUX4MYKPjKKm/Kh0AB6QkkEADs=\}\n\ \n\ DoDisplay\n\ NewGame\n\ return\n\n======\n\[lights_on\ android\ IMG\]\n\nLights\ On\ is\ available\ for\ Android\ on\ Playstore\ \[https://play.google.com/store/apps/details?id=com.game.lightson\]\n======\n\n<<categories>>\ Games\ |\ Application regexp2} CALL {my render {Lights On} \[Keith\ Vetter\]\ 2006-02-09\ :\ Here's\ a\ fun\ litle\ game\ where\ you\ have\ to\ rotate\ nodes\ \nto\ connect\ up\ wires\ to\ light\ up\ every\ node.\ I\ wrote\ a\ somewhat\ similar\ game\nearlier\ called\ \[Lights\ Out\].\n\nFun\ project\ for\ several\ reasons:\ 1)\ implemented\ a\ minimum\ spanning\ntree\ algorithm\ (Prim's)\ 2)\ implemented\ a\ depth-first\ search\ \nand\ 3)\ did\ a\ poor\ man's\ anti-aliasing\ to\ get\ nicer\ looking\ lines.\n\n----\n\[ABU\]\ Really\ nice.\ Just\ for\ the\ blockheads\ like\ me,\ could\ you\ provide\ a\ \"solve\"\ command\ with\ a\ slow\ animation\ ?\n\n\[KPV\]\ There's\ already\ a\ built\ it\ cheat\ command.\ \nJust\ hold\ the\ control\ key\ down\ and\ click\ on\ a\ node.\ That\ will\ncause\ that\ node\ to\ orient\ itself\ correctly.\n\n----\n\[GS\]\ 2010-10-23\ :\ A\ slightly\ modified\ version\ \[http://wfr.tcl.tk/fichiers/pub/lightson-winmo.tcl\]\ for\ touchscreen\ Windows\ Mobile\ device\ with\ \[eTcl\].\ Lights\ bulbs\ are\ larger\ and\ expert\ mod\ has\ been\ disabled\ because\ it\ is\ too\ larger\ to\ fit\ in\ smartphone\ screen\ resolution.\n\n\[http://wfr.tcl.tk/fichiers/images/lightson.gif\]\n\n\[uniquename\]\ 2013aug01\n\nHere\ is\ a\ right-clipped\ image\ of\ the\ 'desktop'\ version\ ---\ along\ with\ a\ (partly-clipped)\ image\ of\ the\ help\ popup.\n\n\[vetter_LightsOn_screenshot_647x461.jpg\]\n\nThis\ is\ the\ initial\ setting\ of\ the\ GUI.\ The\ little\ rods\ rotate\ to\ 'hexagonal-angles'\ ---\ and\ lights\ come\ on\ as\ more\ segments\ are\ attached,\nto\ complete\ the\ circuit\ to\ the\ central\ light.\n\n======\n\ ##+##########################################################################\n\ #\n\ #\ lightsOn.tcl\ --\ based\ on\ http://pyva.net/eng/pc/lights.html\n\ #\ by\ Keith\ Vetter\n\ #\n\ package\ require\ Tk\n\ \n\ set\ G(n)\ 7\n\ array\ set\ S\ \{title\ \"Lights\ On\"\ w\ 600\ h\ 600\ vdist\ 50\ hdist\ 28\}\n\ array\ set\ DRC\ \{0\ \{0\ 2\}\ 1\ \{-1\ 1\}\ 2\ \{-1\ -1\}\ 3\ \{0\ -2\}\ 4\ \{1\ -1\}\ 5\ \{1\ 1\}\}\n\ array\ set\ COLORS\ \{ray1\ \\#4C526C\ ray2\ \\#8C96B4\}\n\ \n\ proc\ DoDisplay\ \{\}\ \{\n\ \ \ \ global\ S\n\ \n\ \ \ \ wm\ title\ .\ \$S(title)\n\ \ \ \ canvas\ .c\ -bg\ black\ -width\ \$S(w)\ -height\ \$S(h)\ -highlightthickness\ 0\n\ \ \ \ label\ .t\ -textvariable\ ::G(tmsg)\ -font\ \{Times\ 18\ bold\}\ \\\n\ \ \ \ \ \ \ \ -fg\ cyan\ -bg\ black\ -anchor\ w\ -padx\ 10\n\ \ \ \ pack\ .t\ -side\ top\ -fill\ x\n\ \ \ \ pack\ .c\ -side\ top\ -fill\ both\ -expand\ 1\n\ \ \ \ bind\ all\ <F2>\ NewGame\n\ \ \ \ bind\ all\ <F3>\ \{console\ show\}\n\ \ \ \ DoMenus\n\ \n\ \ \ \ bind\ .c\ <Configure>\ \{ReCenter\ %W\ %h\ %w\}\ \ \ \ \ \;#\ Force\ 0,0\ to\ be\ in\ center\n\ \ \ \ update\n\ \}\n\ proc\ DoMenus\ \{\}\ \{\n\ \ \ \ menu\ .m\ -tearoff\ 0\n\ \ \ \ .\ configure\ -menu\ .m\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Attach\ menu\ to\ main\ window\n\ \n\ \ \ \ .m\ add\ cascade\ -menu\ .m.game\ -label\ \"Game\"\ -underline\ 0\n\ \ \ \ .m\ add\ cascade\ -menu\ .m.help\ -label\ \"Help\"\ -underline\ 0\n\ \n\ \ \ \ menu\ .m.game\ -tearoff\ 0\n\ \ \ \ .m.game\ add\ command\ -label\ \"New\ Game\"\ -under\ 0\ -command\ NewGame\ -acc\ \"F2\"\n\ \ \ \ .m.game\ add\ separator\n\ \ \ \ .m.game\ add\ radiobutton\ -label\ \"Easy\"\ \ \ -under\ 0\ -variable\ ::G(n)\ -value\ 5\ \ -command\ NewGame\n\ \ \ \ .m.game\ add\ radiobutton\ -label\ \"Normal\"\ -under\ 0\ -variable\ ::G(n)\ -value\ 7\ \ -command\ NewGame\n\ \ \ \ .m.game\ add\ radiobutton\ -label\ \"Hard\"\ \ \ -under\ 0\ -variable\ ::G(n)\ -value\ 9\ \ -command\ NewGame\n\ \ \ \ .m.game\ add\ radiobutton\ -label\ \"Expert\"\ -under\ 0\ -variable\ ::G(n)\ -value\ 11\ -command\ NewGame\n\ \ \ \ .m.game\ add\ separator\n\ \ \ \ .m.game\ add\ command\ -label\ \"Exit\"\ -under\ 1\ -command\ exit\n\ \n\ \ \ \ menu\ .m.help\ -tearoff\ 0\n\ \ \ \ .m.help\ add\ command\ -label\ \"About\"\ -under\ 0\ -command\ About\n\ \}\n\ proc\ DrawBoard\ \{\}\ \{\n\ \ \ \ global\ B\n\ \n\ \ \ \ .c\ delete\ all\n\ \ \ \ for\ \{set\ row\ \$::G(-n2)\}\ \{\$row\ <\ \$::G(n2)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ set\ cmax\ \[expr\ \{\$::G(n)-1-abs(\$row)\}\]\n\ \ \ \ \ \ \ \ for\ \{set\ col\ -\$cmax\}\ \{\$col\ <=\ \$cmax\}\ \{incr\ col\ 2\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ DrawCellRays\ \$row\ \$col\n\ \ \ \ \ \ \ \ \ \ \ \ .c\ create\ image\ \[Cell2XY\ \$row\ \$col\]\ -image\ ::img::ball\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -tag\ b\$row,\$col\n\ \ \ \ \ \ \ \ \ \ \ \ .c\ bind\ b\$row,\$col\ <1>\ \[list\ Click\ \$row\ \$col\ 1\]\n\ \ \ \ \ \ \ \ \ \ \ \ .c\ bind\ r\$row,\$col\ <1>\ \[list\ Click\ \$row\ \$col\ 1\]\n\ \ \ \ \ \ \ \ \ \ \ \ .c\ bind\ b\$row,\$col\ <3>\ \[list\ Click\ \$row\ \$col\ -1\]\n\ \ \ \ \ \ \ \ \ \ \ \ .c\ bind\ r\$row,\$col\ <3>\ \[list\ Click\ \$row\ \$col\ -1\]\n\ \ \ \ \ \ \ \ \ \ \ \ .c\ bind\ b\$row,\$col\ <Control-1>\ \[list\ Cheat\ \$row\ \$col\]\n\ \ \ \ \ \ \ \ \ \ \ \ .c\ bind\ r\$row,\$col\ <Control-1>\ \[list\ Cheat\ \$row\ \$col\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ LightUp\n\ \}\n\ proc\ DrawRay\ \{row\ col\ dir\}\ \{\n\ \ \ \ foreach\ \{r1\ c1\}\ \[MoveDir\ \$row\ \$col\ \$dir\]\ break\n\ \n\ \ \ \ foreach\ \{x0\ y0\}\ \[Cell2XY\ \$row\ \$col\]\ break\n\ \ \ \ foreach\ \{x1\ y1\}\ \[Cell2XY\ \$r1\ \$c1\]\ break\n\ \n\ \ \ \ set\ x2\ \[expr\ \{\$x0\ +\ (\$x1-\$x0)/2\}\]\ \ \ \ \ \ \ \ \ \ \ \;#\ Halfway\ point\n\ \ \ \ set\ y2\ \[expr\ \{\$y0\ +\ (\$y1-\$y0)/2\}\]\n\ \ \ \ set\ tag\ r\$row,\$col\n\ \ \ \ .c\ create\ line\ \$x0\ \$y0\ \$x2\ \$y2\ -tag\ \[list\ r1\ \$tag\]\ -width\ 4\ -fil\ \$::COLORS(ray1)\n\ \ \ \ .c\ create\ line\ \$x0\ \$y0\ \$x2\ \$y2\ -tag\ \[list\ r2\ \$tag\]\ -width\ 2\ -fil\ \$::COLORS(ray2)\n\ \ \ \ .c\ lower\ r\$row,\$col\n\ \}\n\ proc\ DrawCellRays\ \{row\ col\}\ \{\n\ \ \ \ .c\ delete\ r\$row,\$col\n\ \ \ \ foreach\ dir\ \$::B(r,\$row,\$col)\ \{\n\ \ \ \ \ \ \ \ DrawRay\ \$row\ \$col\ \$dir\n\ \ \ \ \}\n\ \}\n\ proc\ Cell2XY\ \{row\ col\}\ \{\n\ \ \ \ set\ x\ \[expr\ \{\$col\ *\ \$::S(hdist)\}\]\n\ \ \ \ set\ y\ \[expr\ \{-\$row\ *\ \$::S(vdist)\}\]\n\ \ \ \ return\ \[list\ \$x\ \$y\]\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ Recenter\ --\ keeps\ 0,0\ at\ the\ center\ of\ the\ canvas\ during\ resizing\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\ \}\n\ \n\ proc\ Timer\ \{\{restart\ 0\}\}\ \{\n\ \ \ \ global\ G\n\ \n\ \ \ \ foreach\ aid\ \[after\ info\]\ \{\ after\ cancel\ \$aid\ \}\n\ \ \ \ if\ \{\$restart\}\ \{\n\ \ \ \ \ \ \ \ set\ G(start)\ \[clock\ seconds\]\n\ \ \ \ \}\n\ \ \ \ if\ \{\$G(state)\ ne\ \"play\"\}\ return\n\ \ \ \ set\ tlen\ \[expr\ \{\[clock\ seconds\]\ -\ \$G(start)\}\]\n\ \ \ \ set\ G(tmsg)\ \[clock\ format\ \$tlen\ -format\ \"%M:%S\"\]\n\ \ \ \ after\ 1000\ Timer\n\ \}\n\ proc\ NewGame\ \{\}\ \{\n\ \ \ \ MakeBoard\n\ \ \ \ DrawBoard\n\ \ \ \ set\ ::G(state)\ play\n\ \ \ \ Timer\ 1\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ MakeBoard\ --\ figures\ out\ all\ the\ nodes\ and\ all\ edges,\ then\ deletes\n\ #\ edges\ leaving\ a\ minimum\ spanning\ tree\ and\ finally\ randomly\ rotates\n\ #\ all\ nodes.\n\ #\n\ proc\ MakeBoard\ \{\}\ \{\n\ \ \ \ global\ B\ G\ EDGES\n\ \n\ \ \ \ unset\ -nocomplain\ B\n\ \ \ \ set\ EDGES\ \{\}\n\ \n\ \ \ \ set\ G(n2)\ \[expr\ \{(\$G(n)+1)/2\}\]\ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Handy\ constants\n\ \ \ \ set\ G(-n2)\ \[expr\ \{1-\$G(n2)\}\]\n\ \n\ \ \ \ for\ \{set\ row\ \$::G(-n2)\}\ \{\$row\ <\ \$::G(n2)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ set\ cmax\ \[expr\ \{\$::G(n)-1-abs(\$row)\}\]\n\ \ \ \ \ \ \ \ for\ \{set\ col\ -\$cmax\}\ \{\$col\ <=\ \$cmax\}\ \{incr\ col\ 2\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ B(c,\$row,\$col)\ 1\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \n\ \ \ \ #\ Compute\ all\ legal\ edges\n\ \ \ \ for\ \{set\ row\ \$::G(-n2)\}\ \{\$row\ <\ \$::G(n2)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ set\ cmax\ \[expr\ \{\$::G(n)-1-abs(\$row)\}\]\n\ \ \ \ \ \ \ \ for\ \{set\ col\ -\$cmax\}\ \{\$col\ <=\ \$cmax\}\ \{incr\ col\ 2\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ B(r,\$row,\$col)\ \[FindNeighbors\ \$row\ \$col\]\n\ \ \ \ \ \ \ \ \ \ \ \ foreach\ dir\ \{0\ 1\ 2\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[lsearch\ \$B(r,\$row,\$col)\ \$dir\]\ >\ -1\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ EDGES\ \[list\ \$row\ \$col\ \$dir\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ set\ G(cnt)\ \[llength\ \[array\ names\ B\ c*\]\]\n\ \n\ \ \ \ #\ Now\ convert\ full\ graph\ into\ minimum\ spanning\ tree\n\ \ \ \ set\ mst\ \[MST\]\n\ \ \ \ foreach\ e\ \$EDGES\ \{\n\ \ \ \ \ \ \ \ if\ \{\[lsearch\ \$mst\ \$e\]\ ==\ -1\}\ \{\ \ \ \ \ \ \ \ \ \ \;#\ Is\ edge\ not\ in\ MST???\n\ \ \ \ \ \ \ \ \ \ \ \ eval\ RemoveEdge\ \$e\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ ...then\ remove\ it\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \n\ \ \ \ #\ Now\ rotate\ randomly\ every\ node\n\ \ \ \ for\ \{set\ row\ \$::G(-n2)\}\ \{\$row\ <\ \$::G(n2)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ set\ cmax\ \[expr\ \{\$::G(n)-1-abs(\$row)\}\]\n\ \ \ \ \ \ \ \ for\ \{set\ col\ -\$cmax\}\ \{\$col\ <=\ \$cmax\}\ \{incr\ col\ 2\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ B(rr,\$row,\$col)\ \$B(r,\$row,\$col)\n\ \ \ \ \ \ \ \ \ \ \ \ RotateCell\ \$row\ \$col\ \[expr\ \{int(rand()*6)\}\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ FindNeighbors\ --\ returns\ list\ of\ all\ legal\ directions\ from\ this\ node\n\ #\n\ proc\ FindNeighbors\ \{row\ col\}\ \{\n\ \ \ \ global\ B\n\ \n\ \ \ \ set\ dirs\ \{\}\n\ \ \ \ foreach\ dir\ \{0\ 1\ 2\ 3\ 4\ 5\}\ \{\n\ \ \ \ \ \ \ \ foreach\ \{r\ c\}\ \[MoveDir\ \$row\ \$col\ \$dir\]\ break\n\ \ \ \ \ \ \ \ if\ \{\[info\ exists\ B(c,\$r,\$c)\]\}\ \{\ lappend\ dirs\ \$dir\ \}\n\ \ \ \ \}\n\ \ \ \ return\ \$dirs\n\ \}\n\ proc\ MoveDir\ \{row\ col\ dir\}\ \{\n\ \ \ \ foreach\ \{dr\ dc\}\ \$::DRC(\$dir)\ break\n\ \ \ \ set\ r1\ \[expr\ \{\$row\ +\ \$dr\}\]\n\ \ \ \ set\ c1\ \[expr\ \{\$col\ +\ \$dc\}\]\n\ \ \ \ return\ \[list\ \$r1\ \$c1\]\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ Click\ --\ handles\ clicking\ on\ a\ node\n\ #\n\ proc\ Click\ \{row\ col\ rdir\}\ \{\n\ \ \ \ RotateCell\ \$row\ \$col\ \$rdir\n\ \ \ \ DrawCellRays\ \$row\ \$col\n\ \ \ \ LightUp\n\ \}\n\ proc\ Cheat\ \{row\ col\}\ \{\n\ \ \ \ set\ ::B(r,\$row,\$col)\ \$::B(rr,\$row,\$col)\n\ \ \ \ DrawCellRays\ \$row\ \$col\n\ \ \ \ LightUp\n\ \}\n\ \n\ proc\ RotateCell\ \{row\ col\ rdir\}\ \{\n\ \ \ \ global\ B\n\ \ \ \ set\ dirs\ \{\}\n\ \ \ \ foreach\ dir\ \$B(r,\$row,\$col)\ \{\n\ \ \ \ \ \ \ \ lappend\ dirs\ \[expr\ \{(\$dir\ +\ \$rdir)\ %\ 6\}\]\n\ \ \ \ \}\n\ \ \ \ set\ B(r,\$row,\$col)\ \$dirs\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ LightUp\ --\ does\ a\ depth-first-search\ to\ find\ all\ connected\ components\n\ #\n\ proc\ LightUp\ \{\}\ \{\n\ \ \ \ global\ DFS\n\ \n\ \ \ \ DFS\n\ \ \ \ set\ solved\ 1\n\ \ \ \ for\ \{set\ row\ \$::G(-n2)\}\ \{\$row\ <\ \$::G(n2)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ set\ cmax\ \[expr\ \{\$::G(n)-1-abs(\$row)\}\]\n\ \ \ \ \ \ \ \ for\ \{set\ col\ -\$cmax\}\ \{\$col\ <=\ \$cmax\}\ \{incr\ col\ 2\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ img\ \"::img::ball2\"\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{!\ \$DFS(\$row,\$col)\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ solved\ 0\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ img\ \"::img::ball\"\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ .c\ itemconfig\ b\$row,\$col\ -image\ \$img\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \n\ \ \ \ if\ \{\$solved\}\ Victory\n\ \}\n\ \n\ proc\ Victory\ \{\}\ \{\n\ \ \ \ global\ G\n\ \n\ \ \ \ if\ \{\$G(state)\ ne\ \"play\"\}\ return\n\ \ \ \ set\ G(state)\ solved\n\ \ \ \ Flash\n\ \}\n\ proc\ Flash\ \{\{cnt\ 3\}\ \{delay\ 200\}\}\ \{\n\ \ \ \ for\ \{set\ i\ 0\}\ \{\$i\ <\ \$cnt\}\ \{incr\ i\}\ \{\n\ \ \ \ \ \ \ \ .c\ config\ -bg\ red\n\ \ \ \ \ \ \ \ .t\ config\ -bg\ red\n\ \ \ \ \ \ \ \ update\n\ \ \ \ \ \ \ \ after\ \$delay\n\ \ \ \ \ \ \ \ .c\ config\ -bg\ black\n\ \ \ \ \ \ \ \ .t\ config\ -bg\ black\n\ \ \ \ \ \ \ \ update\n\ \ \ \ \ \ \ \ after\ \$delay\n\ \ \ \ \}\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ RemoveEdge\ --\ removes\ an\ edge\ for\ a\ given\ node\ and\ the\ reverse\ node\n\ #\n\ proc\ RemoveEdge\ \{row\ col\ dir\}\ \{\n\ \ \ \ global\ B\n\ \n\ \ \ \ foreach\ \{r\ c\}\ \[MoveDir\ \$row\ \$col\ \$dir\]\ break\n\ \ \ \ set\ opp\ \[expr\ \{(\$dir\ +\ 3)\ %\ 6\}\]\n\ \n\ \ \ \ set\ n\ \[lsearch\ \$B(r,\$row,\$col)\ \$dir\]\n\ \ \ \ set\ B(r,\$row,\$col)\ \[lreplace\ \$B(r,\$row,\$col)\ \$n\ \$n\]\n\ \n\ \ \ \ set\ n\ \[lsearch\ \$B(r,\$r,\$c)\ \$opp\]\n\ \ \ \ set\ B(r,\$r,\$c)\ \[lreplace\ \$B(r,\$r,\$c)\ \$n\ \$n\]\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ DFS\ --\ does\ a\ depth-first-search\ from\ the\ origin.\ This\ can\ blow\ out\n\ #\ the\ recursion\ limit\ for\ big\ board\ sizes.\n\ #\n\ proc\ DFS\ \{\}\ \{\n\ \ \ \ global\ DFS\n\ \n\ \ \ \ unset\ -nocomplain\ DFS\n\ \ \ \ set\ DFS(cnt)\ 0\n\ \ \ \ for\ \{set\ row\ \$::G(-n2)\}\ \{\$row\ <\ \$::G(n2)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ set\ cmax\ \[expr\ \{\$::G(n)-1-abs(\$row)\}\]\n\ \ \ \ \ \ \ \ for\ \{set\ col\ -\$cmax\}\ \{\$col\ <=\ \$cmax\}\ \{incr\ col\ 2\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ DFS(\$row,\$col)\ 0\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \n\ \ \ \ _DFS\ 0\ 0\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ _DFS\ --\ recursive\ caller\ for\ DFS\n\ #\n\ proc\ _DFS\ \{row\ col\}\ \{\n\ \ \ \ global\ B\ DFS\n\ \n\ \ \ \ set\ DFS(\$row,\$col)\ 1\n\ \ \ \ incr\ DFS(cnt)\n\ \ \ \ foreach\ dir\ \$B(r,\$row,\$col)\ \{\n\ \ \ \ \ \ \ \ if\ \{!\ \[IsPath\ \$row\ \$col\ \$dir\]\}\ continue\n\ \ \ \ \ \ \ \ foreach\ \{r\ c\}\ \[MoveDir\ \$row\ \$col\ \$dir\]\ break\n\ \ \ \ \ \ \ \ if\ \{\$DFS(\$r,\$c)\ !=\ 0\}\ continue\n\ \ \ \ \ \ \ \ _DFS\ \$r\ \$c\n\ \ \ \ \}\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ IsPath\ --\ return\ true\ if\ there\ is\ a\ path\ from\ row,col\ in\ direction\ dir\n\ #\ \ \ \ \ assumes\ path\ exists\ out\ of\ row,col\ so\ it\ checks\ for\ off\ the\ board\n\ #\ \ \ \ \ and\ is\ there\ a\ matching\ opposite\ path\ from\ destination\n\ #\n\ proc\ IsPath\ \{row\ col\ dir\}\ \{\n\ \ \ \ global\ B\n\ \n\ \ \ \ foreach\ \{r\ c\}\ \[MoveDir\ \$row\ \$col\ \$dir\]\ break\n\ \ \ \ if\ \{!\ \[info\ exists\ B(c,\$r,\$c)\]\}\ \{\ return\ 0\ \}\;#\ Destination\ off\ the\ board\n\ \ \ \ set\ opp\ \[expr\ \{(\$dir\ +\ 3)\ %\ 6\}\]\n\ \ \ \ set\ n\ \[lsearch\ \$B(r,\$r,\$c)\ \$opp\]\n\ \ \ \ return\ \[expr\ \{\$n\ >\ -1\ ?\ 1\ :\ 0\}\]\n\ \}\n\ \n\ proc\ Shuffle\ \{l\}\ \{\n\ \ \ \ set\ len\ \[llength\ \$l\]\n\ \ \ \ set\ len2\ \$len\n\ \ \ \ for\ \{set\ i\ 0\}\ \{\$i\ <\ \$len-1\}\ \{incr\ i\}\ \{\n\ \ \ \ \ \ \ \ set\ n\ \[expr\ \{int(\$i\ +\ \$len2\ *\ rand())\}\]\n\ \ \ \ \ \ \ \ incr\ len2\ -1\n\ \n\ \ \ \ \ \ \ \ #\ Swap\ elements\ at\ i\ &\ n\n\ \ \ \ \ \ \ \ set\ temp\ \[lindex\ \$l\ \$i\]\n\ \ \ \ \ \ \ \ lset\ l\ \$i\ \[lindex\ \$l\ \$n\]\n\ \ \ \ \ \ \ \ lset\ l\ \$n\ \$temp\n\ \ \ \ \}\n\ \ \ \ return\ \$l\n\ \}\n\ proc\ About\ \{\}\ \{\n\ \ \ \ set\ txt\ \"\$::S(title)\\nby\ Keith\ Vetter,\ February\ 2006\\n\\n\"\n\ \ \ \ append\ txt\ \"Turn\ on\ all\ the\ lights!\\n\\n\"\n\ \ \ \ append\ txt\ \"Left\ click:\ rotate\ clockwise\\n\"\n\ \ \ \ append\ txt\ \"Right\ click:\ rotate\ counter-clockwise\\n\"\n\ \ \ \ tk_messageBox\ -message\ \$txt\ -title\ About\n\ \}\n\ ##+##########################################################################\n\ #\n\ #\ MST\ --\ computes\ a\ random\ minimum\ spanning\ tree\ using\ Prim's\ algorithm\n\ #\n\ proc\ MST\ \{\}\ \{\n\ \ \ \ global\ B\ EDGES\n\ \n\ \ \ \ set\ mst\ \{\}\n\ \n\ \ \ \ #\ Mark\ all\ nodes\ as\ unvisited\n\ \ \ \ for\ \{set\ row\ \$::G(-n2)\}\ \{\$row\ <\ \$::G(n2)\}\ \{incr\ row\}\ \{\n\ \ \ \ \ \ \ \ set\ cmax\ \[expr\ \{\$::G(n)-1-abs(\$row)\}\]\n\ \ \ \ \ \ \ \ for\ \{set\ col\ -\$cmax\}\ \{\$col\ <=\ \$cmax\}\ \{incr\ col\ 2\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ visited(\$row,\$col)\ 0\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \n\ \ \ \ set\ edges\ \[Shuffle\ \$EDGES\]\n\ \n\ \ \ \ foreach\ \{r\ c\}\ \[lindex\ \$edges\ 0\]\ break\ \ \ \ \ \ \ \;#\ Start\ with\ random\ node\n\ \ \ \ set\ visited(\$r,\$c)\ 1\n\ \ \ \ while\ \{\[llength\ \$mst\]\ <\ \$::G(cnt)-1\}\ \{\n\ \ \ \ \ \ \ \ #\ Find\ edge\ out\ of\ visited\ nodes\ (inefficient\ but\ who\ cares)\n\ \ \ \ \ \ \ \ for\ \{set\ i\ 0\}\ \{\$i\ <\ \[llength\ \$edges\]\}\ \{incr\ i\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ foreach\ \{r0\ c0\ dir\}\ \[lindex\ \$edges\ \$i\]\ break\ \;#\ Start\ point\n\ \ \ \ \ \ \ \ \ \ \ \ foreach\ \{r1\ c1\}\ \[MoveDir\ \$r0\ \$c0\ \$dir\]\ break\ \;#\ End\ point\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$visited(\$r0,\$c0)\ !=\ \$visited(\$r1,\$c1)\}\ break\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ set\ edges\ \[lreplace\ \$edges\ \$i\ \$i\]\ \ \ \ \ \ \ \;#\ Remove\ from\ edge\ list\n\ \ \ \ \ \ \ \ lappend\ mst\ \[list\ \$r0\ \$c0\ \$dir\]\ \ \ \ \ \ \ \ \ \;#\ Add\ to\ our\ mst\n\ \ \ \ \ \ \ \ set\ visited(\$r0,\$c0)\ 1\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ Mark\ nodes\ as\ visited\n\ \ \ \ \ \ \ \ set\ visited(\$r1,\$c1)\ 1\n\ \ \ \ \}\n\ \n\ \ \ \ return\ \$mst\n\ \}\n\ \n\ ################################################################\n\ \n\ image\ create\ photo\ ::img::ball\ -data\ \{\n\ \ \ \ R0lGODlhCgAKALMAACQmJHd3d6SmpAQC/ExKTJGRkcTCxFxeXDk3Oby6vISGhJyenNDQ0GZnZlRW\n\ \ \ \ VKyurCH5BAEAAAMALAAAAAAKAAoAAwQ5cIyWGHtOjmJNekszHN4jLIUSIAWYBkHTEEUBN0d+ODHu\n\ \ \ \ /I4dIQgMHggAo3EHGCB+uR9CAxg6kJIIADs=\}\n\ image\ create\ photo\ ::img::ball2\ -data\ \{\n\ \ \ \ R0lGODlhCgAKALMAAGRXBJSKBN7MBOzYXLyyBOjkBMq/BN3XBAQC/Pz2fJR6BJSWBPPwBL6aBGRm\n\ \ \ \ BN23BCH5BAEAAAgALAAAAAAKAAoAAwQzECFnzjFAomWtEMFkFQxTCBghkKX5NMaQzPTwPDI9283D\n\ \ \ \ loUX4MYKPjKKm/Kh0AB6QkkEADs=\}\n\ \n\ DoDisplay\n\ NewGame\n\ return\n\n======\n\[lights_on\ android\ IMG\]\n\nLights\ On\ is\ available\ for\ Android\ on\ Playstore\ \[https://play.google.com/store/apps/details?id=com.game.lightson\]\n======\n\n<<categories>>\ Games\ |\ Application} CALL {my revision {Lights On}} CALL {::oo::Obj2145466 process revision/Lights+On} CALL {::oo::Obj2145464 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