#!/bin/sh # # (C) 2005 Markus Triska triska@gmx.at # Public domain code. # # the next line restarts using wish \ exec wish "$0" "$@" set target "" set start "" set current "" set num_moves_necessary 0 set cell_size 25 set colour_0 "#8f5bef" set colour_1 "#17cfcd" proc load_file {file} { global target start num_moves_necessary set whole_object "" set fid [open $file r] while {![eof $fid]} { gets $fid oneline if {[eof $fid]} { break } if {[regexp {^[\n \t]$} $oneline]} { continue } if {$whole_object == "" && [regexp {^%} $oneline]} { continue } append whole_object $oneline if {$whole_object == "" || ![info complete $whole_object]} { continue } eval "array set object {$whole_object}" set whole_object "" if {$object(object) == "target"} { set target "" foreach row $object(value) { lappend target $row } } elseif {$object(object) == "num_moves"} { set num_moves_necessary $object(value) } elseif {$object(object) == "start"} { set start $object(value) } array unset object } if {$whole_object != ""} { error "premature end of file" } close $fid } proc toggle {x y state} { if {$x < 0 || $y < 0 || $y >= [llength $state]} { return $state } if {$x >= [llength [lindex $state 0]]} { return $state } set newval [expr ![lindex [lindex $state $y] $x]] set newstate [lset state $y $x $newval] return $newstate } proc clicked_cell {x y} { global current panel_main target set newstate $current set newstate [toggle [expr $x - 1] [expr $y - 1] $newstate] set newstate [toggle [expr $x] [expr $y - 1] $newstate] set newstate [toggle [expr $x + 1] [expr $y - 1] $newstate] set newstate [toggle [expr $x - 1] $y $newstate] set newstate [toggle $x $y $newstate] set newstate [toggle [expr $x + 1] $y $newstate] set newstate [toggle [expr $x - 1] [expr $y + 1] $newstate] set newstate [toggle $x [expr $y + 1] $newstate] set newstate [toggle [expr $x + 1] [expr $y + 1] $newstate] set current $newstate draw_panel $panel_main $current if {$current == $target} { tk_messageBox -icon info -message "Done, congratulations." -title "Done" } } proc draw_panel {panel state {bind 0}} { global cell_size colour_0 colour_1 $panel delete all set num_y [llength $state] set num_x [llength [lindex $state 0]] set width [expr $num_x * $cell_size] set height [expr $num_y * $cell_size] $panel configure -width $width -height $height for {set i 0} {$i < $num_x} {incr i} { for {set j 0} {$j < $num_y} {incr j} { set x1 [expr $i * $cell_size] set y1 [expr $j * $cell_size] set x2 [expr $x1 + $cell_size] set y2 [expr $y1 + $cell_size] set val [lindex [lindex $state $j] $i] set col "" if {$val} { set col $colour_1 } else { set col $colour_0 } $panel create rect $x1 $y1 $x2 $y2 -tags "$i/$j" -fill $col if {$bind} { $panel bind "$i/$j" "clicked_cell $i $j" } } } } proc reset {} { global panel_main start current set current $start draw_panel $panel_main $current } proc choose_file {} { set file [tk_getOpenFile -defaultextension ".ppn" -filetypes {{Puzpan .ppn} {All *}}] return $file } proc change_file {} { global infile start current panel_target panel_main target set file [choose_file] if {$file == ""} { return } if {[catch [list load_file $file]] != 0} { tk_messageBox -icon info -message "I could not load the file." return } set current $start draw_panel $panel_target $target draw_panel $panel_main $start 1 global moveslbl num_moves_necessary $moveslbl configure -text "Moves necessary: $num_moves_necessary" } # Execution entry point set infile "" if {[llength $argv] > 0} { set infile [lindex $argv 0] } else { set infile [choose_file] } if {[catch [list load_file $infile]] != 0} { tk_messageBox -icon info -message "I could not load the file." -title "Sorry" } set current $start set panel_target [canvas .ptarget] set panel_main [canvas .pmain] set moveslbl [label .moveslbl -text "Moves necessary: $num_moves_necessary"] draw_panel $panel_target $target draw_panel $panel_main $start 1 wm title . "Puzpan" pack $panel_target -padx 10 -pady 10 pack $moveslbl -pady 5 pack $panel_main -padx 10 -pady 10 set f1 [frame .f1] set btnreset [button $f1.reset -text "Reset" -command reset] set btnload [button $f1.load -text "Load..." -command change_file] pack $btnreset -side left -padx 5 pack $btnload -side left -padx 5 pack $f1 -pady 7