Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Plibbles

by dooberwah (Pilgrim)
on Jul 04, 2001 at 05:08 UTC ( #93745=sourcecode: print w/ replies, xml ) Need Help??

Category: Fun Stuff
Author/Contact Info Ben Jacobs <dooberwah@crosswinds.net>
Description: Plibbles is ment to be much like the clasic worm(6) game, but written in Perl. You control a worm that moves about the screent trying to eat numbers. Whenever you eat a number you grow as many segments longer as the number you ate. The object of the game is to get the hishest score by eating the most numbers without running into something.

Todo:

  • Make worm move forward every 0.25 seconds or so.
  • Document the code
  • Clean up the code

    I'm sure that this isn't the only way to do this, (hey, TMTOWTDI after all) and I'm sure the way I thought up isn't the most efficient way, but it's what I could come up with. Any comments/improvments/questions would be very welcome.

  • #!/usr/bin/perl -w
    
    use strict; 
    use Curses; 
    
    srand( time() ^ ($$ + ($$ << 15)) );
    
    my $score = 0;
    my @worm;
    for (my $i=0; $i < 8; $i++) {
        push @worm, { y => 12,
                      x => 9-$i };
    }
    
    my $w = Curses->new();
    
    noecho();
    
    my $maxy;
    my $maxx;
    $w->getmaxyx($maxy, $maxx);
    $w->clear;
    my $t = $w->subwin(1, $maxx, 0, 0);
    my $o = $w->subwin($maxy-1, $maxx, 1, 0);
    my $growing;
    my %prize;
    
    $t->addstr(0, 1, "Plibbles: A worm game in Perl");
    $t->addstr(0, $maxx-8-length($score), "Score: $score");
    $t->refresh;
    
    $o->box('|', '-');
    
    draw_worm(@worm);
    $o->move($worm[0]{y}, $worm[0]{x});
    prize();
    $o->addstr($prize{y}, $prize{x}, $prize{prize});
    $o->refresh();
    
    while(1) 
    {
        my @oldworm;
        for (my $wormlen = @worm - 1; $wormlen >= 0; $wormlen--) {
            $oldworm[$wormlen]{y} = $worm[$wormlen]{y};
            $oldworm[$wormlen]{x} = $worm[$wormlen]{x};
        }
        for (my $wormlen = @worm - 1; $wormlen > 0; $wormlen--) {
            $worm[$wormlen]{y} = $worm[$wormlen-1]{y};
            $worm[$wormlen]{x} = $worm[$wormlen-1]{x};
        }
        my $key = $o->getch();
        if ($key eq 'h') { 
            $worm[0]{x}--;
        } elsif ($key eq 'j') {
            $worm[0]{y}++;
        } elsif ($key eq 'k') {
            $worm[0]{y}--;
        } elsif ($key eq 'l') {
            $worm[0]{x}++;
        } else {
            @worm = @oldworm;
            $o->clear();
            $o->box('|', '-');
            draw_worm(@worm);
            $o->move($worm[0]{y}, $worm[0]{x});
            next;
        }
        if ($growing != 0) {
            push @worm, $oldworm[scalar(@oldworm)];
            $growing--;
        }
        $o->move($worm[0]{y}, $worm[0]{x});
        my $char = $o->inch();
        if ($char =~ /\d/) {
            $growing += $char;
            $score += $char;
            $t->addstr(0, $maxx-8-length($score), "Score: $score");
            $t->refresh();
            prize();
        }
        elsif ($char ne ' ') { 
            crash(); 
        } 
        $o->clear();
        $o->box('|', '-');
        $o->addstr($prize{y}, $prize{x}, $prize{prize});
        draw_worm(@worm);
        $o->move($worm[0]{y}, $worm[0]{x});
        $o->refresh();
    }
    endwin();
    
    sub draw_worm {
        my @worm = @_;
        my $head = shift @worm;
        $o->addstr($head->{y}, $head->{x}, '@');
        foreach my $segment (@worm) {
            $o->addstr($segment->{y}, $segment->{x}, 'o');
        }
    }
    
    sub crash {
        endwin;
        print "\nWell, you ran into something and the game is over.\n";
        print "Your final score was $score\n\n";
        exit;
    }
    
    sub prize {
        my ($a, $b);
        do {
            $a = rand($maxy-3) + 2;
            $b = rand($maxx-2) + 1;
            $o->move($a, $b);
        } while($o->inch ne ' ');
        my $v = int(rand(9) + 1);
        %prize = ( y => $a, x => $b, prize => $v );
    }
    

    Edit by tye to replace tabs with spaces

    Comment on Plibbles
    Download Code
    Re: Plibbles
    by agoth (Chaplain) on Jul 12, 2001 at 15:05 UTC
      I like it, but any reason you dont indent past one level?
      Is that for perlmonks formatting reasons? otherwise it just makes your code harder to follow? just curious....
      sub draw_worm { my @worm = @_; my $head = shift @worm; $o->addstr($head->{y}, $head->{x}, '@'); foreach my $segment (@worm) { $o->addstr($segment->{y}, $segment->{x}, 'o'); if ($bleh) { #stuff } } }

        FYI (where Y=y'all's), each tab in code becomes 4 spaces in my testing. I'm guessing that The Monastery does that translation.

        I've updated the root node to have spaces instead of tabs.

                - tye (but my friends call me "Tye")

    Back to Code Catacombs

    Log In?
    Username:
    Password:

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

    How do I use this? | Other CB clients
    Other Users?
    Others pondering the Monastery: (3)
    As of 2014-10-02 01:12 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      What is your favourite meta-syntactic variable name?














      Results (41 votes), past polls