Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You didn't mention which line was line #25! That could be important.</p> <p>However, look at your <code>while</code> statement. Notice you're comparing <code>$guess</code> with <code>$target</code>, but you haven't set <code>$guess</code> yet. That's set <strong><em>inside</em></strong> you're <code>while</code> loop. This is why you're getting the undefined variable.</p> <p>I also don't see where <code>$counter</code> is set. That could also be an issue.</p> <p>Let's look at your <code>while</code> loop a bit closer:</p> <pre><code>while ( $guess &lt; $target ) { blah, blah, blah } </code></pre> <p>Assuming that there's a <code>$guess</code>, you're looping until the user guesses a number bigger than the <code>$target</code>. Is that what you want? No, you stated that you wanted to give the user eight turns, and that's it. What you want is something more along the lines of:</p> <pre><code> my $count = 1; while ( $count &lt;= 8 ) { $count++; blah, blah, blah } </code></pre> <p>A slightly nicer way of doing this is with a for loop:</p> <pre><code>for ( my $count = 1; $count &lt;= 8; $count++ ) { blah, blah, blah } </code></pre> <p>However, these C-style for loops are so passé. Plus, there's a clearer way of doing this using the <code>1..8</code> syntax. This is the same as saying <code>(1, 2, 3, 4, 5, 6, 7, 8)</code>. It's clean and easy to understand:</p> <pre><code> for my $counter (1..8) { blah, blah, blah } </code></pre> <p>(<strong>NOTE</strong>: Some people use a <code>foreach</code> keyword instead of a <code>for</code> keyword when doing this type of loop to distinguish it from the C-Style for loop. However, some people (cough! Damian Conway, cough!) frown upon the use of <code>foreach</code> since it doesn't really add clarity.)</p> <p>Let's look at another aspect of your logic:</p> <pre><code>if ($guess eq $target) { print "\nCongratulations! You guessed the secret number $target in $counter"; } elsif ($guess &gt; $target) { print "\nYour guess, $guess, is too high."; } elsif ($guess &lt; $target) { print "\nYour guess, $guess, is too low."; } else { #Do this if the guess isn't equal to, greater than or less than the target print "You lose. The number was $target."; } </code></pre> <p>When will your <code>else</code> clause be executed? Answer is never. After all, you won't exeucte it unless <code>$guess</code> is neither greater than, equal to, or less than <code>$target</code>. Also, even if you did <em>lose</em>, you're still in that loop.</p> <p>What you probably want to do is to put the <em>You lose</em> line outside the loop. That way, after the eighth guess and your loop ends, you get the <em>You lose</em> spiel.</p> <p>Also, let's look at this line:</p> <pre><code>chomp ( $guess = &lt;&gt; ); print "Enter guess $counter: "; </code></pre> <p>First, the <code>&lt;&gt;</code> is the <em>null filehandle operator</em> which is very, very different from <code>&lt;STDIN&gt;</code>:</p> <blockquote> <p>The null filehandle &lt;> is special: it can be used to emulate the behavior of sed and awk, and any other Unix filter program that takes a list of filenames, doing the same to each line of input from all of them. Input from &lt;> comes either from standard input, or from each file listed on the command line. Here's how it works: the first time &lt;> is evaluated, the @ARGV array is checked, and if it is empty, $ARGV[0] is set to "-", which when opened gives you standard input. The @ARGV array is then processed as a list of filenames.</p> </blockquote> <p>What you want is <code>&lt;STDIN&gt;</code>.</p> <p>Also notice that you are getting the input before you print out your prompt. You really want to do this instead:</p> <pre><code>print "Enter guess $counter: "; chomp ($guess = &lt;STDIN&gt;); </code></pre> <p>Also, you want to set <code>$|</code> to a nonzero value to turn off buffering. Otherwise, you might still have to enter your <code>$guess</code> before you see the prompt.</p> <p>Here's the revised program <code>Modern::Perl</code> doesn't work on my system, so I use the three separate pragmas to cover it:</p> <pre><code>#! /usr/bin/env perl use strict; use warnings; use feature qw(say); use constant { UPPER_RANGE =&gt; 100, MAX_GUESSES =&gt; 8, }; $| = 1; my $target = int ( ( rand UPPER_RANGE ) + 1 ); for my $counter (1..MAX_GUESSES) { print "Enter guess #$counter: "; chomp ( my $guess = &lt;STDIN&gt; ); if ($guess == $target) { say "Congratulations! You guessed the secret number $target in $counter turns"; exit; } elsif ($guess &gt; $target) { say "Your guess, $guess, is too high."; } else { say "Your guess, $guess, is too low."; } } say "You lose. The number was $target."; </code></pre> <p>A few things I didn't cover:</p> <ul> <li>When doing numeric comparisons, use the <code>==</code> operator and not <code>eq</code> which is for strings.</li> <li>I use <code>say</code> instead of <code>print</code> when I can. The <code>say</code> command is like <code>print</code> except it automatically puts a NL on the end for me.</li> <li>Notice the <code>exit;</code> after I stated you won. I want to end my program at that point.</li> <li>Notice I don't declare all of my variables until I need them. In my program, <code>$guess</code> and <code>$counter</code> only exists inside the <code>for</code> loop while <code>$target</code> exists both inside and outside the <code>for</code> loop.</li> <li>I <code>use constant</code> to help avoid <em>mysterious</em> numbers. For example, <code>1..MAX_GUESSES</code> helps me understand that the loop is going to my maximum guess while <code>1..8</code> doesn't explain why I'm going to 8. Also, I can simply change my constant and suddenly you have 10 changes of guessing a number between 1 and 1000.</li> </ul>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload