Possible Function Problems

Member
Posts: 21
Joined: 2009.05
Post: #1
Greetings all,
I've been working on my Text RPG for a while now... getting it all ready for you guys. Smile While I've been programming, I feel I may be using my functions in a very unintelligent way, though am unsure.

I use functions for a lot of things. Every area in the game is stored in a function. So, if you go to town, I have a town function. If you go to the weapon shop, armor shop, inn, etc. there are functions for each. I also have a series of functions for each part of the shop. So, if you wish to buy a weapon, you go to the weapon buying function, sell a weapon - weapon selling function, etc.

The thing is, I have so many functions, I am starting to get confused. I also fear that by leaving all my functions 'open' I could be draining system resources, when I shouldn't need to. What I mean by leaving the open is:

Code:
Function1()
{
    Function2();
    return;
}

Function2()
{
    Function3();
    return;
}

Function3()
{
    etc...
}

A lot of my functions never actually close, they just move on to the next function. Is this considered bad programming? For my game, I doubt there will be many problems using this style... though on a much larger project, would there be?

Thanks for whatever light you can shed on this possible problem. Smile

~Achi

Edit: I always forget this... I am programming using C99 on Xcode 2.3.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
If you never return, you will eventually run out of stack space and crash. IIRC, the default stack size is about 8M on 10.3+, so it'll take you a while to get there. You can use the ulimit command to reduce the stack size, to see what will happen, if you want to experiment.

How about writing it like this:

Code:
typedef enum State
{
    QUITTING,
    MALL,
    HAT_SHOP,
    HAT_SHOP_BUY,
    HAT_SHOP_SELL,
    ...
} State;

State state = MALL;

void hat_shop(void)
{
    // read input
    if (buying)
    {
        state = HAT_SHOP_BUYING;
        return;
    }
    else if (selling)
    {
        state = HAT_SHOP_SELLING;
        return;
    }
    else if (leaving)
    {
        state = MALL;
        return;
    }
    else
    {
        puts("Speak English, mister!");
        return;
    }
}

// etc...

while (state != QUITTING)
{
    switch(state)
    {
    case HAT_SHOP:
        hat_shop();
        break;
    case HAT_SHOP_BUYING:
        hat_shop_buying();
        break;
    // ...
    default:
        fprintf(stderr, "Silly Achithyn, you made a bug!\n");
        abort();
    }
}

('course, you don't need all those return statements I put in hat_shop() -- they're just there for clarity)
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #3
Aside -- there are much better ways of doing this, but I don't want to confuse you with function pointers just yet Wink
Quote this message in a reply
Member
Posts: 204
Joined: 2002.09
Post: #4
The only time this becomes a technical problem is if you are calling functions recursively without a good stopping condition. Basically, you have a certain amount of room on the stack (a place in memory where things like local variables and function arguments reside) and if you have too many of these "open" functions you may eventually run out of space. In practice this is normally on the range of many, many function calls, so you are very unlikely to have a techincal problem here.
Quote this message in a reply
Member
Posts: 21
Joined: 2009.05
Post: #5
Thanks for the prompt reply guys. Smile I'll see if there is a way I can 'fix' my code without reprogramming all of it. It's not dreadfully long yet, around 2-3 thousand lines, though it would still take a bit longer than I want to spend... hmmm.

At the moment, I can get by with how it is, though your additional methods look pretty interesting. Smile I plan on programming another more advanced text based rpg in Cocoa once I finish this game.

Quote:Aside -- there are much better ways of doing this, but I don't want to confuse you with function pointers just yet.
If you don't mind, please confuse me. Rasp It's a great opportunity for me to learn more. Smile If I don't understand your example, I have plenty of resources at my finger tips to figure it out. You wouldn't believe how much this little game has taught me... I could reprogram my last game, Tic Tac Toe very easily and add a ton of fun features.

Anyway, thanks again for your help. Smile

~Achi
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #6
Well, OK...

The enum and switch statements in my example are completely redundant:

Code:
extern void mall(void);
extern void hat_shop(void);
extern void hat_shop_buying(void);
extern void hat_shop_selling(void);

void (* state)(void) = mall;

void hat_shop(void)
{
    // display prompt, read input, parse input, then:
    if (buying)
    {
        state = hat_shop_buying;
    }
    else if (selling)
    {
        state = hat_shop_selling;
    }
    else if (leaving)
    {
        state = mall;
    }
    else
    {
        puts("Speak English, mister!");
    }
}

// ...

while (state != NULL)
{
    state();
}
Quote this message in a reply
Post Reply