LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 11-11-2003, 12:21 PM   #1
WorldBuilder
Member
 
Registered: Mar 2003
Location: Massachusetts, USA
Distribution: RH 8, Solaris, Windoze eXPunged
Posts: 520

Rep: Reputation: 30
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.
 
Old 11-11-2003, 01:11 PM   #2
WorldBuilder
Member
 
Registered: Mar 2003
Location: Massachusetts, USA
Distribution: RH 8, Solaris, Windoze eXPunged
Posts: 520

Original Poster
Rep: Reputation: 30
Quote:
6. The "letter-guessing" line is solid. How can I make it dashed, so that each dash represents a letter in the word?
Nevermind... I figured out that one. Still pulling my hair out about the rest. Help! Thanks!
 
Old 11-12-2003, 06:13 PM   #3
WorldBuilder
Member
 
Registered: Mar 2003
Location: Massachusetts, USA
Distribution: RH 8, Solaris, Windoze eXPunged
Posts: 520

Original Poster
Rep: Reputation: 30
Hi again, guys...

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;
}
Thanks in advance!

Chris
 
Old 11-21-2003, 05:12 AM   #4
8nasmith
Member
 
Registered: Oct 2003
Location: Cornwall, UK
Distribution: Fedora Core 4
Posts: 268

Rep: Reputation: 30
my god whats that all about i have trouble just loading linux never mind programming it
 
Old 11-21-2003, 07:09 AM   #5
WorldBuilder
Member
 
Registered: Mar 2003
Location: Massachusetts, USA
Distribution: RH 8, Solaris, Windoze eXPunged
Posts: 520

Original Poster
Rep: Reputation: 30
lol, yeah. It can take a while to get used to. I got the script working... Even added a scoring feature.

Chris
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
CMS Perl/CGI/PHP script ANU Programming 2 10-25-2006 10:11 AM
CGI/Perl script problems. Randvegeta Linux - Software 8 12-30-2004 12:24 AM
cgi-bin error regarding perl script hamish Linux - Software 11 12-09-2004 10:16 AM
How to Call a C program from Perl CGI Script anoop_cn Programming 1 05-11-2004 04:37 PM
Need Help With My Perl/cgi Authentication Script dutch357 Programming 0 04-11-2003 09:54 AM


All times are GMT -5. The time now is 02:50 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration