Pages - Menu

Friday 26 October 2012

Implementation of a Hangman game in C

The game allows you to choose one of the six categories, then it randomly chooses a word to be guessed. At the end, it displays the selected word, whether you lose the game or win it, as well as a option to start a new game.

The functions used for console graphics have been discussed in a previous article:

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>
#include<time.h>
#include"GRAPH_LIB.h"

#define MAX_WORD_LENGTH 255 //the maximum length of a word

/*---------------GLOBALS--------------*/
char categories[6][25]; //categories of words
FILE *file = NULL; //pointer to the file to be opened
char word[MAX_WORD_LENGTH]; //the selected word from the file
int newGame = 1; //variable to decide whether or not to start a new game

/*-------------PROTOTYPES-------------*/
/*
 * Description:
 *  Displays the header
 */
void Header(void);

/*
 * Description:
 *  Opens the file containing the words from a category based on the option parameter
 * Parameters:
 *  option - the selected option from the menu of categories
 */
void DecideFile(int option);

/*
 * Description:
 *  Displays the categories' menu and allows the user to select a category
 */
void Menu(void);

/*
 * Description:
 *  Randomly selects a word from the opened file
 */
void DecideWord(void);

/*
 * Description:
 *  Displays a menu allowing the player to decide whether or not to start a new game
 * Returns:
 *  1 - starting a new game
 *  0 - not starting a new game
 */
int NewGame(void);

/*
 * Description:
 *  Displays a message letting know that you lost the game as well as the word you had to guess.
 */
void LostGame(int wordLength);

/*
 * Description:
 *  Displays the word you had to guess and a message letting you know that you won the game.
 */
void WonGame(int wordLength);

/*
 * Description:
 *  Starts the game and contains the game's logic.
 */
int Gameplay(void);

/*-------------IMPLEMENTATION-------------*/
void Header(void)
{
    ConsoleDimensions(120,50);
    ConsoleColours("gray","white");
    DrawRectangle(0,0,120,7,"dark blue");
    GoTo(56,2);
    Colour("dark blue","gray");
    puts("HANGMAN");
    GoTo(55,3);
    puts("July 2012");
    GoTo(49,4);
    puts("Copyright@INFINITE LOOP");
}

void DecideFile(int option)
{
    switch(option)
    {
    case 0:
        file=fopen("actors.txt","rt");
    case 1:
        file=fopen("animals.txt","rt");
    case 2:
        file=fopen("bands.txt","rt");
    case 3:
        file=fopen("countries.txt","rt");
    case 4:
        file=fopen("films.txt","rt");
    case 5:
        file=fopen("sports.txt","rt");
    default:
        file=fopen("actors.txt","rt");
    }
}

void Menu(void)
{
    int i = 0, j = 0;
    int option = 0;
    char move = 32;
    Header();
    //rectangle at the bottom
    StripesOutline(9,41,100,5,"gray","dark blue");
    DrawRectangle(10,42,100,5,"dark gray");
    GoTo(25,44);
    Colour("dark gray","black");
    printf("Use %c and %c to move through the menu. Press Enter to choose a category.",30,31);
    //initialising the categories
    strcpy(categories[0],"  Actors ");
    strcpy(categories[1]," Animals ");
    strcpy(categories[2],"  Bands  ");
    strcpy(categories[3],"Countries");
    strcpy(categories[4],"  Films  ");
    strcpy(categories[5]," Sports  ");
    //the menu
    StripesOutline(44,17,31,15,"gray","cyan");
    DrawRectangle(45,18,31,15,"cyan");
    while(move != 13)
    {
            for(i=0; i<6; i++)
            {
                GoTo(51,20+i*2);
                for(j=0; j<5; j++)//before printing the category
                {
                    if(option == i)
                    {
                        Colour("magenta","magenta");
                        printf("*");
                    }
                    else
                    {
                        Colour("dark blue","dark blue");
                        printf("*");
                    }
                }
                if(option == i)
                {
                    Colour("magenta","white");
                }
                else
                {
                    Colour("dark blue","gray");
                }
                puts(categories[i]);
                GoTo(56+strlen(categories[i]),20+i*2);
                Colour("dark blue","dark blue");
                for(j=0; j<5; j++)//after printing the category
                {
                    if(option == i)
                    {
                        Colour("magenta","magenta");
                        printf("*");
                    }
                    else
                    {
                        printf("*");
                    }
                }
            }
            move=getch();
            if(move == 0x50)//down arrow
            {
                option++;
                if(option == 6)
                {
                    option = 0;
                }
            }
            if(move == 0x48)//up arrow
            {
                option--;
                if (option == -1)
                {
                    option=5;
                }
            }
    }
    DecideFile(option);//opening the file corresponding to the chosen category
}

