Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm new to programming and am writing a choose your own adventure game in C++ and am having trouble with exiting the program.

The way I have it set up is I am using functions as the different pages. So the program jumps around alot say from main to choice 1 to choice 2 to choice 5 to choice 3 and so on. It runs well aslong as I dont choose to go back. I have an int GameOver() function that displays if you die but after that message ends it will jump to another function.

I feel like I am doing this wrong but from all of my searches I can't find the right way to do this.

I have looked at the exit function but I am not sure if that is the right way to go about ending the program so abruptly or if I should end the program so abruptly.

I can post all of my code but really its just a lot of cout's and either a switch statement or if/if else/else loops.

Should my setup be dif.? Should I not jump from functions without returning to main?

share|improve this question
1  
You have a function for every scenario? –  Sidar Feb 26 '13 at 20:27
    
Compared to a book, each page is represented by a function. Main() has access to two functions. Those two functions branch off to two more functions and so on. It doesn't seem like the best way but it works for the most part. –  BenWardo Feb 26 '13 at 21:26
    
Calling the exit function is a perfectly fine way to exit your program. A bit dirty (especially if you want to track down memory leaks), but fine. I wouldn't worry about it at this stage. –  Laurent Couvidou Feb 27 '13 at 16:54

1 Answer 1

up vote 7 down vote accepted

If you never return from functions, you may risk running out of stack space, but practically speaking it sounds like your case may be subject to tail call optimization. It's not an optimization I'd rely on, though; you may want to consider passing some concept of "current state" around or storing it, and letting a "main loop" (literally a loop in your main() function or some other early method) dispatch to other functions based on this state -- it can be a big switch block, or a data structure that relates states to function pointers, or something else.

Those functions can then run, possibly set state, and return to main().

One of your states can therefore trigger an "exit main loop" via break or the like.

A quick sketch of a very simple "state machine" pattern:

int main() {
    bool isRunning = true;
    int nextGameState = GAME_START;
    while ( isRunning ) {
        switch ( nextGameState ) {
            case GAME_START: nextGameState = doGameStart(); break;
            // other states here, following the above pattern
            case EXIT_GAME: isRunning = false; break;
            default: /* error handling here */; break;
        }
    }
    return 0;
}

Another quick possibility would be something like:

extern bool g_isRunning = true; // global (yuck?)

typedef unsigned (*GameStateFunctionPointer)();

static const GameStateFunctionPointer s_gameStateTable[] = 
{
    doGameStart, // index = 0 entry
    // TODO other state functions here
    doGameEnd // index = n entry
};
static const unsigned NUM_GAME_STATES = sizeof( s_gameStateTable ) /
                                        sizeof( s_gameStateTable[0] );

int main() {
    unsigned nextGameState = GAME_START;
    while ( g_isRunning ) {
        if ( nextGameState >= NUM_GAME_STATES ) {
            // bad state
            abort(); // or other error handling
        }

        // call through function pointer to function that
        // does the work of the this state, then determines next state
        nextGameState = s_gameStateTable[ nextGameState ]();
    }

    return 0;
}

Re "going back", you may be able to keep a state history -- a list of prior game states -- rather than just a single nextGameState as above. You can then "go back" trivially by popping a state off this container.

(You may want to look at Deterministic Finite Automata / Nondeterministic Finite Automata -- sometimes more colloquially referred to as "state machines", although there are some non-overlapping bits -- for ideas of how you might design this. I'd strongly advise diagramming your state machine on "paper" if possible!)

(You may also just want to look around for other "game loop" examples, especially for text adventures.)

There are various advantages and disadvantages to both of the above very simple examples. If you're getting into more complicated state machines you might want to look into existing libraries for state machine / DFA / NFA representation.

By the way: exit(0) in and of itself isn't that evil. The OS will clean up after you. The disadvantage is you can't run all your shutdown code, and it makes things like leak tracking or taking other actions on normal shutdown (save game, update high scores, or any number of other things) more difficult.

share|improve this answer
    
Looks like I have some research to do –  BenWardo Feb 26 '13 at 21:29
    
Well, yes and no. Ask 10 different folks about this kind of thing and you'll probably get 10 different answers. Do whatever research interests you, then dive in and make a program. You can always improve it later =) and you'll be better equipped to understand things once you've done an implementation (even if it's going wrong). Remember to use source control (e.g. Mercurial or Subversion) so you can go back in time if one of your experiments goes wrong. =) And more than anything else, try to enjoy it. I do want to emphasize one thing, and that's making diagrams to help! –  leander Feb 26 '13 at 21:35
    
+1 I was going to post saying: Have each story return the next state, this will keep things much cleaner. You've covered that here. –  Byte56 Feb 26 '13 at 21:50

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.