de: Das ist das Haus vom Ni- ko- lausIn other languages, these phrases might be used:
en: This is the house of San- ta Claus fr: C'est la mai-son de Saint Ni- cole it: La ca- sa di San Ni- co- la nl: Dat is het huis van Sin- ter- klaas zh: Sheng Ni- gu- la di xiao fang-ziLES has never heard of it, but suggests a Brazilian version:
pt-BR: Ca-si-nha do Pa-pai No-el}
package require Tk#-- A usage message is a good start (and will be used on "?")
 set about {House of Santa Claus
    Powered by Tcl/Tk!
    Richard Suchenwirth 2005
    Draw the outlined house in one continuous move
    by clicking on the edge circles.
    Click "C" to reset.
    Click "<-" to undo the last move.
    Click "!" for a hint.
 }#-- Build the UI proc main {} {
    global g
    array set g {
        edges {AB AC AD BC BD CD CE DE}
        A {60 240} B {220 240} C {220 120} D {60 120} E {140 40}
    }
    pack [canvas .c -width 240 -height 260]
    .c create window 20 20 -window [button .c.? -width 2 -text ? \
        -command {tk_messageBox -message $::about}]
    .c create window 20 50 -window [button .c.c -width 2 -text C \
        -command {reset .c}]
    .c create window 20 80 -window [button .c.<- -width 2 -text <- \
        -command {undo .c}]
    .c create window 20 110 -window [button .c.! -width 2 -text ! \
        -command {hint .c}]
    foreach edge $g(edges) {
        foreach {from to} [split $edge ""] break
        .c create line [concat $g($from) $g($to)] -width 2 -fill white
    }
    foreach node [array names g ?] {
        node .c $node $g($node)
    }
    .c bind node <1> {clicknode .c}
    reset .c
 }#-- Back to square one :) proc reset w {
    global g
    foreach i [array names g incides,?] {unset g($i)}
    foreach edge $g(edges) {
        foreach {from to} [split $edge ""] break
        lappend g(incides,$from) $to
        lappend g(incides,$to)   $from
    }
    $w delete     line
    $w itemconfig node -fill yellow
    set   g(stack) {}
    catch {unset g(last)}
    foreach event [after info] {after cancel $event}
 }#-- Draw a node as circle, with label proc node {w name pos} {
    foreach {x y} $pos break
    $w create oval [expr $x-5] [expr $y-5] [expr $x+5] [expr $y+5] \
        -outline black -tag [list node $name]
    set tx [expr {$x<140? $x-12: $x>140? $x+12: $x}]
    set ty [expr {$y<120? $y-12: $y>120? $y+12: $y}]
    $w create text $tx $ty -text $name
 }#-- Called when a node is selected, by user or [hint] proc clicknode {w {node -}} {
    global g
    set id [$w find withtag [expr {$node eq "-"? "current": $node}]]
    set name [lindex [$w gettags $id] 1]
    if [info exists g(last)] {
        set last $g(last)
        if {$last eq "" || $last eq $name} {return 0}
        if {[lsearch $g(incides,$last) $name]>=0} {
            $w create line [concat $g($last) $g($name)] -width 5 \
                -tag [list line $last$name]
            lappend g(stack) $last$name $name
            set g(last) $name
            $w itemconfig $last -fill yellow
            $w itemconfig $name -fill blue
            $w raise node
            lremove g(incides,$last) $name
            lremove g(incides,$name) $last
            if [done?] {
                tk_messageBox -message "Made it!"
                reset $w
                return 1
            }
        }
    } else {
        set g(last) $name
        $w itemconfig $name -fill blue
    }
    return 0
 }#-- Undo the last move proc undo w {
    global g
    $w itemconfig [lindex $g(stack) end] -fill yellow
    set g(last) [lindex $g(stack) end-2]
    $w itemconfig $g(last) -fill blue
    set lastedge [lindex $g(stack) end-1]
    $w delete $lastedge
    foreach {from to} [split $lastedge ""] break
    lappend g(incides,$from) $to
    lappend g(incides,$to)   $from
    set g(stack) [lrange $g(stack) 0 end-2]
    if {[llength $g(stack)]==0} {unset g(last)}
 }#-- See if the puzzle is completed proc done? {} {
    foreach i [array names ::g incides,*] {
        if {[llength $::g($i)]} {return 0}
    }
    return 1
 }#-- Demonstrate a possible solution proc hint w {
    reset $w
    set node [lpick {A B}]
    while {![done?]} {
        if [clicknode $w $node] break
        update idletasks
        after 1000
        set node [lpick $::g(incides,$node)]
        if {$node eq ""} {after idle hint $w; break}
    }
 }#-- Generally useful routines: proc lremove {_list element} {
    upvar 1 $_list list
    set pos [lsearch $list $element]
    set list [lreplace $list $pos $pos]
 }
 proc lpick list {
    lindex $list [expr int(rand()*[llength $list])]
 }#-- Let the show begin!main#-- Debugging helpers:
 bind . <Escape> {exec wish $argv0 &; exit}
 bind . <F1>     {console show}if 0 {Category Toys | Arts and crafts of Tcl-Tk programming}

