Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

Tk: pair matching game

by sanPerl (Friar)
on Jan 07, 2007 at 14:59 UTC ( #593400=CUFP: print w/replies, xml ) Need Help??

Dear All,
I wanted to create some educational games for my child. I created this pair matching game. I would like to share it with you all. The rules of the game are very simple
1) Store this code in one folder. Create a folder 'images' and store 35 gif images of approx 40x40 dimensions. (For 70 squares you need 35 images)
2) start it using command 'perl', which will display 70 buttons.
3) Click each button and try to find it match.
4) if you are able to find match then the picture on the button will remain constant or else it will vanish.
Please enjoy the game, since it was done as a passtime excersize the code is Not properly commented. Please forgive me for this. Do let me know your views.
code for ''
use strict; use Tk; use Tk::Button; use Tk::Canvas; use Tk::Photo; use Tk::Splashscreen; #use fileoprn; require Tk::Splash; ##################### my @filearray; opendir( DIR, 'images' ) or die "Can't open images DIR $!"; while ( my $entry = readdir( DIR ) ) { my $type = ( -d "images\\$entry" ) ? "dir" : "file"; push @filearray, "images\\$entry" if (($type eq "file") && ($e +ntry =~ /\.gif$/)); #print "$type\t$entry\t@filearray\n"; } closedir( DIR ); @filearray = (@filearray,@filearray); #################### fisher_yates_shuffle(\@filearray); unshift @filearray, "NIL"; #foreach (@filearray) {print $_,"\n";}; my @arranged_gifs; my $top = new MainWindow(); my $loop_cntr=0; my $state_of_button=-1; my $prev_x = undef; my $prev_y = undef; my $number_of_clicks=0; my $prev_clicked_button=undef; my $button_width= 10; my $button_height= 3; foreach my $x (1..10) { for my $y (1..7) { $loop_cntr++; $arranged_gifs[$x][$y]= $filearray[$loop_cntr]; #print "$loop_cntr:$x:$y:-".$arranged_gifs[$x][$y]."\t".$filea +rray[$loop_cntr]."\n"; my $button = $top->Button(-width => $button_width,-background= +>'yellow', -height =>$button_height,-command=>sub{click_button($x,$y, +\$top->gridSlaves(-row=>$x,-column=>$y), \$prev_clicked_button)}); $button->configure(-text=>'Hey'); $button->grid(-row =>$x , -column =>$y); } } sub click_button($$$){ my ($myx,$myy,$clicked_button,$prev_clicked_button)=@_; if (!${$clicked_button}->cget(-image)) { $number_of_clicks++; my $mywait; my $image = $top->Photo(-format => 'gif' , -file=>$arranged_gi +fs[$myx][$myy]); ${$clicked_button}->configure(-width => 50, -height =>40, -ima +ge=>$image); if ($number_of_clicks == 1) { print "Hello\n"; ${$prev_clicked_button} = ${$clicked_button}; } if ($number_of_clicks == 2) { print "pair\n"; #sleep(2); $number_of_clicks=0; print "#".$arranged_gifs[$myx][$myy]."#". $arranged_gifs[$ +prev_x][$prev_y]."\n"; if ($arranged_gifs[$myx][$myy] ne $arranged_gifs[$prev_x][ +$prev_y]) { ${$prev_clicked_button} -> after (250, [\&hide, ${$pre +v_clicked_button} ]); ${$clicked_button} -> after (250, [\&hide, ${$cli +cked_button}]); } else { print "Got it\n"; } } $prev_x = $myx; $prev_y = $myy; } } sub hide { shift -> configure (-width => $button_width, -height =>$button_hei +ght, -state=>'normal',-image => undef); } sub fisher_yates_shuffle { my $array = shift; my $i; for ($i = @$array; --$i; ) { my $j = int rand ($i+1); next if $i == $j; @$array[$i,$j] = @$array[$j,$i]; } } MainLoop;

Replies are listed 'Best First'.
Re: Tk: pair matching game
by zentara (Archbishop) on Jan 07, 2007 at 18:16 UTC
    Just some comments to help improve your code. :-)

    1. If you would put

    use Tk::JPEG; use Tk::Png;
    in your code, you could extend your filetypes easily, to include gif, jpg, and png.

    2. It is a burden on the user to make 70 '40x40' files. It would be easy for you to allow any images in the images dir, and have your program make thumbnails automatically.

    3. I didn't have the Splash modules installed, nor did I have 70 images handy, so I couldn't run this, but from looking at your code, I suspect there may be a memory gain when you run this. Have you watched the memory while running?

    The reason I suspect this, is that you create a new Photo object in your button's click callback. These Photo objects will hang around in memory. If I was to do this, I would make photo-objects for each thumbnail just once at the start of the script, base64encode them, and stuff them into a hash. Then on your button clicks, just pull the right photo-object out of the hash. To see an example of this , see Tk ImageMap-color-zones

    P.S. I've noticed that the most recent version of Imager causes a problem with that node's code. I'll figure it out an post a fix when I find the problem.

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
      Thanks for your suggestions. Yes I should watch for memory usage also.
Re: Tk: pair matching game
by Tux (Abbot) on Jan 07, 2007 at 17:58 UTC
    BTW Not to criticize the shuffle, but List::Util has a standard shuffle method available
    use List::Util qw( shuffle ); my @list = shuffle 0 .. 51; # shuffle the deck of cards
    FYI List::Util was first released with perl 5.007003 so it is safe to use it in 5.8.x. It is not in 5.6.2, but available on CPAN.
      Good suggestion. I was Not aware of 'shuffle' utility. It will reduce LOC of my next codes indeed.
Re: Tk: pair matching game
by jettero (Monsignor) on Jan 07, 2007 at 15:28 UTC

    I have bookmarked this, because it does some things I find interesting. I find that it's a little windows centric though. You might (or perhaps I might) benefit from using some things like File::Find, Getopt::Std, or Getopt::Long to make it so I can specify the location of the images and so the windows dirnames don't cause trouble on my linux box.

    (I also think this node might have gone under the code section, but I don't feel strongly enough about it to "consider" the node.)


Re: Tk: pair matching game
by Tux (Abbot) on Jan 07, 2007 at 17:39 UTC
    An alternative approach could be to have n images, and know which are the pairs by displaying each image twice in the grid. That way, you can take the images away when a pair is made, and not rely on user actions.
    Nice application idea for kids.
      I made a mistake in my instructions as I said that we have to use 70 images. We need to use 35 images. Thanks for pointing this mistake. I have updated my sets of instructions.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://593400]
Approved by jettero
Front-paged by liverpole
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (4)
As of 2017-02-26 20:41 GMT
Find Nodes?
    Voting Booth?
    Before electricity was invented, what was the Electric Eel called?

    Results (376 votes). Check out past polls.