void DecideWord(void)
{
    int wordsCount = 0;
    int wordNumber = 0;
    int i=0;
    time_t seconds;
    time(&seconds);
    srand(seconds);
    if(file != NULL)
    {
        while(feof(file) == 0)
        {
            fgets(word,255,file);
            wordsCount++;
        }
        wordNumber = rand() % wordsCount;
        rewind(file);
        while(i <= wordNumber)
        {
            fgets(word,255,file);
            i++;
        }
    }
    if(wordNumber+1 != wordsCount)//otherwise it will contain the new line character - ??
    {
        word[strlen(word)-1] = '\0';
    }
}

int NewGame(void)
{
    int newGame = 0;
    char move = 32;
    StripesRectangle(40,42,40,7,"dark gray","gray");
    GoTo(44,44);
    Colour("neon green","black");
    printf("Do you want to start a new game?");
    while(move != 13)
    {
        GoTo(57,46);
        if(newGame == 1)
        {
            Colour("white","black");
        }
        else
        {
            Colour("neon green","black");
        }
        printf(" YES ");
        GoTo(57,47);
        if(newGame == 0)
        {
            Colour("white","black");
        }
        else
        {
            Colour("neon green","black");
        }
        printf("  NO ");
        move=getch();
        if(move == 0x48)//down arrow
        {
            newGame = 1;
        }
        if(move == 0x50)//up arrow
        {
            newGame = 0;
        }
    }
    return newGame;
}

void LostGame(int wordLength)
{
    int  i = 0;
    system("cls");
    Header();
    StripesOutline(39,18,40,6,"gray","neon green");
    DrawRectangle(40,19,40,6,"dark gray");
    GoTo(55,21);
    Colour("dark gray","black");
    puts("GAME OVER");
    GoTo(54,22);
    puts("#You  lost#");
    DoubleBorderGrid((120-6*wordLength)/2,35,3,3,1,wordLength,"gray","white");
    Colour("gray","cyan");
    for(i=0; i<wordLength; i++)
    {
        GoTo((120-6*wordLength)/2+6*i+2,37);
        printf("%c",word[i]);
    }
}

void WonGame(int wordLength)
{
    int i = 0;
    system("cls");
    Header();
    StripesOutline(39,18,40,6,"gray","neon green");
    DrawRectangle(40,19,40,6,"dark gray");
    GoTo(55,21);
    Colour("dark gray","black");
    printf(" GAME OVER");
    GoTo(55,22);
    printf("#You   won#");
    DoubleBorderGrid((120-6*wordLength)/2,35,3,3,1,wordLength,"gray","white");
    Colour("gray","cyan");
    for(i=0; i<wordLength; i++)
    {
        GoTo((120-6*wordLength)/2+6*i+2,37);
        printf("%c",word[i]);
    }
}

int Gameplay(void)
{
    char *constructing = NULL;
    char alphabet[26];
    char letter;
    int missed=6;
    int i=0;
    int k=0;
    int wordLength=0;
    int letterCode = 0;

    DecideWord();
    wordLength=strlen(word);
    constructing =(char*)malloc(sizeof(char)*wordLength);
    memset(constructing,'*',wordLength);
    memset(alphabet,'0',26);
    constructing[wordLength]='\0';

    Header();

    while( missed != 0)
    {
        system("cls");
        Header();
        DoubleBorderGrid((120-6*wordLength)/2,35,3,3,1,wordLength,"gray","white");
        Colour("gray","cyan");
        for(i=0; i<wordLength; i++)
        {
            GoTo((120-6*wordLength)/2+6*i+2,37);
            printf("%c",constructing[i]);
        }
        StripesOutline(39,18,40,6,"gray","white");
        DrawRectangle(40,19,40,6,"cyan");
        GoTo(47,21);
        Colour("cyan","white");
        printf("Remaining wrong guesses: %d",missed);
        GoTo(51,22);
        printf("Enter your guess: ");
        fflush(stdin);
        scanf("%c",&letter);
        letter = toupper(letter);
        letterCode = letter;
        k=0;
        for(i=0; i<wordLength; i++)
        {
            if(word[i] == letter)
            {
                constructing[i]=letter;
                k++;
            }
        }
        if(k == 0 && alphabet[letterCode - 65] == '0')
        {
            missed--;
            alphabet[letterCode - 65] = '1';
        }
        if((strcmp(constructing,word) == 0) && (missed != 0))//the player has won the game
        {
            WonGame(wordLength);
            newGame=NewGame();
            break;
        }
        if(missed == 0)//the player has lost the game
        {
            LostGame(wordLength);
            newGame=NewGame();
        }
    }
    return newGame;
}

void Launcher(void)
{
    system("title http://i-nfiniteloop.blogspot.com Hangman");
    while(newGame != 0)
    {
        Menu();
        system("cls");
        newGame = Gameplay(newGame);
    }
}

int main(void)
{
    Launcher();
    return 0;
}


Screenshots:









No comments:

Post a Comment