summaryrefslogblamecommitdiff
path: root/texad.c
blob: 1b631c30d72ada876630deead02c57bf5eacd674 (plain) (tree)
1
2
3
4
5
6
7
8






                       
             






             
  
 
                



          
  
 
             


                        
  
 

                             

                     
  
 
              
                          
  
 
               

                      
  
 

                       
                 
  
 





                                          
 
                                    








                      
                           
 



                                       
 




                                                       









                                                                                           



                                                     
















                           


                                          











                    
                                







                          
                    







                       
                         




                                                 
                                               
 
                     









                                        
                          


                            
                                                                   




                                                                 
                         

                            
                  







































                                                   
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define INPUT_LIMIT 256
#define PROMPT "> "

enum action {
    UNKNOWN,
    LOOK,
    GO_NORTH,
    GO_SOUTH,
    GO_EAST,
    GO_WEST,
    QUIT
};

enum direction {
    NORTH,
    SOUTH,
    EAST,
    WEST
};

struct room {
    char *title;
    char *description;
    struct door **doors;
};

struct door {
    enum direction direction;
    struct room *src;
    struct room *dst;
};

struct world {
    struct player *player;
};

struct player {
    char *name;
    struct room *room;
};

struct command {
    enum action action;
    char *string;
};

struct world *genesis(void);
void apocalypse(struct world*);
enum action parse(char*);
void move(struct player*, enum direction);
void look(struct room*);
int loop(struct world*);

static struct command commands[] = {
    {LOOK     , "l" },
    {GO_NORTH , "n" },
    {GO_SOUTH , "s" },
    {GO_EAST  , "e" },
    {GO_WEST  , "w" },
    {QUIT     , "q" },
    {UNKNOWN  , NULL}
};

struct world *genesis(void)
{
    struct world *w;
    struct player *p;
    struct room *r1, *r2, *r3;
    struct door *d12, *d21, *d23, *d32;

    w = (struct world*) malloc(sizeof(struct world));
    p = (struct player*) malloc(sizeof(struct player));
    r1 = (struct room*) malloc(sizeof(struct room));
    r2 = (struct room*) malloc(sizeof(struct room));
    r3 = (struct room*) malloc(sizeof(struct room));

    r1->title = "The foo room";
    r1->description = "You are in the foo room. Sunlight streams from the windows.";

    r2->title = "The bar room";
    r2->description = "You are in the bar room. A vague sense of despair washes over you.";

    r3->title = "The baz room";
    r3->description = "You are in the baz room. It is richly furnished.";

    d12 = (struct door*) malloc(sizeof(struct door));
    d21 = (struct door*) malloc(sizeof(struct door));
    d23 = (struct door*) malloc(sizeof(struct door));
    d32 = (struct door*) malloc(sizeof(struct door));

    d12->direction = EAST;
    d12->src = r1;
    d12->dst = r2;

    d21->direction = WEST;
    d21->src = r2;
    d21->dst = r1;

    d23->direction = NORTH;
    d23->src = r2;
    d23->dst = r3;

    d32->direction = SOUTH;
    d32->src = r3;
    d32->dst = r2;

    struct door *ds1[] = {d12, NULL};
    struct door *ds2[] = {d21, d23, NULL};
    struct door *ds3[] = {d32, NULL};

    r1->doors = ds1;
    r2->doors = ds2;
    r3->doors = ds3;

    p->room = r1;

    w->player = p;

    return w;
}

void apocalypse(struct world *w)
{
    free(w->player->room);
    free(w->player);
    free(w);
}

int main(void)
{
    struct world *w;

    w = genesis();
    while (loop(w));
    apocalypse(w);

    exit(EXIT_SUCCESS);
}

void look(struct room *r)
{
    printf("%s: %s\n", r->title, r->description);
    return;
}

void move(struct player *p, enum direction dir)
{
    struct door **ds;
    for (ds = p->room->doors; *ds; ds++)
        if ((*ds)->direction == dir) {
            p->room = (*ds)->dst;
            look(p->room);
            return;
        }
    puts("You can't go that way.");
    return;
}

enum action parse(char *s)
{
    unsigned long i;
    s[strcspn(s, "\n")] = 0;
    for (i = 0; i < sizeof(commands) / sizeof(struct command); i++)
        if (commands[i].string && !strcmp(commands[i].string, s))
            return commands[i].action;
    return UNKNOWN;
}

int loop(struct world *w)
{
    char input[INPUT_LIMIT];
    enum action a;

    printf("%s", PROMPT);
    if (fgets(input, INPUT_LIMIT, stdin) != NULL) {
        a = parse(input);

        switch (a) {

            case LOOK:
                look(w->player->room);
                return 1;

            case QUIT:
                return 0;

            case GO_NORTH:
                move(w->player, NORTH);
                return 1;

            case GO_SOUTH:
                move(w->player, SOUTH);
                return 1;

            case GO_EAST:
                move(w->player, EAST);
                return 1;

            case GO_WEST:
                move(w->player, WEST);
                return 1;

            case UNKNOWN:
                printf("What is \"%s\"?\n", input);
                return 1;
        }

    } else {
        puts("");
        return 0;
    }
}