http://www.perlmonks.org?node_id=1006606

chickenlips has asked for the wisdom of the Perl Monks concerning the following question:

Basically, I have a set of scores that will be pushed into an array each time the program loops (i.e. the person says they want to play again) This is my code so far:
print "Your final score is: $score_total\n\n"; # score organiser. print "Please enter your initials for the high score table: \n"; chomp (my $initial_add = <STDIN>); my @initials_array = (); push (@initials_array, $initial_add); my @score_array = ($score_total); push (@score_array, $score_total); print "Name = $initials_array[0]\tScore = $score_array[0]\n"; print "Initials \t Score \n";
It is worth noting that the variable $score_total is the score from an earlier bit of code, every time this bit finishes and the $score_total is pushed into @score_array, the $score_total gets intialized to 0 again so a new score can be added. How can I go about putting this in a high scores table that is displayed as the above code part : print "Name = $initials_array[0]\tScore = $score_array[0]\n"; I want it to add the scores each time the game is played so that the high scores table gets more populated. THANKS IF ANYONE CAN HELP!!

Replies are listed 'Best First'.
Re: Making a dynamic high scores table
by Athanasius (Archbishop) on Dec 01, 2012 at 16:14 UTC

    When you declare a variable with my, you initialise it. If you do this inside a loop, the variable is re-initialised on each loop iteration. But if you want the variable to grow as the loop iterates, you need to declare it once only, before the loop:

    my @initials; my @scores; while (...) # The major loop { ... push @initials, $initial_add; push @scores, $score_total; ... } # access @initials and @scores here

    Hope that helps,

    Athanasius <°(((><contra mundum

Re: Making a dynamic high scores table
by roboticus (Chancellor) on Dec 01, 2012 at 17:20 UTC

    chickenlips:

    I'd suggest storing the high score list in a file so that when you restart the game, you still have the original values. So your subroutine to save & display high scores might be something like:

    1. Read high-score-list file
    2. Add new score, initials
    3. Sort list
    4. Display
    5. Write back new high-score-list to file

    Optionally, if you want to keep only the top X scores, then after sorting, just write the first X items back to the new file. Also, to prevent a program problem from causing you to lose the entire list, write the new list to a different file. Once you're done, then you can rename the original to original.bak, and then rename the new file to the original name.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: Making a dynamic high scores table
by space_monk (Chaplain) on Dec 01, 2012 at 16:32 UTC

    Just to say that programs that play games don't typically "loop"; they are normally state driven and respond to events instead. The only "loop" is the one containing the event handler(s).

    I'm not saying you can't have a loop to restart the game, but it ain't a good way to continue...

    A Monk aims to give answers to those who have none, and to learn from those who know more.
Re: Making a dynamic high scores table
by kcott (Archbishop) on Dec 02, 2012 at 08:35 UTC

    G'day chickenlips,

    Here's a solution using Tie::File which allows you to keep track of high scores within and between instances of your program running.

    #!/usr/bin/env perl use strict; use warnings; use Tie::File; use constant MAX_HIGH_SCORES_TO_SHOW => 10; my $high_score_data_file = './pm_high_score.dat'; tie my @high_scores, 'Tie::File', $high_score_data_file or die $!; while (1) { print 'Initials (or Return to end): '; chomp (my $initials = <>); last unless length $initials; my $random_score = 1 + int rand 100; print "Random score: $random_score\n"; print "<<<<<<< Before Adding:\n"; display_high_scores(\@high_scores, MAX_HIGH_SCORES_TO_SHOW); add_high_score(\@high_scores, $random_score, $initials); print ">>>>>>> After Adding:\n"; display_high_scores(\@high_scores, MAX_HIGH_SCORES_TO_SHOW); } untie @high_scores; sub add_high_score { my ($high_scores_ref, $score, $name) = @_; my $record = @$high_scores_ref; for (0 .. $#$high_scores_ref) { if ((split /\s+/, $high_scores_ref->[$_])[0] < $score) { $record = $_; last; } } splice @$high_scores_ref, $record, 0, join ' ' => $score, $name; return; } sub display_high_scores { my ($high_scores_ref, $max_to_show) = @_; $max_to_show = MAX_HIGH_SCORES_TO_SHOW unless defined $max_to_show +; $max_to_show = @$high_scores_ref if $max_to_show > @$high_scores_r +ef; my $printf_pattern = "%-5d %s\n"; print "High Score Table\n"; for (0 .. $max_to_show - 1) { printf $printf_pattern => split /\s+/, $high_scores_ref->[$_], + 2; } return; }

    Here's a sample run:

    $ cat pm_high_score.dat cat: pm_high_score.dat: No such file or directory $ pm_high_score.pl Initials (or Return to end): AA Random score: 82 <<<<<<< Before Adding: High Score Table >>>>>>> After Adding: High Score Table 82 AA Initials (or Return to end): BB Random score: 69 <<<<<<< Before Adding: High Score Table 82 AA >>>>>>> After Adding: High Score Table 82 AA 69 BB Initials (or Return to end): $ cat pm_high_score.dat 82 AA 69 BB ... ran several times to exceed MAX_HIGH_SCORES_TO_SHOW ... High Score Table 90 II 90 LL 85 DD 82 AA 81 EE 69 BB 56 CC 55 GG 39 JJ 23 FF Initials (or Return to end): $ cat pm_high_score.dat 90 II 90 LL 85 DD 82 AA 81 EE 69 BB 56 CC 55 GG 39 JJ 23 FF 22 KK 18 HH 16 MM

    -- Ken

Re: Making a dynamic high scores table
by Anonymous Monk on Dec 01, 2012 at 15:30 UTC

    You fill in the blanks

    sub ShowScore { }
Re: Making a dynamic high scores table
by Anonymous Monk on Dec 01, 2012 at 15:43 UTC
    Can you write loop that adds items onto an array?