Page 1 of 1

Creating Hangman A simple walk-through

#1 Hyper  Icon User is offline

  • Banned

Reputation: 108
  • View blog
  • Posts: 2,129
  • Joined: 15-October 08

Posted 20 February 2009 - 03:18 PM

Hello, my name is Dani, first and foremost, I am writing this in the hopes that it'll inspire somebody to learn more about C (or C++... or programming in general!). It doesn't matter how much, or how little you know about a language, you can do some very very! Interesting things with the most basic of things.

You can write games, you can write databases for yourself (ever gone shopping and went "Darn! I missed something on my list!"? I know I have!).
The best part about writing it yourself is you get a sort of "satisfaction" knowing that you! wrote it, and you can modify it, add to it, take away from it, anytime you feel like without having to ask anybody else.
You can give your friends it, your family, your employer/employees, etc. Now onward!

- Designing a menu screen
Personally, one of the most hard parts about programming for me is coming up with ideas of what to do. Doing it is the easy part for me, thinking of what to do is tough.
I've since then settled on a standard system for all my little applications and games. I think you should create your own "standard" too! So no matter what you write, it's easy for you (and others) to find what they need.

Some ideas of a menu might be like: Use 0-9 vertically lined up like this:


Then you simply have at the bottom, "User input: " and let them choose an option and switch statement it, sort of like this:
switch (UserInput) {
     case 0: PlayGame(); break;
     case 1: OptionsMenu(); break;
     case 2: ScoreboardMenu(); break;
     case 4: ExitGame(); break;

     default : printf("That was not an option! Please try again (1-4): );
};


If you like more graphical... "artsy" like menus, with all the bells and whistles you might make something more or less like this (you need to have the ability to jump around the screen; Since this is assuming you're using Windows system, I'll use SetConsoleCursorPosition):
/* Sub-function to move the cursor easily */
void PlaceCursor(const int x, const int y) {

    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

    COORD PlaceCursorHere;
    PlaceCursorHere.X = x;
    PlaceCursorHere.Y = y;

    SetConsoleCursorPosition(hConsole, PlaceCursorHere);
    return;
}

/* the typical code goes here and then! */

    PlaceCursor(25, 5);
    printf("List of Options:");
    PlaceCursor(25, 6);
    printf("1. Play game");
    PlaceCursor(25, 7); /* have to move its Y position down for every option listed */
    printf("2. Options");
    PlaceCursor(25, 8);
    printf("3. Scoreboard");
    PlaceCursor(25, 9);
    printf("Exit");

    /* Now we want to get their input! Over and over again...*/
    while (true) {

        PlaceCursor(0, 10);
        printf("Users input: ");
        scanf("%d", &UserInput);

        switch (UserInput) {
             case 0: PlayGame(); break;
             case 1: OptionsMenu(); break;
             case 2: ScoreboardMenu(); break;
             case 4: ExitGame(); break;
             default : printf("That was not an option! Please try again (1-4): );
        }
    }


Now you have a fancier menu system setup like that. It isn't on the far left, you don't have to use a thousand spaces or tabs, you just move the cursor as needed. :)
Once you've decided on your standard for setting up menus, you can move on, to making games using it; Now don't get me wrong. There isn't anything wrong with using menus, and there isn't anything "right" or "better" about it, I just personally think it makes a game, more complete!

- Choosing a game to replicate or make
Of course, you can use the "Hello World" equivalent of game programming by writing the very easy, but very! Entertaining and fun basic Arcade games - Snake, Asteroids, Pac-Man, Dig-Dug, etc. Or simpler games (more text based) like: Hang-Man, Tic-Tac-Toe, Connect-Four (kind of complex... but not really), etc.
I've decided because I personally like Hang-man the most out of all those (non-Arcade) games, I'll use that as the primary example for this "tutorial."

First thing's first! Design my menu system. I've decided I want a fancy (bells & whistles!) type menu, so I'm going to place everything in the center, except for the inputs, which will be on the left wall.


- Basic routines to make a game more "Managed"
Now I have something very basic, the user can now see clearly what he's supposed to do, and has an easy-way-of-inputting it (unlike some games...).
What now? Oh no! I've run out of ideas! :( But not to worry, for I am here, writing this to help inspire those of you who have no inspiration left at all! :D
Now I'm going to make a simple routine which can build a man to be hanged... Like so! But how would I do that? Hm.. Puzzling. A simple solution would be this:
Send an integer (int) to a function, have the function switch statement the integer sent (see where I'm getting at? The integer being sent is, sort of a "counter" for how many misses the player got).
Here it is completed:

void PlaceCursor(const int x, const int y) {

    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

    COORD PlaceCursorHere;
    PlaceCursorHere.X = x;
    PlaceCursorHere.Y = y;

    SetConsoleCursorPosition(hConsole, PlaceCursorHere);
    return;
}

void MissedLetter(int miss) {

    switch (miss) {
        case 1: PlaceCursor(55, 4); printf("O"); break;
        case 2: PlaceCursor(55, 5); printf("|"); break;
        case 3: PlaceCursor(54, 5); printf("\\"); break;
        case 4: PlaceCursor(56, 5); printf("/"); break;
    }

    return;
}


Now, before I go on I must let you know, in order to do that, you must:
- #include <iostream>
- #include <windows.h> /* for SetConsoleCursorPosition function */

OK! So back to the coding. Now I have a very basic, rudimentary game of Hangman. I have the ability to do nothing! Because there's no code, only a skeleton (poorly designed one at that).
I have the ability to draw a man who is hung with ASCII art (text) through a function which draws based on an integer, and I have a very basic starting menu.
What I need to do now is to complete the game!

- The actual game
Here's three simple things I need to do now (that are left):
- Create a random word (or select it from a list, which I will do)
- Take a users guess (single letters, remember? Not whole words)
- Compare their letter against the letter in the word they're aiming for (I must also take into account, that if they use a duplicate letter)

Here's an easy way of generating a list and selecting from it randomly:
    char *WordLibrary[] = {
        "cat",
        "dog",
        "pan"
    };

    srand(time(NULL));
    int Selected = rand() % 3;
    char *Word = WordLibrary[Selected];



So now I have a word (that was randomly selected) and it is stored in a character array called "Word." Now I have something I can compare user input against.
But wait, there's more (of course there's more, otherwise I'd be all 'Welcome, hope this helps, have fun,' n' stuff! :P)... much much more! Just keep reading and you'll see a fully completed game of Hangman! :D
OK! Step #1 of 3-steps completed. Now to work on Step #2 (Take a users guess)! How would we go about this? We could use cin.getline, which I shall do.
char Guess[2] = {'\0'};

/* other stuff ... */

        PlaceCursor(0, 1);
        printf("Your guess: _\b");
        cin.getline(Guess, 2);
        _flushall();


Tada! Now you're able to get their input (Letter + return, the third is the terminating null zero) and store it in "Guess[0]" so you can compare it with the Word.
You can easily compare it against the word with a loop, and just as a heads up, you don't have to use an integer like this, you can manually continually use "strlen()" instead if you prefer:
    srand(time(NULL));
    int Selected = rand() % 3;
    int miss = 0;
    int Completion = 0; /* How many letters were correct? So we know when he gets ALL the letters of the word right */
    char *Word = WordLibrary[Selected];
    int WordLength = strlen(WordLibrary[Selected]);
    char Guess[2] = {'\0'};

/* other stuff ... */

        for (int x = 0; x < WordLength; x++) {

            if (Guess[0] == Word[x]) {
                PlaceCursor(x + 6, 2);
                printf("%c", Word[x]);
                Completion--;
                break;
            }
        }



This will only see if you got the correct letter of a certain location (first come, first served, meaning if it has x2 A's, it'll only say you got the first one, never the second).
Since cutting this up into 2,000 small segments isn't always helpful, here's the full and completed game, which compiles, links and runs in Dev-C++ 4.9.9.3:

#include <iostream>
#include <windows.h>
using namespace std;

void PlaceCursor(const int x, const int y) {

    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

    COORD PlaceCursorHere;
    PlaceCursorHere.X = x;
    PlaceCursorHere.Y = y;

    SetConsoleCursorPosition(hConsole, PlaceCursorHere);
    return;
}

void MissedLetter(int miss) {

    switch (miss) {
        case 1: PlaceCursor(55, 4); printf("O"); break;
        case 2: PlaceCursor(55, 5); printf("|"); break;
        case 3: PlaceCursor(54, 5); printf("\\"); break;
        case 4: PlaceCursor(56, 5); printf("/"); break;
    }

    return;
}

void ClearConsole() {

    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

    COORD coordScreen = { 0, 0 };
    DWORD cCharsWritten;
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    DWORD dwConSize;

    if (!GetConsoleScreenBufferInfo(hConsole, &csbi)) { return; }
    dwConSize = csbi.dwSize.X * csbi.dwSize.Y;

    if (!FillConsoleOutputCharacter(hConsole, (TCHAR) ' ', dwConSize, coordScreen, &cCharsWritten)) { return; }
    if (!GetConsoleScreenBufferInfo(hConsole, &csbi)) { return; }
    if (!FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten)) { return; }

    return;
}

