Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Get hangman words from text file

by jaffinito34 (Acolyte)
on Dec 04, 2012 at 22:19 UTC ( #1007164=perlquestion: print w/replies, xml ) Need Help??
jaffinito34 has asked for the wisdom of the Perl Monks concerning the following question:

I have this code for hangman however I would like to modify it so that the words come from a text file

#! /usr/bin/perl ###hangman### use strict; my @words = ( "hi", "cat", "home", "country", "computer", "irc", "hat", "wow", "Berlin", "fly", "airplane", "cow", "maps", "make", "run", "sigh", "golf", "running", "hat", "television", "games", "hangman", "pearl", "cat", "dog", "snake", "black", "white", "cabin", "trees", "birds", "animals"); my @hangman = (">", "=", "(", ")", "-", "|", "-", "<"); my $hangman; my @word; my $word; my %found; my $input; #make the input variable global, so all functions can use i +t. &setup; while(1) { #start the game... $input = &getInput; &checkInputAgainstWord; &checkForWord; } exit; sub setup() { $hangman = 0; print "Welcome to hangman, the goal is to guess all the letters in +the word shown!\n"; print "If you guess a wrong letter, you'll see another body part of + this: \n @hangman. If you see all of the body, you lose.\n"; sleep(1); my $number = int( rand( scalar( @words ) ) ); if ($number >= scalar(@words)) { $number -= 1;} #just in case the r +and function is exactly the number of scalars in the words array, thi +s will subtract the number variable by 1 so that it doesn't get an in +dex out-of-bound error. $word = $words[$number]; @word = split //, $word; %found = (); foreach my $char (@word) { $found{$char} = 0; print "_"; } print "\n"; } sub getInput() { my $input; while (length($input) != 1) { $input = <STDIN>; chomp($input); if (length($input) > 1) { print "you entered more than one character.\n"; } } return $input; } sub checkInputAgainstWord() { my $true = 0; foreach my $char (@word) { if ($input =~ m/^$char$/) { $found{$char} = 1; $true = 1; } else { } } if ($true) { &showWord; } else { &showHangman; } } sub showWord() { #show the word with the guessed characters. foreach my $char (@word) { if ($found{$char} == 1) { print $char; } else { print "_"; } } print "\n"; } sub checkForWord() { my $true = 1; foreach my $char (@word) { if ($found{$char} == 1) { } else { $true = 0; } } if ($true==1) { &Won } } sub Won() { print "You got it! play again?y/n\n"; my $answer = <STDIN>; chomp($answer); if($answer =~ m/y/) { &setup; } else { exit; } } sub showHangman() { for (my $i = 0; $i < ($hangman+1); $i++) { print $hangman[$i]; } print "\n"; $hangman++; if ($hangman >= scalar(@hangman)) { &Lost; } } sub Lost() { print "\nYou lost! The word was $word. Play again? y/n\n"; my $input = <STDIN>; chomp($input); if ($input =~ m/y/) { &setup; } else { exit; } }

I was thinking something along the lines of...

open (FILE, '<', 'words.txt'); $count = 0; while ($line = <FILE>){ $Word = split ' ', $line; $listOfWords($count) = $Word; $count += 1;

But I run into errors like "Global symbol "@hangman" requires explicit package name... Any help is appreciated

Replies are listed 'Best First'.
Re: Get hangman words from text file
by kennethk (Abbot) on Dec 04, 2012 at 22:31 UTC

    The error Global symbol "@hangman" requires explicit package name... means that whatever code you are actually running is using strict but does not declare @hangman, perhaps via my or our. You can use diagnostics if you need more clarity on an error message. See Use strict warnings and diagnostics or die. Basic debugging checklist wouldn't hurt either.

    Seeing as your demo code does not emit any errors and there is no such mention in the "along the lines of" code, you need to post the code you are actually running, so we can provide guidance. Your posted code is grossly in line with what you need to do, though my open would likely look more like open my $fh, '<', 'words.txt' or die "Open fail on words.txt: $!\n";

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

Re: Get hangman words from text file
by 2teez (Vicar) on Dec 04, 2012 at 22:56 UTC

    Another thing to check:
    using warnings in your script, shows this Use of uninitialized value $input in numeric ne (!=) at ... line 75. Please check your subroutine getInput.
    Secondly, in my considered opinion, I think it will be better if your subroutine are called without the & in cases like this. Why not just call like this:

    $input = getInput() # and your subroutine are defined as sub getInput{ ... } ...
    Except you know for sure why you are doing otherwise. Please see perlsub for more...

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me
Re: Get hangman words from text file
by rjt (Deacon) on Dec 04, 2012 at 22:34 UTC

    If you put your words on separate lines in the text file (as is usually the case in free dictionaries you can download off the Internet), you can do something like:

    open my $file, '<', 'words.txt' or die "Can't open words: $!"; my @listOfWords = (<$file>); chomp @listOfWords; close $file;

    As for your other error, if you used the exact code in your second block, you actually have round braces instead of the square subscript braces ($listOfWords($count) should be $listOfWords[$count]), and you are missing a closing brace: } at the end of the block. Either of those could cause other errors which might not be obvious if the @hangman error was the first one you saw. In addition to that:

    $Word = split ' ', $line;

    ... will return the count of words found in $line, since $Word is a scalar variable which puts split into scalar context. You would instead write something like:

    push @listOfWords, split(' ', $line);

    (This gets rid of the need for the $count variable.)

Re: Get hangman words from text file
by ww (Archbishop) on Dec 04, 2012 at 22:50 UTC
    Since your existing code (with possible words in the initial array, @words includes both strict and a my declaration of @hangman (and company) the errors message isn't coming from what you've shown us.

    We'll be better able to decipher the problem if you show us the code that actually provokes the error.

    But, for a WAG, I suspect you're trying to populate @hangman from some new code -- perhaps before declaring @hangman. So, yes, amend, emend or update your OP to show us the barest snippet of code which reproduces the problem; we don't need 150 lines, most of it irrelevant to the error you cite.

Re: Get hangman words from text file
by Athanasius (Chancellor) on Dec 05, 2012 at 03:29 UTC

    Just a side note: When populating an array with words, you can save a lot of typing by using qw//:

    my @words = qw( hi cat home country computer irc hat wow Berlin fly airplane cow maps make run sigh golf running hat television games hangman pearl cat dog snake black white cabin trees birds animals );

    See Quote and Quote like Operators.

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1007164]
Approved by ww
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (3)
As of 2018-05-25 03:39 GMT
Find Nodes?
    Voting Booth?