Hangman Program Why Doesn't It Work?

  • Thread starter Thread starter hermy
  • Start date Start date
  • Tags Tags
    Program Work
AI Thread Summary
The discussion centers on troubleshooting a Hangman game program written in C++. The primary issues identified include a non-executing line in the `dashnhang()` function, which prevents the dashes from displaying, and an infinite loop caused by incorrect handling of user input. The program fails to increment the wrong guess counter (`t`) appropriately, leading to repeated prompts for input without progressing. Suggestions for resolution include simplifying the dash drawing logic and implementing a flag to track whether a guessed letter is in the word. A revised code structure is proposed to ensure that the wrong guess counter only increments when a letter is not found after checking all letters in the word. Additionally, concerns about memory usage are addressed, with the consensus that memory limitations are unlikely to be the cause of the issues. The conversation emphasizes the importance of proper indentation for readability and debugging.
hermy
Messages
41
Reaction score
0
Hangman Program! Why Doesn't It Work??

Hi! I wrote this program to play a game of hangman. There were no errors when I compiled it (using turbo c++, on windows), but it's not working the way it is supposed to.

The function dashnhang()worked perfectly well when I placed it and ran it n a separate program, but one line in it doesn't get executed.

Also, there is an infinite loop somewhere due to which the program never stops accepting a value from the user.

Here's the code: (It looks so long only because of the spaces and comments :) )
Code:
#include <fstream.h>
#include <conio.h>
#include <graphics.h>
#include <string.h>
#include <process.h>

/*______________________________________________________________________________
--------------------------------------------------------------------------------
PUZNO(): Reads and returns a puzzle word from the file "hangman.dat".
       The user gives the puzzle no.(i.e. pno)
________________________________________________________________________________
-----------------------------------------------------------------------------*/

char* puzno(int pno)
{
  char line[40];
  ifstream p;
  p.open("hangman.dat");
  for(int i=1; i<=pno; i++)
  p.getline(line, 40);          //In the dat file, each word has been
  return line;                  //placed in a different line.
}

/*_____________________________________________________________________________
-------------------------------------------------------------------------------
DASHNHANG(): Draws the dashes and the basic structure from which you
	   want to hang your man.
_______________________________________________________________________________
----------------------------------------------------------------------------*/

void dashnhang(int size)
{ int a,b;
  detectgraph(&a,&b);
  initgraph(&a, &b, "..\\bgi");

  // Loop to draw dashes
     for (int i=1; i<=size; i++)
      line(55 + 30*i + 10*(i-1), 400, 55 + 30*(i+1) + 10*(i-1), 400);

   //(55 & 400 r the initial x&y coordinate, 30=length of each dash, 10=space betn 2 dashes)

  // To draw hangman
     line(400, 120, 400, 160);
     line(400, 120, 480, 120);
     line(480, 120, 480, 320);
     line(420, 320, 520, 320);

}

/*_____________________________________________________________________________
-------------------------------------------------------------------------------
OOPS(): Whenever you enter a letter which is not a part of the word,
      this function draws the head, then a body, limbs, so on...
_______________________________________________________________________________
-----------------------------------------------------------------------------*/

void oops(int t, int size, char word)
{
  switch(t)
  {
   case 8: {arc(400, 190, 30, 150, 10); 
               gotoxy(15, 15); 
               cout<<"BAD LUCK! \n  The word is: "<<word;}  // Frown

   case 7: {circle(393, 170, 1);  circle(407, 170, 1);}           //The eyes

   case 6: line(400, 230, 430, 200);                                  //Hand

   case 5: line(400, 230, 370, 200);                                  //Hand

   case 4: line(400, 260, 430, 290);                                  //Leg

   case 3: line(400, 260, 370, 290);                                  //Leg

   case 2: line(400, 190, 400, 260);                                  //Body

   case 1: circle(400, 175, 15);                                        //Head

   case 0: dashnhang(size);

  }
if(t==8) exit(0);
}

