Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

tk-picture-scramble-puzzle

by zentara (Archbishop)
on Apr 09, 2004 at 16:25 UTC ( [id://343941]=CUFP: print w/replies, xml ) Need Help??

This was ripped off from the Tk widget demo, but modified by me to run standalone, and with a gif or jpg of your choice. I had it laying around and this node -> Keep the kids amused prompted me to post it.
#!/usr/bin/perl -w #updated April 20,2004 to accept a gif or jpg. # # This program is described in the Perl/Tk column from Volume 1, Issue + 4 of # The Perl Journal (http://tpj.com/tpj), and is included in the Perl/T +k # distribution with permission. # It has been modified by zentara to run outside the widget demo, # and use any gif image use Tk; use Tk::Dialog; use strict; use subs qw(beep create_puz create_ui puz_fini move_piece new_puz rand +omly xy); use Tk::JPEG; my $IMAGE; # gif or jpg Photo image my $IMAGE_HEIGHT; # image height my $IMAGE_WIDTH; # image width my (@LEVELS) = (9, 16, 36, 64); # possible puzzle piece counts my $MW = MainWindow->new; # program's main window my @ORDER; # random puzzle piece ordinals my $PIECES = $LEVELS[2]; # total puzzle piece count my $OLD_PIECES = -1; # previous puzzle piece count my $PF; # puzzle Frame my @PUZ; # puzzle piece information my $SIDE; # pieces per side of puzzle my $SPACE; # shortcut to puzzle space piece my $SPACE_IMAGE; # space piece image my $mf; # menubar my $file = shift || die "need gif or jpg graphic image $!"; my $update = 0; create_ui; create_puz; sub beep {$MW->bell} sub create_puz { return if $PIECES == $OLD_PIECES; if (Exists $PF) { my $image; foreach (@PUZ) { $image = $_->cget(-image); $image = $SPACE_IMAGE if not defined $image; $image->delete; } $PF->destroy; } $PF = $MW->Frame->grid; # create the puzzle frame grid master $OLD_PIECES = $PIECES; $#PUZ = $#ORDER = $PIECES - 1; $SIDE = sqrt $PIECES; my($i, $o, $c, $r, $w, $h, $x, $y, $but, $gif); foreach (0..$#ORDER) {$ORDER[$_] = [$_, undef]} for($i = 0; $i <= $#PUZ; $i++) { $o = $ORDER[$i]->[0]; ($c, $r) = xy $o; # puzzle ordinal to column/row $w = $IMAGE_WIDTH / $SIDE; $h = $IMAGE_HEIGHT / $SIDE; $x = $c * $w; # x/column pixel offset $y = $r * $h; # y/row pixel offset $gif = $PF->Photo; # new, empty, GIF image $gif->copy($IMAGE, -from => $x, $y, $x+$w, $y+$h); $but = $PF->Button(-image => $gif, -relief => 'flat', -borderwidth => 0, -command => \&beep, -highlightthickness => 0, ); $PUZ[$o] = $but; ($c, $r) = xy $i; $but->grid(-column => $c, -row => $r, -sticky => 'nsew'); if ($o == 0) { $SPACE_IMAGE = $gif; $SPACE = $but; } } # forend all puzzle pieces } # end create_puz sub create_ui { # Create a color Photo image of the Xcamel puzzle. $IMAGE = $MW->Photo(-file => $file); $IMAGE_WIDTH = $IMAGE->image('width'); $IMAGE_HEIGHT = $IMAGE->image('height'); # Create the menubar. if($update == 1){ $MW->update} else{ $mf = $MW->Frame(-bg => 'blue')->grid(-sticky => 'ew'); $mf->gridColumnconfigure(1, -weight => 1); } my $mbf = $mf->Menubutton(-text => 'File', -relief => 'raised'); $mbf->command(-label => 'New Puzzle', -command => \&new_puz); $mbf->separator; $mbf->command(-label => 'Quit', -command => sub {Tk::exit}); my $mbp = $mf->Menubutton(-text => 'Prefs', -relief => 'raised'); my $pieces = 'Pieces'; $mbp->cascade(-label => $pieces); my $mbpm = $mbp->cget(-menu); my $mbpmp = $mbpm->Menu; $mbp->entryconfigure($pieces, -menu => $mbpmp); foreach (@LEVELS) { $mbpmp->radiobutton(-label => $_, -variable => \$PIECES, -value => $_, -command => sub{ $update = 1; &create_ui; &create_puz }, ); } my $mbq = $mf->Menubutton(-text => 'Help', -relief => 'raised'); my $about = $MW->Dialog(-text => <<"END" npuz Version 1.0\n Select \"File/New Puzzle\", then click around the red \"space\" to rea +rrange the pieces an END ); $about->configure(-wraplength => '6i'); $mbq->command(-label => 'About', -command => [$about => 'Show']); $mbf->grid(-row => 0, -column => 0, -sticky => 'w'); $mbp->grid(-row => 0, -column => 1, -sticky => 'w'); $mbq->grid(-row => 0, -column => 2, -sticky => 'e'); } # end create_ui sub puz_fini { # Return true iff all puzzle pieces are in order. my($i, $c, $r, %info); for($i = 0; $i <= $#PUZ; $i++) { ($c, $r) = xy $i; %info = $PUZ[$i]->gridInfo; return 0 if $c != $info{-column} or $r != $info{-row}; } return 1; } # end puz_fini sub move_piece { my($piece) = @_; my(%info, $c, $r, $sc, $sr); %info = $piece->gridInfo; ($c, $r) = @info{-column,-row}; %info = $SPACE->gridInfo; ($sc, $sr) = @info{-column,-row}; if ( ($sr == $r and ($sc == $c-1 or $sc == $c+1)) or ($sc == $c and ($sr == $r-1 or $sr == $r+1)) ) { $SPACE->grid(-column => $c, -row => $r); $piece->grid(-column => $sc, -row => $sr); } if (puz_fini) { my $color = ($SPACE->configure(-activebackground))[3]; $SPACE->configure(-image => $SPACE_IMAGE, -activebackground => $color, -background => $color, -relief => 'flat', ); foreach (@PUZ) {$_->configure(-command => \&beep)} } } # end move_piece sub new_puz { srand time; foreach (0..$#ORDER) {$ORDER[$_]->[1] = rand $#ORDER} my @order = sort randomly @ORDER; #@order = @ORDER; # here's how I solve the puzzle (; my($i, $o, $c, $r, $but); for($i = 0; $i <= $#PUZ; $i++) { $o = $order[$i]->[0]; $but = $PUZ[$o]; if ($o == 0) { $but->configure(-background => 'red', -relief => 'sunken', -image => undef, -activebackground => 'red', ); } else { $but->configure(-command => [\&move_piece, $but]); } ($c, $r) = xy $i; $but->grid(-column => $c, -row => $r, -sticky => 'nsew'); } } # end new_puz sub randomly {$a->[1] <=> $b->[1]} # randomize order of puzzle pieces sub xy {my($n) = @_; ($n % $SIDE, int $n / $SIDE)} # ordinal to X/Y MainLoop;

Replies are listed 'Best First'.
Re: tk-picture-scramble-puzzle
by muralikrishna (Initiate) on Apr 20, 2004 at 12:21 UTC
    Nice job zentata. This does not read JPEGs, what needs to be done for that???
      Put use Tk::JPEG; on top of the script and install the Tk::JPEG or Tk::JPEG::Lite module from CPAN or via PPM. With Tk804.* Tk::JPEG is already part of the standard Tk module set.
Re: tk-picture-scramble-puzzle
by zentara (Archbishop) on Apr 20, 2004 at 14:19 UTC
    Yeah, that's easy to do, like eserte shows. I will modify the snippet. :-)

    I'm not really a human, but I play one on earth. flash japh
      But I think the existance of Tk::JPEG should be optional, e.g. with these lines:
      eval q{ use Tk::JPEG }; warn "No JPEG support" if $@; eval q{ use Tk::PNG }; warn "No PNG support" if $@; eval q{ use Tk::TIFF }; warn "No TIFF support" if $@;
      with ot without the warnings...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://343941]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2024-04-19 21:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found