Skip to content

Instantly share code, notes, and snippets.

@totallyuniquelily
Created April 7, 2022 19:37
Show Gist options
  • Save totallyuniquelily/5856e4263f39732743ea623240eeb665 to your computer and use it in GitHub Desktop.
Save totallyuniquelily/5856e4263f39732743ea623240eeb665 to your computer and use it in GitHub Desktop.
(Badly implemented) Sliding block puzzle in Tcl/Tk
#! /bin/env tclsh
package require Tk 8.6
wm geometry . 400x400
font create mainfont -family Consolas -size 40
ttk::style configure TButton -font mainfont
set pre .c.b ; # Button name prefix
# forr {varname ?min? max} ... body
# because c-style for is annoying
proc forr {arg args} {
set varname [lindex $arg 0]
upvar $varname i
set short [expr {[llength $arg]==2}]
set min [expr {$short ? 0 : [lindex $arg 1]}]
set max [expr {$short ? [lindex $arg 1] : [lindex $arg 2]}]
set incr 1; set expr {$i<$max}
if {$max < $min} {
set incr -1; set expr {$i>$max}
}
for {set i $min} $expr {incr i $incr} {
if {[llength $args] > 1} {
uplevel 1 [linsert $args 0 forr]
} {
uplevel 1 [lindex $args 0]
}
}
}
proc init {} {
grid [ttk::frame .c] -sticky nsew
grid columnconfigure . 0 -minsize 200 -weight 1
grid rowconfigure . 0 -minsize 200 -weight 1
forr {i 9} {
set row [expr {$i/3}]
set column [expr {$i%3}]
ttk::button $::pre$i -textvariable ::num$i -command "click $i"
grid $::pre$i -row $row -column $column -sticky nsew
foreach rc {row column} {
grid ${rc}configure .c [set $rc] -minsize 100 -weight 1
}
}
random
}
proc bswap {b1 b2} {
set n1 [set ::num$b1]
set n2 [set ::num$b2]
set ::num$b1 $n2
set ::num$b2 $n1
}
proc hidezero {} {
forr {i 9} {
grid $::pre$i -row [expr {$i/3}] -column [expr {$i%3}] -sticky nsew
}
forr {i 9} { if {![set ::num$i]} { grid forget $::pre$i; break } }
}
proc random {} {
forr {i 9} {set ::num$i $i}
forr {i 9} {
set rand [expr {int(rand()*9)}]
bswap $i $rand
}
hidezero
}
proc click {num} {
forr {i 9} { if {![set ::num$i] } {set zero $i; break} }
set d [expr {abs($num-$zero)}]
set roweq [expr {$num/3 == $zero/3}]
if {($d == 1 && $roweq) || $d == 3} {
bswap $num $zero
hidezero
# checkvictory
}
}
if 0 {
proc checkvictory {} {
set nums {1 2 3 4 5 6 7 8 9 0}
forr {i 9} {
if {[lindex $nums $i] != [set ::num$i]} {return -level 2}
}
puts "You won!"
random
}
}
init
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment