Thread: Help With My Text Adventure Game?

  1. #1
    Registered User
    Join Date
    Nov 2012
    Posts
    19

    Help With My Text Adventure Game?

    so far i have this. And i have some errors. Any suggestions to improve it? My C knowledge is limited :P
    Code:
    #include <stdio.h>
    char character = 'q';
    int main()
    {
        system("clear");
        printf (" __            ___________    ___________    _____________ \n|  |          |           |  |           |  |             |\n|  |          |    ___    |  |    _______|  |____     ____|\n|  |          |   |   |   |  |   |_______        |   |     \n|  |          |   |   |   |  |_______    |       |   |     \n|  |_______   |   |___|   |   _______|   |       |   |     \n|          |  |           |  |           |       |   |     \n|__________|  |___________|  |___________|       |___|     ©\n");
        sleep(1);
        printf ("Press Any Key And Enter To Start.\nPress X To Exit.\n");
        character = getchar();
        getchar();
        while (character != 'x')
        {
            if (character != '\n')
            {
                system("clear");
                printf ("You are lost in the forest.\nYou can only move forward, backwards, left, and right.\nHere are the controls: 8-Up, 2-Down, 4-Left, 6-Right.\nWhat do you do?\n");
                character = getchar();
                printf ("%c\n", character);
                if (character == '8')        //Up
                {
                    system("clear");
                    printf ("Walking...\n");
                    sleep(1);
                    system("clear");
                    printf ("You see an abandoned castle. Now What?\n");
                    character = getchar();
                    getchar();
                    if (character == '8')      //Up
                    {
                        getchar();
                        system("clear");
                        printf ("Walking...\n");
                        sleep(1);
                        system("clear");
                        printf ("You enter the abandonded castle.\n");
                    }
                    if (character == '2')        //Down
                    {
                        getchar();
                        system("clear");
                        printf ("Walking...\n");
                        sleep(1);
                        system("clear");
                        printf ("You arrive back to where you started.\n");
                    }
                    if (character == '4')        //Left
                    {
                        getchar();
                        system("clear");
                        printf ("Walking...\n");
                        sleep(1);
                        system("clear");
                        printf ("You see big hill.\n");
                    }
                    if (character == '6')        //Right
                    {
                        getchar();
                        system("clear");
                        printf ("Walking...\n");
                        sleep(1);
                        system("clear");
                        printf ("You see a stone road\n");
                    }
                }
                if (character == '2')        //Down
                {
                    system("clear");
                    printf ("Walking...\n");
                    sleep(1);
                    system("clear");
                    printf ("You see a crowd of %d zombies. Now What?\n", rand());
                    character = getchar();
                    getchar();
                    if (character == '8')      //Up
                    {
                        system("clear");
                        printf ("Walking...\n");
                        sleep(1);
                        system("clear");
                        printf ("The zombies eat you.\n");
                        sleep(1);
                        system("clear");
                        printf ("Game Over\n");
                        sleep(1);
                        break;
                    }
                    if (character == '2')        //Down
                    {
                        system("clear");
                        printf ("Walking...\n");
                        sleep(1);
                        system("clear");
                        printf ("The zombies eat you.\n");
                        sleep(1);
                        system("clear");
                        printf ("Game Over\n");
                        sleep(1);
                        break;
                    }
                    if (character == '4')        //Left
                    {
                        system("clear");
                        printf ("Walking...\n");
                        sleep(1);
                        system("clear");
                        printf ("The zombies eat you.\n");
                        sleep(1);
                        system("clear");
                        printf ("Game Over\n");
                        sleep(1);
                        break;
                    }
                    if (character == '6')        //Right
                    {
                        system("clear");
                        printf ("Walking...\n");
                        sleep(1);
                        system("clear");
                        printf ("The zombies eat you.\n");
                        sleep(1);
                        system("clear");
                        printf ("Game Over\n");
                        sleep(1);
                        break;
                    }
                }
                if (character == '4')        //Left
                {
                    system("clear");
                    printf ("Walking...\n");
                    sleep(1);
                    system("clear");
                    printf ("You see a hot girl. Now What?\n");
                    character = getchar();
                    getchar();
                    if (character == '8')       //Up
                    {
                        system("clear");
                        printf ("Walking...\n");
                        sleep(1);
                        system("clear");
                        printf ("She sleeps with you and steals all your money.\n");
                        sleep(1);
                        system("clear");
                        printf ("Game Over\n");
                        sleep(1);
                        break;
                    }
                    if (character != '8')       //Down
                    {
                        while (1)
                        {
                            if (character == '8')
                            {
                                system("clear");
                                printf ("Walking...\n");
                                sleep(1);
                                system("clear");
                                printf ("She slaps you for walking away.\n");
                            }
                            else if (character == '2')
                            {
                                system("clear");
                                printf ("Walking...\n");
                                sleep(1);
                                system("clear");
                                printf ("She slaps you for walking away.\n");
                            }
                            else if (character == '4')        //Left
                            {
                                system("clear");
                                printf ("Walking...\n");
                                sleep(1);
                                system("clear");
                                printf ("She slaps you for walking away.\n");
                            }
                            else if (character == '6')        //Right
                            {
                                system("clear");
                                printf ("Walking...\n");
                                sleep(1);
                                system("clear");
                                printf ("She slaps you for walking away.\n");
                            }
                            if (character == 'x')
                            {
                                system("clear");
                                printf ("Goodbye...\n");
                                sleep(1);
                                system("clear");
                                return 0;
                            }
                            character = getchar();
                        }
                    }    
                }
                if (character == '6')        //Right
                {
                    system("clear");
                    printf ("Walking...\n");
                    sleep(1);
                    system("clear");
                    printf ("You see a Lake. Now What?\n");
                    character = getchar();
                    getchar();
                    if (character == '8')       //Up
                    {
                        system("clear");
                        printf ("Walking...\n");
                        sleep(1);
                        system("clear");
                        printf ("You jump into the lake and try to swim across the lake but the current pushes you back. You think you can try to swim across again.\n");
                        character = getchar();
                        getchar();
                        if (character == '8')        //Up
                        {
                            system("clear");
                            printf ("Walking...\n");
                            sleep(1);
                            system("clear");
                            printf ("You try to swim but you drown.\n");
                            sleep(1);
                            system("clear");
                            printf ("Game Over\n");
                            sleep(1);
                            break;
                        }
                        if (character == '2')        //Down
                        {
                            system("clear");
                            printf ("Walking...\n");
                            sleep(1);
                            system("clear");
                            printf ("You cant climb out of the water.\n");
                        }
                        if (character == '4')        //Left
                        {
                            system("clear");
                            printf ("Walking...\n");
                            sleep(1);
                            system("clear");
                            printf ("You cant climb out of the water.\n");
                        }
                        if (character == '6')        //Right
                        {
                            system("clear");
                            printf ("Walking...\n");
                            sleep(1);
                            system("clear");
                            printf ("You cant climb out of the water.\n");
                        }
                    }
                    if (character == '2')        //Down
                    {
                        system("clear");
                        printf ("Walking...\n");
                        sleep(1);
                        system("clear");
                        printf ("You arrive back to where you started.\n");
                    }
                    if (character == '4')        //Left
                    {
                        system("clear");
                        printf ("Walking...\n");
                        sleep(1);
                        system("clear");
                        printf ("There is a fence blocking your way.\n");
                    }
                    if (character == '6')        //Right
                    {
                        system("clear");
                        printf ("Walking...\n");
                        sleep(1);
                        system("clear");
                        printf ("There is a fence blocking your way.\n");
                    }
                }
            }
        }
        system("clear");
        printf ("Goodbye...\n");
        sleep(1);
        system("clear");
        return 0;
    }

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Overall, it looks like a pretty good start for a newbie. It's also a great project because you can keep building on it and improving it as your skills develop. You seem to have a pretty good handle on basic syntax and program flow. Next I would move onto some lessons or tutorials covering intermediate/advanced topics, so you can eventually incorporate that into your game.

    Some general suggestions for starters:

    • Use functions, they will help avoid duplicate code, and make it easier to read, maintain, debug and fix.
    • Don't use global variables (link). Instead, declare them in the appropriate functions (e.g. main), and pass them to other functions as needed.
    • Use named constants, and avoid magic numbers (link).
    • Many people find clearing the terminal to be annoying. Printing a blank line or two is usually sufficient, and would avoid the (IMO annoying) delays/sleeps you have all over. If you really need/want fancier terminal features, look into something like ncurses.


    Compile your program with warnings turned all the way up, and fix them all. Here's what I get when I compile your code:
    Code:
    $ make adv
    gcc -Wall -Wunreachable-code -g -std=c99 -pedantic  -lm -lpthread  adv.c   -o adv
    adv.c: In function ‘main’:
    adv.c:5: warning: implicit declaration of function ‘system’
    adv.c:7: warning: implicit declaration of function ‘sleep’
    adv.c:71: warning: implicit declaration of function ‘rand’
    You need to #include <stdlib.h> to use system() and rand(), and #include <unistd.h> to use sleep().

    Use structs to contain all the information you need for each map coordinate. A 2-d array of these structs would be a great way to represent your map. Study up on structs, arrays and 2-d arrays, and your code for handling movement and printing messages, etc for each map coordinate will be much simpler.

  3. #3
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    The way that is written, the entire game world is written into the code and seems difficult to change; more precisely, the difficulty of changing the code will increase very rapidly as your game world's complexity increases. A simple first-level generalization might be to draw a "map" to represent the different areas/obstacles encountered:

    Code:
    char map[][] = {
        {'F', 'F', 'F', 'F', 'C', 'F'},
        {'F', 'G', 'F', 'F', 'c', 'F'},
        {'F', 'F', 'F', 'F', 'F', 'F'},
        {'F', 'F', 'F', 'H', 'F', 'F'},
        {'F', 'F', 'R', 'F', 'F', 'F'},
        {'F', 'F', 'R', 'F', 'F', 'F'}
        };
    Each char could represent a different type of area. For example, if your character starts at position 0,0 then you know you're in the forest. 'G' could represent the hot girl, 'C' the abandoned castle, and so on. Then keep track of the current position (j,i) of your character.

    Instead of writing

    Code:
    character = getchar();
    if (character == '8') // Up
    {
    
       system("clear");
    
       printf ("Walking...\n");
    
       sleep(1);
    
       system("clear");
    
       //...
    }
    write this instead

    Code:
    #define KEY_UP '8'  // define this together with other constants
    
    if ((c = getchar()) == KEY_UP)
       godown();
    Using KEY_UP instead of '8' makes it obvious what it means. Also you can change it easily later if you support an alternate key layout. Btw if its a text adventure the normal vocabulary is "north, south, east, west" to move the character around.
    Last edited by c99tutorial; 11-30-2012 at 07:48 PM.

  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    The goal is to make the code shorter. What you want is something more like this for a function:
    Code:
    void move(const char *message, const char *walkMsg="Walking...\n")
    {
        system("clear");
        printf(walkMsg);
        sleep(1);
        system("clear");
        printf(message);
    }
    Them call it like this:
    Code:
    move("She slaps you for walking away.\n");
    There are about 25 places you could call the function and each time you save 4 lines. That's 100 lines less already. Now refactor that so that it can be given three arguments and optionally sleep before displaying a third message and you can re-use it in even more places.
    Last edited by iMalc; 11-30-2012 at 08:00 PM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  5. #5
    Registered User
    Join Date
    Nov 2012
    Posts
    19
    Quote Originally Posted by c99tutorial View Post
    The way that is written, the entire game world is written into the code and seems difficult to change; more precisely, the difficulty of changing the code will increase very rapidly as your game world's complexity increases. A simple first-level generalization might be to draw a "map" to represent the different areas/obstacles encountered:

    Code:
    char map[][] = {
        {'F', 'F', 'F', 'F', 'C', 'F'},
        {'F', 'G', 'F', 'F', 'c', 'F'},
        {'F', 'F', 'F', 'F', 'F', 'F'},
        {'F', 'F', 'F', 'H', 'F', 'F'},
        {'F', 'F', 'R', 'F', 'F', 'F'},
        {'F', 'F', 'R', 'F', 'F', 'F'}
        };
    Each char could represent a different type of area. For example, if your character starts at position 0,0 then you know you're in the forest. 'G' could represent the hot girl, 'C' the abandoned castle, and so on. Then keep track of the current position (j,i) of your character.

    Instead of writing

    Code:
    character = getchar();
    if (character == '8') // Up
    {
    
       system("clear");
    
       printf ("Walking...\n");
    
       sleep(1);
    
       system("clear");
    
       //...
    }
    write this instead

    Code:
    #define KEY_UP '8'  // define this together with other constants
    
    if ((c = getchar()) == KEY_UP)
       godown();
    Using KEY_UP instead of '8' makes it obvious what it means. Also you can change it easily later if you support an alternate key layout. Btw if its a text adventure the normal vocabulary is "north, south, east, west" to move the character around.
    Thanks everyone for the responses I really like your idea of the char map, but i dont really know that much about c :P im not 100% sure how to use the map though. could you provide insight? This is a side project for school to help me learn more about c.

  6. #6
    Registered User
    Join Date
    Nov 2012
    Posts
    19
    Quote Originally Posted by iMalc View Post
    The goal is to make the code shorter. What you want is something more like this for a function:
    Code:
    void move(const char *message, const char *walkMsg="Walking...\n")
    {
        system("clear");
        printf(walkMsg);
        sleep(1);
        system("clear");
        printf(message);
    }
    Them call it like this:
    Code:
    move("She slaps you for walking away.\n");
    There are about 25 places you could call the function and each time you save 4 lines. That's 100 lines less already. Now refactor that so that it can be given three arguments and optionally sleep before displaying a third message and you can re-use it in even more places.
    What do i replace with this? lol im a real beginner with this stuff, and i really want to shorten my code :P

  7. #7
    Registered User
    Join Date
    Nov 2012
    Posts
    19
    Oh and also, does anyone know a good c compiler program for windows? I am currently using dev c++ but some of the c commands dont work with it. I have a netbook that uses linux which runs this code fine but i want to work on my desktop because it has a bigger screen.
    And if i want to use the arrow keys (without having to push the enter key) to move instead of the number pad and enter how would i do that? if its even possible?

  8. #8
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    I currently use mingw, in the Code::Blocks IDE. I'm very happy with it.

    You can use arrow keys to control the program, but the code is system dependent (and not portable).
    FAQ > Use directional keys in a console application - Cprogramming.com

  9. #9
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    If you look at the FAQ mentioned by Matticus on the section for "curses" then using these routines should still be fairly portable. For example, there is the PDCurses project which works on both Linux and Windows.

  10. #10
    Registered User
    Join Date
    Nov 2012
    Posts
    19
    Can u link me? I can't find it

  11. #11
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by evilcubed View Post
    Can u link me? I can't find it
    PDCurses?

    PDCurses - Public Domain Curses

  12. #12
    Registered User
    Join Date
    Nov 2012
    Posts
    19
    Quote Originally Posted by c99tutorial View Post
    The game is for a school project so i can only use GNU. Would i need PDCurses to do the char map u did?

  13. #13
    Registered User
    Join Date
    Nov 2012
    Posts
    19
    Also if I made a char map, how would I track the position of the player?

  14. #14
    Ultraviolence Connoisseur
    Join Date
    Mar 2004
    Posts
    555
    Quote Originally Posted by evilcubed View Post
    Also if I made a char map, how would I track the position of the player?

    This is probably giving you way too much, but I'm bored so here it is:
    Code:
    #include <stdio.h>
    
    #define MAX_SIZE    20
    
    enum map_tile {
        F,  /* Forest */
        G,  /* Girl */
        W,  /* Water */
        R,  /* Road */
        B   /* Beach */
    };
    
    struct level {
        const enum map_tile map[MAX_SIZE][MAX_SIZE];
    };
    
    struct player {
        int x, y; /* position in level */
    };
    
    static const struct level LEVEL[] = {
        /* LEVEL 1 */
        {
            {{ F, F, F, G, F, B, B, B, W },
             { F, R, R, F, R, B, B, B, W },
             { F, R, R, R, R, F, F, B, W },
             { F, R, F, F, B, B, B, B, W }}
        }
        /* LEVEL 2 etc ... */
    };
    
    
    int main(void)
    {
        struct player player1 = {0}; /* start at top-left 0,0 */
        unsigned char move;
    
        /* aquire key input into move  */
    
        switch (move) {
            case NORTH:
                /* bounds checking omitted */
                ++player1.y;
                break;
            case SOUTH:
                /* bounds checking omitted */
                --player1.y;
                break;
            case EAST:
                /* bounds checking omitted */
                ++player1.x;
                break;
            case WEST:
                /* bounds checking omitted */
                --player1.x;
                break;
            default:
                /* invalid input */
        }
    
        /* now you use the coordinates of player (x, y) in the LEVEL[0].map to find out where he is in the level */
    
        return 0;
    }

  15. #15
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by evilcubed View Post
    The game is for a school project so i can only use GNU. Would i need PDCurses to do the char map u did?
    PDCurses is "public domain". It means you can use it in any project without any obligation of license fees. If it's for a school project, then you should cite the source, and that's fine.

    No, PDCurses gives you routines to manipulate the text window and keyboard. If you look at the last example in the link from Matticus, there is mention of "curses.h". PDCurses provides something similar for Windows (and Linux).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Text based adventure game.
    By Luminous Lizard in forum C++ Programming
    Replies: 15
    Last Post: 01-06-2012, 11:53 AM
  2. Text adventure game GUI
    By VirtualAce in forum Game Programming
    Replies: 11
    Last Post: 11-07-2007, 06:34 PM
  3. Help with my text adventure game.
    By Haggarduser in forum Game Programming
    Replies: 15
    Last Post: 10-26-2007, 01:53 AM
  4. text adventure game
    By linucksrox in forum Game Programming
    Replies: 18
    Last Post: 07-27-2006, 01:36 PM
  5. Please help (Text Adventure Game)
    By C++angel in forum C++ Programming
    Replies: 9
    Last Post: 02-23-2006, 04:33 PM