Q:

Is there any way to avoid using exit(0)?

I wanted to practice a little with separating logic into functions and using basic recursion in a primitive "Guess my number game", just as a sort of way to see where I'm at in my C programming. 
Here's the code:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0

char playAgain()
{
    printf("\nDo you wanna play again? ");
    char resp = 0;
    while (TRUE) {
        scanf("%c", &resp);
        if (resp == 'y') break;
        if (resp == 'n') break;
    }
    return resp;
}

void play()
{
    srand((int)time(NULL));
    int num = rand() % 10 + 1;
    int guess = 0;
    int flag = 0;
    int attempts = 0;

    printf("\nGuess the number: \n");
    while (TRUE) {
        scanf("%d", &guess);
        if (num > guess)
        {
            printf("Too low! ");
            attempts++;
        }
        else if (num < guess)
        {
            printf("Too high! ");
            attempts++;
        }
        else if (num == guess)
        {
            attempts++;
            printf("You won! You did it in %d attempts", attempts);
            char yo = playAgain();
            if (yo == 'y') play();
            else if (yo == 'n') exit(0);
            else {
                printf("Error!");
                exit(1);
            }
        }
    }

}

int main()
{
    return play();
}

Everything works but I've only managed to make it quit when the user says 'n', by using exit(0) and I've heard it's bad practice. But having spent a couple of hours just noodling around and trying all the other ways I could think of (using flags, for example), I just couldn't make it work. It works for 'y', but as soon as I enter 'n', it doesn't quit and just calls the playAgain() function one more time, or freezes altogether (nothing happens). 
I feel ashamed for not being able to solve this, but I'm out of ideas. Is there any other way, other than exit(0), to make it jump out of play() straight to return 0 in main()? The problem seems to be that I have an infinite game loop, so when the answer is 'n', I need to break out of the loop AND out of the play() function, and that has proven to be problematic. I remember being able to do this easily when I had no functions, but just all the relevant code in main(), but the whole point of this is to use functions. For example, I can't figure out how to make use of a return type of play(), so that it knows when to quit. 
P.S. As always, seeing how often people get accused of this, I assure you this is not homework because I am, and always have been, doing programming strictly as a hobby. There's no professor I answer to, apart from you :-) And trust me that I did try to figure out a solution, but nothing seems to work. It's a question of good vs. bad design, so it's especially important for my self-teaching. exit(0) seems to be a hackish solution and serves no educational purpose. 
P.P.S. By the way, I'm using xCode, and the program runs in its output window. Probably not, but maybe that's the reason quitting with 'n' doesn't work? 
SUMMARY: The code works fine except when the answer is 'n', in which case it just asks "Do you wanna play?" again, or doesn't do anything at all. 

A:

Make your play function return a result:-  int play( void ) {
then instead of exit(1) and exit(0); use return 1; and return 0;
at the end of play put return 0;
then in main
{
return play();
}

instead of recursion,  just make a loop
int play( void)
{
    srand((int)time(NULL));
    int num;
    int guess;
    int flag;

    while(1)
    {
        num = rand() % 10 + 1;
        guess = 0;
        flag = 0;
        printf("\nGuess the number %d: \n", num);
        while (1) {
            scanf("%d", &guess);
            if (num > guess)
            {
                printf("Too low! ");
            }
            else if (num < guess)
            {
                printf("Too high! ");
            }
            else if (num == guess)
            {
                printf("You won!");
                char yo = playAgain();
                if (yo == 'y') break;
                else if (yo == 'n') return 0;
                else {
                    printf("Error!");
                    return  1;
                }

            }
        }
    }

}

and if you want more of a game engine type approach
enum {  
    GUESS,
    GAMEOVER,
    QUIT,

} GAME_STATES;

typedef struct 
{
    enum GAME_STATES state;
    int num;    
    int game_over;
} guessing_game_t;

void init_game(guessing_game_t* g)
{   
    g->state = GUESS;
    g->game_over = 0;
    g->num = rand() % 10 + 1;
}

void evaluate_guess(guessing_game_t* g, int guess)
{
    if(g->num == guess)
    {
        printf("You won!");
        g->state = GAMEOVER;
    }
    else if (g->num > guess)
    {
        printf("Too low! ");
    }
    else if (g->num < guess)
    {
        printf("Too high! ");
    }
}

int input_guess( void )
{
    int guess;
    scanf("%d", &guess);
    return guess;
}

void play_again( guessing_game_t* g)
{   
    char resp = 0;

    printf("\nDo you wanna play again? ");
    scanf("%c", &resp);
    if (resp == 'y') init_game(g);
    if (resp == 'n') g->state = QUIT;

}

void play( guessing_game_t* g)
{
    while(g->state != QUIT)
    {
        switch(g->state)
        {
        case GUESS:
            evaluate_guess(g, input_guess());
            break;
        case GAMEOVER:
            play_again(g);
            break;
        }
    }
}

int main()
{
    guessing_game_t game;
    init_game(&game);
    play(&game);
}