/*_____________________________________________________________________________
-------------------------------------------------------------------------------
DISP(): If the letter you have entered is correct, then this
	function is called. The correct letters are displayed
	on the appropriate dashes.
_______________________________________________________________________________
-----------------------------------------------------------------------------*/

void disp(char c[40], int size)
{
 for(int i=0; i<size; i++)
  if(c[i]!=0)
   {gotoxy(13+5*i, 25);
    cout<<c[i];
   }
}/*____________________________________________________________________________
------------------------------------------------------------------------------
Let's declare some variables we'll need...
______________________________________________________________________________
-----------------------------------------------------------------------------*/
char copy[40], word[40], c; int won, size, pno, t=0;
//____________________________________________________________________________
//----------------------------------------------------------------------------// Main starts here:
void main()
{
for(int cat=0; cat<40; cat++)                  //We create a string full of zeroes
  copy[cat]=0;

cout<<"Enter a no. between 1 and 10:   \n";
cin>>pno;

strcpy(word,puzno(pno));                       //Word = puzno(pno)

size=strlen(word);

dashnhang(size);

while(t<8)                                     // t = no.of wrong tries
  {cout<<"pls enter a letter : "
   cin>>c;    cout<<"\n"                   // User guesses a letter
   for (int i=0; i<size; i++)
   if (c==word[i])                            // Check if c is present in word
     {copy[i]=c;
      disp(copy, size);
      
      won=strcmp(word, copy);
      if (won==0)                              //If all letters hav been guessed
        {gotoxy(15, 15);                       //display the message
         cout<<"YOU WON!";
         exit(0);
        }
      else
        {t++;
         oops(t, size, word);
        }
     }
  }
}
For the dat file, you can copy the stuff below to notepad and save it as hangman.dat:

detroit
orlando
bangalore
birmingham
chennai
hyderabad
phoenix
madrid
paris
tokio
 
Last edited:
Technology news on Phys.org


We're not going to do your homework for you. You need to describe where you're stuck, tell us what you've tried, and so on.

- Warren
 


This is not a homework project. I made it myself. As I said before, if you run the program, you will not notice any dashes, which should have been there if the function dashnhang() had worked properly. Also, you will notice that the program never stops accepting values. I have included comments after each line in the program, so I don't think I need to elaborate more on how it works.
 


hey hermy. nice to see someone else who codes for the hell of it. I just thought I'd drop my two cents that your line command loop for making the dashes looks way too complicated. maybe something more like:

for (int i=0; i<size; i++)
line(40*i + 55, 400, 40*i + 75, 400); //this should be in accordance to what you wrote in your comments

let me know if this works for you.
 
Last edited:


also, I noticed why it (seemingly) never ends. you only increment t when you've guessed a letter in the word and haven't won yet. this is obviously not what you want.
(...dude, this style is terrible. I'd highly recommend indenting correctly, it helps to catch a lot of dumb mistakes. I'm fixing it, just so I can read it easier.)
also, I'm unfamiliar with C++, but are you not supposed to end the line below "while" with a semi-colon?
I'm gunna paste the properly indented code below. the indentation more clearly shows the error. I'm gunna let you know right now that you're gunna want to use a flag. like... in pseudocode:
Code:
boolean letterFound = false;
for(i=0; i<length; i++)
   if(c == word[i])
      letterFound = true;

if(letterFound = false){
  t++;
  oops;
}
Code:
while(t<8){                                     // t = no.of wrong tries
   cout<<"pls enter a letter : "
   cin>>c;    
   cout<<"\n";                   // User guesses a letter
   for (int i=0; i<size; i++)
     if (c==word[i]){                            // Check if c is present in word
       copy[i]=c;
       disp(copy, size);
      
       won=strcmp(word, copy);
       if (won==0){                              //If all letters hav been guessed
         gotoxy(15, 15);                       //display the message
         cout<<"YOU WON!";
         exit(0);
       }else{
         t++;
         oops(t, size, word);
       }
     }
}
 


