[Keith Vetter] 2014-04-23 : I recently came across the simple yet addictive puzzle game http://moh97.us/flow/%|%Flow Colors%|%, and I decided it would be fun to write my own version of the game. The object of Flow Colors is lay pipes to connect all pairs of colors. A level is solved when all the colors are paired and the entire board is filled. Flow Colors is based on a game by Mohammed el-Madhoun (see [http://moh97.us/flow]). ====== ##+########################################################################## # # flowColors.tcl -- plays game Flow Colors # http://moh97.us/flow/ # by Keith Vetter April 2014 # package require Tk package require tooltip set S(state) play set S(stage) 1 set S(level) 1 set S(solved) {} set S(margin) 75 set S(sz) 90 set S(radius,factor) .35 set S(lwidth,factor) .30 set S(stageButton,size) 4 set S(fade,params) {20 20} set S(hints,canDo) 0 set S(hints,used) 0 set S(shiftStage,params) {100 10} set S(darken,0) 30 set S(darken,1) 70 if {$tcl_platform(os) eq "Darwin"} { set S(rcFile) [file join $::env(HOME) Library Preference flowColors.rc] } elseif {$tcl_platform(os) eq "windows"} { set S(rcFile) [file join $::env(HOME) flowColors.rc] } else { set S(rcFile) [file join $::env(HOME) .flowColorsrc] } array set SOLUTIONS {} set CLR(bg) black set CLR(fg) white set CLR(txt) red set CLR(dialog,bg) bisque set CLR(dialog,fg) black set CLR(dialog,txt) gray20 set CLR(dialog,button) [::tk::Darken $CLR(dialog,bg) 50] set CLR(dialog,button) bisque4 set CLR(dialog,highlight) pink set CLR(star) darkgoldenrod set CLR(stageButton,off) white set CLR(stageButton,on) red catch {font delete myDialogFont} catch {font delete myDisplayFont} font create myDialogFont {*}[font actual {Helvetica 14 bold}] font create myDisplayFont {*}[font actual {Helvetica 18 bold}] font create myDisplayFontBig {*}[font actual {Helvetica 32 bold}] font create myDisplayFontTitle {*}[font actual {Helvetica 56 bold}] array set BOARDS { 1,1 {6 blue 0 1 5 0 cyan 4 2 1 4 darkorange 0 0 4 0 green 0 2 2 2 red 5 2 0 5 yellow 3 2 0 4} 1,2 {6 blue 0 2 3 5 cyan 3 3 4 4 darkorange 0 1 4 5 green 0 5 2 5 red 2 3 4 1 yellow 2 2 4 2} 1,3 {6 blue 1 4 4 4 darkorange 1 3 4 2 green 2 5 3 2 red 0 0 1 5 yellow 2 3 4 1} 1,4 {6 blue 1 4 4 4 darkorange 4 3 5 2 green 1 1 4 2 yellow 2 3 5 3} 1,5 {6 blue 0 1 3 2 darkorange 1 1 4 3 green 1 3 5 5 yellow 0 2 1 4} 1,6 {6 blue 0 0 5 4 darkorange 3 4 4 1 green 2 0 2 4 yellow 2 3 4 4} 1,7 {6 blue 3 2 5 0 cyan 3 4 4 2 darkorange 1 1 3 5 green 0 5 2 5 red 0 3 2 4 yellow 1 3 3 3} 1,8 {6 blue 0 2 2 3 darkorange 1 1 3 2 green 1 2 4 4 red 2 5 4 0 yellow 0 3 1 5} 1,9 {6 blue 0 4 4 4 darkorange 2 2 5 1 green 0 5 3 3 red 1 2 4 1 yellow 3 2 5 2} 1,10 {6 blue 4 1 4 5 cyan 1 2 1 5 darkorange 2 0 5 5 green 0 1 0 5 red 0 0 2 5 yellow 3 1 3 5} 1,11 {6 blue 1 1 2 5 darkorange 1 2 1 4 green 3 5 4 0 red 1 5 3 4 yellow 4 1 4 4} 1,12 {6 blue 0 1 3 3 darkorange 1 1 2 3 green 0 2 5 1 yellow 1 2 5 0} 1,13 {6 blue 0 2 2 0 darkorange 4 1 5 0 green 1 1 4 4 red 1 2 2 5 yellow 1 4 4 0} 1,14 {6 blue 1 4 5 5 darkorange 0 4 4 5 green 1 2 5 1 red 3 3 5 3 yellow 5 0 5 2} 1,15 {6 blue 1 0 2 1 cyan 2 4 5 1 darkorange 4 3 5 2 green 2 3 4 4 red 2 0 5 0 yellow 0 0 5 3} 1,16 {6 blue 0 3 5 0 cyan 0 2 1 0 darkorange 2 4 4 4 green 2 3 3 1 red 3 3 4 1 yellow 1 4 4 0} 1,17 {6 blue 1 3 5 4 cyan 2 1 3 2 darkorange 2 4 4 4 green 2 3 4 0 red 0 5 1 1 yellow 0 1 4 2} 1,18 {6 blue 4 2 4 4 darkorange 0 5 5 0 green 1 1 5 2 red 2 1 2 3 yellow 1 5 5 3} 1,19 {6 blue 0 5 2 2 darkorange 0 1 3 4 green 0 0 2 4 red 1 5 2 3 yellow 4 1 4 4} 1,20 {6 blue 3 3 4 1 darkorange 0 0 5 3 green 2 4 3 2 yellow 3 4 4 3} 1,21 {6 blue 0 0 1 1 cyan 0 4 5 0 darkorange 0 3 2 3 green 0 5 5 1 red 0 1 2 1 yellow 2 0 3 3} 1,22 {6 blue 0 0 4 3 darkorange 2 0 4 2 green 2 1 3 2 red 0 5 4 0 yellow 1 0 3 3} 1,23 {6 blue 0 5 5 5 darkorange 1 5 4 5 green 2 2 2 4 yellow 2 5 3 2} 1,24 {6 blue 3 2 4 1 cyan 0 5 5 5 darkorange 1 0 1 3 green 0 0 1 2 red 0 2 4 3 yellow 3 1 4 4} 1,25 {6 blue 2 3 2 5 cyan 2 2 3 4 darkorange 0 2 0 5 green 0 1 5 0 red 1 5 5 1 yellow 3 3 4 4} 1,26 {6 blue 3 3 5 0 darkorange 2 3 3 0 green 1 0 4 3 red 0 0 5 3 yellow 4 2 5 1} 1,27 {6 blue 2 4 5 4 darkorange 0 0 4 1 green 1 5 5 3 red 1 4 4 4 yellow 1 0 5 2} 1,28 {6 blue 4 1 4 4 darkorange 1 1 5 0 green 0 0 2 3 yellow 0 1 5 1} 1,29 {6 blue 1 0 3 5 cyan 4 5 5 3 darkorange 1 3 4 4 green 2 3 3 0 red 1 1 2 0 yellow 1 2 4 1} 1,30 {6 blue 1 1 4 5 darkorange 3 1 5 0 green 1 3 4 4 red 1 0 3 5 yellow 2 1 4 1} 2,1 {7 blue 0 6 6 5 cyan 3 4 6 6 darkorange 1 5 2 1 green 3 3 4 2 red 1 6 5 4 yellow 4 4 5 5} 2,2 {7 blue 1 3 1 5 cyan 3 2 4 5 darkorange 1 2 5 2 green 2 2 3 5 magenta 0 1 6 2 red 0 2 6 3 yellow 3 3 4 4} 2,3 {7 blue 4 0 6 6 brown 3 0 5 1 cyan 0 0 1 6 darkorange 2 3 4 5 green 2 4 3 6 magenta 2 0 2 2 red 3 2 4 6 yellow 1 0 2 6} 2,4 {7 blue 4 4 5 1 darkorange 4 2 5 4 green 1 0 6 0 red 5 0 5 5 yellow 2 2 3 4} 2,5 {7 blue 0 1 3 4 cyan 0 0 6 1 darkorange 3 1 6 6 green 1 5 4 4 red 2 1 4 2 yellow 0 2 2 3} 2,6 {7 blue 1 1 3 0 cyan 2 5 4 6 darkorange 0 5 2 2 green 0 6 1 5 magenta 3 5 4 1 red 4 0 5 6 yellow 1 4 4 2} 2,7 {7 blue 3 1 3 3 darkorange 2 0 4 2 green 1 0 2 1 red 1 1 1 5 yellow 4 1 4 5} 2,8 {7 blue 4 3 4 6 cyan 0 6 1 1 darkorange 1 6 5 1 green 0 4 6 5 magenta 5 3 6 6 red 3 3 3 6 yellow 3 2 5 2} 2,9 {7 blue 2 4 2 6 cyan 1 1 4 6 darkorange 0 5 1 0 green 1 2 4 5 red 0 6 3 6 yellow 3 1 5 5} 2,10 {7 blue 2 4 6 4 cyan 0 1 6 0 darkorange 1 1 6 2 green 5 2 6 5 red 3 3 5 5 yellow 4 3 6 3} 2,11 {7 blue 1 0 2 3 cyan 1 2 3 3 darkorange 3 1 5 4 green 5 1 5 3 magenta 1 1 4 0 red 1 5 5 5 yellow 3 4 5 0} 2,12 {7 blue 5 5 6 2 cyan 3 0 6 0 darkorange 2 2 6 6 green 2 0 2 3 magenta 3 1 6 1 red 1 5 2 1 yellow 3 6 4 3} 2,13 {7 blue 1 2 1 4 cyan 2 4 3 3 darkorange 0 6 3 6 green 4 0 5 6 red 1 1 1 5 yellow 0 5 4 6} 2,14 {7 blue 3 2 4 1 brown 1 2 5 1 cyan 1 4 6 0 darkorange 1 1 3 1 green 2 2 4 3 magenta 1 5 6 6 red 1 3 2 6 yellow 4 5 6 3} 2,15 {7 blue 0 2 3 1 darkorange 0 1 1 0 green 1 2 3 3 red 1 1 1 4 yellow 1 5 5 1} 2,16 {7 blue 3 3 4 5 darkorange 3 2 5 5 green 4 6 5 1 red 5 2 5 6 yellow 6 0 6 2} 2,17 {7 blue 2 1 3 4 cyan 4 1 6 2 darkorange 3 1 3 5 green 5 1 5 6 magenta 1 1 2 4 red 0 6 4 5 yellow 3 2 5 5} 2,18 {7 blue 2 5 5 3 cyan 4 6 6 6 darkorange 4 5 6 5 green 1 1 5 2 magenta 3 6 5 0 red 2 6 5 1 yellow 1 5 2 2} 2,19 {7 blue 4 6 6 6 cyan 1 5 4 5 darkorange 5 5 6 2 green 3 5 4 3 red 3 6 6 1 yellow 0 3 6 0} 2,20 {7 blue 2 1 3 3 darkorange 1 3 4 1 green 0 0 0 2 red 0 3 1 2 yellow 2 4 3 1} 2,21 {7 blue 0 0 1 4 cyan 3 0 6 0 darkorange 0 4 2 3 green 1 0 3 3 red 1 5 5 2 yellow 2 0 3 1} 2,22 {7 blue 1 4 3 2 cyan 4 5 5 1 darkorange 4 6 6 0 green 1 2 2 0 magenta 1 5 5 0 red 0 0 1 3 yellow 5 2 5 5} 2,23 {7 blue 4 5 6 5 cyan 0 6 4 3 darkorange 1 6 3 3 green 0 0 4 4 red 0 4 5 3 yellow 3 4 6 6} 2,24 {7 blue 5 4 6 6 cyan 1 5 5 6 darkorange 0 6 2 0 green 1 6 4 1 red 6 0 6 3 yellow 3 3 4 6} 2,25 {7 blue 2 1 6 5 cyan 4 1 6 4 darkorange 3 1 5 5 green 0 0 6 3 red 0 1 1 5 yellow 0 6 1 1} 2,26 {7 blue 0 2 6 0 darkorange 1 5 4 5 green 0 1 4 1 red 2 2 5 3 yellow 5 0 5 5} 2,27 {7 blue 0 3 6 6 darkorange 2 1 3 3 green 1 5 4 5 red 0 4 3 1 yellow 1 4 2 2} 2,28 {7 blue 0 5 6 1 cyan 4 0 5 5 darkorange 4 1 6 0 green 0 2 3 4 magenta 0 0 1 3 red 1 5 3 3 yellow 1 0 2 3} 2,29 {7 blue 2 2 2 4 cyan 3 1 4 4 darkorange 5 3 6 6 green 4 3 5 0 red 2 1 4 5 yellow 5 1 5 4} 2,30 {7 blue 0 5 3 6 cyan 1 5 3 4 darkorange 0 0 4 0 green 0 2 0 4 magenta 1 2 2 4 red 4 1 5 5 yellow 1 0 4 2} 3,1 {8 blue 3 4 5 4 cyan 1 4 2 7 darkorange 3 3 4 4 green 1 6 2 4 red 0 4 7 1 yellow 1 7 2 5} 3,2 {8 blue 0 1 5 5 cyan 0 2 7 3 darkorange 1 6 7 1 green 3 3 5 0 red 0 0 7 0 yellow 3 0 3 2} 3,3 {8 blue 2 2 5 7 cyan 4 4 6 1 darkorange 5 3 7 6 green 4 7 7 7 red 0 1 4 3 yellow 1 3 1 6} 3,4 {8 blue 5 7 6 3 cyan 1 6 3 6 darkorange 4 7 5 2 green 1 7 3 1 magenta 2 3 3 7 red 4 4 6 2 yellow 0 0 6 7} 3,5 {8 blue 0 7 4 5 cyan 3 3 6 1 darkorange 7 2 7 7 green 0 6 4 1 red 1 3 3 1 yellow 3 6 7 1} 3,6 {8 blue 0 7 4 6 cyan 6 2 7 6 darkorange 1 4 4 7 green 6 1 7 7 magenta 1 0 5 4 red 0 0 5 7 yellow 2 0 7 1} 3,7 {8 blue 3 1 4 4 darkorange 1 0 2 4 green 2 2 4 1 red 3 6 6 1 yellow 0 7 1 5} 3,8 {8 blue 5 2 5 7 cyan 0 5 6 4 darkorange 0 6 2 1 green 0 7 5 1 magenta 5 3 6 1 red 5 4 7 7 yellow 4 4 6 7} 3,9 {8 blue 1 1 4 0 cyan 4 5 5 1 darkorange 2 2 3 0 green 1 2 4 3 red 3 5 5 0 yellow 1 6 6 6} 3,10 {8 blue 0 7 4 6 cyan 0 3 0 5 darkorange 1 7 4 2 green 1 1 1 4 red 4 4 7 0 yellow 3 1 6 7} 3,11 {8 blue 7 1 7 3 cyan 1 6 3 6 darkorange 4 3 5 6 green 0 5 2 4 magenta 0 6 7 0 red 5 3 6 6 yellow 3 3 4 1} 3,12 {8 blue 2 4 2 6 cyan 1 4 6 6 darkorange 4 7 5 5 green 1 6 3 1 red 0 1 7 4 yellow 0 6 5 2} 3,13 {8 blue 6 4 6 6 cyan 3 6 5 2 darkorange 0 0 5 6 green 2 5 4 4 red 0 7 3 7 yellow 2 3 6 0} 3,14 {8 blue 1 4 3 3 cyan 4 7 5 2 darkorange 7 0 7 5 green 5 3 7 7 red 2 5 4 6 yellow 0 2 7 6} 3,15 {8 blue 2 5 6 2 cyan 6 5 6 7 darkorange 4 4 5 7 green 0 1 7 3 red 3 6 7 7 yellow 2 4 4 3} 3,16 {8 blue 3 4 6 3 cyan 2 4 6 2 darkorange 1 4 4 0 green 0 0 0 7 magenta 0 6 6 6 red 3 2 5 2 yellow 4 4 5 0} 3,17 {8 blue 0 0 7 6 brown 3 1 3 4 cyan 4 0 5 4 darkorange 3 0 4 6 green 5 6 7 4 magenta 2 1 5 5 red 4 4 6 1 yellow 5 3 6 2} 3,18 {8 blue 1 0 2 2 brown 3 5 4 2 cyan 0 0 2 0 darkorange 0 4 5 4 green 2 7 7 7 magenta 4 3 5 2 purple 3 0 3 6 red 1 5 1 7 yellow 1 6 2 5} 3,19 {8 blue 3 4 4 6 brown 1 1 2 6 cyan 0 1 3 2 darkorange 0 6 2 4 green 6 1 6 6 magenta 3 3 4 0 red 1 4 2 1 yellow 4 5 5 6} 3,20 {8 blue 5 5 6 3 brown 6 2 7 4 cyan 4 7 7 5 darkorange 0 2 6 1 green 3 0 7 3 magenta 1 4 1 6 purple 0 5 2 7 red 0 4 3 7 yellow 1 1 3 5} 3,21 {8 blue 0 7 4 7 brown 0 5 7 1 cyan 4 5 6 6 darkorange 0 6 2 6 green 2 1 7 5 magenta 5 3 7 2 red 3 3 6 1 yellow 4 1 7 3} 3,22 {8 blue 0 6 2 2 cyan 1 2 6 1 darkorange 0 4 1 5 green 2 3 6 6 red 1 6 3 4 yellow 4 5 7 1} 3,23 {8 blue 1 2 2 6 cyan 0 7 1 4 darkorange 1 3 6 6 green 0 0 6 4 magenta 1 5 7 3 red 5 4 6 1 yellow 4 1 6 5} 3,24 {8 blue 4 6 5 5 cyan 1 2 2 3 darkorange 0 2 1 1 green 0 1 7 0 magenta 3 3 5 6 red 2 5 4 5 yellow 3 1 7 1} 3,25 {8 blue 1 4 6 6 cyan 0 3 7 6 darkorange 3 1 7 0 green 5 3 6 0 magenta 0 0 2 1 red 1 3 7 2 yellow 1 1 4 3} 3,26 {8 blue 0 0 2 2 brown 2 5 4 4 cyan 1 1 3 1 darkorange 1 3 7 0 green 3 2 5 5 magenta 4 2 5 4 red 5 0 5 6 yellow 1 0 5 2} 3,27 {8 blue 3 5 6 2 cyan 2 7 6 5 darkorange 1 7 7 3 green 3 4 5 2 magenta 1 1 6 3 red 6 7 7 4 yellow 5 5 6 4} 3,28 {8 blue 1 7 7 3 cyan 3 6 7 4 darkorange 1 3 7 7 green 3 3 5 1 magenta 1 2 3 1 red 4 1 5 4 yellow 2 5 6 1} 3,29 {8 blue 0 3 3 7 cyan 1 6 6 6 darkorange 2 3 6 5 green 1 1 3 5 red 2 1 5 2 yellow 3 1 6 4} 3,30 {8 blue 4 3 6 1 cyan 1 6 3 6 darkorange 0 4 0 6 green 2 2 4 2 magenta 0 5 3 5 red 1 4 6 3 yellow 5 5 6 2} 4,1 {9 blue 1 3 2 7 brown 5 7 7 1 cyan 1 2 2 3 darkorange 2 4 2 6 green 4 1 4 3 magenta 3 7 5 1 purple 5 8 6 1 red 1 1 4 4 yellow 5 0 6 2} 4,2 {9 blue 0 0 3 7 brown 0 7 3 0 cyan 4 7 7 5 darkorange 5 1 7 1 green 4 3 8 3 magenta 3 5 5 5 red 3 3 7 2 yellow 5 4 8 2} 4,3 {9 blue 0 2 1 0 cyan 3 1 7 1 darkorange 4 4 6 4 green 6 3 7 6 magenta 2 5 4 0 red 7 5 8 8 yellow 3 0 3 8} 4,4 {9 blue 4 8 8 8 cyan 0 8 6 4 darkorange 0 1 1 3 green 1 8 3 4 magenta 5 8 7 8 red 3 8 4 4 yellow 0 0 3 7} 4,5 {9 blue 1 7 6 5 brown 2 5 6 4 cyan 6 7 7 2 darkorange 1 0 7 1 green 0 0 3 3 magenta 2 0 6 8 red 5 3 7 7 yellow 1 4 3 6} 4,6 {9 blue 3 5 6 4 brown 6 5 8 6 cyan 4 4 7 4 darkorange 3 4 7 0 green 8 0 8 4 magenta 3 6 6 0 purple 1 5 6 7 red 4 6 7 7 white 5 0 8 7 yellow 1 1 1 4} 4,7 {9 blue 2 7 5 7 brown 6 7 8 8 cyan 2 3 6 3 darkorange 4 2 6 6 green 2 1 6 4 magenta 0 6 7 8 purple 1 7 5 6 red 1 2 3 1 white 0 4 5 2 yellow 0 0 8 0} 4,8 {9 blue 0 0 1 8 brown 5 2 6 4 cyan 2 3 8 8 darkorange 2 8 3 5 green 1 0 7 4 magenta 1 5 1 7 red 4 7 6 7 yellow 6 2 6 6} 4,9 {9 blue 0 0 3 8 brown 0 1 2 8 cyan 2 7 6 2 darkorange 0 3 3 3 green 1 7 4 5 magenta 2 6 4 6 red 6 7 7 4 yellow 1 1 6 6} 4,10 {9 blue 7 6 8 8 cyan 5 1 8 5 darkorange 7 5 7 8 green 6 1 6 8 magenta 2 6 5 6 red 2 2 6 6 yellow 4 3 7 1} 4,11 {9 blue 4 2 5 3 brown 4 0 8 0 cyan 1 1 2 5 darkorange 1 4 7 7 green 7 2 8 5 magenta 4 4 8 4 purple 3 0 5 1 red 1 2 6 5 yellow 0 0 4 3} 4,12 {9 blue 4 8 5 6 brown 2 0 7 7 cyan 1 1 1 4 darkorange 1 6 2 1 green 5 2 5 5 magenta 3 2 8 4 red 1 7 3 3 yellow 6 2 7 6} 4,13 {9 blue 3 4 5 7 brown 3 2 4 4 cyan 5 5 7 6 darkorange 4 5 7 7 green 1 7 7 1 magenta 4 2 6 4 red 5 4 8 3 yellow 2 2 2 7} 4,14 {9 blue 6 4 6 6 brown 1 1 2 7 cyan 6 1 8 0 darkorange 1 4 7 0 green 5 7 6 3 magenta 2 6 3 4 purple 2 1 3 3 red 1 3 4 5 yellow 4 8 6 2} 4,15 {9 blue 2 7 4 2 cyan 0 0 4 3 darkorange 1 0 1 7 green 5 3 6 1 magenta 4 6 6 6 red 3 2 3 4 yellow 2 0 4 0} 4,16 {9 blue 2 2 2 5 brown 0 7 6 7 cyan 7 1 8 8 darkorange 0 6 3 1 green 0 8 5 6 magenta 6 3 7 2 purple 4 6 5 1 red 0 4 6 4 yellow 1 6 3 2} 4,17 {9 blue 1 3 4 6 cyan 4 7 7 0 darkorange 3 3 6 6 green 4 8 8 0 red 1 4 1 6 yellow 1 7 4 5} 4,18 {9 blue 1 4 7 1 brown 4 3 7 3 cyan 0 8 8 8 darkorange 6 5 8 7 green 4 4 7 6 magenta 5 5 5 7 purple 2 6 3 3 red 1 6 7 2 yellow 4 5 8 6} 4,19 {9 blue 1 6 5 7 brown 1 4 1 7 cyan 4 7 8 8 darkorange 5 1 7 5 green 0 7 4 5 magenta 1 3 4 1 purple 2 4 6 2 red 3 3 7 6 yellow 3 4 4 6} 4,20 {9 blue 1 1 6 3 brown 3 8 4 4 cyan 1 7 6 8 darkorange 3 0 6 5 green 3 1 3 6 magenta 5 6 8 8 purple 5 7 7 8 red 0 5 2 4 yellow 0 4 6 2} 4,21 {9 blue 3 6 5 3 cyan 4 2 7 2 darkorange 1 1 6 5 green 3 2 7 8 magenta 2 6 6 8 red 5 2 6 6 yellow 5 5 7 7} 4,22 {9 blue 5 1 7 2 brown 0 5 0 8 cyan 3 6 7 7 darkorange 0 4 6 4 green 4 7 5 2 magenta 1 4 2 1 purple 2 2 4 4 red 2 6 5 8 yellow 2 8 6 2} 4,23 {9 blue 4 0 8 0 brown 1 5 4 6 cyan 1 8 7 7 darkorange 1 4 2 1 green 2 6 8 7 magenta 1 6 3 8 purple 5 2 6 6 red 3 3 6 7 yellow 2 4 6 4} 4,24 {9 blue 1 1 4 3 brown 1 4 4 7 cyan 4 4 7 6 darkorange 0 2 6 8 green 1 3 5 8 magenta 1 2 6 2 red 2 3 7 7 yellow 2 4 5 7} 4,25 {9 blue 2 7 6 3 brown 1 4 2 6 cyan 0 0 8 0 darkorange 4 7 6 4 green 0 1 6 8 magenta 0 8 4 3 red 1 5 6 6 yellow 0 2 6 7} 4,26 {9 blue 7 4 8 0 brown 1 7 5 2 cyan 2 7 5 6 darkorange 7 6 7 8 green 0 4 3 5 magenta 4 0 7 3 purple 4 4 8 8 red 1 4 2 1 yellow 2 2 6 6} 4,27 {9 blue 3 5 4 3 brown 0 2 8 1 cyan 0 3 6 4 darkorange 1 5 7 6 green 3 3 6 6 magenta 5 1 7 1 red 1 4 7 3 yellow 0 1 3 0} 4,28 {9 blue 2 6 8 4 cyan 3 6 7 4 darkorange 2 4 7 6 green 1 1 7 3 magenta 6 6 7 5 red 5 0 7 1 yellow 1 4 2 7} 4,29 {9 blue 4 1 4 5 brown 4 2 4 4 cyan 0 0 3 7 darkorange 1 0 1 4 green 5 7 7 3 magenta 1 7 8 1 red 4 7 5 5 yellow 2 7 6 2} 4,30 {9 blue 1 1 8 0 brown 2 0 7 3 cyan 0 7 3 3 darkorange 4 7 7 7 green 0 8 4 1 magenta 5 4 7 6 purple 7 8 8 5 red 0 6 2 3 yellow 6 6 6 8} 5,1 {9 blue 0 6 3 6 cyan 4 6 6 7 darkorange 0 0 3 5 green 0 7 5 3 magenta 7 7 8 6 red 2 1 2 3 yellow 0 8 8 7} 5,2 {9 blue 0 0 0 8 brown 7 6 7 8 cyan 2 5 5 3 darkorange 2 0 4 0 green 5 0 8 8 magenta 4 4 5 2 red 1 0 4 5 yellow 5 1 6 6} 5,3 {9 blue 0 5 4 5 brown 3 2 7 2 cyan 7 8 8 0 darkorange 0 0 0 4 green 0 6 6 8 magenta 2 3 8 8 purple 3 3 6 4 red 0 8 5 8 yellow 0 7 5 7} 5,4 {9 blue 0 8 8 1 cyan 8 2 8 8 darkorange 0 5 8 0 green 2 3 5 3 red 5 4 6 3 yellow 2 2 2 4} 5,5 {9 blue 0 0 0 6 cyan 5 6 8 8 darkorange 0 8 6 6 green 0 5 6 1 red 7 3 7 6 yellow 4 5 8 0} 5,6 {9 blue 0 0 4 0 brown 6 2 7 6 cyan 4 2 5 6 darkorange 0 2 0 7 green 0 1 3 6 magenta 5 2 5 5 purple 4 1 7 5 red 2 3 7 7 white 0 8 5 0 yellow 1 7 2 2} 5,7 {9 blue 0 7 3 7 brown 5 2 5 7 cyan 1 5 4 5 darkorange 0 6 4 7 green 0 8 1 4 magenta 7 1 7 5 purple 0 0 0 5 red 4 0 7 8 yellow 1 0 2 0} 5,8 {9 blue 0 0 0 7 brown 7 4 7 8 cyan 3 2 4 8 darkorange 0 8 3 8 green 1 7 8 0 magenta 5 3 7 3 purple 7 2 8 8 red 3 1 5 2 yellow 2 1 3 3} 5,9 {9 blue 0 1 0 8 brown 8 0 8 8 cyan 6 1 6 6 darkorange 0 0 1 7 green 3 7 4 1 magenta 7 1 7 6 purple 1 8 7 8 red 5 1 7 7 yellow 2 7 7 0} 5,10 {9 blue 0 7 3 3 cyan 3 7 7 1 darkorange 0 8 8 8 green 1 7 3 4 red 2 7 8 7 yellow 0 0 5 0} 5,11 {9 blue 7 8 8 0 brown 5 4 5 7 cyan 0 3 5 8 darkorange 8 1 8 8 green 3 2 6 8 magenta 1 3 1 7 purple 2 3 5 3 red 2 2 6 0 white 2 4 2 7 yellow 1 1 6 1} 5,12 {9 blue 0 7 8 0 brown 7 2 7 4 cyan 3 2 3 8 darkorange 0 8 2 8 green 1 7 5 7 magenta 4 2 7 5 red 2 2 2 7 yellow 6 7 8 4} 5,13 {9 blue 1 2 1 8 brown 6 4 7 4 cyan 4 4 8 8 darkorange 0 8 8 7 green 0 0 8 0 magenta 5 4 5 7 purple 3 3 3 8 red 4 3 7 3 yellow 2 8 7 2} 5,14 {9 blue 0 1 6 2 brown 3 6 6 4 cyan 2 7 4 6 darkorange 0 0 7 2 green 0 3 0 8 magenta 4 5 6 5 purple 3 7 8 7 red 0 2 5 2 white 8 2 8 6 yellow 1 3 8 8} 5,15 {9 blue 0 8 5 8 cyan 5 7 7 8 darkorange 2 0 2 7 green 3 0 8 8 magenta 6 3 6 8 red 4 4 4 7 yellow 3 7 7 1} 5,16 {9 blue 0 2 0 5 brown 5 1 6 6 cyan 3 2 3 5 darkorange 1 0 4 1 green 0 6 5 6 magenta 2 0 7 6 purple 5 2 5 5 red 2 2 2 5 white 8 2 8 5 yellow 0 8 8 6} 5,17 {9 blue 0 0 7 8 brown 8 0 8 8 cyan 2 2 5 2 darkorange 5 7 6 1 green 0 8 6 8 magenta 6 2 6 7 red 2 5 5 5 yellow 1 2 5 6} 5,18 {9 blue 0 1 5 1 brown 6 1 6 8 cyan 1 7 2 4 darkorange 0 2 5 8 green 0 0 8 8 magenta 3 4 3 6 purple 7 1 7 8 red 0 8 4 8 yellow 0 3 0 7} 5,19 {9 blue 0 7 4 1 brown 4 6 4 8 cyan 2 7 3 4 darkorange 0 1 8 0 green 0 8 4 4 magenta 4 3 8 3 purple 6 2 8 2 red 2 2 8 1 yellow 1 7 3 3} 5,20 {9 blue 0 1 2 1 brown 3 2 4 5 cyan 1 8 2 8 darkorange 0 0 8 8 green 0 2 2 2 magenta 3 5 3 8 purple 5 2 5 7 red 1 4 4 2 white 7 3 7 8 yellow 0 8 3 3} 5,21 {9 blue 0 4 3 4 darkorange 0 1 0 2 green 1 2 4 2 red 7 7 8 2 yellow 0 0 8 3} 5,22 {9 blue 0 1 7 1 brown 6 3 6 5 cyan 4 2 5 2 darkorange 0 0 3 3 green 0 8 3 2 magenta 5 3 5 5 red 2 3 2 7 yellow 1 3 8 8} 5,23 {9 blue 0 0 2 8 brown 7 1 7 5 cyan 6 1 8 7 darkorange 0 8 2 7 green 1 2 1 8 magenta 5 8 8 8 red 4 8 5 1 yellow 4 6 7 6} 5,24 {9 blue 4 3 6 3 brown 3 8 8 0 cyan 2 1 2 8 darkorange 4 2 6 2 green 5 1 5 5 magenta 3 7 7 0 red 1 6 3 6 yellow 0 0 0 8} 5,25 {9 blue 1 1 5 0 brown 3 3 5 2 cyan 1 3 7 7 darkorange 0 0 4 4 green 2 1 5 1 magenta 2 3 7 0 red 7 1 7 6 yellow 0 3 8 0} 5,26 {9 blue 0 0 7 1 cyan 2 5 2 6 darkorange 0 1 6 1 green 0 2 1 4 magenta 0 4 8 0 red 2 4 6 4 yellow 0 3 6 3} 5,27 {9 blue 1 1 5 1 cyan 2 5 7 5 darkorange 0 1 8 5 green 2 2 2 4 magenta 1 5 7 7 red 1 2 2 6 yellow 1 4 4 3} 5,28 {9 blue 1 0 7 0 brown 5 8 8 8 cyan 0 7 3 4 darkorange 0 0 0 6 green 1 6 8 0 magenta 0 8 4 4 red 2 6 5 3 yellow 2 2 6 3} 5,29 {9 blue 0 1 8 2 brown 1 7 8 3 cyan 5 5 7 5 darkorange 0 0 7 0 green 4 2 4 4 magenta 5 6 7 6 red 4 5 5 4 yellow 3 5 8 8} 5,30 {9 blue 1 1 1 3 brown 6 2 8 2 cyan 3 0 3 5 darkorange 2 2 8 8 green 1 4 6 3 magenta 4 0 5 3 red 2 3 4 3 yellow 5 4 5 6} } ################################################################ proc DoDisplay {} { wm title . "Flow Colors" set sz [expr {2*$::S(margin) + $::S(sz) * 6}] set ::S(X0) [expr {$sz/2}] canvas .c -width $sz -height $sz -bd 0 -highlightthickness 0 -bg $::CLR(bg) pack .c -side top -fill both -expand 1 bind .c {Recenter %W %h %w} bind .c <1> {DoButton down %x %y} bind .c {DoButton move %x %y} bind .c {DoButton up %x %y} if {[file exists ~/misc/tcl/console.tcl]} { uplevel #0 source ~/misc/tcl/console.tcl bind all {console show} } } proc DrawConstants {} { global S CLR B .c create rect -$::S(X0) -$::S(X0) $::S(X0) $::S(X0) -tag border -fill {} \ -outline white -width 5 set top [lindex [Cell2XY 0 0] 0 1] set y [expr {(-$::S(X0) + $top) / 2}] set x [expr {abs($y)}] .c create text 0 $y -text "Flow Colors" -font myDisplayFontTitle \ -anchor c -fill red set star [MakeStar $x $y [expr {$top - $y - 5}]] .c create poly $star -fill $CLR(star) -outline $CLR(star) -tag solvedStar lassign [lindex [Cell2XY $::B(N) 0] 0] xLeft y lassign [lindex [Cell2XY $::B(N) $::B(N)] 0] xRight incr y 5 .c create text $xLeft $y -font myDisplayFont -fill $::CLR(txt) \ -anchor nw -tag level,txt # Navigation buttons .c create image -60 $y -image ::img::left -anchor n -tag prev .c create image 0 $y -image ::img::undo -anchor n -tag undo .c create image 60 $y -image ::img::right -anchor n -tag next # Help .c create image $xRight $y -image ::img::help -anchor ne -tag help CanvasButtonBinding .c help "" "" Help ::tooltip::tooltip .c -items help "Help" .c create image [expr {$xRight-48-5}] $y -image ::img::up -anchor ne -tag up } proc DrawBoard {stage level} { global B S L BOARDS set S(stage) $stage set S(level) $level set S(level,txt) "Stage $stage\nLevel $level" set S(stages) [llength [array names BOARDS *,30]] unset -nocomplain B set boardSpec [lassign $BOARDS($stage,$level) N] ComputeSizes $N set B(N) $N set B(xy0) [expr {round(-$N/2. * $S(sz))}] set B(almost) 0 .c delete all DrawConstants for {set row 0} {$row < $N} {incr row} { for {set col 0} {$col < $N} {incr col} { lassign [Cell2XY $row $col] xy .c create rect $xy -tag cell_${row},$col -fill $::CLR(bg) \ -outline $::CLR(fg) set B($row,$col) {} } } # Draw all the nodes unset -nocomplain L foreach {clr row1 col1 row2 col2} $boardSpec { lassign [Cell2XY $row1 $col1] . xy1 lassign [Cell2XY $row2 $col2] . xy2 set id1 [.c create oval $xy1 -fill $clr -outline $clr -tag node] set id2 [.c create oval $xy2 -fill $clr -outline $clr -tag node] set B($row1,$col1) [list node $clr] set B($row2,$col2) [list node $clr] set L(path,$clr) {} set L(delete,$clr) {} set L(done,$clr) 0 .c bind $id1 [list DoHint $clr] .c bind $id2 [list DoHint $clr] } # Level indicator .c itemconfig level,txt -text $S(level,txt) -anchor nw # Button bindings and tooltips CanvasButtonBinding .c prev "" "" {PlayAgain -1} CanvasButtonBinding .c undo "" "" {PlayAgain 0} CanvasButtonBinding .c next "" "" {PlayAgain 1} ::tooltip::tooltip .c -items prev "Previous puzzle" ::tooltip::tooltip .c -items undo "Restart puzzle" ::tooltip::tooltip .c -items next "Next puzzle" # Choose level button CanvasButtonBinding .c up "" "" ShowPickPuzzlePage ::tooltip::tooltip .c -items up "Choose level" .c itemconfig solvedStar \ -state [expr {[HasBeenSolved $S(stage) $S(level)] ? "" : "hidden"}] } proc DrawPickPuzzlePage {} { global S B CLR set N 6 ComputeSizes $N set B(N) $N set B(xy0) [expr {round(-$N/2. * $S(sz))}] .c delete all DrawConstants .c itemconfig solvedStar -state hidden for {set row 0} {$row < 5} {incr row} { for {set col 0} {$col < $N} {incr col} { for {set stage 1} {$stage <= $S(stages)} {incr stage} { set num [expr {1 + $row*$N + $col}] set fauxCol [expr {$col + ($stage - $S(stage))*$N}] set txt_tag "pick$stage,$num" lassign [Cell2XY [expr {$row+0}] $fauxCol] . xy x y set box_tag [.c create oval $xy -fill black -outline white \ -width 2 -tag [list oval stage stage,$stage]] if {[HasBeenSolved $stage $num]} { set star [MakeStar $x $y [expr {$S(radius) - 1}]] .c create poly $star -fill $CLR(star) -outline $CLR(star) \ -tag [list star stage stage,$stage $txt_tag] } incr x 1 ; incr y 2 .c create text $x $y -text $num -fill white \ -font "Helvetica 32 bold" \ -tag [list txt stage stage,$stage $txt_tag] CanvasButtonBinding .c $txt_tag $box_tag \ $::CLR(dialog,highlight) [list PlayChosenPuzzle $num] } } } .c itemconfig stage -state hidden .c itemconfig stage,$S(stage) -state {} # Stage and Help set N [lindex $::BOARDS($S(stage),1) 0] set range "\n([expr {$S(stage)*30-29}]-[expr {$S(stage)*30}])" .c itemconfig level,txt -text "$N x $N$range" -anchor w # Navigation buttons .c delete undo CanvasButtonBinding .c prev "" "" {ShiftStage -1} CanvasButtonBinding .c next "" "" {ShiftStage 1} ::tooltip::tooltip .c -items prev "Previous stage" ::tooltip::tooltip .c -items next "Next stage" StageButtons $S(stage) .c delete up } proc HasBeenSolved {stage level} { return [expr {[lsearch $::S(solved) $stage,$level] > -1}] } proc StageButtons {which} { if {[.c find withtag stageButton] eq ""} { lassign [.c bbox prev] . . x0 . lassign [.c bbox next] x1 y0 . y1 set gap [expr {($x1 - $x0)/double($::S(stages))}] set y [expr {($y0 + $y1) / 2}] for {set stage 1} {$stage <= $::S(stages)} {incr stage} { set x [expr {$x0 - $gap/2 + $stage * $gap}] set xy [Box $x $y $::S(stageButton,size)] .c create oval $xy -tag [list stageButton stageButton,$stage] \ -width 1 } } .c itemconfig stageButton -fill $::CLR(stageButton,off) \ -outline $::CLR(stageButton,off) .c itemconfig stageButton,$which -fill $::CLR(stageButton,on) \ -outline $::CLR(stageButton,on) } proc ShiftStage {dir} { global S if {$dir < 0 && $S(stage) == 1} return if {$dir > 0 && $S(stage) == $S(stages)} return set nextStage [expr {$S(stage) + $dir}] set N [lindex $::BOARDS($nextStage,1) 0] set range "\n([expr {$nextStage*30-29}]-[expr {$nextStage*30}])" .c itemconfig level,txt -text "$N x $N$range" .c itemconfig stage,$nextStage -state {} StageButtons $nextStage lassign [.c bbox stage,$S(stage)] x0 lassign [.c bbox stage,$nextStage] x1 lassign $S(shiftStage,params) steps delay set delta [expr {($x0 - $x1) / double($steps)}] AnimateMove stage $delta 0 0 MyWait .c itemconfig stage,$S(stage) -state hidden set S(stage) $nextStage } proc AnimateMove {tag xDelta yDelta step} { lassign $::S(shiftStage,params) steps delay .c move $tag $xDelta $yDelta incr step if {$step < $steps} { after $delay [list AnimateMove $tag $xDelta $yDelta $step] } else { set ::S(wait) 1 } } proc DoButton {action x y} { global L B if {$::S(state) ne "play"} return lassign [XY2Cell [.c canvasy $y] [.c canvasx $x]] row col if {$row < 0 || $row >= $B(N) || $col < 0 || $col >= $B(N)} return lassign $B($row,$col) what clr if {$action eq "down"} { if {$what eq ""} return if {$what eq "node"} { # Starting from a node set L(delete,$clr) $L(path,$clr) set L(path,$clr) [list [list $row $col]] set L(done,$clr) 0 set L(clr) $clr array unset L stolen,* ShowPath $L(clr) } else { # Starting from the middle of a path set L(clr) $clr array unset L stolen,* AdjustPath $row $col $L(clr) ShowPath $L(clr) } return } if {! [info exists L(clr)]} return if {$action eq "move" && $L(clr) ne ""} { lassign [lindex $L(path,$L(clr)) end] lastRow lastCol set drow [expr {abs($row - $lastRow)}] set dcol [expr {abs($col - $lastCol)}] if {! (($drow == 1 && $dcol == 0) || ($drow == 0 && $dcol == 1))} return set stolen [StealCell $row $col $L(clr)] if {$stolen eq "node"} return AdjustPath $row $col $L(clr) if {$stolen eq "endNode"} { set L(done,$clr) 1 } ShowPath $L(clr) if {$stolen eq "endNode"} { ;# Is path complete? set L(clr) "" } CheckUnsteal return } if {$action eq "up"} { unset L(clr) if {$what ne "node"} return CheckVictory } } # Handles toClr's pipe wanting to move to row,col # which may cause another pipe to be truncated proc StealCell {row col toClr} { global L B lassign $B($row,$col) who oldClr if {$who eq ""} {return empty} set n [lsearch -exact $L(path,$oldClr) [list $row $col]] if {$oldClr eq $toClr} { if {$who ne "node"} { return self } if {$n == -1} { return endNode } return startNode } if {$who eq "node"} {return node} # Here when truncating oldClr's path set n [lsearch -exact $L(path,$oldClr) [list $row $col]] if {$n == -1} { tk_messageBox -icon error \ -message "B and L messed up for $row $col $toClr" return } # Remember then truncate clr's pipe #set L(stolen,$row,$col) [list $oldClr $L(path,$oldClr)] lappend L(stolen,$oldClr) [list $row $col $L(done,$oldClr) $L(path,$oldClr)] set L(delete,$oldClr) [lrange $L(path,$oldClr) $n end] set L(path,$oldClr) [lrange $L(path,$oldClr) 0 $n-1] set L(done,$oldClr) 0 ShowPath $oldClr return steal } proc CheckUnsteal {} { global L B foreach arr [array names L stolen,*] { set clr [lindex [split $arr ","] 1] # NB. ordering is very important: search from end of old path # backwards, then if found we can ignore everything closer to beginning for {set idx 0} {$idx < [llength $L($arr)]} {incr idx} { set steal [lindex $L($arr) $idx] lassign $steal row col done oldPath if {$B($row,$col) ne ""} continue set L(path,$clr) $oldPath set L(delete,$clr) "" set L(done,$clr) $done set L($arr) [lrange $L($arr) 0 $idx-1] ShowPath $clr break } } } # Adds row, col to clr's path, truncating path if it intersects itself proc AdjustPath {row col clr} { global L set L(delete,$clr) {} set n [lsearch -exact $L(path,$clr) [list $row $col]] if {$n + 1 == [llength $L(path,$clr)]} return if {$n > -1} { set L(delete,$clr) [lrange $L(path,$clr) $n+1 end] set L(path,$clr) [lrange $L(path,$clr) 0 $n] } else { lappend L(path,$clr) [list $row $col] } } # draws path for clr, deleting everything in L(delete,...) and # drawing L(path,...) proc ShowPath {clr} { global L S B # Stuff to be deleted foreach cell $L(delete,$clr) { lassign $cell row col if {[lindex $B($row,$col) 0] ne "node"} { set B($row,$col) "" } .c itemconfig cell_${row},$col -fill $::CLR(bg) } set L(delete,$clr) {} set xy {} foreach cell $L(path,$clr) { lassign $cell row col if {[lindex $B($row,$col) 0] ne "node"} { set B($row,$col) [list path $clr] } lassign [Cell2XY $row $col] . . x y lappend xy $x $y set bgClr [::tk::Darken $clr $S(darken,$L(done,$clr))] .c itemconfig cell_${row},$col -fill $bgClr } if {[llength $L(path,$clr)] < 2} { .c delete path,$clr return } if {[.c find withtag path,$clr] eq ""} { .c create line $xy -tag path,$clr -fill $clr \ -width $S(lwidth) -capstyle round .c raise node } else { .c coords path,$clr $xy } } proc DoHint {clr} { global L S SOLUTIONS if {! $S(hints,canDo)} { MyDialog "Turn on hints on\nthe help dialog" ok {destroy .dialog} return } if {![info exists SOLUTIONS($S(stage),$S(level))]} { MyDialog "No hints available\nfor this level" ok {destroy .dialog} return } incr S(hints,used) set hintPath [GetHintPath $clr] set L(delete,$clr) $L(path,$clr) set L(path,$clr) {} ShowPath $clr set L(path,$clr) $hintPath set L(done,$clr) 1 foreach cell $hintPath { lassign $cell row col StealCell $row $col $clr } ShowPath $clr CheckVictory } proc GetHintPath {clr} { global S BOARDS SOLUTIONS array set DIRS {w {0 -1} e {0 1} n {-1 0} s {1 0}} set me "$S(stage),$S(level)" set idx [lsearch $BOARDS($me) $clr] lassign [lrange $BOARDS($me) $idx+1 $idx+4] row0 col0 row1 col1 set steps [dict get $SOLUTIONS($me) $clr] # The saved path may be from either end, build up both set path0 [list [list $row0 $col0]] set path1 [list [list $row1 $col1]] set lastStep "" # steps is: e3nws5 and count could be 2 digits, hence regsub foreach step [regsub -all {[nsew]} $steps " \& "] { set cnt 1 if {[string is integer $step]} { set cnt [expr {$step - 1}] set step $lastStep } while {[incr cnt -1] >= 0} { lassign $DIRS($step) drow dcol set row [expr {[lindex $path0 end 0] + $drow}] set col [expr {[lindex $path0 end 1] + $dcol}] lappend path0 [list $row $col] set row [expr {[lindex $path1 end 0] + $drow}] set col [expr {[lindex $path1 end 1] + $dcol}] lappend path1 [list $row $col] } set lastStep $step } # Determine which path is correct if {[lindex $path0 end] eq [list $row1 $col1]} { return $path0 } return $path1 } # Determine size of a cell which determines the size of everything else proc ComputeSizes {N} { global S set w [expr {max([winfo width .c], [winfo reqwidth .c])}] set w [expr {$w - 2*$S(margin)}] set S(sz) [expr {$w/$N}] set S(sz2) [expr {$S(sz)/2}] set S(radius) [expr {$S(sz) * $S(radius,factor)}] set S(lwidth) [expr {$S(sz) * $S(lwidth,factor)}] } proc CheckVictory {} { global L B foreach arr [array names L path,*] { if {[llength $L($arr)] < 2} return lassign $arr . clr lassign [lindex $L($arr) 0] row col if {[lindex $B($row,$col) 0] ne "node"} return lassign [lindex $L($arr) end] row col if {[lindex $B($row,$col) 0] ne "node"} return } # Every cell must be used for {set row 0} {$row < $B(N)} {incr row} { for {set col 0} {$col < $B(N)} {incr col} { if {$B($row,$col) eq ""} { AlmostVictory return } } } Victory return 1 } proc AlmostVictory {} { if {$::B(almost)} return set ::B(almost) 1 MyDialog "Almost done!\nNow fill all the cells" "skip ahead" {PlayAgain 1} \ "keep playing" {destroy .dialog} } proc Victory {} { global S SOLUTIONS .c itemconfig solvedStar -state "" set me "$S(stage),$S(level)" if {$S(hints,used) > 0} { set hintText "\nwith a hint" } else { set hintText "" if {! [HasBeenSolved $S(stage) $S(level)]} { #set SOLUTIONS($me) [CompactPaths] set S(solved) [lsort -dictionary -unique [concat $me $S(solved)]] WriteRC } } if {$me eq [lindex [lsort -dictionary [array names ::BOARDS]] end]} { MyDialog "You finished the\nlast level!$hintText" \ "restart" {PlayAgain 1} "play again" {PlayAgain 0} } else { MyDialog "Finished!$hintText" "next level" {PlayAgain 1} \ "play again" {PlayAgain 0} } } proc CompactPaths {} { array set DIRS {1,0 s -1,0 n 0,1 e 0,-1 w} set allPaths {} foreach arr [array names ::L path,*] { set thisPath [lindex [split $arr ","] 1] append thisPath " " set row0 -1 foreach cell $::L($arr) { lassign $cell row1 col1 if {$row0 > -1} { set drow [expr {$row1 - $row0}] set dcol [expr {$col1 - $col0}] append thisPath $DIRS($drow,$dcol) } lassign [list $row1 $col1] row0 col0 } lappend allPaths $thisPath } return [join $allPaths " "] } proc MakeStar {x y delta} { set pi [expr {acos(-1)}] # Compute distance to inner corner #set x1 [expr {$delta * cos(54 * $pi/180)}] ;# Unit vector to inner point set y1 [expr {sin(54 * $pi/180)}] set y2 [expr {$delta * sin(18 * $pi/180)}] ;# Y value to match set delta2 [expr {$y2 / $y1}] # Now get all coordinates of the 5 outer and 5 inner points for {set i 0} {$i < 10} {incr i} { set d [expr {($i % 2) == 0 ? $delta : $delta2}] set theta [expr {(90 + 36 * $i) * $pi / 180}] set x1 [expr {$x + $d * cos($theta)}] set y1 [expr {$y - $d * sin($theta)}] lappend coords $x1 $y1 } return $coords } proc ShowPickPuzzlePage {} { set ::S(state) pick FadeOut all DrawPickPuzzlePage FadeIn all } proc PlayChosenPuzzle {level} { set ::S(level) $level PlayAgain 0 } proc PlayAgain {delta} { global S BOARDS destroy .dialog FadeOut all set S(state) play set S(hints,used) 0 set S(level) [expr {max(1,$S(level)+$delta)}] if {! [info exists BOARDS($S(stage),$S(level))]} { incr S(stage) $delta set S(level) [expr {$delta > 0 ? 1 : 30}] } if {! [info exists BOARDS($S(stage),$S(level))]} { set S(stage) 1 set S(level) 1 } WriteRC DrawBoard $S(stage) $S(level) FadeIn all } proc MyDialog {txt args} { set C .dialog destroy $C set w [expr {50 + max(150,[MeasureText $txt])}] set x [expr {$w/2}] set bg purple4 canvas $C -width $w -height 170 -bd 0 -highlightthickness 0 \ -bg $::CLR(dialog,bg) place $C -anchor c -relx .5 -rely .5 $C delete all $C create text $x 20 -text $txt -fill $::CLR(dialog,txt) \ -font myDialogFont -anchor n foreach {txt command} $args { set y [expr {[lindex [$C bbox all] 3] + 15}] set id [$C create text $x $y -text $txt -fill $::CLR(dialog,txt) \ -font myDialogFont -anchor n] lassign [$C bbox $id] . y0 . y1 set id1 [$C create rect \ 25 [expr {$y0-5}] [expr {$w-25}] [expr {$y1+5}] \ -fill $::CLR(dialog,button) -outline $::CLR(dialog,fg) \ -width 2] $C raise $id CanvasButtonBinding $C $id $id1 $::CLR(dialog,highlight) $command } lassign [$C bbox all] . . x1 y1 incr y1 20 $C config -height $y1 set id [$C create rect 0 0 $w $y1 -fill $::CLR(dialog,bg) \ -outline $::CLR(dialog,fg) -width 5] $C lower $id update idletasks grab $C } proc MeasureText {txt} { set longest 0 foreach line [split $txt \n] { set longest [expr {max($longest,[font measure myDialogFont $line])}] } return $longest } proc Box {x y r} { return [list [expr {$x-$r}] [expr {$y-$r}] [expr {$x+$r}] [expr {$y+$r}]] } proc Cell2XY {row col} { global B S set x [expr {$B(xy0) + $col * $S(sz) + $S(sz2)}] set y [expr {$B(xy0) + $row * $S(sz) + $S(sz2)}] set box [Box $x $y $S(sz2)] set oval [Box $x $y $S(radius)] return [list $box $oval $x $y] } proc Test_Cell2XY {} { set x0 0 for {set i 0} {$i < 7} {incr i} { lassign [Cell2XY $i $i] box oval x y set delta [expr {$x - $x0}] puts "$i : $x $delta" set x0 $x } } proc XY2Cell {cx cy} { global B S set row [expr {int(($cx - $B(xy0)) / $S(sz))}] set col [expr {int(($cy - $B(xy0)) / $S(sz))}] return [list $row $col] } proc Recenter {W h w} { set h [expr {$h/2}] set w [expr {$w/2}] $W config -scrollregion [list -$w -$h $w $h] } proc FadeIn {tag} { FadeOut $tag fadein } proc FadeOut {tag {fadein fadeout}} { set ids [expr {$tag eq "all" ? [.c find all] : [.c find withtag $tag]}] set FADING [dict create] foreach id $ids { if {[.c itemcget $id -tag] eq "border"} continue set type [.c type $id] if {$type eq "image"} continue set gradient [Gradient [.c itemcget $id -fill] black] if {$fadein eq "fadein"} { set gradient [lreverse $gradient] } set fading [list fill $gradient] if {$type in {"oval" "rectangle" "polygon"}} { set gradient [Gradient [.c itemcget $id -outline] black] if {$fadein eq "fadein"} { set gradient [lreverse $gradient] } lappend fading outline $gradient } dict set FADING $id $fading } DoFade $FADING 0 MyWait } proc DoFade {FADING step} { lassign $::S(fade,params) steps delay foreach id [dict keys $FADING] { foreach {what gradient} [dict get $FADING $id] { set clr [lindex $gradient $step] .c itemconfig $id -$what $clr } } incr step if {$step < $steps} { after $delay [list DoFade $FADING $step] } else { set ::S(wait) 1 } } proc MyWait {} { destroy .grab label .grab ; place .grab -x -100 -y -100 ; grab .grab tkwait variable ::S(wait) destroy .grab } proc Gradient {fromColor toColor} { if {[info exists ::MEM($fromColor,$toColor)]} { return $::MEM($fromColor,$toColor) } set steps [lindex $::S(fade,params) 0] lassign [winfo rgb . $fromColor] r1 g1 b1 lassign [winfo rgb . $toColor] r2 g2 b2 set steps [expr {$steps <= 1 ? 1 : double($steps - 1)}] set gradient {} for {set step 0} {$step <= $steps} {incr step} { set r [expr {int(($r2 - $r1) * $step / $steps + $r1) * 255 / 65535}] set g [expr {int(($g2 - $g1) * $step / $steps + $g1) * 255 / 65535}] set b [expr {int(($b2 - $b1) * $step / $steps + $b1) * 255 / 65535}] lappend gradient [format "#%.2x%.2x%.2x" $r $g $b] } set ::MEM($fromColor,$toColor) $gradient return $gradient } proc CanvasButtonBinding {C text_tag box_tag highlight cmd} { global _CB set who "$C,$text_tag" set oldFill [expr {$box_tag ne "" ? [$C itemcget $box_tag -fill] : ""}] set oldOutline [expr {$box_tag ne "" ? [$C itemcget $box_tag -outline] : ""}] set _CB($who,data) [list "" $C $box_tag $highlight $oldOutline $oldFill $cmd] foreach tag [list $text_tag $box_tag] { if {$tag eq ""} continue foreach action {Button-1 ButtonRelease-1 Leave Enter} { $C bind $tag <$action> [list _CanvasButtonBinding $who $action] } } } proc _CanvasButtonBinding {who what} { global _CB lassign $_CB($who,data) state C box_tag highlight oldOutline oldFill cmd if {$what eq "Button-1"} { lset _CB($who,data) 0 "in" if {$box_tag ne ""} {$C itemconfig $box_tag -fill $highlight -outline $highlight} } elseif {$what eq "ButtonRelease-1"} { lset _CB($who,data) 0 "" if {$box_tag ne ""} {$C itemconfig $box_tag -fill $oldFill -outline $highlight} if {$state eq "in"} {uplevel #0 $cmd} } elseif {$what eq "Leave"} { if {$state ne ""} { lset _CB($who,data) 0 "out" } if {$box_tag ne ""} {$C itemconfig $box_tag -fill $oldFill -outline $oldOutline} } elseif {$what eq "Enter"} { if {$state ne ""} { lset _CB($who,data) 0 "in" } if {$box_tag ne ""} { if {$state eq ""} { $C itemconfig $box_tag -outline $highlight } else { $C itemconfig $box_tag -fill $highlight -outline $highlight } } } } proc Help {} { set msg "Flow Colors\nby Keith Vetter\n\n" append msg "The object of Flow Colors is\n" append msg "lay pipes to connect all pairs\n" append msg "of colors. A level is solved\n" append msg "when all the colors are paired\n" append msg "and the entire board is filled.\n\n" append msg "Flow Colors is based on a game\n" append msg "by Mohammed el-Madhoun\n" append msg "http://moh97.us/flow\n" if {[llength [array names ::SOLUTIONS]] > 0} { MyDialog $msg "ok" {destroy .dialog} "hints" {HelpHint} } else { MyDialog $msg "ok" {destroy .dialog} } } proc HelpHint {} { set ::S(hints,canDo) 1 set msg "Flow Colors Hints\n\n" append msg "You can now get a hint by\n" append msg "holding down the shift key\n" append msg "and double right click on\n" append msg "any node.\n" MyDialog $msg "ok" {destroy .dialog} } proc ReadRC {} { if {[file exists $::S(rcFile)]} { uplevel #0 source $::S(rcFile) } if {[info exists ::S(lastPuzzle)] && [llength $::S(lastPuzzle)] == 2} { lassign $::S(lastPuzzle) ::S(stage) ::S(level) } } proc WriteRC {} { global S SOLUTIONS catch { set fout [open $S(rcFile) w] puts $fout "set ::S(lastPuzzle) {$S(stage) $S(level)}" puts $fout "set ::S(solved) {$S(solved)}" if {0} { puts $fout "array set SOLUTIONS {" foreach arr [lsort -dictionary [array names SOLUTIONS]] { puts $fout " $arr {$SOLUTIONS($arr)}" } puts $fout "}" } close $fout } } ################################################################ image create photo ::img::left -data { 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 AElFTkSuQmCC} array set SOLUTIONS { 1,1 {blue s5w green s2 darkorange n4 cyan s3w2 red e3n5 yellow en3e} 1,2 {blue wn3w2 green s2 darkorange ws5e5n cyan se red n3e2s yellow n2} 1,3 {red e5s yellow w2s2 blue s3 green s3w2n2w darkorange sw2n4e3} 1,4 {yellow e2n5w2s2 blue n3 green wn3 darkorange nwn3w2s5e2} 1,5 {yellow s2e2n blue e2s2w4n5e green ne2s5 darkorange s3e2} 1,6 {yellow wsw3n2ene2 blue e5s5w green nw4s darkorange ene2} 1,7 {blue n5e2s3 green s2 darkorange s2w4n4 cyan e2n red n2w yellow s2} 1,8 {red s3w5n yellow e2s blue s2w2nwn3e2 green e2s3 darkorange ses} 1,9 {red n3e yellow n2 blue s4 green s2e2n5 darkorange en2w3s5e} 1,10 {blue w4 green e4 darkorange s3e5 cyan w3 red w4nwn yellow e4} 1,11 {red w4n3e5s yellow e3 blue se4 green se5n2 darkorange e2} 1,12 {yellow ne4n3w2 blue ws3e3 green e3s5w4 darkorange w2n} 1,13 {red ene2s2 yellow ne2s2e3n2wn2 blue n2e2 green wn2w2n darkorange en} 1,14 {red n2 yellow n5e3s2ws3 blue s4e green n4e darkorange n4w} 1,15 {blue es green ses darkorange ne cyan n2en2e2s red s3 yellow e2n5w5} 1,16 {blue e2s5w5 green wsw darkorange s2 cyan ne2 red e2n yellow n2ene3} 1,17 {blue e2s4w green se3n3 darkorange s2 cyan nw red w3sw yellow ws3ese} 1,18 {red e2 yellow e2n4 blue e2 green e3s2w3s2e darkorange w5s5} 1,19 {red w2s yellow e3 blue w3s2 green s5e5n3w darkorange s3e3} 1,20 {yellow en blue n2e2s green s2w2n4e4s darkorange e2n5w5} 1,21 {blue se green e4n5 darkorange s2 cyan s4w4s red en2w yellow se3} 1,22 {red s5w5n yellow e3s2 blue en4w4 green nw darkorange sese} 1,23 {yellow e3n blue w5s5e5 green w2 darkorange w4n3e4} 1,24 {blue en green ese darkorange sw3n cyan s5 red e2s3ws yellow sw4n2e} 1,25 {blue w2 green ws5 darkorange w3 cyan s3e3n2w red n4e4 yellow se} 1,26 {red e5s5w2 yellow en blue w2sws green en3w4 darkorange ne3} 1,27 {red ws2es yellow s4e2 blue en3w green nwn4e3s darkorange n4w} 1,28 {yellow e4n5w4 blue e3 green s2e3 darkorange e3s2w4s2} 1,29 {blue ne5s3 green s2wsw2n2 darkorange es3 cyan sw2 red en yellow nen2} 1,30 {red ne5s3 yellow ws2e blue sw2n3wnw green es3 darkorange e2n2w} 2,1 {blue w6s6e5 green sw darkorange w4s cyan e2s3 red w3n2ene4n yellow nw} 2,2 {blue e2 green nw3 magenta w2n6e darkorange ws4e cyan sw2nwn red e3n6w4 yellow es} 2,3 {blue w6n2 green se2 magenta e2 darkorange w2n2 brown es2 red s2e4n cyan e6s yellow wnw5} 2,4 {red n3ene4s4 yellow nw2 blue n2e2se green e6n6w6s darkorange w2n} 2,5 {blue se3s2 green en3 darkorange s2ese4 cyan s6e red es2 yellow e4s5w3n3} 2,6 {blue enwn2e2sw green sw magenta se4n2 darkorange sen3e2 cyan es2 red sw6n2 yellow e2n3} 2,7 {red e4 yellow se4n blue e2 green ne6s2w5 darkorange s4e6n3w2sw2} 2,8 {blue w3 green w5n6e4 magenta nw3 darkorange n3e5n cyan wsw4 red e3 yellow s2} 2,9 {blue w2 green w3n3 darkorange ne5 cyan sws4e6n2 red sw3s2e3 yellow w4n2} 2,10 {blue n4 green en6w4s5 darkorange s5e cyan ws6 red n2e2s4 yellow n2} 2,11 {blue ne3s2 green w2 magenta sws2 darkorange se3s cyan s2e red n4 yellow se6n6w2s3} 2,12 {blue sw3 green n2e6s2w3 magenta n3 darkorange s3e2ne2s2 cyan s3 red ne4 yellow ne3} 2,13 {blue e2 green sw6n2 darkorange s3 cyan ws red ses2e2nen2 yellow wsw4n2wn3e5} 2,14 {blue en green n2w magenta n3wn2 darkorange s2 brown nw2s5e red n2w3s cyan s4w2sw2 yellow e2n2} 2,15 {red sws4e6n6w2s yellow s4w4 blue es2es2w3n green wn2 darkorange ws} 2,16 {red ese3n yellow e2 blue e2s green n4w6s5e darkorange wnw3n3e4sw3s} 2,17 {blue e2se green e2se3n magenta nw3 darkorange n3w5s3e cyan w2n2e red en4 yellow wnw2n} 2,18 {blue w2s3 green n2wn2 magenta se4n3e2 darkorange s2 cyan s2 red n2w6s4es yellow ne3} 2,19 {blue n2 green ne2 darkorange sw3 cyan sw3s3e2ne red n5e3ne2s3 yellow n6e3} 2,20 {red w2s5e6n6w3 yellow ese2n2 blue nw2 green w2 darkorange e2s4w4n} 2,21 {blue wnw3 green e2s2e darkorange es2w3s2e5n6w2 cyan s3 red s4w3 yellow es} 2,22 {blue e4n3w2s green w2s magenta n2ene4n darkorange s2w6 cyan w4s red nw3 yellow e3} 2,23 {blue n2 green s6e4n2 darkorange ne3n cyan wsw3s3e red w2n5e3 yellow n3w2} 2,24 {blue se2 green sw4s2w darkorange n2e6 cyan wnw2sw3n2en2e4 red w3 yellow e3s} 2,25 {blue en3w3nw2 green s6e3 darkorange ese3s cyan se3s red nw4 yellow e3se2n2} 2,26 {red n3w yellow e2n2wn2e3s4e blue e6n6w4 green ws4e darkorange n3} 2,27 {red e2s5w5n2 yellow s2e2n3 blue w6n6e3 green s3 darkorange n2w2s} 2,28 {blue e5n6w green e2s3 magenta ese2 darkorange nen cyan w3n2w2s red se2n3 yellow se3} 2,29 {blue e2 green se2n2e darkorange w3n cyan nw3 red ne4s3 yellow nwn4e6s5w2} 2,30 {blue es3 green e2 magenta e2s darkorange es2e2s2e3s2w6n2 cyan s2w red se4 yellow s2e2s} 3,1 {blue es2w green s5w3nwn3e2 darkorange se cyan w3s5ese5n5 red w4s7e yellow n2e2s} 3,2 {blue n4w4n green sw3s darkorange ene4n5 cyan e5s7w4 red s2e4s3w3sws yellow e2} 3,3 {blue e4s3e green n4w5sws2e4s3e2s darkorange w3s2e6 cyan s2w3 red ws4e3 yellow e3} 3,4 {blue wsw3 green n3e6s magenta nw4 darkorange e3ne2 cyan w4s2e4 red wn2e3 yellow sw7n7} 3,5 {blue s4w2 green w6s4e darkorange e5 cyan e6nw4nenw red n2e2 yellow wn2e2n3e2ne2swse} 3,6 {blue n2w3n2e4 green nw4nw2s magenta es3e3s darkorange n3w3 cyan w4n red e2s3e3s2e2 yellow wn5} 3,7 {red wnenes6wn3ws3wn2wnws2esw3n2es yellow w2s blue e3s green wn2ene2sw darkorange ne4s2} 3,8 {blue n2w4sws green n2ene5n2 magenta sw2 darkorange sw5s cyan w5s7e4n red w2n2w yellow wn2w2} 3,9 {blue enes2e2n5w4se green es3 darkorange ne2 cyan se4n2 red n3e2s7w7n2 yellow n5} 3,10 {blue wswseswse green w2nw2se darkorange nes2wse2nesenen4 cyan w2 red n2w4s5 yellow sw6n4} 3,11 {blue e2 green wsesw magenta es7w3nw4s darkorange eneses cyan s2 red e2se yellow esw2n5es3en3es3} 3,12 {blue e2 green wnw3sws2 darkorange e2n cyan wsws2ws2e4se2nw red ws7e4 yellow e2nwne2senen3w} 3,13 {blue e2 green wnwn2e3s darkorange s5ese2ne3 cyan n3w5s4es red n3 yellow se7n3w2nwnw} 3,14 {blue sw2s2en green n2w4 darkorange e5 cyan wn4e2ne4s4 red nes2w2se2 yellow w2s6e6s} 3,15 {blue wn5ene5s4w2n2 green ws7e3 darkorange se3 cyan e2 red w3nwnwn3ene3s2 yellow nen} 3,16 {blue n3e green s7w2n7w5 magenta s6 darkorange n3e4 cyan w3s4e red s2 yellow s2e4n3} 3,17 {blue e7s7w green enen magenta e4s3 darkorange n3w6s2 brown w3 red w3s2 cyan s3e3nen yellow ne} 3,18 {blue e2s green s5 magenta sw darkorange s5 purple s4w6n4 brown ws2e4n3 red ne2s cyan ese2n3w3 yellow en} 3,19 {blue s2w4s2e7n3w green w5 magenta sw3 darkorange es3w2nw brown ene3ses red wsw2 cyan ws3e2 yellow se} 3,20 {blue ne2 green w3n4 magenta w2 darkorange w2s2es4 purple n2w2 brown n2e4s2w2s red wnw3n2e cyan e2n3 yellow es2e3} 3,21 {blue s4 green e2n2wn2wn2w4s magenta sws darkorange s2 brown wn7e5 red nenen cyan wn2 yellow en5w2sws} 3,22 {blue es7w5n5 green w3n4 darkorange nw cyan ws5 red s2e2n4 yellow wn7e3seses2} 3,23 {blue w4n green w2sw2n7 magenta e2s6w4 darkorange nw2s3e5s3 cyan w3s red ne3 yellow n2w4} 3,24 {blue wn4e2s3 green ws7 magenta s3e3n darkorange ses5e5n7w5 cyan es red s2 yellow s4} 3,25 {blue e2s5 green w3s magenta e2s2w darkorange ene3n3w3 cyan en7w4 red se2s5w3 yellow w3n3e} 3,26 {blue e2s2 green enene2s3ws magenta wnw darkorange e7n7w4s brown nen red se6n cyan s2 yellow s3ese} 3,27 {blue wn4e4s green w2s2 magenta n2e3n3w5 darkorange nw7s7e3 cyan enen3 red e3n yellow ws} 3,28 {blue nw7s7e3 green s2w2 magenta n2e darkorange n5wnw3 cyan e2n4 red en2e2s3 yellow e4n4} 3,29 {blue w3s7e7n4 green e3nes3 darkorange es2es2 cyan n4en2ws red nenwnw yellow s3e2nes} 3,30 {blue n5e2s3 green n2 magenta s3 darkorange es7w7n7e4 cyan s2 red e3n2w2n3 yellow w3s} 4,1 {blue nw4 green e2 magenta e4n2e2 darkorange w2 purple s3w8n2e brown e6n2 red s2e3s cyan wn yellow e4n2e2n4w8s5} 4,2 {blue e6ses2 green s4 magenta n2 darkorange s2 brown es8w4n2e2n4wnw5s2 red n4e cyan s3w2 yellow n3w3s2ws4e2} 4,3 {blue ne2 green e2nw3ne3nwnwswnw2s3 magenta s4e2n6e2ne3sw2 darkorange s2 cyan s4 red w5ne2 yellow nene2ne5s3} 4,4 {blue ws4e green w4s2 magenta s2 darkorange s4e2s2w4n7 cyan w6s6e2 red nw3s2w yellow s8e6n5e} 4,5 {blue en2en3 green e2s3e magenta s6e8n2 darkorange es6 brown s3ws red w4n2 cyan nen5w5s2es2w2s3 yellow e2s2} 4,6 {blue s2ws green e4 magenta nw5s4w darkorange e2n4e2 purple n5w2 brown s2e white en8w8s5 red wn3 cyan wn3e yellow e3} 4,7 {blue n3 green n2e2ses5 magenta e2s7 darkorange ws4e5n2 purple ws4 brown s2e white s2e3n7w red en2 cyan s4 yellow s8} 4,8 {blue e8s green e4s2w3s4e3 magenta w2 darkorange ne3 brown ese3n4w2sw4s red n2 cyan w8n6e3 yellow nw3sw} 4,9 {blue s8e8n5 green w2s3 magenta s2 darkorange n3 brown es4e2n4e4s2 red e3n cyan s3w5s yellow w3sw2n6} 4,10 {blue se2 green en2w2n4e8s6 magenta n3 darkorange wn6w6s2e3s4e cyan w5n3e red wn4w3 yellow e2n3} 4,11 {blue se green e3s magenta w3n2e3n2 darkorange e3s6 purple es2 brown s4 red eseses3 cyan ne7s8w2n6w yellow nwnw2n2} 4,12 {blue sw2 green w3 magenta w4n5e2 darkorange wsw4 brown n2e8s3wsw6s3e4se3n2ws red swsw3 cyan e3 yellow e4s} 4,13 {blue n2w3 green n6e6 magenta s2e4n8w8s8e2n4 darkorange es2es brown wnw red ws3 cyan s2e yellow w5} 4,14 {blue e2 green se4n2 magenta sw2 darkorange n2e6nenen3w4s purple se2 brown nw2sw3nw red w5n4e3s cyan en2 yellow s2e6n4} 4,15 {blue w6s2e green w3s3enesenesen3wsw3 magenta s2 darkorange e7 cyan e8s8w2nen4w2sw2 red e2 yellow s2} 4,16 {blue w3 green s7w2n2 magenta en darkorange wsw4s2 purple ne5 brown n6 red sen2w3sw2n6e4 cyan wse8 yellow e4n2} 4,17 {blue ne5s3w2s green e8n4 darkorange nwsw5ne4n3w2n2w2sesws2enesen cyan s3w7 red w2 yellow sw2s2} 4,18 {blue w3s6 green w2n3 magenta w2 darkorange n2w2 purple sw3 brown s3 red n5e3ne cyan s8 yellow w6n8e7s4w2} 4,19 {blue s3w7n8e6s green es3w3s magenta w2s3 darkorange w4n2 purple n4e2 brown sw2nw red s3e3s cyan n4w yellow sw2n2} 4,20 {blue e2s5 green swsws2w3n4 magenta s3e2 darkorange s2w5n5 purple wn2 brown n3w2s2wsws red sws cyan n2wn3 yellow n4w2n2e4} 4,21 {blue n2e3 green sw8n5e2 magenta n6w8s2e6 darkorange wn2e3n3w6 cyan wn3e red sese3n yellow n2w2} 4,22 {blue s2e green s2es2w8n4e2s magenta w3s darkorange w4s3e3s2es purple e2s2 brown w3 red n2wnw cyan s4e yellow nw3s6w2nw} 4,23 {blue s4 green en4wnwn magenta eses darkorange ne3 purple wsw3n2 brown s3e red nw3n2w cyan nw8s3es5e5ne yellow w2s2es2e} 4,24 {blue s3w2n6 green n5w5s magenta s5 darkorange w2s8e8n2 brown e3s3 red nw2n3w2n cyan s3e2 yellow e2s3e} 4,25 {blue sw3s2ws green s8e7n2 magenta n4e5 darkorange en2e2 brown w2n red e3s4w2s cyan s8 yellow s7e5n} 4,26 {blue e4n green w5n3e4 magenta s3e3 darkorange w2 purple w3n2w4n2e3 brown e3nen3e red w3s cyan en3 yellow e2n6w3s2w3} 4,27 {blue swswn green wnen3w2sw magenta s2 darkorange e2s6w brown wn4en3en red wse2nese3n8w4s cyan s2ws4e2 yellow ws3} 4,28 {blue e4n4w3n2e green sw3n2en5 magenta ne darkorange s3e3s2w cyan nwn6e5s3w2 red n5e2s7w yellow e3s} 4,29 {blue nw4s green s2w4 magenta w2sw5s6e darkorange e4 brown e2 red w4s2ese6n4w cyan e8s3w yellow ws4w4} 4,30 {blue n5en2 green s2w3s2w2s2es2w3n4 magenta es2e darkorange s3 purple sw3 brown wn7w2s2 red n2e3 cyan sw3s2w yellow n3w2s3} 5,1 {blue s3 green s5w4 magenta w6ne7 darkorange s6en3e3n2w3ne4s3 cyan w4s2e5 red w2 yellow s8w} 5,2 {blue e8 green w8n3 magenta se2n2 darkorange s2 brown e2 red e8s5wn4ws3wn cyan nw2n2esenesen yellow s2e4ne} 5,3 {blue s4 green s6e2 magenta w2s6e7 darkorange e4 purple s4en brown s4 red s5 cyan w3n2wn4w4s7 yellow n5} 5,4 {blue ne7n7 green s3 darkorange w5seswse2sw2se2sw2s2 cyan e6 red e4n6wswsesw2se2sw2 yellow ne2s} 5,5 {blue esw5s6w2n7 green w4s6 darkorange w3n4e5n2 cyan n5w4s2e2 red w3 yellow e7n4w2} 5,6 {blue s4 green s3e5 magenta w3 darkorange e5 purple s3e4 brown e4s white s3e8n8 red n5w4 cyan e4s yellow w5s} 5,7 {blue s3 green s6w7n2e3nw2n2esen magenta e4 darkorange s4e purple e5 brown w5 red swnwsw6n4 cyan s3 yellow sen2w} 5,8 {blue e7 green enwn6e7 magenta s2 darkorange s3 purple se6 brown w4 red swn3 cyan se2n2e3sw2s2wse4nw2ne2 yellow e2s} 5,9 {blue e7 green e6n magenta w5 darkorange w2swnwswnwswn2 purple s6 brown e8 red n2w6 cyan e5 yellow wsw6s4} 5,10 {blue n3e4 green w3ses3w4n5es4e2n darkorange n8 cyan s4w6 red w7n2e6n4e yellow s5} 5,11 {blue ne8 green s3e6 magenta w4 darkorange w7 purple s3 brown n2es2en2es2 white e3 red n6e2s2 cyan e5s5 yellow s5} 5,12 {blue w7s8 green w6n4e6 magenta e6s4w3n darkorange s2 brown e2 red e5 cyan e6 yellow swnw5s2e3} 5,13 {blue w6 green s8 magenta w3 darkorange w6n8e7 purple w5 brown e3sw3 red s3 cyan e4s4 yellow n5e6} 5,14 {blue s6e green e5 magenta s2 darkorange wswn8 purple s5 brown w2s3 white w4 red n5 cyan s3w3n5e4 yellow n7w5} 5,15 {blue n5 green s5e8 magenta w5 darkorange n2w7s2 cyan w6n2e5 red e3 yellow n6es3en3e3sw2se3} 5,16 {blue e3 green s5 magenta w5swn6 darkorange nes4 purple e3 brown w5n white w3 red nwswnws cyan senesen yellow e2nwnenwnenwnenwne} 5,17 {blue w8n7 green s6 magenta w5 darkorange n6e6s5 brown e8 red s3 cyan s3 yellow n4w2s4wn4w} 5,18 {blue s5 green s8e8 magenta e2 darkorange s5e6 purple w7 brown e7 red s4 cyan w4s3e4n2w3 yellow w4} 5,19 {blue n3ene5 green s3w3s2e3sw3se3sw4n4 magenta s4 darkorange ws8 purple n2 brown e2 red n3en3 cyan ne3 yellow w4s2} 5,20 {blue s2 green s2 magenta wn2w2sesw darkorange s8e8 purple e5 brown ws4ene6n2w3 white w5 red e2n3 cyan s yellow n3e5} 5,21 {red w2ne7 yellow s6e8s2w5 blue s2e4nw3ne3nw4ne4nw4 green s3 darkorange s5e2n5w} 5,22 {blue s7 green w6s3 magenta nese darkorange s8e5nesen2wnenw2nw2 brown wse2ne red swnw3 cyan s yellow e5s7} 5,23 {blue s3e8n green w6 magenta s3 darkorange w7s2e6 brown w4 red wsw6 cyan e6s2 yellow sw6n4e6} 5,24 {blue e3n2w3 green e4 magenta s4w7 darkorange w2s2e2 brown e8n5 red w6s2e6 cyan nwsw6 yellow w8} 5,25 {blue ws4 green n3 magenta ne6n4w3 darkorange w2n4w2 brown e2s2w3 red w5 cyan e4s6 yellow e8n8w5} 5,26 {blue s7e green s7e5n6w3 magenta e8n8w4 darkorange s6 cyan s4en4 red s4 yellow s6} 5,27 {blue s4 green s4wse3nwnen3 magenta e2s6 darkorange ws8e5 cyan s5 red ne6s8w2n6 yellow ws3} 5,28 {blue s6 green w5s7w magenta s3w2se5n4en4 darkorange e6 brown s3 red w3s3 cyan s3ws4wn4w yellow s4e} 5,29 {blue s5es3 green n4e6s2w4s2 magenta s2 darkorange sen2wn6 brown n7e4 red e2s4w3n3 cyan s2 yellow e3s5} 5,30 {blue e2 green e3s5w4 magenta w2s3wn4 darkorange w2n2e8s8 brown se5sw5 red e3s2w3 cyan esene3 yellow w2} } image create photo ::img::undo -data { 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} image create photo ::img::right -data { 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 JRQAAAAASUVORK5CYII= } image create photo ::img::help -data { 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 } image create photo ::img::up -data { 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 rkJggg== } ################################################################ ReadRC DoDisplay DrawBoard $S(stage) $S(level)  return ====== <> Games | Tcl/Tk Games | Application