--- newsudoku.txt 2010-01-05 12:57:02.000000000 -0800 +++ sudoku-procs.txt 2010-01-05 12:57:12.000000000 -0800 @@ -30,11 +30,34 @@ # each row, column, and square has 9 associated entries # use nested lists like 2 dimensional arrays -proc buildAssociations {} { +namespace eval ::sud { - global rows cols squares + variable rows + variable cols + variable squares - set rows [ list \ + variable arabicmode + variable duplicatesfound + variable invalidfound + variable kanji1to9 + + variable cellbgcolorA + variable cellbgcolorB + variable cellerrorcolor + variable celldupcolor + variable cellchangedcolor + variable checkcolor + + variable arabicarray + variable cellarray + variable cellbgcolorarray + variable kanjiarray + variable possarray +} + +proc ::sud::buildAssociations {} { + + variable rows [list \ {0 1 2 3 4 5 6 7 8} \ {9 10 11 12 13 14 15 16 17} \ {18 19 20 21 22 23 24 25 26} \ @@ -45,7 +68,7 @@ {63 64 65 66 67 68 69 70 71} \ {72 73 74 75 76 77 78 79 80} ] - set cols [ list \ + variable cols [list \ {0 9 18 27 36 45 54 63 72} \ {1 10 19 28 37 46 55 64 73} \ {2 11 20 29 38 47 56 65 74} \ @@ -56,7 +79,7 @@ {7 16 25 34 43 52 61 70 79} \ {8 17 26 35 44 53 62 71 80} ] - set squares [ list \ + variable squares [list \ {0 1 2 9 10 11 18 19 20} \ {3 4 5 12 13 14 21 22 23} \ {6 7 8 15 16 17 24 25 26} \ @@ -72,9 +95,11 @@ # set up up arabic to/from kanji translations # and the list of 9 kanji digits equivalent to 1-9 -proc buildTranslations {} { +proc ::sud::buildTranslations {} { - global kanjiarray arabicarray global kanji1to9 + variable kanjiarray + variable arabicarray + variable kanji1to9 array set kanjiarray {1 \u4e00 2 \u4e8c 3 \u4e09 4 \u56db \ 5 \u4e94 6 \u516d 7 \u4e03 8 \u516b 9 \u4e5c} @@ -90,7 +115,7 @@ # pop up a warning message inside the main window -proc popMessage {message color} { +proc ::sud::popMessage {message color} { # don't allow multiple window creations if called more than once @@ -109,7 +134,7 @@ # set the color of the CHECK button -proc setCheckButtonColor {color} { +proc ::sud::setCheckButtonColor {color} { .sudoku.buttons.checkButton configure -bg $color } @@ -117,19 +142,19 @@ # build the board -proc buildGrid {} { +proc ::sud::buildGrid {} { - global cellarray + variable cellarray for {set rowind 0} {$rowind < 9} {incr rowind} { set gridlist "" for {set colind 0} {$colind < 9} {incr colind} { set cellind [expr $rowind * 9 + $colind] - entry .sudoku.board.cellentry$cellind -textvariable cellarray($cellind) \ + entry .sudoku.board.cellentry$cellind -textvariable ::sud::cellarray($cellind) \ -width 2 -font {courrier 20} -justify center bind .sudoku.board.cellentry$cellind \ - [list validEntryKey %W $cellind] + [list ::sud::validEntryKey %W $cellind] lappend gridlist .sudoku.board.cellentry$cellind } eval grid $gridlist @@ -140,10 +165,11 @@ # set the board's background colors and the array that # holds the default colors for future reference -proc setBackgroundColors {} { +proc ::sud::setBackgroundColors {} { - global cellbgcolorarray - global cellbgcolorA cellbgcolorB + variable cellbgcolorarray + variable cellbgcolorA + variable cellbgcolorB for {set rowind 0} {$rowind < 9} {incr rowind} { set gridlist "" @@ -167,9 +193,9 @@ # each element is a list of 1-9 that gets pruned as the possibles # get reduced until only one remains (hopefully) in a given element -proc buildPossible {} { +proc ::sud::buildPossible {} { - global possarray + variable possarray set possibles [list 1 2 3 4 5 6 7 8 9] @@ -183,9 +209,9 @@ # possible array element - this may boil down to a single # statement so just fold it into calling code??? -proc clearPossibleElementAll {index} { +proc ::sud::clearPossibleElementAll {index} { - global possarray + variable possarray # make sure it remains a list - but empty @@ -197,9 +223,9 @@ # possible array element - this may boil down to a single # statement so just fold it into calling code??? -proc clearPossibleElementValue {index value} { +proc ::sud::clearPossibleElementValue {index value} { - global possarray + variable possarray set possarray($index) \ [lsearch -all -inline -not -exact $possarray($index) $value] @@ -211,9 +237,9 @@ # not redundant since prune proc only eliminates a single value, not # the entire list (as must happen if cell already occupied) -proc clearPossiblesPerEntry {} { +proc ::sud::clearPossiblesPerEntry {} { - global cellarray + variable cellarray for {set index 0} {$index < 81} {incr index} { if {[nineCheck $cellarray($index)]} { @@ -227,9 +253,9 @@ # exactly ONE possible value # returns found value if == 1, else returns 0 -proc checkPossibleForOne {index} { +proc ::sud::checkPossibleForOne {index} { - global possarray + variable possarray if {[llength $possarray($index)] == 1} { return $possarray($index) @@ -242,11 +268,12 @@ # sets the actual board to that value if it finds any # set bg color to ?something? if new entry -proc updateBoard {} { +proc ::sud::updateBoard {} { - global cellarray possarray - global cellchangedcolor - global arabicmode + variable cellarray + variable possarray + variable cellchangedcolor + variable arabicmode for {set index 0} {$index < 81} {incr index} { set singlevalue [checkPossibleForOne $index] @@ -269,14 +296,17 @@ # this is different than finding a single possible value # in a possible element, which is done elsewhere -proc scanEntityForOne { entitytype } { +proc ::sud::scanEntityForOne { entitytype } { - global rows cols squares - global cellarray possarray - global cellchangedcolor - global arabicmode + variable rows + variable cols + variable squares + variable cellarray + variable possarray + variable cellchangedcolor + variable arabicmode - foreach entity [subst $$entitytype] { + foreach entity [set $entitytype] { for {set numeral 1} {$numeral < 10} {incr numeral} { # for each entity, count number of each numeral # if count == 1 set the board cell that matches @@ -314,9 +344,7 @@ # check all entities for single occurance of a # given numeral and if found updates board in that location -proc scanAllEntitiesForOne {} { - - global rows cols squares +proc ::sud::scanAllEntitiesForOne {} { scanEntityForOne rows scanEntityForOne cols @@ -328,11 +356,14 @@ # if the board has an entry, clear that value from all possibles # in the associated entity type - row, column, or square -proc prunePossiblesPerEntity {entitytype} { +proc ::sud::prunePossiblesPerEntity {entitytype} { - global cellarray possarray - global rows cols squares - global arabicmode + variable cellarray + variable possarray + variable rows + variable cols + variable squares + variable arabicmode # each entity is a sub-list of 9 board cell index values # grab each index value and see if there is a board entry @@ -340,7 +371,7 @@ # possibles at the other indices in the entity (delete from # possible array, not the board array - foreach entity [subst $$entitytype] { + foreach entity [set $entitytype] { for {set index 0} {$index < 9} {incr index} { # cellindex points to board entry to test set cellindex [lindex $entity $index] @@ -367,9 +398,7 @@ # already has an entry in board then clean out all copies of # an existing board numeral in it's subsuming entities -proc pruneAllPossibles {} { - - global rows cols squares +proc ::sud::pruneAllPossibles {} { clearPossiblesPerEntry prunePossiblesPerEntity rows @@ -380,40 +409,40 @@ # ckeck for space or null -proc checkSpaceOrNull {x} { +proc ::sud::checkSpaceOrNull {x} { - return [expr {[string equal $x " "] || [string equal $x {}]}] + expr {[string equal $x " "] || [string equal $x {}]} } # to check for legit kanji cell contents # kanji 0-9, space, null all OK -proc kanjiAllCheck {x} { +proc ::sud::kanjiAllCheck {x} { - global kanji1to9 + variable kanji1to9 - return [expr {([lsearch -exact -inline $kanji1to9 $x] != {}) \ - || [checkSpaceOrNull $x]}] + expr {([lsearch -exact -inline $kanji1to9 $x] != {}) + || [checkSpaceOrNull $x]} } # to check for legit arabic cell contents # 0-9, space, null all OK -proc arabicAllCheck {x} { +proc ::sud::arabicAllCheck {x} { - return [expr {(([string is int -strict $x] && ($x >=0) && ($x<=9)) \ - || [checkSpaceOrNull $x])}] + expr {(([string is int -strict $x] && ($x >=0) && ($x<=9)) + || [checkSpaceOrNull $x])} } # check for legal numeral, space, or null entry # kanji or arabic numeral based on flag -proc allCheck {x} { +proc ::sud::allCheck {x} { - global arabicmode + variable arabicmode if {$arabicmode} { return [arabicAllCheck $x] @@ -425,44 +454,42 @@ # check for arabic 1-9 -proc arabicNineCheck {x} { +proc ::sud::arabicNineCheck {x} { - return [expr {[string is int -strict $x] && ($x >= 1) && ($x <= 9)}] + expr {[string is int -strict $x] && ($x >= 1) && ($x <= 9)} } # check for kanji 1-9 -proc kanjiNineCheck {x} { +proc ::sud::kanjiNineCheck {x} { - global kanji1to9 + variable kanji1to9 - return [expr {[lsearch -exact -inline $kanji1to9 $x] != {}}] + expr {[lsearch -exact -inline $kanji1to9 $x] != {}} } # check for a numeral - arabic or kanji depending on flag -proc nineCheck {x} { +proc ::sud::nineCheck {x} { - global arabicmode + variable arabicmode if {$arabicmode} { return [arabicNineCheck $x] } else { return [kanjiNineCheck $x] } - -# return [expr {[string is int -strict $x] && ($x >= 1) && ($x <= 9)}] } # do translations arabic/kanji # return question mark if invalid input -proc toKanji {arabic} { +proc ::sud::toKanji {arabic} { - global kanjiarray + variable kanjiarray if {[arabicNineCheck $arabic]} { return $kanjiarray($arabic) @@ -476,9 +503,9 @@ } -proc toArabic {kanji} { +proc ::sud::toArabic {kanji} { - global arabicarray + variable arabicarray if {[kanjiNineCheck $kanji]} { return $arabicarray($kanji) @@ -498,10 +525,10 @@ # what to return if not a legit input? "?" or ??? # and maybe don't change the original if "?" -proc allKanji {} { +proc ::sud::allKanji {} { - global cellarray - global arabicmode + variable cellarray + variable arabicmode if {!$arabicmode} { return @@ -516,10 +543,10 @@ } } -proc allArabic {} { +proc ::sud::allArabic {} { - global cellarray - global arabicmode + variable cellarray + variable arabicmode if {$arabicmode} { return @@ -537,9 +564,9 @@ # count the number of non-zero board entries UNUSED SO FAR -proc countEntries {} { +proc ::sud::countEntries {} { - global cellarray + variable cellarray set count 0 for {set index 0} {$index < 81} {incr index} { @@ -556,9 +583,9 @@ # are processed # validation routine checks textvariable contents, not key -proc validEntryKey {win index} { +proc ::sud::validEntryKey {win index} { - global checkcolor + variable checkcolor # set CHECK button color to *something* since entry # touched by key stroke @@ -568,7 +595,7 @@ # call validate but only after keystrokes have updated # "key" means we are calling validEntry due to keystroke(s) - after 0 validEntry "key" $win $index + after 0 ::sud::validEntry "key" $win $index } @@ -593,12 +620,14 @@ # the cell contains a valid arabic numberal, do the # conversion FIRST -proc validEntry {why win index} { +proc ::sud::validEntry {why win index} { - global cellbgcolorarray cellerrorcolor checkcolor - global invalidfound - global cellarray - global arabicmode + variable cellbgcolorarray + variable cellerrorcolor + variable cellarray + + variable invalidfound + variable arabicmode if {[string equal $why "key"] && !$arabicmode && \ [arabicNineCheck $cellarray($index)]} { @@ -619,7 +648,7 @@ # validate all cells manually # empty arg to validEntry means not due to keystroke(s) -proc validateAll {} { +proc ::sud::validateAll {} { for {set index 0} {$index < 81} {incr index} { validEntry "" .sudoku.board.cellentry$index $index @@ -633,12 +662,15 @@ # use lindex at lowest level to avoid redundant checking -proc checkEntityType {entitytype} { +proc ::sud::checkEntityType {entitytype} { - global celldupcolor - global cellarray - global rows cols squares - global duplicatesfound + variable rows + variable cols + variable squares + variable cellarray + + variable celldupcolor + variable duplicatesfound # don't test non- 1-9 digit elements # start index at one past the element we are testing against @@ -647,7 +679,7 @@ # entity is a list of the cell numbers associated with entity # element and other contain cell numbers under test - foreach entity [subst $$entitytype] { + foreach entity [set $entitytype] { for {set index 0} {$index < 8} {incr index} { set element [lindex $entity $index] for {set undex [expr $index + 1]} {$undex < 9} {incr undex} { @@ -667,10 +699,10 @@ # test all entities for duplicate entries -# if dupes found global duplicatesfound will be set TRUE +# if dupes found variable duplicatesfound will be set TRUE -proc checkAllEntityTypes {} { +proc ::sud::checkAllEntityTypes {} { checkEntityType rows checkEntityType cols @@ -682,12 +714,10 @@ # no invalid entries, no duplicates # error flags set by called routines -proc checkAll {} { - - global duplicatesfound invalidfound +proc ::sud::checkAll {} { - set duplicatesfound FALSE - set invalidfound FALSE + variable duplicatesfound FALSE + variable invalidfound FALSE validateAll checkAllEntityTypes @@ -703,11 +733,10 @@ # make sure we are in arabic mode at start -proc initArabicMode {} { +proc ::sud::initArabicMode {} { - global arabicmode + variable arabicmode TRUE - set arabicmode TRUE .sudoku.buttons.arabicButton configure -relief sunken .sudoku.buttons.kanjiButton configure -relief raised } @@ -715,10 +744,10 @@ # initialize board -proc initBoard {} { +proc ::sud::initBoard {} { - global cellarray - global cellbgcolorarray + variable cellarray + variable cellbgcolorarray for {set cellind 0} {$cellind < 81} {incr cellind} { set cellarray($cellind) "" @@ -733,22 +762,23 @@ # create board # build display grid and initialize background color array -# build global textvariable and background color arrays here - -proc createBoard {} { - - global cellarray cellbgcolorarray - global cellbgcolorA cellbgcolorB cellerrorcolor celldupcolor \ - cellchangedcolor checkcolor +# build textvariable and background color arrays here - # background alternating colors, error colors +proc ::sud::createBoard { + {bgColorA gray} + {bgColorB lightgray} + {errorColor red} + {dupColor orange} + {changedColor white} + {checkColor yellow} +} { - set cellbgcolorA gray - set cellbgcolorB lightgray - set cellerrorcolor red - set celldupcolor orange - set cellchangedcolor white - set checkcolor yellow + variable cellbgcolorA $bgColorA + variable cellbgcolorB $bgColorB + variable cellerrorcolor $errorColor + variable celldupcolor $dupColor + variable cellchangedcolor $changedColor + variable checkcolor $checkColor buildGrid } @@ -756,18 +786,18 @@ # add buttons to main window -proc createButtons {} { +proc ::sud::createButtons {} { button .sudoku.buttons.resetButton -text RESET -font {courrier 12} \ - -bg white -command initBoard + -bg white -command ::sud::initBoard button .sudoku.buttons.checkButton -text CHECK -font {courrier 12} \ - -bg white -command checkAll + -bg white -command ::sud::checkAll button .sudoku.buttons.stepButton -text SOLVE -font {courrier 12} \ - -bg white -command solveStep + -bg white -command ::sud::solveStep button .sudoku.buttons.arabicButton -text 123 -font {courrier 12} \ - -bg white -command allArabic + -bg white -command ::sud::allArabic button .sudoku.buttons.kanjiButton -text \u56db\u4e94\u516d -font {courrier 12} \ - -bg white -command allKanji + -bg white -command ::sud::allKanji set buttons [list .sudoku.buttons.resetButton .sudoku.buttons.checkButton \ .sudoku.buttons.stepButton .sudoku.buttons.arabicButton .sudoku.buttons.kanjiButton] @@ -783,7 +813,7 @@ # for erasing and modifying existing board # also runs check -proc solveStep {} { +proc ::sud::solveStep {} { setBackgroundColors @@ -816,14 +846,14 @@ # build the row column and square associations with the actual # board array, set up the arabic <-> kanji translations -buildAssociations -buildTranslations +::sud::buildAssociations +::sud::buildTranslations # set up and initialize display grid and colors -createBoard -createButtons -initBoard +::sud::createBoard +::sud::createButtons +::sud::initBoard pack .sudoku.board .sudoku.buttons pack .sudoku