daytripper said:
for (int i=0; i<size; i++)
line(40*i + 55, 400, 40*i + 75, 400);

thanks daytripper, this bit of code is definitely cooler than the one before, but i again come across the same problem: it works when i place it in a separate program, but doesn't show up in this particular one.

my compiler can not identify bool, it's just not in its dictionary. i could definitely use a flag though.

as for the problem with the infinite loop thing, it all started with a missing } . here's the revised code :

Code:
while(t<8)                                     // t = no.of wrong tries
{  cin>>c;                                     // User guesses a letter
   
   for (int i=0; i<size; i++)
         
        if (c==word[i])                             // Check if c is present in word
              { copy[i]=c;
                 disp(copy, size);
                 won=strcmp(word, copy);
                 
                  if (won==0)                              //If all letters hav been guessed
                      { gotoxy(15, 15);                       
                         cout<<"YOU WON!";           //display the message
                         exit(0);
                      } 
              
               }
      
          else                                                // i.e. c is not present in the word
          {t++;
           oops(t, size);
          }

};


I do hope the indenting is slightly better this time, but the bad news is that the infinite loop still exists.

also, i was wondering if the reason the dashes are not visible was due to lack of memory or something (i use a ram of 1 gb, duo core processor), i mean how can it work in some other program when it doesn't work here?
 


hey man. sorry for the long overdue reply, I hope this is still relevant.

I don't think this problem is due to a lack of memory. There's not really anything about this program that would cause any significant use of memory.

I'm not sure if you're actually running into an infinite loop. It looks more like your program should terminate prematurely. The big problem here is that your code is running FOR EACH LETTER in the word. Let's look at an example. Let's say the word is "temperature" and I guess "w". obviously, W is not in the word temperature, so let's look at it line by line.

so right now, we just entered the for loop with c='W' and word="temperature". the for loop says "for each letter in temperature, check to see if that letter is W". so the if statement inside your for loop returns false for each letter in the word. I guessed wrong once and yet by the time this for loop is over, t=11 and the oops function has been run 11 times.

to sort out this problem, USE A FRIGGIN FLAG! C++ doesn't recognize bools in general, but just use an int with 0 as false and 1 as true. perhaps call this flag "letterFound" and then run your if statement AFTER the for loop has completed. if c==word, then set letterFound=1. after the for loop is done, letterFound should be 1 in the case that the letter that I guessed exists in the word and 0 in the case that the letter doesn't exist in the word.

as for the dashes not appearing, that seems like a more technical problem. try drawing a line without the for loops. build it up from basics and hopefully the error will show itself.

again, sorry for the late reply. I know how frustrating that can be. let me know how all this works out. I can write the code for you, if you'd like, but I don't think the finished source code is ever what we're after ;)
 


eh, screw it. i think this is what you want:
Code:
while(t<8){                                     // t = no.of wrong tries
   cout<<"pls enter a letter : "
   cin>>c;    
   cout<<"\n";
   int letterFound = 0;                   // User guesses a letter
   for (int i=0; i<size; i++)
      if(c==word[i])
         letterFound = 1;     

   if (letterFound==1){                            // Check if c is present in word
       copy[i]=c;
       disp(copy, size);
      
       won=strcmp(word, copy);
       if (won==0){                              //If all letters hav been guessed
         gotoxy(15, 15);                       //display the message
         cout<<"YOU WON!";
         exit(0);
       }
    }else{
       t++;
       oops(t, size, word);
    }
}
exit(0);

not sure about that last line, it might not be necessary. I don't actually write in C++
 


thanks dude, i finally got the problem, but I'm on d run now, i'll definitely try that. never mind that u were late, i don't get to log on quite often nowadays.
 
Back
Top