int main() {

    char *WordLibrary[] = {
        "cat",
        "dog",
        "pan"
    };

    StartGame:

    srand(time(NULL));
    int Selected = rand() % 3;
    int miss = 0;
    char *Word = WordLibrary[Selected];
    int WordLength = strlen(WordLibrary[Selected]);
    char Guess[2] = {'\0'};
    char CorrectlyPicked[WordLength];
    strset(CorrectlyPicked, '\0');

    int Completion = WordLength;
    bool GotOne = false;
    bool GotAlready = false;

    PlaceCursor(30, 0);
    printf("- Hangman -");

    PlaceCursor(25, 1);
    printf("1. Play a round");
    PlaceCursor(25, 2);
    printf("2. Exit game");

    PlaceCursor(0, 4);
    printf("Input: ");
    int UserInput = 0;
    scanf("%d", &UserInput);

    switch (UserInput) {
        case 1: ClearConsole(); _flushall(); break;
        case 2: goto Exit; break; /* Using gotos is bad practice generally, but this is only an example */

        default : PlaceCursor(0, 4); printf("Incorrect answer! Try again: ");
    }

    PlaceCursor(0, 2);
    printf("Word: ");

    PlaceCursor(0, 3);
    printf("Victory status: FALSE");

    for (int x = 0; x < WordLength; x++) { PlaceCursor(x + 6, 2); printf("_"); }

    while (true) {

        PlaceCursor(0, 1);
        printf("Your guess: _\b");
        cin.getline(Guess, 2);
        _flushall();

        for (int x = 0; x < WordLength; x++) {

            if (Guess[0] == Word[x]) {
                if (CorrectlyPicked[x] == Word[x]) { GotAlready = true; break; }
                CorrectlyPicked[x] = Word[x];

                PlaceCursor(x + 6, 2);
                printf("%c", Word[x]);
                Completion--;
                GotOne = true;
                break;
            }
        }

        if (GotOne == false && GotAlready == false) { miss++; MissedLetter(miss); }
        else { GotOne = false; GotAlready = false; }

        if (Completion == 0) { break; }
    }

    PlaceCursor(0, 3);
    printf("Victory status:");
    printf(" TRUE ");

    /* Reset all game values */
    GotOne = false;
    GotAlready = false;
    miss = 0;

    cin.get();
    ClearConsole();
    goto StartGame; /* again! Bad practice, this should be wrapped into a while loop */

    Exit:
    cin.get();
    return 0;
}


