summaryrefslogblamecommitdiff
path: root/texad.c
blob: 91f75ba6ae7a092eff702a8ce66ac664a5925315 (plain) (tree)
1
2
3
4
5
6



                   
                  
 









                             
                           
 

                     

                      
 

                   

                          
 



                                              
 

                                                                                      
 

                                                                                             
 

                                                                           
 


                           
 


                           
 


                            
 


                            
 
                            




                           
                                                


                                                 
 
                   





                  
                                







                          
                    







                       
                         




                                                 
                                               
 
                     
                                          




                                    
     



                                   
                          


                            
                                                            




                                                                 
                         

                            
                  


































                                                   

          
                 
     

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

#include "texad.h"

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 *r[3];
    struct door *d[4];

    unsigned int i;

    w = malloc(sizeof *w);
    p = malloc(sizeof *p);

    for (i = 0; i < sizeof r / sizeof *r; i++)
        r[i] = malloc(sizeof *r);
    for (i = 0; i < sizeof d / sizeof *d; i++)
        d[i] = malloc(sizeof *d);

    r[0]->title = "The foo room";
    r[0]->description = "You are in the foo room. Sunlight streams from the windows.";

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

    r[2]->title = "The baz room";
    r[2]->description = "You are in the baz room. It is richly furnished.";

    d[0]->direction = EAST;
    d[0]->src = r[0];
    d[0]->dst = r[1];

    d[1]->direction = WEST;
    d[1]->src = r[1];
    d[1]->dst = r[0];

    d[2]->direction = NORTH;
    d[2]->src = r[1];
    d[2]->dst = r[2];

    d[3]->direction = SOUTH;
    d[3]->src = r[2];
    d[3]->dst = r[1];

    struct door *ds[][3] = {
        {d[0], NULL, NULL},
        {d[1], d[2], NULL},
        {d[3], NULL, NULL}
    };

    for (i = 0; i < sizeof r / sizeof *r; i++) {
        r[i]->doors = malloc(sizeof ds[i]);
        memcpy(r[i]->doors, ds[i], sizeof ds[i]);
    }

    p->room = r[0];

    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)
            continue;
        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 *commands; 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;
}