Add transitions between rooms
This commit is contained in:
		
							parent
							
								
									ebbe925652
								
							
						
					
					
						commit
						db45910125
					
				| @ -9,7 +9,12 @@ | |||||||
| Game *game_create(void) { | Game *game_create(void) { | ||||||
|   Game *g = malloc(sizeof(Game)); |   Game *g = malloc(sizeof(Game)); | ||||||
|   g->should_close = false; |   g->should_close = false; | ||||||
|   g->rooms.count = 0; | 
 | ||||||
|  |   g->rooms = malloc(sizeof(Rooms)); | ||||||
|  |   g->rooms->count = 0; | ||||||
|  | 
 | ||||||
|  |   g->transitions = malloc(sizeof(Transitions)); | ||||||
|  |   g->transitions->count = 0; | ||||||
| 
 | 
 | ||||||
|   Log *log = create_log(); |   Log *log = create_log(); | ||||||
|   g->log = log; |   g->log = log; | ||||||
| @ -26,7 +31,7 @@ Game *game_create(void) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void free_game(Game *g) { | void free_game(Game *g) { | ||||||
|   free_rooms(g->rooms); |   free_rooms(*g->rooms); | ||||||
|   free_input(g->input); |   free_input(g->input); | ||||||
|   free_log(g->log); |   free_log(g->log); | ||||||
|   free(g); |   free(g); | ||||||
| @ -49,13 +54,27 @@ bool string_in(const char *input, ...) { | |||||||
| Command command_from_string(const char *string) { | Command command_from_string(const char *string) { | ||||||
|   if (string_in(string, "QUIT", "Q", "EXIT", "CLOSE", NULL)) { |   if (string_in(string, "QUIT", "Q", "EXIT", "CLOSE", NULL)) { | ||||||
|     return COMMAND_QUIT; |     return COMMAND_QUIT; | ||||||
|   } else if (string_in(string, "LOOK", "L", NULL)) { |   } | ||||||
|  |   if (string_in(string, "LOOK", "L", NULL)) { | ||||||
|     return COMMAND_LOOK; |     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; |   return COMMAND_UNKNOWN; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #define INVALID_COMMAND "I don't know how to " | ||||||
| void game_handle_command(Game *g, const char *command) { | void game_handle_command(Game *g, const char *command) { | ||||||
|   Input *input = g->input; |   Input *input = g->input; | ||||||
| 
 | 
 | ||||||
| @ -67,6 +86,10 @@ void game_handle_command(Game *g, const char *command) { | |||||||
|     push_line_to_log(input->log, g->current_room->description); |     push_line_to_log(input->log, g->current_room->description); | ||||||
|     break; |     break; | ||||||
|   default: |   default: | ||||||
|  |     char *response = malloc(strlen(INVALID_COMMAND) + strlen(command) + 1); | ||||||
|  |     sprintf(response, INVALID_COMMAND "%s", command); | ||||||
|  |     push_line_to_log(input->log, response); | ||||||
|  |     free(response); | ||||||
|     break; |     break; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @ -80,21 +103,20 @@ void game_load_rooms(Game *g) { | |||||||
|   FILE *rooms_file = fopen(ROOMS_PATH, "r"); |   FILE *rooms_file = fopen(ROOMS_PATH, "r"); | ||||||
| 
 | 
 | ||||||
|   while ((fgets(room_buffer, 2000, rooms_file)) != NULL) { |   while ((fgets(room_buffer, 2000, rooms_file)) != NULL) { | ||||||
| 
 |  | ||||||
|     char *token = strtok(room_buffer, "|"); |     char *token = strtok(room_buffer, "|"); | ||||||
| 
 | 
 | ||||||
|     g->rooms.rooms[g->rooms.count].name = malloc(strlen(token) + 1); |     g->rooms->rooms[g->rooms->count].name = malloc(strlen(token) + 1); | ||||||
|     strcpy(g->rooms.rooms[g->rooms.count].name, token); |     strcpy(g->rooms->rooms[g->rooms->count].name, token); | ||||||
| 
 | 
 | ||||||
|     token = strtok(NULL, "|"); |     token = strtok(NULL, "|"); | ||||||
|     g->rooms.rooms[g->rooms.count].description = malloc(strlen(token) + 1); |     g->rooms->rooms[g->rooms->count].description = malloc(strlen(token) + 1); | ||||||
|     strcpy(g->rooms.rooms[g->rooms.count].description, token); |     strcpy(g->rooms->rooms[g->rooms->count].description, token); | ||||||
|      |      | ||||||
|     g->rooms.count++; |     g->rooms->count++; | ||||||
|   } |   } | ||||||
|   fclose(rooms_file); |   fclose(rooms_file); | ||||||
| 
 | 
 | ||||||
|   g->current_room = &g->rooms.rooms[0]; |   g->current_room = &g->rooms->rooms[0]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void game_handle_input(Game *g) { | void game_handle_input(Game *g) { | ||||||
|  | |||||||
| @ -3,26 +3,33 @@ | |||||||
| 
 | 
 | ||||||
| typedef struct Game Game; | typedef struct Game Game; | ||||||
| 
 | 
 | ||||||
|  | typedef enum Command { | ||||||
|  |   COMMAND_LOOK, | ||||||
|  |   COMMAND_QUIT, | ||||||
|  |   COMMAND_UNKNOWN, | ||||||
|  |   COMMAND_NORTH, | ||||||
|  |   COMMAND_SOUTH, | ||||||
|  |   COMMAND_EAST, | ||||||
|  |   COMMAND_WEST, | ||||||
|  | } Command; | ||||||
|  | 
 | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
| #include "input.h" | #include "input.h" | ||||||
| #include "room.h" | #include "room.h" | ||||||
|  | #include "transition.h" | ||||||
| #include "log.h" | #include "log.h" | ||||||
| 
 | 
 | ||||||
| struct Game { | struct Game { | ||||||
|   bool should_close; |   bool should_close; | ||||||
|   Input *input; |   Input *input; | ||||||
|   Log *log; |   Log *log; | ||||||
|   Rooms rooms; |   Rooms *rooms; | ||||||
|   Room *current_room; |   Room *current_room; | ||||||
|  |   Transitions *transitions; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| typedef enum Command { |  | ||||||
|   COMMAND_LOOK, |  | ||||||
|   COMMAND_QUIT, |  | ||||||
|   COMMAND_UNKNOWN, |  | ||||||
| } Command; |  | ||||||
| 
 |  | ||||||
| Game *game_create(void); | Game *game_create(void); | ||||||
|  | Command command_from_string(const char *string); | ||||||
| void game_handle_command(Game *g, const char *command); | void game_handle_command(Game *g, const char *command); | ||||||
| void game_load_rooms(Game *g); | void game_load_rooms(Game *g); | ||||||
| void game_run_until_close(Game *g); | void game_run_until_close(Game *g); | ||||||
|  | |||||||
| @ -1,4 +1,6 @@ | |||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <stdio.h> | ||||||
| #include "room.h" | #include "room.h" | ||||||
| 
 | 
 | ||||||
| void free_room(Room r) { | void free_room(Room r) { | ||||||
| @ -12,3 +14,13 @@ void free_rooms(Rooms r) { | |||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | Room *find_room(Rooms *r, const char *name) { | ||||||
|  |   for (int i = 0; i < r->count; i++) { | ||||||
|  |     if (strcmp(r->rooms[i].name, name) == 0) { | ||||||
|  |       return &r->rooms[i]; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   printf("Couldn't find room %s\n", name); | ||||||
|  |   return NULL; | ||||||
|  | } | ||||||
|  | |||||||
| @ -16,5 +16,6 @@ struct Rooms { | |||||||
| 
 | 
 | ||||||
| void free_room(Room r); | void free_room(Room r); | ||||||
| void free_rooms(Rooms r); | void free_rooms(Rooms r); | ||||||
|  | Room *find_room(Rooms *r, const char *name); | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -1,3 +1,3 @@ | |||||||
| FIRST_ROOM|This is the initial room in the game. Nothing special about it. | 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 another room. This one is painted blue. | SECOND_ROOM|This is a small room. It's painted blue. There's a door on the south wall. | ||||||
| LAST_ROOM|Another unremarkable room. | LAST_ROOM|This room is in disrepair. A beam partially blocks the doorway to the west. | ||||||
|  | |||||||
							
								
								
									
										32
									
								
								01_text_adventure/transition.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								01_text_adventure/transition.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include "transition.h" | ||||||
|  | #include "game.h" | ||||||
|  | 
 | ||||||
|  | #define TRANSITIONS_PATH "./transitions.txt" | ||||||
|  | 
 | ||||||
|  | char transition_buffer[2001]; | ||||||
|  | void game_load_transitions(Game *g) { | ||||||
|  |   FILE *transitions_file = fopen(TRANSITIONS_PATH, "r"); | ||||||
|  | 
 | ||||||
|  |   while ((fgets(transition_buffer, 2000, transitions_file)) != NULL) { | ||||||
|  |     char *token = strtok(transition_buffer, "|"); | ||||||
|  | 
 | ||||||
|  |     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, "|"); | ||||||
|  |     g->transitions->transitions[g->transitions->count].description = malloc(strlen(token) + 1); | ||||||
|  |     strcpy(g->transitions->transitions[g->transitions->count].description, token); | ||||||
|  |      | ||||||
|  |     g->transitions->count++; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   fclose(transitions_file); | ||||||
|  | } | ||||||
							
								
								
									
										24
									
								
								01_text_adventure/transition.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								01_text_adventure/transition.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | #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); | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										4
									
								
								01_text_adventure/transitions.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								01_text_adventure/transitions.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | 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 crounch under the beam and return to the room. | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user