Is This A Good Question/Topic? 0
  • +

Replies To: Creating Hangman

#2 Nykc  Icon User is offline

  • Gentleman of Leisure
  • member icon

Reputation: 725
  • View blog
  • Posts: 8,638
  • Joined: 14-September 07

Posted 24 February 2009 - 09:58 AM

Very nice tutorial.

Keep up the good work!
Was This Post Helpful? 0
  • +
  • -

#3 calebjonasson  Icon User is offline

  • $bert = new DragonUnicorn(); $bert->rawr();
  • member icon

Reputation: 209
  • View blog
  • Posts: 989
  • Joined: 28-February 09

Posted 03 March 2009 - 06:38 PM

nice little hangman game you made there! im adding some words :)
Was This Post Helpful? 0
  • +
  • -

#4 macmc2  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 25-June 09

Posted 25 June 2009 - 09:20 PM

I have DEV C++ compiler and whenever i tell it to comply the data you labeled as the opening menu or title screen or something like that it says there are all sorts of errors what do i do?
Was This Post Helpful? 0
  • +
  • -

#5 bladejsc1997  Icon User is offline

  • New D.I.C Head

Reputation: -2
  • View blog
  • Posts: 7
  • Joined: 25-June 09

Posted 31 December 2009 - 12:30 AM

Very nice tutorial, however in the "Hangman completed" box. That coding has a few errors.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1