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($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;
}