Compare commits
6 Commits
9ef8e88b9a
...
465ac02048
Author | SHA1 | Date | |
---|---|---|---|
465ac02048 | |||
ad6a921bef | |||
d730c3ab9f | |||
b4d93cffc2 | |||
01cf8c08db | |||
03ab78940f |
@ -3,7 +3,7 @@ CFLAGS=-Wall -lraylib -lGL -lm -lpthread -ldl -lrt -lX11
|
||||
|
||||
.PHONY: clean run
|
||||
|
||||
game: data/actions.c data/rooms.c data/transitions.c data/words.c data/flags.c *.c
|
||||
game: data/actions.c data/rooms.c data/words.c data/flags.c *.c
|
||||
$(CC) *.c $(CFLAGS) -o game
|
||||
|
||||
data/%.c: data/%.txt
|
||||
|
@ -1,9 +1,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "action.h"
|
||||
#include "effect.h"
|
||||
#include "predicate.h"
|
||||
#include "game.h"
|
||||
#include "parse.h"
|
||||
#include "util.h"
|
||||
|
||||
void load_action(Game *g, char *line) {
|
||||
@ -59,9 +61,33 @@ void load_action(Game *g, char *line) {
|
||||
|
||||
#include "data/actions.c"
|
||||
void game_load_actions(Game *g) {
|
||||
g->actions = malloc(sizeof(Actions));
|
||||
g->actions->count = 0;
|
||||
parse_multiline_string(g, data_actions_txt, &load_action);
|
||||
printf("loaded actions\n");
|
||||
}
|
||||
|
||||
Action *find_action(Actions *actions, char *command) {
|
||||
return NULL;
|
||||
Action *find_action(Game *g, const char *command) {
|
||||
Command *c = parse(g, command);
|
||||
int priority = -1;
|
||||
Action *a = NULL;
|
||||
bool failed_predicate;
|
||||
for (int i = 0; i < g->actions->count; i++) {
|
||||
Action *ca = &g->actions->actions[i];
|
||||
if (ca->priority < priority) continue;
|
||||
for (int j = 0; j < ca->words_count; j++) {
|
||||
if (c->words[j] == NULL) break;
|
||||
if (c->words[j] != ca->words[j]) break;
|
||||
failed_predicate = false;
|
||||
for (int k = 0; k < ca->predicates_count; k++) {
|
||||
if (!predicate_fulfilled(g, ca->predicates[k])) failed_predicate = true;
|
||||
}
|
||||
if (failed_predicate) break;
|
||||
if (j == ca->words_count - 1) {
|
||||
priority = ca->priority;
|
||||
a = ca;
|
||||
}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
@ -26,6 +26,6 @@ struct Actions {
|
||||
};
|
||||
|
||||
void game_load_actions(Game *g);
|
||||
Action *find_action(Actions *actions, char *command);
|
||||
Action *find_action(Game *g, const char *command);
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,14 @@
|
||||
QUIT | * | 1000 | Bye! | QUIT_GAME()
|
||||
LOOK | * | 1 | * | LOOK_ROOM()
|
||||
NORTH | * | 1 | You can't go north from here. |
|
||||
SOUTH | * | 1 | You can't go south from here. |
|
||||
EAST | * | 1 | You can't go east from here. |
|
||||
WEST | * | 1 | You can't go west from here. |
|
||||
NORTH | IN(FIRST_ROOM) | 10 | You head through the door. | GOTO(SECOND_ROOM)
|
||||
SOUTH | IN(SECOND_ROOM) | 10 | You head back through the door. | GOTO(FIRST_ROOM)
|
||||
EAST | IN(FIRST_ROOM) | 10 | You crouch under the beam and enter the room. | GOTO(LAST_ROOM)
|
||||
WEST | IN(LAST_ROOM) | 10 | You crouch under the beam and return to the room. | GOTO(FIRST_ROOM)
|
||||
PULL | * | 1 | You don't see anything to pull |
|
||||
PULL | IN(LEVER_ROOM) | 10 | What do you want to pull? |
|
||||
PULL LEVER | IN(LEVER_ROOM) | 100 | You pull the lever. Nice. | ENABLE(LEVER_PULLED)
|
||||
PULL LEVER | IN(LEVER_ROOM) & ENABLED(LEVER_PULLED) | 1000 | You already pulled it. |
|
||||
PULL | IN(FIRST_ROOM) | 10 | What do you want to pull? |
|
||||
PULL LEVER | IN(FIRST_ROOM) | 100 | You pull the lever. Nice. | ENABLE(LEVER_PULLED)
|
||||
PULL LEVER | IN(FIRST_ROOM) & ENABLED(LEVER_PULLED) | 1000 | You already pulled it. |
|
||||
|
@ -1,4 +0,0 @@
|
||||
FIRST_ROOM|N|SECOND_ROOM|You head through the door.
|
||||
SECOND_ROOM|S|FIRST_ROOM|You head back through the door.
|
||||
FIRST_ROOM|E|LAST_ROOM|You crouch under the beam and enter the room.
|
||||
LAST_ROOM|W|FIRST_ROOM|You crouch under the beam and return to the room.
|
@ -1,3 +1,9 @@
|
||||
PULL|PULL,YANK,TUG
|
||||
ROPE|ROPE,CORD,STRING,CABLE
|
||||
LEVER|LEVER
|
||||
QUIT|QUIT,Q,EXIT
|
||||
NORTH|NORTH,N
|
||||
SOUTH|SOUTH,S
|
||||
EAST|EAST,E
|
||||
WEST|WEST,W
|
||||
LOOK|LOOK,L
|
||||
|
@ -26,6 +26,12 @@ void cause_effect(Game *g, Effect *e) {
|
||||
case EFFECT_DISABLE:
|
||||
find_flag(g->flags, e->argument)->value = 0;
|
||||
break;
|
||||
case EFFECT_QUIT_GAME:
|
||||
g->should_close = true;
|
||||
break;
|
||||
case EFFECT_LOOK_ROOM:
|
||||
push_line_to_log(g->input->log, g->current_room->description);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,11 +55,17 @@ Effect *create_effect(Game *g, const char *string) {
|
||||
e->type = EFFECT_ENABLE;
|
||||
} else if (strcmp(token, "DISABLE") == 0) {
|
||||
e->type = EFFECT_DISABLE;
|
||||
} else if (strcmp(token, "QUIT_GAME") == 0) {
|
||||
e->type = EFFECT_QUIT_GAME;
|
||||
} else if (strcmp(token, "LOOK_ROOM") == 0) {
|
||||
e->type = EFFECT_LOOK_ROOM;
|
||||
}
|
||||
|
||||
token = strtok_r(NULL, ")", &strtok_guy);
|
||||
e->argument = malloc(strlen(token) + 1);
|
||||
strcpy(e->argument, token);
|
||||
if (token) {
|
||||
e->argument = malloc(strlen(token) + 1);
|
||||
strcpy(e->argument, token);
|
||||
}
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
@ -80,5 +92,11 @@ void print_effect(Effect *e) {
|
||||
case EFFECT_DISABLE:
|
||||
printf("DISABLE(%s)", e->argument);
|
||||
break;
|
||||
case EFFECT_QUIT_GAME:
|
||||
printf("QUIT_GAME()");
|
||||
break;
|
||||
case EFFECT_LOOK_ROOM:
|
||||
printf("LOOK_ROOM()");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ typedef enum EffectType {
|
||||
EFFECT_DECREMENT,
|
||||
EFFECT_ENABLE,
|
||||
EFFECT_DISABLE,
|
||||
EFFECT_QUIT_GAME,
|
||||
EFFECT_LOOK_ROOM,
|
||||
} EffectType;
|
||||
|
||||
#include "game.h"
|
||||
|
@ -13,14 +13,16 @@ void load_flag(Game *g, char *line) {
|
||||
|
||||
token = strtok(NULL, "|");
|
||||
flag->value = atoi(token);
|
||||
printf("AGH %s\n", token);
|
||||
|
||||
g->flags->count++;
|
||||
}
|
||||
|
||||
#include "data/flags.c"
|
||||
void game_load_flags(Game *g) {
|
||||
g->flags = malloc(sizeof(Flags));
|
||||
g->flags->count = 0;
|
||||
parse_multiline_string(g, data_flags_txt, &load_flag);
|
||||
printf("loaded flags\n");
|
||||
}
|
||||
|
||||
int flag_value(Flags *f, char *key) {
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include "game.h"
|
||||
#include "transition.h"
|
||||
#include "input.h"
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
@ -11,16 +10,16 @@
|
||||
#include "flag.h"
|
||||
#include "predicate.h"
|
||||
#include "action.h"
|
||||
#include "parse.h"
|
||||
|
||||
Game *game_create(void) {
|
||||
Game *g = malloc(sizeof(Game));
|
||||
g->should_close = false;
|
||||
|
||||
g->rooms = malloc(sizeof(Rooms));
|
||||
g->rooms->count = 0;
|
||||
|
||||
g->transitions = malloc(sizeof(Transitions));
|
||||
g->transitions->count = 0;
|
||||
game_load_words(g);
|
||||
game_load_flags(g);
|
||||
game_load_actions(g);
|
||||
game_load_rooms(g);
|
||||
|
||||
Log *log = create_log();
|
||||
g->log = log;
|
||||
@ -34,15 +33,6 @@ Game *game_create(void) {
|
||||
|
||||
g->input = input;
|
||||
|
||||
g->words = malloc(sizeof(Words));
|
||||
g->words->count = 0;
|
||||
|
||||
g->flags = malloc(sizeof(Flags));
|
||||
g->flags->count = 0;
|
||||
|
||||
g->actions = malloc(sizeof(Actions));
|
||||
g->actions->count = 0;
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
@ -53,83 +43,26 @@ void free_game(Game *g) {
|
||||
free(g);
|
||||
}
|
||||
|
||||
bool string_in(const char *input, ...) {
|
||||
va_list argp;
|
||||
va_start(argp, input);
|
||||
char *candidate;
|
||||
while ((candidate = va_arg(argp, char*))) {
|
||||
if (strcmp(input, candidate) == 0) {
|
||||
va_end(argp);
|
||||
return true;
|
||||
#define INVALID_COMMAND "I don't know how to %s"
|
||||
void game_handle_command(Game *g, const char *command) {
|
||||
if (strlen(command) == 0) {
|
||||
push_line_to_log(g->input->log, "?");
|
||||
return;
|
||||
}
|
||||
|
||||
Action *a = find_action(g, command);
|
||||
if (a) {
|
||||
if (strcmp(a->description, "*") != 0) push_line_to_log(g->input->log, a->description);
|
||||
for (int i = 0; i < a->effects_count; i++) {
|
||||
cause_effect(g, a->effects[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Command command_from_string(const char *string) {
|
||||
if (string_in(string, "QUIT", "Q", "EXIT", "CLOSE", NULL)) {
|
||||
return COMMAND_QUIT;
|
||||
}
|
||||
if (string_in(string, "LOOK", "L", NULL)) {
|
||||
return COMMAND_LOOK;
|
||||
}
|
||||
if (string_in(string, "NORTH", "N", NULL)) {
|
||||
return COMMAND_NORTH;
|
||||
}
|
||||
if (string_in(string, "SOUTH", "S", NULL)) {
|
||||
return COMMAND_SOUTH;
|
||||
}
|
||||
if (string_in(string, "EAST", "E", NULL)) {
|
||||
return COMMAND_EAST;
|
||||
}
|
||||
if (string_in(string, "WEST", "W", NULL)) {
|
||||
return COMMAND_WEST;
|
||||
}
|
||||
|
||||
return COMMAND_UNKNOWN;
|
||||
}
|
||||
|
||||
#define INVALID_DIRECTIONAL_COMMAND "I can't go %s from here"
|
||||
void game_handle_directional_command(Game *g, const char *c) {
|
||||
Room *r = g->current_room;
|
||||
Transition *transition = find_transition(g->transitions, r, command_from_string(c));
|
||||
|
||||
if (transition) {
|
||||
push_line_to_log(g->input->log, transition->description);
|
||||
g->current_room = transition->to;
|
||||
} else {
|
||||
char *response = malloc(strlen(INVALID_DIRECTIONAL_COMMAND) + strlen(c) + 1);
|
||||
sprintf(response, INVALID_DIRECTIONAL_COMMAND, c);
|
||||
char *response = malloc(strlen(INVALID_COMMAND) + strlen(command) + 1);
|
||||
sprintf(response, INVALID_COMMAND, command);
|
||||
push_line_to_log(g->input->log, response);
|
||||
free(response);
|
||||
}
|
||||
}
|
||||
|
||||
#define INVALID_COMMAND "I don't know how to %s"
|
||||
void game_handle_command(Game *g, const char *command) {
|
||||
Input *input = g->input;
|
||||
|
||||
switch (command_from_string(command)) {
|
||||
case COMMAND_QUIT:
|
||||
g->should_close = true;
|
||||
break;
|
||||
case COMMAND_LOOK:
|
||||
push_line_to_log(input->log, g->current_room->description);
|
||||
break;
|
||||
case COMMAND_NORTH:
|
||||
case COMMAND_SOUTH:
|
||||
case COMMAND_EAST:
|
||||
case COMMAND_WEST:
|
||||
game_handle_directional_command(g, command);
|
||||
break;
|
||||
default:
|
||||
char *response = malloc(strlen(INVALID_COMMAND) + strlen(command) + 1);
|
||||
sprintf(response, INVALID_COMMAND, command);
|
||||
push_line_to_log(input->log, response);
|
||||
free(response);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void game_handle_input(Game *g) {
|
||||
|
@ -1,9 +1,11 @@
|
||||
#ifndef _FD_GAME_
|
||||
#define _FD_GAME_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct Game Game;
|
||||
|
||||
typedef enum Command {
|
||||
typedef enum CommandType {
|
||||
COMMAND_LOOK,
|
||||
COMMAND_QUIT,
|
||||
COMMAND_UNKNOWN,
|
||||
@ -11,12 +13,10 @@ typedef enum Command {
|
||||
COMMAND_SOUTH,
|
||||
COMMAND_EAST,
|
||||
COMMAND_WEST,
|
||||
} Command;
|
||||
} CommandType;
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "input.h"
|
||||
#include "room.h"
|
||||
#include "transition.h"
|
||||
#include "log.h"
|
||||
#include "word.h"
|
||||
#include "flag.h"
|
||||
@ -28,14 +28,13 @@ struct Game {
|
||||
Log *log;
|
||||
Rooms *rooms;
|
||||
Room *current_room;
|
||||
Transitions *transitions;
|
||||
Words *words;
|
||||
Flags *flags;
|
||||
Actions *actions;
|
||||
};
|
||||
|
||||
Game *game_create(void);
|
||||
Command command_from_string(const char *string);
|
||||
CommandType command_from_string(const char *string);
|
||||
void game_handle_command(Game *g, const char *command);
|
||||
void game_load_rooms(Game *g);
|
||||
void game_run_until_close(Game *g);
|
||||
|
@ -1,53 +1,16 @@
|
||||
#include "game.h"
|
||||
#include "../raylib.h"
|
||||
#include "log.h"
|
||||
#include "input.h"
|
||||
#include "parse.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define TARGET_FPS 60
|
||||
#include "../raylib.h"
|
||||
|
||||
#include "game.h"
|
||||
|
||||
int main(void) {
|
||||
InitWindow(800, 450, "Text Adventure");
|
||||
SetTargetFPS(TARGET_FPS);
|
||||
SetTargetFPS(60);
|
||||
|
||||
Game *g = game_create();
|
||||
game_load_rooms(g);
|
||||
g->current_room = &g->rooms->rooms[0];
|
||||
game_load_transitions(g);
|
||||
game_load_words(g);
|
||||
game_load_flags(g);
|
||||
game_load_actions(g);
|
||||
|
||||
for (int i = 0; i < g->actions->count; i++) {
|
||||
for (int j = 0; j < g->actions->actions[i].words_count; j++) {
|
||||
printf("%s ", g->actions->actions[i].words[j]->word);
|
||||
}
|
||||
|
||||
printf("|");
|
||||
for (int j = 0; j < g->actions->actions[i].predicates_count; j++) {
|
||||
if (j > 0) printf(" & ");
|
||||
print_predicate(g->actions->actions[i].predicates[j]);
|
||||
}
|
||||
|
||||
printf("|%d|%s|", g->actions->actions[i].priority, g->actions->actions[i].description);
|
||||
|
||||
for (int j = 0; j < g->actions->actions[i].effects_count; j++) {
|
||||
if (j > 0) printf(" & ");
|
||||
print_effect(g->actions->actions[i].effects[j]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("before action\n");
|
||||
printf("lever_pulled: %d\n", flag_value(g->flags, "LEVER_PULLED"));
|
||||
cause_effect(g, g->actions->actions[2].effects[0]);
|
||||
printf("after action\n");
|
||||
printf("lever_pulled: %d\n", flag_value(g->flags, "LEVER_PULLED"));
|
||||
|
||||
game_run_until_close(g);
|
||||
CloseWindow();
|
||||
|
@ -3,28 +3,27 @@
|
||||
#include <string.h>
|
||||
#include "game.h"
|
||||
#include "word.h"
|
||||
#include "parse.h"
|
||||
|
||||
Command *parse(Game *g, const char *typed_command) {
|
||||
Command *c = malloc(sizeof(Command));
|
||||
for (int i = 0; i < MAX_WORDS_IN_COMMAND; i++) {
|
||||
c->words[i] = NULL;
|
||||
}
|
||||
|
||||
#define MAX_WORDS_IN_COMMAND 4
|
||||
void parse(Game *g, char *typed_command) {
|
||||
printf("Typed command: %s\n", typed_command);
|
||||
char *bluh = malloc(strlen(typed_command) + 1);
|
||||
strcpy(bluh, typed_command);
|
||||
|
||||
Word **command = malloc(MAX_WORDS_IN_COMMAND * sizeof(Word));
|
||||
int word_count = 0;
|
||||
char *token = strtok(bluh, " ");
|
||||
|
||||
while (word_count < MAX_WORDS_IN_COMMAND && token != NULL) {
|
||||
command[word_count] = find_word(g->words, token);
|
||||
c->words[word_count] = find_word(g->words, token);
|
||||
|
||||
word_count++;
|
||||
token = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
for(int i = 0; i < word_count; i++) {
|
||||
printf("%s ", command[i]->word);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
free(bluh);
|
||||
return c;
|
||||
}
|
||||
|
@ -1,7 +1,15 @@
|
||||
#ifndef _FD_PARSE_
|
||||
#define _FD_PARSE_
|
||||
#include "game.h"
|
||||
|
||||
void parse(Game *g, char *typed_command);
|
||||
typedef struct Command Command;
|
||||
|
||||
#include "game.h"
|
||||
#include "word.h"
|
||||
|
||||
#define MAX_WORDS_IN_COMMAND 4
|
||||
struct Command {
|
||||
Word *words[4];
|
||||
};
|
||||
Command *parse(Game *g, const char *typed_command);
|
||||
|
||||
#endif
|
||||
|
@ -20,7 +20,11 @@ void load_room(Game *g, char *line) {
|
||||
|
||||
#include "data/rooms.c"
|
||||
void game_load_rooms(Game *g) {
|
||||
g->rooms = malloc(sizeof(Rooms));
|
||||
g->rooms->count = 0;
|
||||
parse_multiline_string(g, data_rooms_txt, &load_room);
|
||||
printf("loaded rooms\n");
|
||||
g->current_room = &g->rooms->rooms[0];
|
||||
}
|
||||
|
||||
void free_room(Room r) {
|
||||
|
@ -1,37 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "transition.h"
|
||||
#include "game.h"
|
||||
#include "util.h"
|
||||
|
||||
void load_transition(Game *g, char *line) {
|
||||
char *token = strtok(line, "|");
|
||||
g->transitions->transitions[g->transitions->count].from = find_room(g->rooms, token);
|
||||
|
||||
token = strtok(NULL, "|");
|
||||
g->transitions->transitions[g->transitions->count].via = command_from_string(token);
|
||||
|
||||
token = strtok(NULL, "|");
|
||||
g->transitions->transitions[g->transitions->count].to = find_room(g->rooms, token);
|
||||
|
||||
token = strtok(NULL, "\n");
|
||||
g->transitions->transitions[g->transitions->count].description = malloc(strlen(token) + 1);
|
||||
strcpy(g->transitions->transitions[g->transitions->count].description, token);
|
||||
|
||||
g->transitions->count++;
|
||||
}
|
||||
|
||||
#include "data/transitions.c"
|
||||
void game_load_transitions(Game *g) {
|
||||
parse_multiline_string(g, data_transitions_txt, &load_transition);
|
||||
}
|
||||
|
||||
Transition *find_transition(Transitions *t, Room *from, Command via) {
|
||||
for (int i = 0; i < t->count; i++) {
|
||||
Transition *candidate = &t->transitions[i];
|
||||
if (candidate->from == from && candidate->via == via) return candidate;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#ifndef _FD_TRANSITION_
|
||||
#define _FD_TRANSITION_
|
||||
|
||||
typedef struct Transition Transition;
|
||||
typedef struct Transitions Transitions;
|
||||
|
||||
#include "game.h"
|
||||
#include "room.h"
|
||||
|
||||
struct Transition {
|
||||
Room *from;
|
||||
Command via;
|
||||
Room *to;
|
||||
char *description;
|
||||
};
|
||||
|
||||
struct Transitions {
|
||||
Transition transitions[200];
|
||||
int count;
|
||||
};
|
||||
|
||||
void game_load_transitions(Game *g);
|
||||
Transition *find_transition(Transitions *t, Room *from, Command via);
|
||||
|
||||
#endif
|
@ -23,7 +23,10 @@ void load_word(Game *g, char *line) {
|
||||
|
||||
#include "data/words.c"
|
||||
void game_load_words(Game *g) {
|
||||
g->words = malloc(sizeof(Words));
|
||||
g->words->count = 0;
|
||||
parse_multiline_string(g, data_words_txt, &load_word);
|
||||
printf("loaded words\n");
|
||||
}
|
||||
|
||||
Word *find_word(Words *words, char *word_or_syn) {
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define _FD_WORD_
|
||||
typedef struct Word Word;
|
||||
typedef struct Words Words;
|
||||
typedef struct Words Words;
|
||||
|
||||
#include "game.h"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user