perl newbie. hangman.cgi script displaying strangely (additional code) on the web.
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
perl newbie. hangman.cgi script displaying strangely (additional code) on the web.
Hi all,
I'm a newbie trying to learn perl and cgi. I have written a script which you can find here. There are several problems.[list=1][*]When you first arrive at that url, you'll notice that there is additional html-like code visible on the page, as well as an extra "New Game" button. Why are those visible?[*]You'll also notice that when you first arrive at that url, the game doesn't actually work. You can input letters, but nothing happens when you guess.[*]If you click one of the "New Game" buttons, though, it will THEN start a "working" game! Why doesn't it just do that from the get-go?[*]Even when a new game is started, you only get 9 tries for letters, not 10. Why?[*]When you complete a game (win or lose), it should flash text saying "Sorry (or Congratulations), you're word was 'whatever'. It does, but it also adds more of that html-like code there. Why?[*]The "letter-guessing" line is solid. How can I make it dashed, so that each dash represents a letter in the word?[*]If at that point you start a new game, the last letter you guessed on the previous game starts off as a newly-chosen letter for the new game. Why?[/list=1]
I think that's it for problems. Any ideas would be most appreciated! Thank you so much! Here's the code the the perl/cgi script:
Code:
#!/usr/bin/perl
use CGI ':standard';
use CGI::Carp 'fatalsToBrowser';
use Fcntl;
use SDBM_File;
$max_tries = 10;
%current = ( 'word' => "evermeet",
'tries_left' => "10",
'letters' => "",
'revealed' => "________",);
tie(%hash, 'SDBM_File', '/tmp/game_file.sdbm', O_CREAT|O_RDWR, 0666) || die $!;
&PrintHeader();
my $tries_left = $current{'tries_left'};
my @guessed_letters = split( //, $current{'letters'} );
my $secret_word = $current{'word'};
my $revealed_word = $current{'revealed'};
my $this_guess = "";
my $guessed_string = "";
my $found_letter = 0;
$this_guess = param('guess');
$found_letter = &GuessLetter($this_guess);
if( $tries_left > 0 ) {
if( ($current{'word'} eq $current{'revealed'}) && ($tries_left < $max_tries) )
{
&PrintContent();
&win();
}
else {
if( $found_letter == 0 ) {
$tries_left--;
}
push(@guessed_letters, $this_guess );
$guessed_string = join( "", @guessed_letters );
$current{'tries_left'} = $tries_left;
$current{'letters'} = $guessed_string;
&PrintContent();
$hash{$id} = $current{'word'}."~".$current{'tries_left'}."~". $current{'letters'}."~".$current{'revealed'};
}
}
else {
&PrintContent();
&lose();
}
untie(%hash);
sub generate_gameid() {
for ($j = 0; $j <= 9; $j++) {
$id .= int(rand 9);
}
return $id;
}
sub win {
my $the_cookie = cookie ( -name=>'gameid',
-value=>$id,
-expires=>'+1h');
print header(-cookie=>$the_cookie),
start_html("Hangman - Congratulations!"),
"Congratulations, your word was:",
h2($current{'word'}),
start_form,
submit (-name=>"new_game", -label=>"New Game"),
end_form,
end_html;
}
sub lose
{
my $the_cookie = cookie ( -name=>'gameid',
-value=>$id,
-expires=>'+1h');
print header(-cookie=>$the_cookie),
start_html("Hangman - Sorry!"),
"Sorry, your word was:",
h2($current{'word'}),
start_form, submit (-name=>"new_game", -label=>"New Game"),
end_form,
end_html;
}
sub PrintHeader() {
my $the_cookie;
my $saved_game;
if(param('new_game')) {
$id = &generate_gameid();
$the_cookie = cookie ( -name=>'gameid',
-value=>$id,
-expires=>'+1h');
&InitGame();
}
else {
$id = cookie('gameid');
$saved_game = $hash{$id};
&LoadGame($saved_game);
}
print header(-cookie=>$the_cookie);
}
sub PrintContent() {
print start_html( -title=>"Hangman!", -onLoad=>"document.forms[0].guess.select()"),
h1("Hangman!"),
h1($current{'revealed'}),
"Tries Remaining: ",
b($current{'tries_left'}),
br,
"Letters guessed so far: ",
b(em(join " ", split //, $current{'letters'})),
br,
start_form,
"Next Guess: ",
textfield ( -name=>"guess", -size=>5, -maxlength=>1, -default=>''),
br, br,
submit (-name=>"submit", -label=>"Guess"),
submit (-name=>"new_game", -label=>"New Game"),
end_form,
end_html;
}
sub InitGame() {
my $word = &FetchWord();
$current{'word'} = $word;
$current{'tries_left'} = $max_tries;
$current{'letters'} = "";
$current{'revealed'} = &MakeLines($word);
}
sub LoadGame() {
my $foo = $_[0];
my @saved_game = split(/~/,$foo);
$current{'word'} = $saved_game[0];
$current{'tries_left'} = $saved_game[1];
$current{'letters'} = $saved_game[2];
$current{'revealed'} = $saved_game[3];
}
sub FetchWord() {
my $word = "superman";
my @lines;
my @words;
my $line_count = 0;
my $word_count = 0;
my $rand_line = 0;
my $rand_word = 0;
open( DICTIONARY, "words.txt" ) or die "Cannot open file: $!\n";
@lines = <DICTIONARY>;
$line_count = @lines;
$rand_line = int(rand $line_count);
@words = split(/,/, $lines[$rand_line] );
$word_count = @words;
$rand_word = int(rand $word_count);
$word = $words[$rand_word];
chomp($word);
close( DICTIONARY );
return $word;
}
sub MakeLines() {
my @word = split(//, $_[0]);
my $letter = "";
my $blanks = "";
foreach $letter(@word) {
$blanks .= "_";
}
return $blanks;
}
sub GuessLetter() {
my $guess = $_[0];
my @word = split(//,$current{'word'});
my $letter = "";
my @old_revealed = split(//,$current{'revealed'});
my @new_revealed = @old_revealed;
my $new_revealed_string = "";
my $got_one = 0;
my $count = 0;
foreach $letter(@word) {
if($guess eq $letter) {
print LOG "Matched letter [$guess] at position [$count]\n";
$new_revealed[$count] = $guess;
$got_one = 1;
}
else {
$new_revealed[$count] = $old_revealed[$count];
}
$count++;
}
$new_revealed_string = join("",@new_revealed);
$current{'revealed'} = $new_revealed_string;
return $got_one;
}
Again, I'm a newbie, so please be gentle! Thanks, guys!
Chris
Last edited by WorldBuilder; 11-11-2003 at 12:22 PM.
Ok, I have fixed everything regarding this script, except for one final thing... When first visiting the site, it says:
"Sorry, your word was:"
New Game button
If I then press the "New Game" button, that game starts and works fine.
I don't understand why it doesn't go directly to a new, working game. Can anyone help me with that? I've been pulling my hair out for a while on this one. URL is http://www.bartlett-family.net/cgi-bin/hangman2.cgi
New code:
Code:
#!/usr/bin/perl
use CGI ':standard';
use CGI::Carp 'fatalsToBrowser';
use Fcntl;
use SDBM_File;
$max_tries = 10;
%current = ('tries_left' => 10, 'letters' => '', 'revealed' => '________');
tie(%hash, 'SDBM_File', '/tmp/game_file.sdbm', O_CREAT|O_RDWR, 0666) || die $!;
&PrintHeader();
my $tries_left = $current{'tries_left'};
my @guessed_letters = split( //, $current{'letters'} );
my $secret_word = $current{'word'};
my $revealed_word = $current{'revealed'};
my $this_guess = 0;
my $guessed_string = "";
my $found_letter = 0;
$this_guess = param('guess');
$found_letter = &GuessLetter($this_guess);
if( $tries_left-1 > 0) {
if( ($current{'word'} eq $current{'revealed'}) && ($tries_left <= $max_tries) ) {
#&PrintContent();
&win();
}
else {
if( $found_letter == 0 && $this_guess) {
$tries_left--;
}
push(@guessed_letters, $this_guess);
$guessed_string = join( "", @guessed_letters);
$current{'tries_left'} = $tries_left;
$current{'letters'} = $guessed_string;
&PrintContent();
$hash{$id} = $current{'word'}."~".$current{'tries_left'}."~". $current{'letters'}."~".$current{'revealed'};
}
}
else {
#&PrintContent();
&lose();
}
untie(%hash);
exit(0);
sub generate_gameid() {
for ($j = 0; $j <= 9; $j++) {
$id .= int(rand 9);
}
return $id;
}
sub win {
#my $the_cookie = cookie ( -name=>'gameid',
# -value=>$id,
# -expires=>'+1h');
#print header(-cookie=>$the_cookie),
print start_html("Hangman - Congratulations!"),
"Congratulations, your word was:",
h2($current{'word'}),
start_form,
submit (-name=>"new_game", -label=>"New Game"),
end_form,
end_html;
}
sub lose {
#my $the_cookie = cookie ( -name=>'gameid',
# -value=>$id,
# -expires=>'+1h');
#print header(-cookie=>$the_cookie),
print start_html("Hangman - Sorry!"),
"Sorry, your word was:",
h2($current{'word'}),
start_form, submit (-name=>"new_game", -label=>"New Game"),
end_form,
end_html;
}
sub PrintHeader {
my $the_cookie;
my $saved_game;
if(param('new_game')) {
$id = &generate_gameid();
$the_cookie = cookie ( -name=>'gameid',
-value=>$id,
-expires=>'+1h');
&InitGame();
}
else {
$id = cookie('gameid');
$saved_game = $hash{$id};
&LoadGame($saved_game);
}
print header(-cookie=>$the_cookie);
}
sub PrintContent {
print start_html( -title=>"Hangman!", -onLoad=>"document.forms[0].guess.select()"),
h1("Hangman!"),
h1({-style=>'letter-spacing:5px'},$current{'revealed'}),
"Tries Remaining: ",
b($current{'tries_left'}),
br,
"Letters guessed so far: ",
b(em(join " ", split //, $current{'letters'})),
br,
start_form,
"Next Guess: ",
textfield ( -name=>'guess', -size=>5, -maxlength=>1, -default=>'', override=>1),
submit (-name=>'submit', -label=>'Guess'),br,br,
submit (-name=>'new_game', -label=>'New Game'),
end_form,
end_html;
}
sub InitGame {
my $word = &FetchWord();
$current{'word'} = $word;
$current{'tries_left'} = $max_tries;
$current{'letters'} = "";
$current{'revealed'} = &MakeLines($word);
}
sub LoadGame {
my $foo = $_[0];
my @saved_game = split(/~/,$foo);
$current{'word'} = $saved_game[0];
$current{'tries_left'} = $saved_game[1];
$current{'letters'} = $saved_game[2];
$current{'revealed'} = $saved_game[3];
}
sub FetchWord {
#my $word = "superman";
my @lines;
my @words;
my $line_count = 0;
my $word_count = 0;
my $rand_line = 0;
my $rand_word = 0;
open( DICTIONARY, "words.txt" ) or die "Cannot open file: $!\n";
@lines = <DICTIONARY>;
close( DICTIONARY );
$line_count = @lines;
$rand_line = int(rand $line_count);
@words = split(/,/, $lines[$rand_line] );
$word_count = @words;
$rand_word = int(rand $word_count);
$word = $words[$rand_word];
chomp($word);
return $word;
}
sub MakeLines {
my $blanks;
$blanks .= "_" for (1..length($_[0]));
return $blanks;
}
sub GuessLetter {
my $guess = $_[0];
my @word = split(//,$current{'word'});
my $letter = "";
my @old_revealed = split(//,$current{'revealed'});
my @new_revealed = @old_revealed;
my $new_revealed_string = "";
my $got_one = 0;
my $count = 0;
foreach $letter(@word) {
if(lc($guess) eq lc($letter)) {
#print LOG "Matched letter [$guess] at position [$count]\n";
$new_revealed[$count] = $guess;
$got_one = 1;
}
# else {
# $new_revealed[$count] = $old_revealed[$count];
# }
$count++;
}
$new_revealed_string = join("",@new_revealed);
$current{'revealed'} = $new_revealed_string;
return $got_one;
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.