summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2016-12-02 10:16:11 +1300
committerTom Ryder <tom@sanctum.geek.nz>2016-12-02 10:16:11 +1300
commit3d79228ad58825ffd704d75c2ab47f55b9acc58c (patch)
treeee10b8ccea84e9410dcf1e16161c14cdfb497599
downloadtexad-3d79228ad58825ffd704d75c2ab47f55b9acc58c.tar.gz
texad-3d79228ad58825ffd704d75c2ab47f55b9acc58c.zip
First commit
-rw-r--r--Makefile9
-rw-r--r--texad.c216
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
diff --git a/texad.c b/texad.c
new file mode 100644
index 0000000..9a09acf
--- /dev/null
+++ b/texad.c
@@ -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;
+ }
+}