in reply to newbie learning perl

I've reworked your code somewhat. The most important change is to add strictures (use strict; use warnings; - see The strictures, according to Seuss), but I've also added the start of collision detection (which may have an off by 1 bug in it), allowed the number of display rows to be set and refactored the code somewhat (in part to show off some Perl stuff like join and arrays).

This code is not tested because I can't quickly find a working ANSI Terminal emulation for Windows 8.

#!/usr/bin/perl use strict; use warnings; use Term::ANSIScreen qw/:color :cursor :screen/; use Term::ReadKey; my $rows = 50; ReadMode('noecho'); cls; setscroll (1, $rows); locate 1, 1; my @screenRows; # Create the initial screen push @screenRows, newRow() for 1 .. $rows; print join "\n", @screenRows, ''; my $wait = 1; my $skierx = 40; while (1) { if (defined(my $key = ReadKey(-1))) { if ($key eq "j") { --$skierx; } elsif ($key eq "k") { ++$skierx; } elsif ($key eq "x") { exit; } } # Generate and show a new line shift @screenRows; push @screenRows, newRow(); print $screenRows[-1]; # Collision detection if (' ' ne substr $screenRows[$rows / 2], $skierx - 1, 1) { locate $rows, 1; print "Crash!\n"; exit; } # Show skier's updated position locate $rows / 2, $skierx; print "V"; # wait select(undef, undef, undef, $wait); #pauses here $wait -= 0.003; } sub newRow { my $col = int(rand(80)); return ' ' x $col . 'T' . (' ' x (78 - $col)); }
Perl is the programming world's equivalent of English

Replies are listed 'Best First'.
Re^2: newbie learning perl
by Anonymous Monk on Feb 19, 2015 at 18:04 UTC

    Ouch! So much I dont understand. What is the difference between use strict; & use warnings; and the default settings? Is there an advantage to using my when assigning a value?

      If you don't use "strict" and "my" Perl makes any variables you use "global" (it's a little more subtle that that, but the details aren't important for now). As a general thing global variables are bad news because it's hard to tell where their value might change. "my" declares a variable in the local scope and strict enforces that. strict picks up errors that can be detected at compile time before the program runs.

      warnings tell you about dodgy stuff that happens as the program runs, like variables that are used before they have been given a value or using == where eq should be used.

      In Perl scope is important. It controls where a lexical variable (one declared with my) can be used. For example:

      use strict; use warnings; $undeclaredVar = 0; # strict gets grumpy about this because the variab +le isn't declared my $globalVar = 0; # This variable can be used by any following part o +f the code for my $loopVar (1 .. 10) { # In the scope of the for loop. $loopVar can only be used within t +his loop # Loop variables are somewhat magical my $localVar = $loopVar * 3; # This variable is also local to the +loop. It # is a different variable each time through the loop! my $globalVar = $localVar; # Bad! This $globalVar hides the $glo +balVar # declared outside the loop. Reusing variable names like this +is very # bad style! if ($localVar == 9) { my $nestedVar = rand(10); # This variable is only available in +side this # if block. It's not available in the else part or after t +he if } else { my $nestedVar = rand($localVar); # Reusing the name here is ok +, but note # that this is a different variable than the $nestedVar in + the if # block. Note that we can use variables from the encompass +ing # scope in a nested scope. } my @trailingVar; # This array variable isn't available to any earl +ier part # of the program. In general declare variables in as small a s +cope as # you can and initialize them to the first value they should h +ave. # Arrays and hashes are created empty so they don't generally +need an # explicit initial value. } my @anotherGlobal = ('Hello', 'World'); # This global array variable i +sn't # available to the loop code above because it's declared after the + loop. # Note that we can initialize an array variable using a list
      Perl is the programming world's equivalent of English

        I added use strict and use warnings. Yikes, lots of errors. I tried to clean them all up. Down to one I cant figure out. Global symbol "@xloc" requires explicit package name The array xloc is used in 2 locations so generates this warning twice. Each item in the array represents the x location of a T and the location in the array represents the y location. The line: if ($skierx eq $xloc$skiery) {print "CRASH!!!"; exit;} is how I detect that the skier has hit a tree. A different warning said I should use $ instead of @ infront of xloc. I dont get it. I seek the wisdom of the monks.

        #!/usr/bin/perl use strict; use warnings; use Win32::Console::ANSI; use Term::ANSIScreen qw/:color :cursor :screen/; use Term::ReadKey; ReadMode('noecho'); cls; my $col = 0; my $skierx = 40; my $skiery = 0; my $score = 0; my $key = 0; my $wait = .3; my $y = 1; #fill the screen with Ts while ($y < 100) { $col = int(rand(80)); printf ("%${col}s\n", "T"); $y = $y + 1; } $wait = 1; $skierx = 40; $skiery = 0; $y = $y + 5; locate $y,1; print " ------------------------- Ready Set GO! --------------- +----------"; while (1 < 2) { while (not defined ($key = ReadKey(-1))) { # here when no key pressed # place a T and save X location in array, position in array = Y $col = int(rand(80)); $y = $y + 1; $xloc[$y] = $col; locate $y,$col; print "T\n"; # place V $skiery = $y - 50; locate $skiery,$skierx; print "V"; #crash??? if ($skierx eq $xloc[$skiery]) {print "CRASH!!!"; exit;} #score if ($skiery < 105) {locate $skiery,1; print "PRACTICE";} if ($skiery > 105) {$score = $score + 1;locate $skiery,1; print +"$score";} # keep speeding up, reducing pause time select(undef, undef, undef, $wait); #pauses here #$wait = $wait - .005; if ($score eq 50) {$wait = .25;} if ($score eq 100) {$wait = .2;} if ($score eq 150) {$wait = .15;} if ($score eq 200) {$wait = .1;} } # here when key pressed if ($key eq ",") {$skierx = $skierx - 1;} if ($key eq ".") {$skierx = $skierx + 1;} if ($key eq "x") {exit;} } END{ ReadMode('restore'); }