diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2016-12-02 10:16:11 +1300 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2016-12-02 10:16:11 +1300 |
commit | 3d79228ad58825ffd704d75c2ab47f55b9acc58c (patch) | |
tree | ee10b8ccea84e9410dcf1e16161c14cdfb497599 | |
download | texad-3d79228ad58825ffd704d75c2ab47f55b9acc58c.tar.gz texad-3d79228ad58825ffd704d75c2ab47f55b9acc58c.zip |
First commit
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | texad.c | 216 |
2 files changed, 225 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..34a8185 --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +.PHONY: all clean + +CC = clang +CFLAGS = -std=c99 -Weverything -Wno-padded + +all : texad + +clean : + rm -f texad @@ -0,0 +1,216 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define INPUT_LIMIT 256 +#define PROMPT "> " + +typedef enum { + UNKNOWN, + LOOK, + GO_NORTH, + GO_SOUTH, + GO_EAST, + GO_WEST, + QUIT +} action; + +typedef enum { + NORTH, + SOUTH, + EAST, + WEST +} direction; + +typedef struct room { + char *title; + char *description; + struct door **doors; +} room; + +typedef struct door { + direction direction; + struct room *src; + struct room *dst; +} door; + +typedef struct world { + struct player *player; +} world; + +typedef struct player { + char *name; + struct room *room; +} player; + +typedef struct { + action action; + char *string; +} command; + +world *genesis(void); +void apocalypse(world*); +action parse(char*); +void move(player*, direction); +void look(room*); +int loop(world*); + +static command commands[] = { + {LOOK , "l" }, + {GO_NORTH , "n" }, + {GO_SOUTH , "s" }, + {GO_EAST , "e" }, + {GO_WEST , "w" }, + {QUIT , "q" }, + {UNKNOWN , NULL} +}; + +world *genesis(void) +{ + world *w; + player *p; + room *r1, *r2, *r3; + door *d12, *d21, *d23, *d32; + + w = (world*) malloc(sizeof(world)); + p = (player*) malloc(sizeof(player)); + r1 = (room*) malloc(sizeof(room)); + r2 = (room*) malloc(sizeof(room)); + r3 = (room*) malloc(sizeof(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 = (door*) malloc(sizeof(door)); + d21 = (door*) malloc(sizeof(door)); + d23 = (door*) malloc(sizeof(door)); + d32 = (door*) malloc(sizeof(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; + + door *ds1[] = {d12, NULL}; + door *ds2[] = {d21, d23, NULL}; + door *ds3[] = {d32, NULL}; + + r1->doors = ds1; + r2->doors = ds2; + r3->doors = ds3; + + p->room = r1; + + w->player = p; + + return w; +} + +void apocalypse(world *w) +{ + free(w->player->room); + free(w->player); + free(w); +} + +int main(void) +{ + world *w; + + w = genesis(); + while (loop(w)); + apocalypse(w); + + exit(EXIT_SUCCESS); +} + +void look(room *r) +{ + printf("%s: %s\n", r->title, r->description); + return; +} + +void move(player *p, direction dir) +{ + 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; +} + +action parse(char *s) +{ + unsigned long i; + s[strcspn(s, "\n")] = 0; + for (i = 0; i < sizeof(commands) / sizeof(command); i++) + if (commands[i].string && !strcmp(commands[i].string, s)) + return commands[i].action; + return UNKNOWN; +} + +int loop(world *w) +{ + char input[INPUT_LIMIT]; + 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; + } +} |