Perl - More than One Secret Word

I took a many and varied path to finally come up with the programming elements that I thought I would need to accomplish the task of having more than one secret word (the homework assignment from the last lesson).  At first I thought a series of separate scalar variables could store multiple secret words with a guess doing a comparison against all of the series.

But then I thought about maintaining the series of secret words, for example, having the secret words change depending upon the day of the week, etc., and that complicated matters.

So then I thought what if I could store all of the possible answers in a list, or (preferably) an array?  What are the odds that Perl would have such a programming element available for me to use?  Pretty good I'd say, off hand!  And, certain enough, we can have each element of the array be a separate scalar variable that can be independently set or accessed.  And, to top it all off, the entire array can also be given a value in one fell swoop!  So, I assigned a value of three possible good "passwords" to an entire array named @words by doing the following:

	@words = ("camel","llama","alpaca");

You'll want to note that array variable names begin with @, so that they are distinct from scalar variable names.

What if you didn't want to write quote marks all the time when setting up your values to load into the list?  There's an operator - qw() (quote word[s]) - that can be used as follows:

	@words = qw(camel llama alpaca);

You'll want to note the spaces that separate the array values (as opposed to the commas when using actual "quotes")! In addition, qw is just one of four "quote operators" that work to automagically "quote" (or 'quote' or `backtick`) strings or string values in a Perl program!

OK, once the array is assigned a value, you can access each element using a subscript reference.  Thus, from our example(s) above, $words[0] is camel, $words[1] is llama, and $words[2] is alpaca.  And, otherwise, the subscript could be an expression as well.  So, if we set $index to 2, then $words[$index] is alpaca.

You'll want to note that subscript references start with $ rather than @ because they refer to a single element of the array rather than the whole array.

Going back to last week's example program and rewriting to take advantage of these new discoveries, here's the code:

#!/usr/bin/perl -w
@words = qw(camel llama alpaca);
print "What is your name? ";
$name = <STDIN>;
chomp ($name);
if ($name eq "Larry") {
	print "Hello, Larry!  How good of you to be here!\n";
}
else {
	print "Hello, $name!\n"; 			# ordinary greeting
	print "What is the secret word? ";
	$guess = <STDIN>;
	chomp ($guess);
	$index = 0; 					# try this word first
	$correct_guess_flag = "maybe";			# is the guess correct or not?
	while ($correct_guess_flag eq "maybe") {	# keep checking until we know
		if ($words[$index] eq $guess) {		# right?
			$correct_guess_flag = "yes";	# yes!
		}
		elsif ($index < 2) {			# more words to look at?
			$index = $index + 1;		# look at the next word next time
		}
		else {
			print "Wrong, try again.  What is the secret word? ";
			$guess = <STDIN>;
			chomp ($guess);
			$index = 0;			# start checking at the first word 
		}					# again
	}						# end of while not correct
	print "Good guess!  Have a great day!!";
}

Note that we are using the scalar variable $correct_guess_flag to indicate that we either have found a good password or we are still looking for one.

Additionally, this program shows the elsif block (note the spelling elsif) of the if-then-else statement.  This exact construct is not present in all programming languages; it's an abbreviation of the else block together with a new if condition, but without nesting inside another pair of curly braces.  It's a very Perl-like thing to compare a set of conditions in a cascaded if-elsif-elsif-elsif-else chain.  Perl doesn't really have the equivalent of C's "switch" or Pascal's "case" structure (although in our advanced Perl workshop we'll build one ourselves [and without too much trouble either]).

Now, in this program, anyone who comes along could guess any of the three words and be successful.  Alrighty, then!  Next lesson, let's see how we can modify this program to allow for a secret word to be different for each person who is given access to the program.  What programming elements do you suppose are required to accomplish this task?