diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e7b68afef..f1a6a3193b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ find_package(Curses REQUIRED) set(CHIVENTURE_MODULES action_management battle checkpointing cli common custom-actions game-state libobj npc openworld playerclass skilltrees ui wdl) + include_directories(include/) add_subdirectory(src/action_management) diff --git a/include/openworld/default_items.h b/include/openworld/default_items.h new file mode 100644 index 0000000000..a9a27ae96f --- /dev/null +++ b/include/openworld/default_items.h @@ -0,0 +1,14 @@ +#ifndef _DEFAULT_ITEM_H +#define _DEFAULT_ITEM_H + +#include "common/uthash.h" +#include "default_items.h" +#include "game-state/game_state_common.h" +#include "game-state/item.h" + +/*get_default_items() returns all the default defined +* items in a hash table. +*/ +item_hash_t *get_default_items(); + +#endif /* _DEFAULT_ITEM_H */ diff --git a/include/openworld/default_rooms.h b/include/openworld/default_rooms.h new file mode 100644 index 0000000000..7a8746d1ae --- /dev/null +++ b/include/openworld/default_rooms.h @@ -0,0 +1,36 @@ +#ifndef _DEFAULT_ROOM_H +#define _DEFAULT_ROOM_H + +#include "default_items.h" +#include "game-state/game_state_common.h" +#include "game-state/room.h" +#include "gen_structs.h" + +/* copy_item_to_hash is a helper function to deep copy +* items from the src hash to the dest hash using name +* as the key for lookup. +* Input: +* - item_hash_t *dst, *src: the source and destination hash tables +* - char *name: the key for look up +* Output: SUCCESS or FAILURE +*/ +int copy_item_to_hash(item_hash_t **dst, item_hash_t *src, char *name); + + +/*make_default_rooms adds all the defined default rooms+items for a themed +* "bucket" (a name for a group of related rooms). In the case where the +* "bucket" IS NOT part of the default definitions, there are optional +* parameters for a short_desc, long_desc that will be used to define a +* new roomspec. In future springs, the npc struct will be added. +* +* Input: +* - char *bucket: the string identifier for the theme of the set of rooms +* char **sh_desc: optional , unless "bucket" IS NOT default defn, use as a room short_desc. +* - char *l_desc: similar purpose to sh_desc but for long_desc +* +* Output: +* - roomspec_t updated hash +*/ +roomspec_t *make_default_room(char *bucket, char *sh_desc, char *l_desc); + +#endif /* _DEFAULT_ROOM_H */ diff --git a/include/openworld/gen_structs.h b/include/openworld/gen_structs.h index 890e14c5fa..3b7f527921 100644 --- a/include/openworld/gen_structs.h +++ b/include/openworld/gen_structs.h @@ -1,209 +1,215 @@ -/* Team RPG-Openworld - * - * Gen-Structs header file - * - * gen_structs.h: This file: contains all of the necessary high level structs - * that are necessary for generating a room. - * - * Create the generation structs that will contain the necessary info for - * autogenerating a room - * - * See chiventure/src/openworld/gen_structs.c source code to see implementation. - */ - -#include -#include -#include -#include "game-state/game.h" -#include "game-state/game_state_common.h" - -/* -- STRUCTS -- */ - -/* roomspec_t struct - * This struct will carry the necessary info for creating a room. - * The struct contains: - * - char *short_desc: short description for room - * - char *long_desc: long description for room - * - item_hash_t *items: hash table of items in room - * - path_hash_t *paths: hash table of paths in room - */ -typedef struct roomspec { - char *short_desc; - char *long_desc; - item_hash_t *items; -} roomspec_t; - -/* speclist_t struct - * This struct functions as a llist of all the roomspec_t's - * The struct contains: - * - roomspec_t *spec: pointer to some room specification - * - speclist_t *next: pointer to the next part of the list. - */ -typedef struct speclist { - roomspec_t *spec; - struct speclist *prev; - struct speclist *next; -}speclist_t; - -/* gencontext_t struct - * This struct will carry the info for the generation algorithm - * The struct contains: - * - path_t *open_paths: the open path we are connecting the room to; - * - int level: this is the players current level - * - int num_open_paths: the number of openpaths that need to be generated in the room. - * - speclist_t *speclist: the llist of roomspect_t that each hold the room info. - */ -typedef struct gencontext { - path_t *open_paths; - int num_open_paths; - int level; - speclist_t *speclist; -} gencontext_t; - - -/* -- FUNCTIONS -- */ - - -/* GENCONTEXT */ - -/* init_gencontext - * Initializes a gencontext_t struct with the given paramaters. The gencontext - * must be pointing to some valid memory. - * - * parameters: - * - context: the gencontext* struct that we are initializing. - * - level: stores the players level. - * - openpaths: number of open paths to generate in the room - * - numnpcs: the number of npcs to generate in the room - * - speclist: the speclist we are choosing our roomspec from - * - * returns: - * SUCCESS - for SUCCESS - * FAILURE - if failed to initialize - */ -int init_gencontext(gencontext_t *context, path_t *open_paths, int level, int num_open_paths, speclist_t *speclist); - -/* gencontext_new - * Creates a new gencontext_t* based off the given parameters. - * - * parameters: - * - level: stores the players level. - * - openpaths: number of open paths to generate in the room - * - numnpcs: the number of npcs to generate in the room - * - speclist: the speclist we are choosing our roomspec from - * - * returns: - * gencontext_t *contextnew - the new gencontext - * NULL - if fails to create a new gencontext. - */ -gencontext_t* gencontext_new(path_t *open_paths, int level, int num_openpaths, speclist_t *speclist); - -/* gencontext_free - * Frees a gencontext_t* and returns whether or not it was successful - * - * parameters: - * - context: gencontext_t* that we are attempting to fre - * - * returns: - * SUCCESS - for SUCCESS - * FAILURE - if failed to free - */ -int gencontext_free(gencontext_t *context); - -/* ROOMSPEC */ - -/* init_roomspec - * Initializes a roomspec_t struct with the given paramaters. The roomspec - * must be pointing to some valid memory. - * - * parameters: - * - spec: the pointer to the roomspec_t we are initializing - * - short_desc: the short description - * - long_desc: the long description - * - items: ptr to the hash table of the items - * - * returns: - * SUCCESS - for SUCCESS - * FAILURE - if failed to initialize - */ -int init_roomspec(roomspec_t *spec, char *short_desc, char *long_desc, item_hash_t *items); - -/* roomspec_new - * Creates a new roomspec_t* based off the given parameters. - * - * parameters: - * - short_desc: the short description - * - long_desc: the long description - * - items: ptr to the hash table of the items - * - * returns: - * roomspec_t *roomspecnew - the new roomspec - * NULL - if fails to create a new roomspec. - */ -roomspec_t* roomspec_new(char *short_desc, char *long_desc, item_hash_t *items); - -/* roomspec_free - * Frees a gencontext_t* and returns whether or not it was succesful. - * - * parameters: - * - spec: roomspec_t* that we are attempting to free - * - * returns: - * SUCCESS - for SUCCESS - * FAILURE - if failed to free - */ -int roomspec_free(roomspec_t *spec); - -/* SPECLIST */ - -/* init_speclist - * Initializes a speclist_t struct with the given paramaters. The speclist - * must be pointing to some valid memory. - * - * parameters: - * - list: the pointer to the speclist_t we are initializing - * - spec: the pointer to the roomspec_t - * - * returns: - * SUCCESS - for SUCCESS - * FAILURE - if failed to initialize - */ -int init_speclist(speclist_t *list, roomspec_t *spec); - - -/* speclist_new - * Creates a speclist_t struct with the given paramaters. - * - * parameters: - * - spec: the pointer to the roomspec_t - * - * returns: - * speclist_t *listnew = the new speclist - * NULL - if failed to create a speclist - */ -speclist_t* speclist_new(roomspec_t *spec); - -/* speclist_free - * Free's a speclist_t struct and returns whether or not it was successful - * - * parameters: - * - list: the pointer to the speclist_t we are freeing - * - * returns: - * SUCCESS - for SUCCESS - * FAILURE - if failed to free - */ -int speclist_free(speclist_t *list); - -/* speclist_free_all - * Free's all speclist's from the given list - * However, this function will not free the roomspec's inside of speclist - * - * parameters: - * - list: the speclist we are freeing from and onward. - * - * returns: - * SUCCESS - for SUCCESS - * FAILURE - if failed to free - */ -int speclist_free_all(speclist_t *list); +/* Team RPG-Openworld +* +* Gen-Structs header file +* +* gen_structs.h: This file: contains all of the necessary high level structs +* that are necessary for generating a room. +* +* Create the generation structs that will contain the necessary info for +* autogenerating a room +* +* See chiventure/src/openworld/gen_structs.c source code to see implementation. +*/ + +#include +#include +#include +#include "game-state/game.h" +#include "game-state/game_state_common.h" + +/* -- STRUCTS -- */ + +/* roomspec_t struct +* This struct will carry the necessary info for creating a room. +* The struct contains: +* - char *room_name: room name and hash key +* - char *short_desc: short description for room +* - char *long_desc: long description for room +* - item_hash_t *items: hash table of items in room +* - UT_hash_handle hh: hash handle for room spec +*/ +typedef struct roomspec { + char *room_name; + char *short_desc; + char *long_desc; + item_hash_t *items; + + UT_hash_handle hh; +} roomspec_t; + +/* speclist_t struct +* This struct functions as a llist of all the roomspec_t's +* The struct contains: +* - roomspec_t *spec: pointer to some room specification +* - speclist_t *next: pointer to the next part of the list. +*/ +typedef struct speclist { + roomspec_t *spec; + struct speclist *prev; + struct speclist *next; +} speclist_t; + +/* gencontext_t struct +* This struct will carry the info for the generation algorithm +* The struct contains: +* - path_t *open_paths: the open path we are connecting the room to; +* - int level: this is the players current level +* - int num_open_paths: the number of openpaths that need to be generated in the room. +* - speclist_t *speclist: the llist of roomspect_t that each hold the room info. +*/ +typedef struct gencontext { + path_t *open_paths; + int num_open_paths; + int level; + speclist_t *speclist; +} gencontext_t; + + +/* -- FUNCTIONS -- */ + + +/* GENCONTEXT */ + +/* init_gencontext +* Initializes a gencontext_t struct with the given paramaters. The gencontext +* must be pointing to some valid memory. +* +* parameters: +i* - context: the gencontext* struct that we are initializing. +* - level: stores the players level. +* - openpaths: number of open paths to generate in the room +* - numnpcs: the number of npcs to generate in the room +* - speclist: the speclist we are choosing our roomspec from +* +* returns: +* SUCCESS - for SUCCESS +* FAILURE - if failed to initialize +*/ +int init_gencontext(gencontext_t *context, path_t *open_paths, int level, int num_open_paths, speclist_t *speclist); + +/* gencontext_new +* Creates a new gencontext_t* based off the given parameters. +* +* parameters: +* - level: stores the players level. +* - openpaths: number of open paths to generate in the room +* - numnpcs: the number of npcs to generate in the room +* - speclist: the speclist we are choosing our roomspec from +* +* returns: +* gencontext_t *contextnew - the new gencontext +* NULL - if fails to create a new gencontext. +*/ +gencontext_t* gencontext_new(path_t *open_paths, int level, int num_openpaths, speclist_t *speclist); + +/* gencontext_free +* Frees a gencontext_t* and returns whether or not it was successful +* +* parameters: +* - context: gencontext_t* that we are attempting to fre +* +* returns: +* SUCCESS - for SUCCESS +* FAILURE - if failed to free +*/ +int gencontext_free(gencontext_t *context); + +/* ROOMSPEC */ + +/* init_roomspec +* Initializes a roomspec_t struct with the given paramaters. The roomspec +* must be pointing to some valid memory. +* +* parameters: +* - spec: the pointer to the roomspec_t we are initializing +* - room_name: the room name +* - short_desc: the short description +* - long_desc: the long description +* - items: ptr to the hash table of the items +* +* returns: +* SUCCESS - for SUCCESS +* FAILURE - if failed to initialize +*/ +int init_roomspec(roomspec_t *spec, char *room_name, char *short_desc, char *long_desc, item_hash_t *items); + +/* roomspec_new +* Creates a new roomspec_t* based off the given parameters. +* +* parameters: +* - room_name: the room name +* - short_desc: the short description +* - long_desc: the long description +* - items: ptr to the hash table of the items +* +* returns: +* roomspec_t *roomspecnew - the new roomspec +* NULL - if fails to create a new roomspec. +*/ +roomspec_t* roomspec_new(char *room_name, char *short_desc, char *long_desc, item_hash_t *items); + +/* roomspec_free +* Frees a gencontext_t* and returns whether or not it was succesful. +* +* parameters: +* - spec: roomspec_t* that we are attempting to free +* +* returns: +* SUCCESS - for SUCCESS +* FAILURE - if failed to free +*/ +int roomspec_free(roomspec_t *spec); + +/* SPECLIST */ + +/* init_speclist +* Initializes a speclist_t struct with the given paramaters. The speclist +* must be pointing to some valid memory. +* +* parameters: +* - list: the pointer to the speclist_t we are initializing +* - spec: the pointer to the roomspec_t +* +* returns: +* SUCCESS - for SUCCESS +* FAILURE - if failed to initialize +*/ +int init_speclist(speclist_t *list, roomspec_t *spec); + + +/* speclist_new +* Creates a speclist_t struct with the given paramaters. +* +* parameters: +* - spec: the pointer to the roomspec_t +* +* returns: +* speclist_t *listnew = the new speclist +* NULL - if failed to create a speclist +*/ +speclist_t* speclist_new(roomspec_t *spec); + +/* speclist_free +* Free's a speclist_t struct and returns whether or not it was successful +* +* parameters: +* - list: the pointer to the speclist_t we are freeing +* +* returns: +* SUCCESS - for SUCCESS +* FAILURE - if failed to free +*/ +int speclist_free(speclist_t *list); + +/* speclist_free_all +* Free's all speclist's from the given list +* However, this function will not free the roomspec's inside of speclist +* +* parameters: +* - list: the speclist we are freeing from and onward. +* +* returns: +* SUCCESS - for SUCCESS +* FAILURE - if failed to free +*/ +int speclist_free_all(speclist_t *list); diff --git a/src/openworld/CMakeLists.txt b/src/openworld/CMakeLists.txt index 2d614559f8..c2f1b61177 100644 --- a/src/openworld/CMakeLists.txt +++ b/src/openworld/CMakeLists.txt @@ -1,4 +1,7 @@ add_library(openworld + src/gen_structs.c + src/default_rooms.c + src/default_items.c src/gen_structs.c) target_include_directories(openworld PRIVATE src/) @@ -6,4 +9,3 @@ target_include_directories(openworld PRIVATE src/) target_link_libraries(openworld wdl) target_link_libraries(openworld game-state) target_link_libraries(openworld common) - diff --git a/src/openworld/README.md b/src/openworld/README.md index a12d5bd1e5..7442fe9051 100644 --- a/src/openworld/README.md +++ b/src/openworld/README.md @@ -1 +1 @@ -Team RPG-Openworld, Auto-generate rooms +Team RPG-Openworld, Auto-generate rooms README.MD diff --git a/src/openworld/src/default_items.c b/src/openworld/src/default_items.c new file mode 100644 index 0000000000..2f75e5365f --- /dev/null +++ b/src/openworld/src/default_items.c @@ -0,0 +1,114 @@ +/* Implementations of the item struct */ +#include "common/uthash.h" +#include "game-state/room.h" +#include "openworld/default_items.h" + +/* see default_items.h */ +item_hash_t *get_default_items() +{ + + item_hash_t *hash = NULL; + + item_t *hat = item_new("hat", "a top hat", + "A black top hat with monogrammed A. L."); + HASH_ADD_STR(hash, item_id, hat); + + item_t *apple = item_new("apple", "a red apple", + "A juicy Red Delicious apple"); + HASH_ADD_STR(hash, item_id, apple); + + item_t *cow = item_new("cow", "A black and white cow", + "A black and white cow called Mavis"); + HASH_ADD_STR(hash, item_id, cow); + + item_t *fruit = item_new("fruit", "a bowl of fruit", + "A bowl of fruit resting on a surface"); + HASH_ADD_STR(hash, item_id, fruit); + + item_t *ladder = item_new("ladder", "a wood ladder", + "A wooden ladder with 5 rungs resting on a door"); + HASH_ADD_STR(hash, item_id, ladder); + + item_t *yam = item_new("yam", "a rotting yam", + "A singular rotting yam with flies flying around"); + HASH_ADD_STR(hash, item_id, yam); + + item_t *ice = item_new("ice", "a bag of ice", + "A bag of crunchy ice"); + HASH_ADD_STR(hash, item_id, ice); + + item_t *jug = item_new("jug", "a brown jug", + "A brown jug with something inside"); + HASH_ADD_STR(hash, item_id, jug); + + item_t *tray = item_new("tray", "a red plastic tray", + "A red plastic tray with some ketchup stains"); + HASH_ADD_STR(hash, item_id, tray); + + item_t *book = item_new("book", "a worn old book", + "A green book titled 'Survival Instincts'"); + HASH_ADD_STR(hash, item_id, book); + + item_t *door = item_new("door", "a normal door", + "A wooden door with a worn doorknob"); + HASH_ADD_STR(hash, item_id, door); + + item_t *pencil = item_new("pencil", "a no.2 pencil", + "A sharpened no.2 yellow pencil"); + HASH_ADD_STR(hash, item_id,pencil); + + item_t *quill = item_new("quill", "a quail quill", + "A quail quill in a pot of black ink"); + HASH_ADD_STR(hash, item_id, quill); + + item_t *watercolors = item_new("watercolors", + "a set of watercolors with brush", + "Used watercolors and dusty brush"); + HASH_ADD_STR(hash, item_id, watercolors); + + item_t *nail = item_new("nail", "a normal nail", + "A regular metail nail"); + HASH_ADD_STR(hash, item_id, nail); + + item_t *gold = item_new("gold", "three gold coins", + "Three shiny gold coins the size of your eye"); + HASH_ADD_STR(hash, item_id, gold); + + item_t *eagle = item_new("eagle", "a bald eagle", + "A bald eagle calmly perched on a ledge nearby"); + HASH_ADD_STR(hash, item_id, eagle); + + item_t *umbrella = item_new("umbrella", "a black umbrella", + "A black polyester umbrella with M.P. initials"); + HASH_ADD_STR(hash, item_id, umbrella); + + item_t *rabbit = item_new("rabbit", "a white rabbit", + "A live, fluffy white rabbit hiding in the corner"); + HASH_ADD_STR(hash, item_id, rabbit); + + item_t *zebra = item_new("zebra", "a small zebra", + "A small zebra calmly munching on some grass"); + HASH_ADD_STR(hash, item_id, zebra); + + item_t *mirror = item_new("mirror", "an oval mirror", + "A dusty oval mirror with one big crack"); + HASH_ADD_STR(hash, item_id, mirror); + + item_t *kettle = item_new("kettle", "a black kettle", + "A black kettle on a stove"); + HASH_ADD_STR(hash, item_id,kettle); + + item_t *olive = item_new("olive", "a black olive", + "A singular, unrefrigerated black olive"); + HASH_ADD_STR(hash, item_id, olive); + + item_t *video = item_new("video", "a dvd video", + "A DVD video with an illegible label"); + HASH_ADD_STR(hash, item_id, video); + + item_t *xylophone = item_new("xylophone", "a colorful xylophone", + "A children's xylophone with a pair of mallets"); + HASH_ADD_STR(hash, item_id, xylophone); + + return hash; +} diff --git a/src/openworld/src/default_rooms.c b/src/openworld/src/default_rooms.c new file mode 100644 index 0000000000..25b05cabac --- /dev/null +++ b/src/openworld/src/default_rooms.c @@ -0,0 +1,208 @@ +#include +#include + +#include "common/utlist.h" +#include "common/uthash.h" +#include "openworld/default_items.h" +#include "openworld/default_rooms.h" + +/* see default_rooms.h */ +int copy_item_to_hash(item_hash_t **dst, item_hash_t *src, char *name) +{ + item_t *old_item; + HASH_FIND_STR(src, name, old_item); + if (old_item == NULL) { + return FAILURE; + } + + item_t *new_item = item_new(old_item->item_id, old_item->short_desc, old_item->long_desc); + if (new_item == NULL) { + return FAILURE; + } + HASH_ADD_STR(*dst, item_id, new_item); + return SUCCESS; +} + +/* see default_rooms.h */ +roomspec_t *make_default_room(char *bucket, + char *sh_desc, char *l_desc) +{ + + roomspec_t *hash = NULL; + int rc; + + assert(bucket != NULL); + + if ((!!strcmp(bucket, "school")) && (!!strcmp(bucket, "farmhouse")) + && (!!strcmp(bucket, "castle"))) { + roomspec_t *room = roomspec_new(bucket, sh_desc, l_desc, NULL); + //now add to hash + HASH_ADD_STR(hash, room_name, room); + } else { + + item_hash_t *def = get_default_items(); + + //CLOSET + roomspec_t *closet = roomspec_new("closet", + "A broom closet", + "A small broom closet with supplies", + NULL); + copy_item_to_hash(&closet->items, def, "door"); + copy_item_to_hash(&closet->items, def, "tray"); + copy_item_to_hash(&closet->items, def, "mirror"); + copy_item_to_hash(&closet->items, def, "jug"); + copy_item_to_hash(&closet->items, def, "hat"); + + //HALLWAY + roomspec_t *hallway = roomspec_new("hallway", "A well-lit hallway", + "A sterile, white hallway with no windows", + NULL); + copy_item_to_hash(&hallway->items, def, "door"); + copy_item_to_hash(&hallway->items, def, "nail"); + copy_item_to_hash(&hallway->items, def, "fruit"); + copy_item_to_hash(&hallway->items, def, "tray"); + copy_item_to_hash(&hallway->items, def, "book"); + + //LIBRARY + item_hash_t *libr_items = NULL; + roomspec_t *library = roomspec_new("library", + "This is a library room with resources", + "An old, dusty library with" + " skill-boosting resources like books and potions", + NULL); + copy_item_to_hash(&library->items, def, "book"); + copy_item_to_hash(&library->items, def, "quill"); + copy_item_to_hash(&library->items, def, "pencil"); + copy_item_to_hash(&library->items, def, "video"); + copy_item_to_hash(&library->items, def, "mirror"); + + if (!strcmp(bucket, "school")) { + //CAFETERIA + roomspec_t *cafeteria = roomspec_new("cafeteria", + "A grungy cafeteria", + "A messy high school" + " cafeteria with trays and tables out", + NULL); + copy_item_to_hash(&cafeteria->items, def, "apple"); + copy_item_to_hash(&cafeteria->items, def, "tray"); + copy_item_to_hash(&cafeteria->items, def, "ice"); + copy_item_to_hash(&cafeteria->items, def, "fruit"); + copy_item_to_hash(&cafeteria->items, def, "yam"); + + //CLASSROOM + roomspec_t *classroom = roomspec_new("classroom", + "A medium-sized classroom" + " with 30 desks", + "A geography teacher's" + " classroom with 30 desks", + NULL); + copy_item_to_hash(&classroom->items, def, "book"); + copy_item_to_hash(&classroom->items, def, "door"); + copy_item_to_hash(&classroom->items, def, "pencil"); + copy_item_to_hash(&classroom->items, def, "watercolors"); + copy_item_to_hash(&classroom->items, def, "video"); + + //now add all the roomspecs to the hash + HASH_ADD_STR(hash, room_name, closet); + HASH_ADD_STR(hash, room_name, library); + HASH_ADD_STR(hash, room_name, hallway); + HASH_ADD_STR(hash, room_name, cafeteria); + HASH_ADD_STR(hash, room_name, classroom); + } else if (!strcmp(bucket, "farmhouse")) { + //BARN + roomspec_t *barn = roomspec_new("barn", "A red barn", + "A red barn with stables inside", + NULL); + copy_item_to_hash(&barn->items, def, "apple"); + copy_item_to_hash(&barn->items, def, "cow"); + copy_item_to_hash(&barn->items, def, "eagle"); + copy_item_to_hash(&barn->items, def, "rabbit"); + copy_item_to_hash(&barn->items, def, "yam"); + + //OPEN FIELD + roomspec_t *field = roomspec_new("open field", + "An open field outside", + "An open field with grass" + " and a clear view", + NULL); + copy_item_to_hash(&field->items, def, "apple"); + copy_item_to_hash(&field->items, def, "zebra"); + copy_item_to_hash(&field->items, def, "cow"); + copy_item_to_hash(&field->items, def, "eagle"); + copy_item_to_hash(&field->items, def, "rabbit"); + + //KITCHEN + roomspec_t *kitchen = roomspec_new("kitchen", + "A 60s era (outdated) kitchen", + "An outdated kitchen with obvious" + " wear-and-tear", + NULL); + copy_item_to_hash(&kitchen->items, def, "ice"); + copy_item_to_hash(&kitchen->items, def, "jug"); + copy_item_to_hash(&kitchen->items, def, "olive"); + copy_item_to_hash(&kitchen->items, def, "tray"); + copy_item_to_hash(&kitchen->items, def, "yam"); + + //LIVING ROOM + roomspec_t *living = roomspec_new("living room", + "A living room with basic items", + "A plain, unremarkable living room", + NULL); + copy_item_to_hash(&living->items, def, "watercolors"); + copy_item_to_hash(&living->items, def, "video"); + copy_item_to_hash(&living->items, def, "xylophone"); + copy_item_to_hash(&living->items, def, "hat"); + copy_item_to_hash(&living->items, def, "mirror"); + + //now add to hash + HASH_ADD_STR(hash, room_name, closet); + HASH_ADD_STR(hash, room_name, barn); + HASH_ADD_STR(hash, room_name, field); + HASH_ADD_STR(hash, room_name, kitchen); + HASH_ADD_STR(hash, room_name, living); + } else { + //DUNGEON + roomspec_t *dungeon = roomspec_new("dungeon", + "A dark dungeon", + "A dank, dark dungeon with traps" + " and enemies to battle", + NULL); + copy_item_to_hash(&dungeon->items, def, "nail"); + copy_item_to_hash(&dungeon->items, def, "book"); + copy_item_to_hash(&dungeon->items, def, "ladder"); + copy_item_to_hash(&dungeon->items, def, "gold"); + copy_item_to_hash(&dungeon->items, def, "yam"); + + //THRONE ROOM + roomspec_t *throne = roomspec_new("throne room", + "This is a throne room", + "A regal throne room decked out " + "with lavish items", + NULL); + copy_item_to_hash(&throne->items, def, "gold"); + copy_item_to_hash(&throne->items, def, "door"); + copy_item_to_hash(&throne->items, def, "mirror"); + copy_item_to_hash(&throne->items, def, "jug"); + copy_item_to_hash(&throne->items, def, "hat"); + + //Now add to hash + HASH_ADD_STR(hash, room_name, closet); + HASH_ADD_STR(hash, room_name, hallway); + HASH_ADD_STR(hash, room_name, library); + HASH_ADD_STR(hash, room_name, dungeon); + HASH_ADD_STR(hash, room_name, throne); + + } + + item_hash_t *elem, *tmp; + HASH_ITER(hh, def, elem, tmp) { + HASH_DELETE(hh, def, elem); // remove from hashtable + item_free(elem); // free the item + } + free(def); + } + return hash; +} + + + diff --git a/src/openworld/src/gen_structs.c b/src/openworld/src/gen_structs.c index 18602d1191..47d8ac6ae7 100644 --- a/src/openworld/src/gen_structs.c +++ b/src/openworld/src/gen_structs.c @@ -1,167 +1,185 @@ - /*Team RPG-Openworld - * - * autogenerate.c: This file. Function definitions of the functions - * specified in chiventure/include/autogenerate.h - * - * Room module that autogenerates string of rooms connected via paths when - * a "dead-end" room is entered - * - * See chiventure/include/autogenerate.h header file to see function - * prototypes and purposes - */ - -#include -#include -#include -#include "openworld/gen_structs.h" -#include "common/utlist.h" - -/* see gen_structs.h */ -int init_gencontext(gencontext_t *context, path_t *open_paths, int level, int num_open_paths, speclist_t *speclist){ - - if (context == NULL) - return FAILURE; - - context->level = level; - context->open_paths = open_paths; - context->num_open_paths = num_open_paths; - context->speclist = speclist; - return SUCCESS; -} - - -/* see gen_structs.h */ -gencontext_t* gencontext_new(path_t *open_paths, int level, int num_open_paths, speclist_t *speclist){ - - gencontext_t *contextnew = calloc(1, sizeof(gencontext_t)); - - if (contextnew == NULL){ - fprintf(stderr, "calloc failed to allocate space for contextnew. \n"); - return NULL; - } - - init_gencontext(contextnew, open_paths, level, num_open_paths, speclist); - return contextnew; -} - -/* see gen_structs.h */ -int gencontext_free(gencontext_t *context){ - - if (context == NULL) - return FAILURE; - - free(context); - return SUCCESS; -} - -/* see gen_structs.h */ -int roomspec_free(roomspec_t *spec){ - - if (spec == NULL) - return FAILURE; - - if (spec->short_desc){ - free(spec->short_desc); - } - - if (spec->long_desc){ - free(spec->long_desc); - } - - free(spec); - return SUCCESS; -} - -/* see gen_structs.h */ -int init_roomspec(roomspec_t *spec, char *short_desc, char *long_desc, item_hash_t *items){ - - if (spec == NULL) - return FAILURE; - - spec->short_desc = calloc(MAX_SDESC_LEN + 1, sizeof(char)); - if (spec->short_desc == NULL){ - roomspec_free(spec); - fprintf(stderr, "calloc failed to allocate space for spec's short_desc. \n"); - return FAILURE; - } - - spec->long_desc = calloc(MAX_LDESC_LEN + 1, sizeof(char)); - if (spec->long_desc == NULL){ - free(spec->short_desc); - roomspec_free(spec); - fprintf(stderr, "calloc failed to allocate space for spec's short_desc. \n"); - return FAILURE; - } - - strncpy(spec->short_desc, short_desc, MAX_SDESC_LEN); - strncpy(spec->long_desc, long_desc, MAX_LDESC_LEN); - spec->items = items; - return SUCCESS; -} - -/* see gen_structs.h */ -roomspec_t* roomspec_new(char *short_desc, char *long_desc, item_hash_t *items){ - - roomspec_t *roomspecnew = calloc(1, sizeof(roomspec_t)); - - if (roomspecnew == NULL){ - fprintf(stderr, "calloc failed to allocate space for roomspecnew. \n"); - return NULL; - } - - int check = init_roomspec(roomspecnew, short_desc, long_desc, items); - if (check != FAILURE){ - return roomspecnew; - } - return NULL; -} - -/* see gen_structs.h */ -int init_speclist(speclist_t *list, roomspec_t *spec){ - - if (list == NULL) - return FAILURE; - - list->spec = spec; - list->prev = NULL; - list->next = NULL; - return SUCCESS; -} - -/* see gen_structs.h */ -speclist_t* speclist_new(roomspec_t *spec){ - - speclist_t *listnew = calloc(1, sizeof(speclist_t)); - - if (listnew == NULL){ - fprintf(stderr, "calloc failed to allocate space for listnew. \n"); - return NULL; - } - - init_speclist(listnew, spec); - return listnew; -} - -/* see gen_structs.h */ -int speclist_free(speclist_t *list){ - - if (list == NULL) - return FAILURE; - - free(list); - return SUCCESS; -} - -/* see gen_structs.h */ -int speclist_free_all(speclist_t *list){ - - if (list == NULL) - return FAILURE; - - speclist_t *elt, *tmp; - DL_FOREACH_SAFE(list, elt, tmp){ - DL_DELETE(list, elt); - speclist_free(elt); - } - return SUCCESS; -} +/*Team RPG-Openworld +* +* autogenerate.c: This file. Function definitions of the functions +* specified in chiventure/include/autogenerate.h +* +* Room module that autogenerates string of rooms connected via paths when +* a "dead-end" room is entered +* +* See chiventure/include/autogenerate.h header file to see function +* prototypes and purposes +*/ + +#include +#include +#include +#include "openworld/gen_structs.h" +#include "common/utlist.h" + +/* see gen_structs.h */ +int init_gencontext(gencontext_t *context, path_t *open_paths, int level, int num_open_paths, speclist_t *speclist) +{ + + if (context == NULL) + return FAILURE; + + context->level = level; + context->open_paths = open_paths; + context->num_open_paths = num_open_paths; + context->speclist = speclist; + return SUCCESS; +} + + +/* see gen_structs.h */ +gencontext_t* gencontext_new(path_t *open_paths, int level, int num_open_paths, speclist_t *speclist) +{ + + gencontext_t *contextnew = calloc(1, sizeof(gencontext_t)); + + if (contextnew == NULL) { + fprintf(stderr, "calloc failed to allocate space for contextnew. \n"); + return NULL; + } + + init_gencontext(contextnew, open_paths, level, num_open_paths, speclist); + return contextnew; +} + +/* see gen_structs.h */ +int gencontext_free(gencontext_t *context) +{ + + if (context == NULL) + return FAILURE; + + free(context); + return SUCCESS; +} + +/* see gen_structs.h */ +int roomspec_free(roomspec_t *spec) +{ + + if (spec == NULL) + return FAILURE; + + if (spec->short_desc) { + free(spec->short_desc); + } + + if (spec->long_desc) { + free(spec->long_desc); + } + + free(spec); + return SUCCESS; +} + +/* see gen_structs.h */ +int init_roomspec(roomspec_t *spec, char *room_name, char *short_desc, char *long_desc, item_hash_t *items) +{ + + if (spec == NULL) + return FAILURE; + + spec->room_name = calloc(MAX_SDESC_LEN + 1, sizeof(char)); + if (spec->room_name == NULL){ + roomspec_free(spec); + fprintf(stderr, "calloc failed to allocate space for spec's room name.\n"); + return FAILURE; + } + + spec->short_desc = calloc(MAX_SDESC_LEN + 1, sizeof(char)); + if (spec->short_desc == NULL) { + roomspec_free(spec); + fprintf(stderr, "calloc failed to allocate space for spec's short_desc. \n"); + return FAILURE; + } + + spec->long_desc = calloc(MAX_LDESC_LEN + 1, sizeof(char)); + if (spec->long_desc == NULL) { + free(spec->short_desc); + roomspec_free(spec); + fprintf(stderr, "calloc failed to allocate space for spec's short_desc. \n"); + return FAILURE; + } + + strncpy(spec->room_name, room_name, MAX_SDESC_LEN); + strncpy(spec->short_desc, short_desc, MAX_SDESC_LEN); + strncpy(spec->long_desc, long_desc, MAX_LDESC_LEN); + spec->items = items; + return SUCCESS; +} + +/* see gen_structs.h */ +roomspec_t* roomspec_new(char *room_name, char *short_desc, char *long_desc, item_hash_t *items) +{ + + roomspec_t *roomspecnew = calloc(1, sizeof(roomspec_t)); + + if (roomspecnew == NULL) { + fprintf(stderr, "calloc failed to allocate space for roomspecnew. \n"); + return NULL; + } + + int check = init_roomspec(roomspecnew, room_name, short_desc, long_desc, items); + if (check == FAILURE) { + return NULL; + } + return roomspecnew; +} + +/* see gen_structs.h */ +int init_speclist(speclist_t *list, roomspec_t *spec) +{ + + if (list == NULL) + return FAILURE; + + list->spec = spec; + list->prev = NULL; + list->next = NULL; + return SUCCESS; +} + +/* see gen_structs.h */ +speclist_t* speclist_new(roomspec_t *spec) +{ + + speclist_t *listnew = calloc(1, sizeof(speclist_t)); + + if (listnew == NULL) { + fprintf(stderr, "calloc failed to allocate space for listnew. \n"); + return NULL; + } + + init_speclist(listnew, spec); + return listnew; +} + +/* see gen_structs.h */ +int speclist_free(speclist_t *list) +{ + + if (list == NULL) + return FAILURE; + + free(list); + return SUCCESS; +} + +/* see gen_structs.h */ +int speclist_free_all(speclist_t *list) +{ + + if (list == NULL) + return FAILURE; + + speclist_t *elt, *tmp; + DL_FOREACH_SAFE(list, elt, tmp) { + DL_DELETE(list, elt); + speclist_free(elt); + } + return SUCCESS; +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 80cfc33b71..52766ede76 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -8,4 +8,4 @@ add_subdirectory(npc) add_subdirectory(openworld) add_subdirectory(playerclass) add_subdirectory(ui) -add_subdirectory(wdl) \ No newline at end of file +add_subdirectory(wdl) diff --git a/tests/openworld/CMakeLists.txt b/tests/openworld/CMakeLists.txt index 66b3c5c403..430b4374fa 100644 --- a/tests/openworld/CMakeLists.txt +++ b/tests/openworld/CMakeLists.txt @@ -1,8 +1,9 @@ set(TEST_EXE test-openworld) add_executable(${TEST_EXE} - test_structs.c - main.c) +test_rooms.c +test_items.c +main.c) target_link_libraries(${TEST_EXE} ${CRITERION_LIBRARY}) diff --git a/tests/openworld/test_items.c b/tests/openworld/test_items.c new file mode 100644 index 0000000000..139eb8dccf --- /dev/null +++ b/tests/openworld/test_items.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include "common/uthash.h" +#include "openworld/default_items.h" + +/* Tests the functions in default_items.h */ + +/* testing get_default_items for hat */ +Test(item, default_hat) +{ + item_hash_t *def = get_default_items(); + cr_assert_not_null(def, "get_default_items() NULL, and failed"); + + item_t *hat; + HASH_FIND_STR(def, "hat", hat); + cr_assert_not_null(hat, "get_default_items(hat) NULL, and failed"); + cr_assert_str_eq(hat->item_id, "hat", + "get_default_items(hat) wrong item id"); + cr_assert_str_eq(hat->short_desc, "a top hat", + "get_default_items(hat) wrong item id"); + cr_assert_str_eq(hat->long_desc, "A black top hat with monogrammed A. L.", + "get_default_items(hat) wrong item id"); +} + +/* testing get_default_items for gold */ +Test(item, default_gold) +{ + item_hash_t *def = get_default_items(); + cr_assert_not_null(def, "get_default_items() NULL, and failed"); + + item_t *gold; + HASH_FIND_STR(def, "gold", gold); + cr_assert_not_null(def, "get_default_items(gold) NULL, and failed"); + + cr_assert_str_eq(gold->item_id, "gold", + "get_default_items(gold) wrong item id"); + cr_assert_str_eq(gold->short_desc, "three gold coins", + "get_default_items(gold) wrong short desc"); + cr_assert_str_eq(gold->long_desc, "Three shiny gold coins the size of your eye", + "get_default_items(gold) wrong long desc"); +} + +/* test get_default_items for kettle */ +Test(item, default_kettle) +{ + item_hash_t *def = get_default_items(); + cr_assert_not_null(def, "get_default_items() NULL, and failed"); + + item_t *kettle; + HASH_FIND_STR(def, "kettle", kettle); + cr_assert_not_null(def, "get_default_items(kettle) NULL, and failed"); + + cr_assert_str_eq(kettle->item_id, "kettle", + "get_default_items(kettle) wrong item id"); + cr_assert_str_eq(kettle->short_desc, "a black kettle", + "get_default_items(kettle) wrong short desc"); + cr_assert_str_eq(kettle->long_desc, "A black kettle on a stove", + "get_default_items(kettle) wrong long desc"); +} diff --git a/tests/openworld/test_rooms.c b/tests/openworld/test_rooms.c new file mode 100644 index 0000000000..60a493a5a2 --- /dev/null +++ b/tests/openworld/test_rooms.c @@ -0,0 +1,210 @@ +#include +#include +#include +#include "openworld/default_items.h" +#include "openworld/default_rooms.h" + +/* Tests the functions in default_rooms.h */ + +/* testing copy_item_to_hash for item id */ +Test(room, copy_apple){ + item_hash_t *def = get_default_items(); + item_hash_t *tmp = NULL; + item_t *item; + int rc; + + rc = copy_item_to_hash(&tmp, def, "apple"); + cr_assert_not_null(tmp); + + HASH_FIND_STR(tmp, "apple", item); + cr_assert_str_eq(item->item_id, "apple"); +} + +/* testing copy_item_to_hash for short desc/long desc */ +Test(room, copy_book){ + item_hash_t *def = get_default_items(); + item_hash_t *tmp = NULL; + item_t *item; + int rc; + + rc = copy_item_to_hash(&tmp, def, "olive"); + cr_assert_not_null(tmp); + + HASH_FIND_STR(tmp, "olive", item); + cr_assert_str_eq(item->short_desc, "a black olive"); + cr_assert_str_eq(item->long_desc, "A singular, unrefrigerated black olive"); +} + +/* testing make_default_room for school */ +Test(room, make_default_school) +{ + roomspec_t *hash = make_default_room("school", NULL, NULL); + cr_assert_not_null(hash, "make_default_room failed"); + + roomspec_t *r1, *r2, *r3, *r4, *r5, *r6; + HASH_FIND_STR(hash, "library", r1); + HASH_FIND_STR(hash, "classroom", r2); + HASH_FIND_STR(hash, "closet", r3); + HASH_FIND_STR(hash, "cafeteria", r4); + HASH_FIND_STR(hash, "hallway", r5); + + //check if not empty + cr_assert_not_null(r1); + cr_assert_not_null(r2); + cr_assert_not_null(r3); + cr_assert_not_null(r4); + cr_assert_not_null(r5); + + + //check if room id matches hash room name + cr_assert_str_eq(r1->room_name, "library"); + cr_assert_str_eq(r2->room_name, "classroom"); + cr_assert_str_eq(r3->room_name, "closet"); + cr_assert_str_eq(r4->room_name, "cafeteria"); + cr_assert_str_eq(r5->room_name, "hallway"); + + //make sure items are assigned to rooms (and not empty) + item_t *r1_item, *r2_item, *r3_item, *r4_item, *r5_item; + + HASH_FIND_STR(r1->items, "book", r1_item); + cr_assert_not_null(r1_item); + cr_assert_str_eq(r1_item->item_id, "book"); + + HASH_FIND_STR(r2->items, "pencil", r2_item); + cr_assert_not_null(r2_item); + cr_assert_str_eq(r2_item->item_id, "pencil"); + + HASH_FIND_STR(r3->items, "door", r3_item); + cr_assert_not_null(r3_item); + cr_assert_str_eq(r3_item->item_id, "door"); + + HASH_FIND_STR(r4->items, "tray", r4_item); + cr_assert_not_null(r4_item); + cr_assert_str_eq(r4_item->item_id, "tray"); + + HASH_FIND_STR(r5->items,"door", r5_item); + cr_assert_not_null(r5_item); + cr_assert_str_eq(r5_item->item_id, "door"); +} + +/* testing make_default_room for farmhouse */ +Test(room, make_default_farm) +{ + roomspec_t *hash = make_default_room("farmhouse", NULL, NULL); + cr_assert_not_null(hash, "make_default_room failed"); + + roomspec_t *r1, *r2, *r3, *r4, *r5, *r6; + HASH_FIND_STR(hash, "living room", r1); + HASH_FIND_STR(hash, "open field", r2); + HASH_FIND_STR(hash, "closet", r3); + HASH_FIND_STR(hash, "kitchen", r4); + HASH_FIND_STR(hash, "barn", r5); + + //check if not empty + cr_assert_not_null(r1); + cr_assert_not_null(r2); + cr_assert_not_null(r3); + cr_assert_not_null(r4); + cr_assert_not_null(r5); + + + //check if room id matches hash room name + cr_assert_str_eq(r1->room_name, "living room"); + cr_assert_str_eq(r2->room_name, "open field"); + cr_assert_str_eq(r3->room_name, "closet"); + cr_assert_str_eq(r4->room_name, "kitchen"); + cr_assert_str_eq(r5->room_name, "barn"); + + //make sure items are assigned to rooms (and not empty) + item_t *r1_item, *r2_item, *r3_item, *r4_item, *r5_item; + + HASH_FIND_STR(r1->items, "xylophone", r1_item); + cr_assert_not_null(r1_item); + cr_assert_str_eq(r1_item->item_id, "xylophone"); + + HASH_FIND_STR(r2->items, "eagle", r2_item); + cr_assert_not_null(r2_item); + cr_assert_str_eq(r2_item->item_id, "eagle"); + + HASH_FIND_STR(r3->items, "door", r3_item); + cr_assert_not_null(r3_item); + cr_assert_str_eq(r3_item->item_id, "door"); + + HASH_FIND_STR(r4->items, "ice", r4_item); + cr_assert_not_null(r4_item); + cr_assert_str_eq(r4_item->item_id, "ice"); + + HASH_FIND_STR(r5->items,"cow", r5_item); + cr_assert_not_null(r5_item); + cr_assert_str_eq(r5_item->item_id, "cow"); +} + +/* testing make_default_room for castle */ +Test(room, make_default_castle) +{ + roomspec_t *hash = make_default_room("castle", NULL, NULL); + cr_assert_not_null(hash, "make_default_room failed"); + + roomspec_t *r1, *r2, *r3, *r4, *r5, *r6; + HASH_FIND_STR(hash, "dungeon", r1); + HASH_FIND_STR(hash, "throne room", r2); + HASH_FIND_STR(hash, "closet", r3); + HASH_FIND_STR(hash, "library", r4); + HASH_FIND_STR(hash, "hallway", r5); + + //check if not empty + cr_assert_not_null(r1); + cr_assert_not_null(r2); + cr_assert_not_null(r3); + cr_assert_not_null(r4); + cr_assert_not_null(r5); + + + //check if room id matches hash room name + cr_assert_str_eq(r1->room_name, "dungeon"); + cr_assert_str_eq(r2->room_name, "throne room"); + cr_assert_str_eq(r3->room_name, "closet"); + cr_assert_str_eq(r4->room_name, "library"); + cr_assert_str_eq(r5->room_name, "hallway"); + + //make sure items are assigned to rooms (and not empty) + item_t *r1_item, *r2_item, *r3_item, *r4_item, *r5_item; + + HASH_FIND_STR(r1->items, "nail", r1_item); + cr_assert_not_null(r1_item); + cr_assert_str_eq(r1_item->item_id, "nail"); + + HASH_FIND_STR(r2->items, "gold", r2_item); + cr_assert_not_null(r2_item); + cr_assert_str_eq(r2_item->item_id, "gold"); + + HASH_FIND_STR(r3->items, "door", r3_item); + cr_assert_not_null(r3_item); + cr_assert_str_eq(r3_item->item_id, "door"); + + HASH_FIND_STR(r4->items, "book", r4_item); + cr_assert_not_null(r4_item); + cr_assert_str_eq(r4_item->item_id, "book"); + + HASH_FIND_STR(r5->items,"door", r5_item); + cr_assert_not_null(r5_item); + cr_assert_str_eq(r5_item->item_id, "door"); +} + + +/* testing make_default_room for undef bucket, bogus sh_desc, l_desc */ +Test(room, make_default_undef_bogus) +{ + roomspec_t *hash = make_default_room("pharmacy", "short bogus", + "long bogus"); + cr_assert_not_null(hash, "make_default_room failed"); + + roomspec_t *r; + HASH_FIND_STR(hash, "pharmacy", r); + + cr_assert_not_null(hash, "make_default_room failed"); + cr_assert_str_eq(r->short_desc, "short bogus", + "make_default_room failed"); + cr_assert_str_eq(r->long_desc, "long bogus", + "make_default_room failed"); +}