Compare commits
5 Commits
91903e04dc
...
e09013036f
Author | SHA1 | Date | |
---|---|---|---|
e09013036f | |||
8299f0f1cb | |||
746ae7abab | |||
bfc20bdfce | |||
42e90b8531 |
@ -7,7 +7,7 @@ endif
|
||||
|
||||
.PHONY: clean run
|
||||
|
||||
game: data/actions.c data/rooms.c data/words.c data/flags.c *.c
|
||||
game: data/actions.c data/rooms.c data/room_ins.c data/words.c data/flags.c *.c
|
||||
$(CC) *.c $(CFLAGS) -o game
|
||||
|
||||
data/%.c: data/%.txt
|
||||
|
@ -1,14 +1,17 @@
|
||||
QUIT | * | 1000 | Bye! | QUIT_GAME()
|
||||
LOOK | * | 1 | * | LOOK_ROOM()
|
||||
HELP | * | 1 | Type commands to explore the environment. Use 'LOOK' to examine the room you're in, or 'LOOK <item>' to examine an item closely. 'N', 'S', 'E', and 'W' will move you in the four cardinal directions, and 'I' will let you check your inventory. The parser is not very advanced, so do your best. 'Q', 'QUIT', or 'EXIT' will let you quit. |
|
||||
INVENTORY | * | 1 | Your inventory is empty. |
|
||||
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)
|
||||
EAST | IN(FIRST_ROOM) & ENABLED(LEVER_PULLED) | 20 | You crouch under the portcullis and enter the room. | GOTO(LAST_ROOM)
|
||||
EAST | IN(FIRST_ROOM) | 10 | There is a portcullis in the way. |
|
||||
WEST | IN(LAST_ROOM) | 10 | You crouch under the portcullis and return to the room. | GOTO(FIRST_ROOM)
|
||||
PULL | * | 1 | You don't see anything to pull |
|
||||
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. |
|
||||
PULL | IN(SECOND_ROOM) | 10 | What do you want to pull? |
|
||||
PULL LEVER | IN(SECOND_ROOM) | 100 | You pull the lever and the sound of grinding machinery comes from the first room. | ENABLE(LEVER_PULLED)
|
||||
PULL LEVER | IN(SECOND_ROOM) & ENABLED(LEVER_PULLED) | 1000 | You already pulled it. |
|
||||
|
4
01_text_adventure/data/room_ins.txt
Normal file
4
01_text_adventure/data/room_ins.txt
Normal file
@ -0,0 +1,4 @@
|
||||
FIRST_ROOM | * | 1 | You are in a plain room. A doorway is on the north wall, and a portcullis obstructs a doorway to the east.
|
||||
FIRST_ROOM | ENABLED(LEVER_PULLED) | 10 | You are in a plain room. A doorway is on the north wall, and the doorway once obstructed by the portcullis is to the east.
|
||||
SECOND_ROOM | * | 1 | This is a small room. It's painted blue. There's a doorway on the south wall, and a conspicuous lever in the middle of the floor.
|
||||
LAST_ROOM | * | 1 | This room is in disrepair. A doorway is open to the west.
|
@ -1,3 +1,3 @@
|
||||
FIRST_ROOM|This is a plain room. A wooden door is on the north wall, and a beam semi-obstructs an open doorway to the east.
|
||||
SECOND_ROOM|This is a small room. It's painted blue. There's a door on the south wall.
|
||||
LAST_ROOM|This room is in disrepair. A beam partially blocks the doorway to the west.
|
||||
FIRST_ROOM
|
||||
SECOND_ROOM
|
||||
LAST_ROOM
|
||||
|
@ -7,3 +7,5 @@ SOUTH|SOUTH,S
|
||||
EAST|EAST,E
|
||||
WEST|WEST,W
|
||||
LOOK|LOOK,L
|
||||
INVENTORY|INVENTORY,I,INV
|
||||
HELP|HELP,H
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "game.h"
|
||||
#include "flag.h"
|
||||
#include "effect.h"
|
||||
#include "room_in.h"
|
||||
|
||||
void cause_effect(Game *g, Effect *e) {
|
||||
if (e == NULL) return;
|
||||
@ -12,7 +13,7 @@ void cause_effect(Game *g, Effect *e) {
|
||||
case EFFECT_NOOP:
|
||||
break;
|
||||
case EFFECT_GOTO:
|
||||
g->current_room = find_room(g->rooms, e->argument);
|
||||
change_current_room(g, find_room(g->rooms, e->argument));
|
||||
break;
|
||||
case EFFECT_INCREMENT:
|
||||
find_flag(g->flags, e->argument)->value++;
|
||||
@ -30,7 +31,7 @@ void cause_effect(Game *g, Effect *e) {
|
||||
g->should_close = true;
|
||||
break;
|
||||
case EFFECT_LOOK_ROOM:
|
||||
push_line_to_log(g->input->log, g->current_room->description);
|
||||
push_line_to_log(g->input->log, find_room_in(g)->description);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ Game *game_create(void) {
|
||||
game_load_flags(g);
|
||||
game_load_actions(g);
|
||||
game_load_rooms(g);
|
||||
game_load_room_ins(g);
|
||||
|
||||
Log *log = create_log();
|
||||
g->log = log;
|
||||
@ -33,6 +34,7 @@ Game *game_create(void) {
|
||||
|
||||
g->input = input;
|
||||
|
||||
change_current_room(g, &g->rooms->rooms[0]);
|
||||
return g;
|
||||
}
|
||||
|
||||
@ -84,3 +86,11 @@ void game_run_until_close(Game *g) {
|
||||
game_draw(g);
|
||||
}
|
||||
}
|
||||
|
||||
void change_current_room(Game *g, Room *r) {
|
||||
g->current_room = r;
|
||||
if (!r->visited) {
|
||||
push_line_to_log(g->input->log, find_room_in(g)->description);
|
||||
}
|
||||
r->visited = true;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ typedef enum CommandType {
|
||||
|
||||
#include "input.h"
|
||||
#include "room.h"
|
||||
#include "room_in.h"
|
||||
#include "log.h"
|
||||
#include "word.h"
|
||||
#include "flag.h"
|
||||
@ -27,6 +28,7 @@ struct Game {
|
||||
Input *input;
|
||||
Log *log;
|
||||
Rooms *rooms;
|
||||
RoomIns *room_ins;
|
||||
Room *current_room;
|
||||
Words *words;
|
||||
Flags *flags;
|
||||
@ -41,5 +43,6 @@ void game_run_until_close(Game *g);
|
||||
void game_handle_input(Game *g);
|
||||
void game_draw(Game *g);
|
||||
void free_game(Game *g);
|
||||
void change_current_room(Game *g, Room *r);
|
||||
|
||||
#endif
|
||||
|
@ -11,9 +11,7 @@ void load_room(Game *g, char *line) {
|
||||
g->rooms->rooms[g->rooms->count].name = malloc(strlen(token) + 1);
|
||||
strcpy(g->rooms->rooms[g->rooms->count].name, token);
|
||||
|
||||
token = strtok(NULL, "|");
|
||||
g->rooms->rooms[g->rooms->count].description = malloc(strlen(token) + 1);
|
||||
strcpy(g->rooms->rooms[g->rooms->count].description, token);
|
||||
g->rooms->rooms[g->rooms->count].visited = false;
|
||||
|
||||
g->rooms->count++;
|
||||
}
|
||||
@ -24,12 +22,10 @@ void game_load_rooms(Game *g) {
|
||||
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) {
|
||||
free(r.name);
|
||||
free(r.description);
|
||||
}
|
||||
|
||||
void free_rooms(Rooms r) {
|
||||
|
@ -4,9 +4,11 @@
|
||||
typedef struct Room Room;
|
||||
typedef struct Rooms Rooms;
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct Room {
|
||||
char *name;
|
||||
char *description;
|
||||
bool visited;
|
||||
};
|
||||
|
||||
struct Rooms {
|
||||
|
71
01_text_adventure/room_in.c
Normal file
71
01_text_adventure/room_in.c
Normal file
@ -0,0 +1,71 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "game.h"
|
||||
#include "room_in.h"
|
||||
#include "util.h"
|
||||
|
||||
void load_room_in(Game *g, char *line) {
|
||||
RoomIn *ri = &g->room_ins->room_ins[g->room_ins->count];
|
||||
ri->predicates_count = 0;
|
||||
|
||||
char *line_token_guy;
|
||||
char *line_token = strtok_r(line, "|", &line_token_guy);
|
||||
|
||||
Room *r = find_room(g->rooms, line_token);
|
||||
g->room_ins->room_ins[g->room_ins->count].room = r;
|
||||
|
||||
line_token = strtok_r(NULL, "|", &line_token_guy);
|
||||
|
||||
char *room_in_token_guy;
|
||||
char room_in_buffer[200];
|
||||
strcpy(room_in_buffer, line_token);
|
||||
char *room_in_word = strtok_r(room_in_buffer, " &", &room_in_token_guy);
|
||||
while (room_in_word != NULL) {
|
||||
Predicate *p = create_predicate(g, room_in_word);
|
||||
ri->predicates[ri->predicates_count++] = p;
|
||||
room_in_word = strtok_r(NULL, " &", &room_in_token_guy);
|
||||
}
|
||||
|
||||
line_token = strtok_r(NULL, "|", &line_token_guy);
|
||||
ri->priority = atoi(line_token);
|
||||
|
||||
line_token = strtok_r(NULL, "|", &line_token_guy);
|
||||
g->room_ins->room_ins[g->room_ins->count].description = malloc(strlen(line_token) + 1);
|
||||
strcpy(g->room_ins->room_ins[g->room_ins->count].description, line_token);
|
||||
|
||||
g->room_ins->count++;
|
||||
}
|
||||
|
||||
#include "data/room_ins.c"
|
||||
void game_load_room_ins(Game *g) {
|
||||
g->room_ins = malloc(sizeof(RoomIns));
|
||||
g->room_ins->count = 0;
|
||||
parse_multiline_string(g, data_room_ins_txt, &load_room_in);
|
||||
printf("loaded room ins\n");
|
||||
}
|
||||
|
||||
RoomIn *find_room_in(Game *g) {
|
||||
RoomIn *ri;
|
||||
int priority = -1;
|
||||
bool failed_predicate;
|
||||
for (int i = 0; i < g->room_ins->count; i++) {
|
||||
RoomIn *cri = &g->room_ins->room_ins[i];
|
||||
if (cri->priority < priority) continue;
|
||||
if (cri->room != g->current_room) continue;
|
||||
failed_predicate = false;
|
||||
|
||||
for (int j = 0; j < cri->predicates_count; j++) {
|
||||
if (!predicate_fulfilled(g, cri->predicates[j])) failed_predicate = true;
|
||||
}
|
||||
if (failed_predicate) break;
|
||||
priority = cri->priority;
|
||||
ri = cri;
|
||||
}
|
||||
|
||||
if (ri) return ri;
|
||||
|
||||
printf("Couldn't find a valid room_in\n");
|
||||
return &g->room_ins->room_ins[0];
|
||||
}
|
28
01_text_adventure/room_in.h
Normal file
28
01_text_adventure/room_in.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef _FD_ROOM_IN_
|
||||
#define _FD_ROOM_IN_
|
||||
|
||||
typedef struct RoomIn RoomIn;
|
||||
typedef struct RoomIns RoomIns;
|
||||
|
||||
#include "game.h"
|
||||
#include "room.h"
|
||||
#include "predicate.h"
|
||||
|
||||
struct RoomIn {
|
||||
Room *room;
|
||||
Predicate *predicates[10];
|
||||
int predicates_count;
|
||||
int priority;
|
||||
char *description;
|
||||
};
|
||||
|
||||
struct RoomIns {
|
||||
RoomIn room_ins[200];
|
||||
int count;
|
||||
};
|
||||
|
||||
void game_load_room_ins(Game *g);
|
||||
RoomIns *find_room_ins(Room *r);
|
||||
RoomIn *find_room_in(Game *g);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user