diff --git a/build-project.sh b/build-project.sh old mode 100644 new mode 100755 diff --git a/run_test_display_gcov.sh b/run_test_display_gcov.sh old mode 100644 new mode 100755 index 3926413..1a2bfb2 --- a/run_test_display_gcov.sh +++ b/run_test_display_gcov.sh @@ -1,3 +1,4 @@ +ls #Small scirpt to run the tests and generate the coverage report #cleans artifacts before building date diff --git a/src/c/commands.c b/src/c/commands.c new file mode 100644 index 0000000..7b7eeff --- /dev/null +++ b/src/c/commands.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include + +#include "map.h" + +char* getPossibleCommands(Room r, int playerPosition) +{ + char commands[][20] = {}; + + char *msg = malloc(sizeof(char) * (500)); + strcpy(msg, ""); //assign char (string) that no leading zero result + if (playerPosition > 0) + { + strcat(msg, "You can move south from here\n"); + } + + if (playerPosition < mapMax - 1) + { + strcat(msg, "You can move north from here\n"); + } + + if (r.shopAvailable == 1) + { + strcat(msg, "You can call 'shop' to buy items.\n"); + } + + return msg; +} diff --git a/src/c/commands.h b/src/c/commands.h new file mode 100644 index 0000000..22bc63d --- /dev/null +++ b/src/c/commands.h @@ -0,0 +1,8 @@ +#ifndef COMMANDS_H +#define COMMANDS_H + +#include "map.h" + +char* getPossibleCommands(Room r, int playerPosition); + +#endif // COMMANDS_H \ No newline at end of file diff --git a/src/c/items.c b/src/c/items.c new file mode 100644 index 0000000..e44fdbc --- /dev/null +++ b/src/c/items.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include + +#include "nav_helper.h" +#include "items.h" + +Item *getItems(char *itemsMapFile) +{ + static Item getItems[maxItems]; + + FILE *stream; + char *line = NULL; + size_t len = 0; + ssize_t read; + + stream = fopen(itemsMapFile, "r"); + if (stream == NULL) + { + printf("ERROR: couldn't open or find file: ITEMS!\n"); + exit(EXIT_FAILURE); // exit + } + + char delimiter[] = ";"; + + /* print line by line from file */ + int lineCounter = 0; + while ((read = getline(&line, &len, stream)) != -1) + { + // printf("Retrieved line of length %u :\n", read); + if (startsWith(line, "#") == 0) + { + char *arr[itemAttributesMax]; + char *token = strtok(line, delimiter); + int countToken = 0; + while (token != NULL) + { + arr[countToken] = token; + token = strtok(NULL, ";"); + + countToken += 1; + } + free(token); + + Item i; + i.id = atoi(arr[0]); + strcpy(i.itemName, arr[1]); + // printf(arr[2]); + i.price = atoi(arr[3]); + + getItems[lineCounter] = i; + lineCounter += 1; + } + } + return getItems; +} + +int getItemPrice(Item *item) +{ + return item->price; +} + +void setItemPrice(Item *item, int price) +{ + item->price = price; +} + +int getItemShopAvailable(Item *item) +{ + return item->inShopAvailable; +} + +void setItemShopAvailable(Item *item, bool value) +{ + item->inShopAvailable = value; +} \ No newline at end of file diff --git a/src/c/items.h b/src/c/items.h new file mode 100644 index 0000000..3d56b65 --- /dev/null +++ b/src/c/items.h @@ -0,0 +1,25 @@ +#ifndef ITEMS_H +#define ITEMS_H + +#define itemAttributesMax 4 // for items +#define maxItems 100 // for inventory/item list + +#include + +typedef struct +{ + int id; + char itemName[50]; + bool inShopAvailable; + int price; +} Item; + +Item *getItems(char *itemsMapFile); + +int getItemPrice(Item *item); +void setItemPrice(Item *item, int price); + +int getItemShopAvailable(Item *item); +void setItemShopAvailable(Item *item, bool value); + +#endif \ No newline at end of file diff --git a/src/c/main.c b/src/c/main.c new file mode 100644 index 0000000..0396155 --- /dev/null +++ b/src/c/main.c @@ -0,0 +1,262 @@ +// BIBs +#include +#include +#include +#include + +#include "map.h" +#include "nav_helper.h" +#include "items.h" +#include "shop.h" +#include "player.h" +#include "commands.h" + +bool gameRunning; +bool acceptedRules; + +// declare needed variables +Room *map; +Item *availableItems; +Player actualPlayer; +int inputCounter = 0; + +// content +char *gameInstructionsFile = "../../src/content/game_instructions.txt"; +char *gameMapFile = "../../src/content/game.map"; +char *itemsMapFile = "../../src/content/items.map"; + +// navigation +int playerPosition = 0; +int lastPlayerPosition = 0; + +// function declarations +void printInit(); +void setUp(); +void acceptInstructions(); +void processInput(); +int checkExit(); +int checkMove(); +void printStatus(); + +int main() +{ + // init and instructions + printInit(); + + if (acceptedRules == 1) + { + setUp(); + + char userInput[20]; // maximum defined user input length + while (gameRunning == 1) // while running + { + // Print current status + printStatus(); + + // User Input + scanf(" %s", userInput); + printf("\n"); + + // NEXT STEP: + // Processing + processInput(userInput); + } + } + return 0; +} + +// init dialogue +void printInit() +{ + FILE *stream; + char *line = NULL; + size_t len = 0; + ssize_t read; + + stream = fopen(gameInstructionsFile, "r"); + if (stream == NULL) + { + printf("ERROR: couldn't open or find file: INSTRUCTIONS !\n"); + exit(EXIT_FAILURE); // exit + } + + /* print line by line from file */ + while ((read = getline(&line, &len, stream)) != -1) + { + // printf("Retrieved line of length %u :\n", read); + printf("%s", line); + } + + free(line); /* Deallocate allocated memory */ + fclose(stream); /* closing file */ + + acceptInstructions(); +} + +// setUp +void setUp() +{ + // define variables + actualPlayer.id = 1; + actualPlayer.wallet = 100; + gameRunning = 1; + + // get Content + map = getMap(gameMapFile); + availableItems = getItems(itemsMapFile); +} + +// accept rules and instructions for init dialogue +void acceptInstructions() +{ + char userInput[1]; + bool inputState = 0; + int acceptCounter = 0; + while (inputState == 0) + { + scanf(" %c", userInput); + if (strcasecmp(userInput, "y") == 0) + { + acceptedRules = 1; + inputState = 1; // break while + } + else if (strcasecmp(userInput, "n") == 0) + { + printf("You didn't read our rules & instructions. The game will close now. \n\n"); + acceptedRules = 0; + inputState = 1; // break while + } + else + { + printf("Invalid Input!\n"); + } + } +} + +// process user input +void processInput(char userInput[20]) +{ + if (checkExit(userInput) == 1) + { + gameRunning = 0; + printf("!GAME EXIT!\n"); + } + else if (strcmp(userInput, "shop") == 0) + { + Room actualRoom = map[playerPosition]; + if (actualRoom.shopAvailable == 1) + { + int *result = malloc(sizeof(int) * 2); + result = openShop(availableItems, actualPlayer); // result > 0 -> integer = index of item OR result = 0 -> cancel + if (result[0] == 0) + { + actualPlayer = buyItem(availableItems, result[1], actualPlayer); + } + else if (result[0] == 1) + { + actualPlayer = sellItem(result[1], actualPlayer); + } + } + else + { + printf("You can't access the shop from here."); + } + } + else if (strcmp(userInput, "inventory") == 0) + { + showInventory(actualPlayer); + } + else if (checkMove(userInput) == 1) + { + printf("Wrong Input!\n"); + } +} + +// function for checking user input of exit +int checkExit(char userInput[20]) +{ + if (strcmp(userInput, "esc") == 0 || strcmp(userInput, "exit") == 0 || strcmp(userInput, "quit") == 0) + { + return 1; + } + + return 0; +} + +// check is user moved +int checkMove(char userInput[20]) +{ + Room r = map[playerPosition]; + inputCounter += 1; + if (strcmp(userInput, "north") == 0) + { + lastPlayerPosition = playerPosition; + if (playerPosition == (int)(mapMax - 1)) + { + printf("You have reached the border. You have to go in the other direction!\n"); + } + else + { + playerPosition = r.successor; + } + + return 0; + } + else if (strcmp(userInput, "south") == 0) + { + lastPlayerPosition = playerPosition; + if (playerPosition > 0) + { + playerPosition = r.predecessor; + } + else + { + printf("You have reached the border. You have to go in the other direction!\n"); + } + + return 0; + } + else + { + return 1; + } +} + +// print actual location and messages from game.map +void printStatus() +{ + Room actualRoom = map[playerPosition]; + char moveMessage[30]; + + if (lastPlayerPosition > playerPosition) + { + strcpy(moveMessage, "You went to the south!"); + } + else if (lastPlayerPosition < playerPosition) + { + strcpy(moveMessage, "You went to the north!"); + } + else if (lastPlayerPosition == playerPosition && playerPosition == 0) + { + strcpy(moveMessage, "START"); + } + else + { + strcpy(moveMessage, "You didn't move"); + } + + if (lastPlayerPosition != playerPosition || playerPosition == 0 && inputCounter == 0) + { + printf("\n\n################################################################################\n"); + + printf("--> %s <--\n", moveMessage); + printf("%s\n", actualRoom.nameRoom); + printf("%s\n", actualRoom.msgRoom); + printf("\n"); + + char *possibleCommands = malloc(sizeof(char) * (500)); + possibleCommands = getPossibleCommands(map[playerPosition], playerPosition); + printf("%s", possibleCommands); + free(possibleCommands); + } +} \ No newline at end of file diff --git a/src/c/map.c b/src/c/map.c new file mode 100644 index 0000000..1221b8f --- /dev/null +++ b/src/c/map.c @@ -0,0 +1,90 @@ +// headers +#include "map.h" + +Room *getMap(char *gameMapFile) +{ + static Room fillMap[mapMax]; + + FILE *stream; + char *line = NULL; + size_t len = 0; + ssize_t read; + + stream = fopen(gameMapFile, "r"); + if (stream == NULL) + { + printf("ERROR: couldn't open or find file: MAP!\n"); + exit(EXIT_FAILURE); // exit + } + + char delimiter[] = ";"; + + /* print line by line from file */ + int lineCounter = 0; + while ((read = getline(&line, &len, stream)) != -1) + { + + // printf("Retrieved line of length %u :\n", read); + if (startsWith(line, "#") == 0) + { + char *arr[roomAttributesMax]; + char *token = strtok(line, delimiter); + int countToken = 0; + while (token != NULL) + { + arr[countToken] = token; + token = strtok(NULL, ";"); + + countToken += 1; + } + free(token); + + Room r; + r.id = atoi(arr[0]); + strcpy(r.nameRoom, arr[1]); + strcpy(r.msgRoom, arr[2]); + r.successor = atoi(arr[3]); + r.predecessor = atoi(arr[4]); + memcpy(r.items, arr[5], sizeof arr[5]); + r.shopAvailable = atoi(arr[6]); + + fillMap[lineCounter] = r; + lineCounter += 1; + } + } + + free(line); /* Deallocate allocated memory */ + fclose(stream); /* closing file */ + + return fillMap; +}; + +int getRoomSuccessor(Room *room) +{ + return room->successor; +} + +void setRoomSuccessor(Room *room, int successorSet) +{ + room->successor = successorSet; +} + +int getRoomPredecessor(Room *room) +{ + return room->predecessor; +} + +void setRoomPredecessor(Room *room, int predecessorSet) +{ + room->predecessor = predecessorSet; +} + +bool getRoomShopAvailable(Room *room) +{ + return room->shopAvailable; +} + +void setRoomShopAvailable(Room *room, bool shopAvailableSet) +{ + room->shopAvailable = shopAvailableSet; +} \ No newline at end of file diff --git a/src/c/map.h b/src/c/map.h new file mode 100644 index 0000000..1cff482 --- /dev/null +++ b/src/c/map.h @@ -0,0 +1,39 @@ +#ifndef MAP_H +#define MAP_H + +//bibs +#include +#include +#include +#include + +#include "nav_helper.h" + +//defs +#define mapMax 4 // for map (adjust to txt count of rooms -> game.map) +#define roomAttributesMax 7 // for room struct (adjust to txt count of room-attributes -> game.map) + +typedef struct Room +{ + int id; + char nameRoom[20]; + char msgRoom[150]; + int successor; + int predecessor; + char items[10]; + bool shopAvailable; +} Room; + +Room *getMap(char *gameMapFile); + + +int getRoomSuccessor(Room *room); +void setRoomSuccessor(Room *room, int successorSet); + +int getRoomPredecessor(Room *room); +void setRoomPredecessor(Room *room, int predecessorSet); + +bool getRoomShopAvailable(Room *room); +void setRoomShopAvailable(Room *room, bool shopAvailableSet); + +#endif // MAP_H \ No newline at end of file diff --git a/src/c/nav_helper.c b/src/c/nav_helper.c new file mode 100644 index 0000000..e36961d --- /dev/null +++ b/src/c/nav_helper.c @@ -0,0 +1,12 @@ +//bibs +#include + +//headers +#include "nav_helper.h" + +bool startsWith(const char *a, const char *b) +{ + if (strncmp(a, b, strlen(b)) == 0) + return 1; + return 0; +}; \ No newline at end of file diff --git a/src/c/nav_helper.h b/src/c/nav_helper.h new file mode 100644 index 0000000..9e513d2 --- /dev/null +++ b/src/c/nav_helper.h @@ -0,0 +1,9 @@ +#ifndef NAV_HELPER_H +#define NAV_HELPER_H + +#include +#include + +bool startsWith(const char *a, const char *b); + +#endif \ No newline at end of file diff --git a/src/c/player.c b/src/c/player.c new file mode 100644 index 0000000..0e3fedd --- /dev/null +++ b/src/c/player.c @@ -0,0 +1,123 @@ +#include +#include +#include +#include + +#include "player.h" + +// PLAYER INVENTORY + +// add and remove +Player addItemToInventory(Item *availableItems, int itemIndex, Player actualPlayer) +{ + int counter = actualPlayer.itemCounter; + actualPlayer.itemInventory[counter] = availableItems[itemIndex - 1]; // -1 to get right index (items begin - 1,2,3,4...) + actualPlayer.itemCounter += 1; + + return actualPlayer; +} + +Player removeItemFromInventory(int itemIndex, Player actualPlayer) +{ + Item items[maxItems]; // actualPlayer.itemInventory + int i, index = -1; + + for (i = 0; i < maxItems; i++) + { + if (i == itemIndex) + { + // printf("%d - '%s' has been removed from inventory.\n", actualPlayer.itemInventory[i].id, actualPlayer.itemInventory[i].itemName); + index = i; + break; + } + } + + if (index != -1) + { + // shift all the element from index+1 by one position to the left + for (i = index; i < maxItems - 1; i++) + actualPlayer.itemInventory[i] = actualPlayer.itemInventory[i + 1]; + + /*printf("New Array : "); + for(i = 0; i < maxItems - 1; i++) + printf("%d ",actualPlayer.itemInventory[i].id);*/ + } + else + printf("Element Not Found\n"); + + actualPlayer.itemCounter = actualPlayer.itemCounter - 1; + + return actualPlayer; +} + +// currency +Player setTotal(Player actualPlayer, int value) +{ + actualPlayer.wallet = value; + return actualPlayer; +} + +Player addMoneyToPlayer(Player actualPlayer, int money) +{ + int newTotal = money + actualPlayer.wallet; + actualPlayer = setTotal(actualPlayer, newTotal); + return actualPlayer; +} + +Player removeMoneyFromPlayer(Player actualPlayer, int money) +{ + int newTotal = actualPlayer.wallet - money; + actualPlayer = setTotal(actualPlayer, newTotal); + return actualPlayer; +} + +//add and remove items with currency +Player buyItem(Item *availableItems, int itemIndex, Player actualPlayer) +{ + int itemPrice = availableItems[itemIndex - 1].price; + if (actualPlayer.wallet >= itemPrice) + { + actualPlayer = addItemToInventory(availableItems, itemIndex, actualPlayer); + actualPlayer = removeMoneyFromPlayer(actualPlayer, itemPrice); + printf("You bought item[%d] for %d$! \nYour balance is now: %d$\n", itemIndex, itemPrice, actualPlayer.wallet); + return actualPlayer; + } + else + { + printf("You don't have enough money.\n\n"); + return actualPlayer; + } +} + +Player sellItem(int itemIndex, Player actualPlayer) +{ + int priceItemSell = actualPlayer.itemInventory[itemIndex].price; + actualPlayer = addMoneyToPlayer(actualPlayer, actualPlayer.itemInventory[itemIndex].price / 2); + printf("Item has been sold for 50%% of the purchase price (purchase price: %d$)! \nYour balance is now: %d$\n", priceItemSell, actualPlayer.wallet); + + actualPlayer = removeItemFromInventory(itemIndex, actualPlayer); + return actualPlayer; +} + +// show +void showInventory(Player actualPlayer) +{ + int inventoryItemCounter = actualPlayer.itemCounter; + + if (inventoryItemCounter == 0) + { + printf("*** Inventory is empty *** \n\n"); + } + else + { + printf("*** Inventory *** \n\n"); + + for (int i = 0; i < actualPlayer.itemCounter; i++) + { + // printf("%d: %d - %s\n", i, inventory[i].id, inventory[i].itemName); + printf("> %s - %d\n", actualPlayer.itemInventory[i].itemName, i); + } + } + + printf("\n\n"); +} diff --git a/src/c/player.h b/src/c/player.h new file mode 100644 index 0000000..4518f70 --- /dev/null +++ b/src/c/player.h @@ -0,0 +1,30 @@ +#ifndef PLAYER_H +#define PLAYER_H + +#include "items.h" + +typedef struct +{ + int id; + int itemCounter; + Item itemInventory[100]; + int wallet; +} Player; + +//add and remove items +Player addItemToInventory(Item *availableItem, int itemIndex, Player actualPlayer); +Player removeItemFromInventory(int index, Player actualPlayer); + +//currency +Player setTotal(Player actualPlayer, int value); +Player addMoneyToPlayer(Player actualPlayer, int money); +Player removeMoneyFromPlayer(Player actualPlayer, int money); + +//add and remove items with currency +Player buyItem(Item *availableItems, int itemIndex, Player actualPlayer); +Player sellItem(int itemIndex, Player actualPlayer); + +//show +void showInventory(Player actualPlayer); + +#endif \ No newline at end of file diff --git a/src/c/shop.c b/src/c/shop.c new file mode 100644 index 0000000..88e0659 --- /dev/null +++ b/src/c/shop.c @@ -0,0 +1,144 @@ +#include +#include +#include +#include +#include + +#include "shop.h" +#include "player.h" + +int *openShop(Item *availableItems, Player actualPlayer) +{ + int mode = 0; + int *x = malloc(sizeof(int) * 2); + + int userModeInput; + fflush(stdout); + bool selectMode = 1; + while (selectMode == 1) + { + printf("Please type '0' for buy or '1' to sell items!\n"); + while (scanf(" %d", &userModeInput) != 1) + { + printf("Invalid [index]. Please try again: "); + fflush(stdout); + } + + if (userModeInput > 1 || userModeInput < 0) + { + printf("Invalid [index]. Please try again: "); + } + else if (userModeInput == 0) + { + mode = 0; + selectMode = 0; + } + else if (userModeInput == 1) + { + mode = 1; + selectMode = 0; + } + } + + int userInput; + fflush(stdout); + bool shopIsOpen = 1; + + if (mode == 0) + { + + while (shopIsOpen == 1) + { + printf("*** SHOP-Items *** \n\n"); + + // printf("%-5s %-30s %5s\n", "Index", "Name", "Price"); + for (int i = 0; i < 6; i++) + { + printf("%-5d %-40s %5d$\n", availableItems[i].id, availableItems[i].itemName, availableItems[i].price); + } + + printf("\n-> to buy items type '[index of item]' \n-> write '0' to quit the shop'\n\n"); + + while (scanf(" %d", &userInput) != 1) + { + printf("Invalid [index]. Please try again: "); + fflush(stdout); + } + + if (userInput > 0) + { + x[0] = mode; + x[1] = userInput; + return x; + // BUY ITEM added later -> addItemToInventory(userInput); + } + else if (userInput == 0) + { + shopIsOpen = 0; + printf("Enjoy your items, have a great day!\n"); + x[0] = -1; + x[1] = -1; + return x; + } + else + { + printf("Invalid [index]. Please try again: "); + } + } + } + else if (mode == 1) + { + while (shopIsOpen == 1) + { + if (actualPlayer.itemCounter > 0) + { + printf("*** Your inventory *** \n\n"); + + // printf("%-5s %-30s %5s\n", "Index", "Name", "Price"); + for (int i = 0; i < actualPlayer.itemCounter; i++) + { + printf("%-5d %-40s %5d$\n", i+1, actualPlayer.itemInventory[i].itemName, actualPlayer.itemInventory[i].price); + } + + printf("\n-> to sell items type '[index of item]' \n-> write '0' to quit the shop'\n\n"); + + while (scanf(" %d", &userInput) != 1) + { + printf("Invalid [index]. Please try again: "); + fflush(stdout); + } + + if (userInput > 0) + { + x[0] = mode; + x[1] = userInput-1; //index begin on 1 because we will cancel with 0 + return x; + // BUY ITEM added later -> addItemToInventory(userInput); + } + else if (userInput == 0) + { + shopIsOpen = 0; + printf("Enjoy your money, have a great day!\n"); + x[0] = -1; + x[1] = -1; + return x; + } + else + { + printf("Invalid [index]. Please try again: "); + } + } + else + { + shopIsOpen = 0; + printf("*** Your inventory is empty *** \n\n"); + x[0] = -1; + x[1] = -1; + return x; + } + } + } + + x[0] = -1; + return x; +} \ No newline at end of file diff --git a/src/c/shop.h b/src/c/shop.h new file mode 100644 index 0000000..bb41f3b --- /dev/null +++ b/src/c/shop.h @@ -0,0 +1,9 @@ +#ifndef SHOP_H +#define SHOP_H + +#include "items.h" +#include "player.h" + +int *openShop(Item *availableItems, Player actualPlayer); + +#endif \ No newline at end of file diff --git a/src/c/weapon.c b/src/c/weapon.c new file mode 100644 index 0000000..a29d223 --- /dev/null +++ b/src/c/weapon.c @@ -0,0 +1,61 @@ +#include "weapon.h" + +char *getName(Weapon *weapon) +{ + return weapon->name; +} + +void setName(Weapon *weapon, char *nameToSet) +{ + weapon->name = nameToSet; +} + +char *getFullName(Weapon *weapon) +{ + return weapon->fullName; +} + +void setFullName(Weapon *weapon, char *fullNameToSet) +{ + weapon->fullName = fullNameToSet; +} + +int getTypeID(Weapon *weapon) +{ + return weapon->typeID; +} + +void setTypeID(Weapon *weapon, int typeToSet) +{ + weapon->typeID = typeToSet; +} + +int getDamageModifier(Weapon *weapon) +{ + return weapon->damageModifier; +} + +void setDamageModifier(Weapon *weapon, int modifierSet) +{ + weapon->damageModifier = modifierSet; +} + +int getBaseDamage(Weapon *weapon) +{ + return weapon->baseDamage; +} + +void setBaseDamage(Weapon *weapon, int baseDmgSet) +{ + weapon->baseDamage = baseDmgSet; +} + +bool getAvailable(Weapon *weapon) +{ + return weapon->canBeUsed; +} + +void setAvailable(Weapon *weapon, bool availableSet) +{ + weapon->canBeUsed = availableSet; +} \ No newline at end of file diff --git a/src/c/weapon.h b/src/c/weapon.h new file mode 100644 index 0000000..d016ec9 --- /dev/null +++ b/src/c/weapon.h @@ -0,0 +1,41 @@ +#ifndef WEAPON_H +#define WEAPON_H + +#include +#include +#include +#include + +typedef struct +{ + int id; + char *fullName; + char *name; + int typeID; + char *typeName; + int damageModifier; + int baseDamage; + bool canBeUsed; +} Weapon; + +char *getName(Weapon *weapon); +void setName(Weapon *weapon, char *nameToSet); + +char *getFullName(Weapon *weapon); +void setFullName(Weapon *weapon, char *fullNameToSet); + +int getTypeID(Weapon *weapon); +void setTypeID(Weapon *weapon, int typeToSet); + +// typeName placeholder + +int getDamageModifier(Weapon *weapon); +void setDamageModifier(Weapon *weapon, int modifierSet); + +int getBaseDamage(Weapon *weapon); +void setBaseDamage(Weapon *weapon, int baseDmgSet); + +bool getAvailable(Weapon *weapon); +void setAvailable(Weapon *weapon, bool availableSet); + +#endif \ No newline at end of file diff --git a/src/content/game.map b/src/content/game.map new file mode 100644 index 0000000..96a4241 --- /dev/null +++ b/src/content/game.map @@ -0,0 +1,6 @@ +# LINES WITH '#' AT BEGINNING GET IGNORED +#ID;NAME ORT;MSG;successor;predeacessor;items(comma seperated);shop available (1=y,0=n); +0;office;welcome to office;1;-1;1,2;0 +1;hospital;welcome to the hospital;2;0;3;0 +2;fire department;welcome to fire department;3;1;4;1 +3;police station;welcome to police;4;2;5,6;0 \ No newline at end of file diff --git a/src/content/game_instructions.txt b/src/content/game_instructions.txt new file mode 100644 index 0000000..e089751 --- /dev/null +++ b/src/content/game_instructions.txt @@ -0,0 +1,53 @@ + + +************************************************************************************************************ + _____ __ __ ______ _____ _______ _____ _______ + / ____| /\ | \/ | ____| / ____|__ __|/\ | __ \__ __| + | | __ / \ | \ / | |__ | (___ | | / \ | |__) | | | + | | |_ | / /\ \ | |\/| | __| \___ \ | | / /\ \ | _ / | | + | |__| |/ ____ \| | | | |____ ____) | | |/ ____ \| | \ \ | | + \_____/_/ \_\_| |_|______| |_____/ |_/_/ \_\_| \_\ |_| + +************************************************************************************************************ + + + | | /| / /__ / /______ __ _ ___ / /____ / |/ / _ | / |/ / __/ + | |/ |/ / -_) / __/ _ \/ ' \/ -_) / __/ _ \ / / __ |/ /|_/ / _/ + |__/|__/\__/_/\__/\___/_/_/_/\__/ \__/\___/ /_/|_/_/ |_/_/ /_/___/ + + +///////////////////////////////////////////////////////////////////////////////////////////// + +INSTRUCTIONS: + +how to move on the map +enter "north" to go north +enter "south" to go south + + +alltime commands: +- 'inventory' -> will show your items that you have bought or found () + +special commands (not available at any time during the game): +- 'shop' -> opens the shop where you can buy or sell items + +CURRENTLY NOT AVAILABLE FEATURES (will be available soon): +- "use [item]" +- "find [item]" +WARNING: Pickups are always hidden, find them with "find [item]" and take them with "take [item]" + +How to leave the game: +use "esc", "exit" or "quit" to leave the game + + +And remember, EVERY point/room has something you can do. +Have fun! + + +///////////////////////////////////////////////////////////////////////////////////////////// + + +************************************************************************************************************ + + +did you read our rules and instructions? Yes(y) or No(n) diff --git a/src/content/items.map b/src/content/items.map new file mode 100644 index 0000000..0dcc59c --- /dev/null +++ b/src/content/items.map @@ -0,0 +1,8 @@ +# LINES WITH '#' AT BEGINNING GET IGNORED +#ID;NAME;inShopAvailable;price +1;healing potion;1;20 +2;shield;1;50 +3;UV flashlight;1;80 +4;key for police station;0;9999 +5;acid;1;9999 +6;gun;0;9999 \ No newline at end of file diff --git a/test/c/test_commands.c b/test/c/test_commands.c new file mode 100644 index 0000000..aa20fa0 --- /dev/null +++ b/test/c/test_commands.c @@ -0,0 +1,37 @@ +#ifdef TEST + +#include "unity.h" +#include "commands.h" +#include "map.h" +#include "nav_helper.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void test_commands(void) +{ + /* arrange */ + // Hier die Werte eingeben/deklarieren + Room* mapData; + mapData = getMap("./src/content/game.map"); + int playerPosition = 3; //last player position in north - so you can only move to south + char* expectedString = "You can move south from here\n"; + + /* act */ + // Die Funktion wird ausgeführt + char* msg = getPossibleCommands(mapData[playerPosition], playerPosition); + + /* TEST AUSGABE zur Kontrolle */ + printf("%s", msg); + + /* assert */ + // Vergleichen mit Inhalt + TEST_ASSERT_EQUAL_STRING(expectedString, msg); +} + +#endif // TEST \ No newline at end of file diff --git a/test/c/test_items.c b/test/c/test_items.c new file mode 100644 index 0000000..8083d3b --- /dev/null +++ b/test/c/test_items.c @@ -0,0 +1,109 @@ +#ifdef TEST + +#include "unity.h" +#include "nav_helper.h" +#include "items.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void test_items(void) +{ + /* arrange */ + // Hier die Werte eingeben/deklarieren + Item *items; + int expectedItemID = 1; + int expectedSecondItemID = 2; + + /* act */ + // Die Funktion wird ausgeführt + items = getItems("./src/content/items.map"); + + /* make visible OUTPUT */ + for (int i = 0; i < 4; i++) + { + printf("%s\n", items[i].itemName); + } + + /* assert */ + // Vergleichen mit Inhalt von game.Map File + TEST_ASSERT_EQUAL_INT(expectedItemID, items[0].id); + TEST_ASSERT_EQUAL_INT(expectedSecondItemID, items[1].id); +} + +void test_setItemPrice(void) +{ + // arrange + int price = 50, result; + + // act + Item test; + setItemPrice(&test, price); + result = test.price; + + //output + printf("---------------------------------------------------\n"); + printf("setItemPrice | price to set: %d -> item.price: %d", price, result); + + // assert + TEST_ASSERT_EQUAL(price, result); +} + + +void test_getItemPrice(void) +{ + // arrange + int price = 50, result; + + // act + Item test; + test.price = price; + result = getItemPrice(&test); + + //output + printf("getItemPrice | price should be: %d -> price is: %d", price, result); + + // assert + TEST_ASSERT_EQUAL(price, result); +} + +void test_getItemShopAvailable(void) +{ + // arrange + bool value = true, result; + + // act + Item test; + test.inShopAvailable = value; + result = getItemShopAvailable(&test); + + //output + printf("getItemShopAvailable | value should be: %d -> is: %d", value, result); + + // assert + TEST_ASSERT_EQUAL(value, result); +} + +void test_setItemShopAvailable(void) +{ + // arrange + bool value = true, result; + + // act + Item test; + setItemShopAvailable(&test, value); + result = test.inShopAvailable; + + //output + printf("setItemShopAvailable | value should be: %d -> is: %d", value, result); + + // assert + TEST_ASSERT_EQUAL(value, result); +} + +#endif // TEST diff --git a/test/c/test_map.c b/test/c/test_map.c new file mode 100644 index 0000000..fce9775 --- /dev/null +++ b/test/c/test_map.c @@ -0,0 +1,153 @@ +#ifdef TEST + +#include "unity.h" +#include "map.h" +#include "nav_helper.h" + + +void setUp(void) +{ + +} + +void tearDown(void) +{ +} + +void test_map(void) +{ + /* arrange */ + // Hier die Werte eingeben + Room *map; + + /* act */ + // Die Funktion wird ausgeführt + map = getMap("./src/content/game.map"); + + for (int i = 0; i < 4; i++) + { + printf("%s\n", map[i].nameRoom); + } + + /* assert */ + // Vergleichen mit Inhalt von game.Map File + int officeExpectedSuccessor = 1; + int officeExpectedID = 0; + + int fdExpectedSuccessor = 3; + int fdExpectedID = 2; + + TEST_ASSERT_EQUAL_INT(officeExpectedSuccessor, map[0].successor); + TEST_ASSERT_EQUAL_INT(officeExpectedID, map[0].id); + + TEST_ASSERT_EQUAL_INT(fdExpectedSuccessor, map[2].successor); + TEST_ASSERT_EQUAL_INT(fdExpectedID, map[2].id); +} + +void test_getRoomSuccessor(void) +{ + // arrange + int successor = 1, result; + Room test; + test.successor = successor; + + /* act */ + // Die Funktion wird ausgeführt + result = getRoomSuccessor(&test); + + // output + printf("---------------------------------------------------------\n"); + printf("getRoomSuccessor | Successor should be: %d -> is: %d", successor, result); + + // assert + TEST_ASSERT_EQUAL(successor, result); +} + +void test_setRoomSuccessor(void) +{ + // arrange + int successor = 2, result; + + // act + Room test; + setRoomSuccessor(&test, successor); + result = test.successor; + + //output + printf("setRoomSuccessor | successor to set: %d -> is: %d", successor, result); + + // assert + TEST_ASSERT_EQUAL(successor, result); +} + +void test_getRoomPredecessor(void) +{ + // arrange + int predecessor = 1, result; + Room test; + test.predecessor = predecessor; + + /* act */ + // Die Funktion wird ausgeführt + result = getRoomPredecessor(&test); + + // output + printf("getRoomPredecessor | Successor should be: %d -> is: %d", predecessor, result); + + // assert + TEST_ASSERT_EQUAL(predecessor, result); +} + +void test_setRoomPredecessor(void) +{ + // arrange + int predecessor = 3, result; + + // act + Room test; + setRoomPredecessor(&test, predecessor); + result = test.predecessor; + + //output + printf("setRoomPredecessor | successor to set: %d -> is: %d", predecessor, result); + + // assert + TEST_ASSERT_EQUAL(predecessor, result); +} + +void test_getRoomShopAvailable(void) +{ + // arrange + bool available = true, result; + Room test; + test.shopAvailable = available; + + /* act */ + // Die Funktion wird ausgeführt + result = getRoomShopAvailable(&test); + + // output + printf("getRoomShopAvailable | shopAvailable should be: %d -> is: %d", available, result); + + // assert + TEST_ASSERT_EQUAL(available, result); +} + +void test_setRoomShopAvailable(void) +{ + // arrange + bool available = true, result; + + // act + Room test; + setRoomShopAvailable(&test, available); + result = test.shopAvailable; + + //output + printf("setRoomShopAvailable | shopAvailable set to: %d -> after set: %d", available, result); + + // assert + TEST_ASSERT_EQUAL(available, result); +} + +#endif // TEST diff --git a/test/c/test_nav_helper.c b/test/c/test_nav_helper.c new file mode 100644 index 0000000..cbf1d42 --- /dev/null +++ b/test/c/test_nav_helper.c @@ -0,0 +1,36 @@ +#ifdef TEST + +#include "unity.h" +#include "nav_helper.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void test_nav_helper(void) +{ + /* arrange */ + // Hier die Werte eingeben + char* stringToCheckIsTrue = "#test"; + char* stringToCheckIsFalse = "test"; + + /* act */ + // Die Funktion wird ausgeführt + bool valueIsTrue = startsWith(stringToCheckIsTrue,"#"); + bool valueIsFalse = startsWith(stringToCheckIsFalse, "#"); + + //Output + printf("%s startet mit '#' = %d\n",stringToCheckIsTrue, valueIsTrue); + printf("%s startet mit '#' = %d",stringToCheckIsFalse, valueIsFalse); + + /* assert */ + // Vergleichen mit Inhalt + TEST_ASSERT_TRUE(valueIsTrue); + TEST_ASSERT_FALSE(valueIsFalse); +} + +#endif // TEST \ No newline at end of file diff --git a/test/c/test_player.c b/test/c/test_player.c new file mode 100644 index 0000000..5e86752 --- /dev/null +++ b/test/c/test_player.c @@ -0,0 +1,155 @@ +#ifdef TEST + +#include "unity.h" +#include "player.h" +#include "items.h" +#include "nav_helper.h" + +Item *availableItems; +Player actualPlayer; +void setUp(void) +{ + availableItems = getItems("./src/content/items.map"); +} + +void tearDown(void) +{ +} + +void test_addItemToInventory(void) +{ + /* arrange */ + // Hier die Werte eingeben/deklarieren + int shopItemIndex = 1; + + /* act */ + // Die Funktion wird ausgeführt + actualPlayer = addItemToInventory(availableItems, shopItemIndex, actualPlayer); + + /* assert */ + // Vergleichen mit Inhalt von game.Map File + TEST_ASSERT_EQUAL_INT(shopItemIndex, actualPlayer.itemInventory[0].id); +} + +void test_removeItemFromInventory(void) +{ + /* arrange */ + // Hier die Werte eingeben/deklarieren + int itemToRemove = 0; // index to remove (we already bought it in function above) + + /* act */ + // Die Funktion wird ausgeführt + Item itemBeforeRemove = actualPlayer.itemInventory[0]; + actualPlayer = removeItemFromInventory(itemToRemove, actualPlayer); // then remove + Item itemAfterRemove = actualPlayer.itemInventory[0]; + + // OUTPUT + printf("removeItem | ID_before: %d -> ID_after: %d", itemBeforeRemove.id, itemAfterRemove.id); + + /* assert */ + // Vergleichen mit Inhalt von game.Map File + TEST_ASSERT_NOT_EQUAL_UINT8(itemBeforeRemove.id, itemAfterRemove.id); +} + +void test_setTotal(void) +{ + /* arrange */ + // Hier die Werte eingeben/deklarieren + int setMoney = 100; + + /* act */ + // Die Funktion wird ausgeführt + int valueBefore = actualPlayer.wallet; + actualPlayer = setTotal(actualPlayer, setMoney); + int valueAfter = actualPlayer.wallet; + + // OUTPUT + printf("setTotal | before: %d -> after: %d", valueBefore, valueAfter); + + /* assert */ + // Vergleichen mit Inhalt + TEST_ASSERT_EQUAL_INT(setMoney, actualPlayer.wallet); + TEST_ASSERT_NOT_EQUAL_UINT8(valueBefore, valueAfter); +} + +void test_addMoneyToPlayer(void) +{ + /* arrange */ + // Hier die Werte eingeben/deklarieren + // balance = 70 + int valueToAdd = 20; + int checkSum = actualPlayer.wallet + valueToAdd; + + /* act */ + // Die Funktion wird ausgeführt + actualPlayer = addMoneyToPlayer(actualPlayer, valueToAdd); + + // OUTPUT + printf("%d$ has been added to your balance. TOTAL: %d$", valueToAdd, actualPlayer.wallet); + + /* assert */ + // Vergleichen mit Inhalt von game.Map File + TEST_ASSERT_EQUAL_INT(checkSum, actualPlayer.wallet); +} + +void test_removeMoneyFromPlayer(void) +{ + /* arrange */ + // Hier die Werte eingeben/deklarieren + int valueToRemove = 20; + int checkSum = actualPlayer.wallet - valueToRemove; + + /* act */ + // Die Funktion wird ausgeführt + actualPlayer = removeMoneyFromPlayer(actualPlayer, valueToRemove); + + // OUTPUT + printf("%d$ has been removed from your balance. TOTAL: %d$", valueToRemove, actualPlayer.wallet); + + /* assert */ + // Vergleichen mit Inhalt von game.Map File + TEST_ASSERT_EQUAL_INT(checkSum, actualPlayer.wallet); +} + +void test_buyItem(void) +{ + /* arrange */ + // Hier die Werte eingeben/deklarieren + int itemIndex = 2; // price = 50 + int checkSum = actualPlayer.wallet - availableItems[itemIndex-1].price; + + /* act */ + // Die Funktion wird ausgeführt + actualPlayer = buyItem(availableItems, itemIndex, actualPlayer); + + /* assert */ + // Vergleichen mit Inhalt von game.Map File + TEST_ASSERT_EQUAL_INT(itemIndex, actualPlayer.itemInventory[0].id); //check if item has right ID + TEST_ASSERT_EQUAL_INT(checkSum, actualPlayer.wallet); //check money after transfer + +} + +void test_sellItem(void) +{ + /* arrange */ + // Hier die Werte eingeben/deklarieren + int buyItemID = 1; // prepare sell + actualPlayer = addItemToInventory(availableItems, buyItemID, actualPlayer); // prepare sell + + int itemToRemove = 0; // index to remove (we already bought it in function above) + + /* act */ + // Die Funktion wird ausgeführt + Item itemBeforeRemove = actualPlayer.itemInventory[0]; + actualPlayer = sellItem(itemToRemove, actualPlayer); // then remove + Item itemAfterRemove = actualPlayer.itemInventory[0]; + + // OUTPUT + //printf("sellItem | before: %d -> after: %d", itemBeforeRemove.id, itemAfterRemove.id); + + /* assert */ + // Vergleichen mit Inhalt von game.Map File + TEST_ASSERT_NOT_EQUAL_UINT8(itemBeforeRemove.id, itemAfterRemove.id); +} + +#endif // TEST diff --git a/test/c/test_weapon.c b/test/c/test_weapon.c new file mode 100644 index 0000000..609aa62 --- /dev/null +++ b/test/c/test_weapon.c @@ -0,0 +1,224 @@ +#ifdef TEST + +#include "unity.h" +#include "weapon.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void test_getName(void) +{ + // arrange + char *nameOfWeapon = "Kukri", *result; + Weapon test; + test.name = nameOfWeapon; + + /* act */ + // Die Funktion wird ausgeführt + result = getName(&test); + + // output + printf("getName | name should be: %s -> is: %s", nameOfWeapon, result); + + // assert + TEST_ASSERT_EQUAL(nameOfWeapon, result); +} + +void test_setName(void) +{ + // arrange + char *nameWeapon = "switchblade", *result; + + // act + Weapon test; + setName(&test, nameWeapon); + result = test.name; + + // output + printf("setName | name set to: %s -> after set: %s", nameWeapon, result); + + // assert + TEST_ASSERT_EQUAL(nameWeapon, result); +} + +void test_getFullName(void) +{ + // arrange + char *nameOfWeapon = "Kukri v2", *result; + Weapon test; + test.fullName = nameOfWeapon; + + /* act */ + // Die Funktion wird ausgeführt + result = getFullName(&test); + + // output + printf("getFullName | fullName should be: %s -> is: %s", nameOfWeapon, result); + + // assert + TEST_ASSERT_EQUAL(nameOfWeapon, result); +} + +void test_setFullName(void) +{ + // arrange + char *fullNameWeapon = "switchblade v2", *result; + + // act + Weapon test; + setFullName(&test, fullNameWeapon); + result = test.fullName; + + // output + printf("setFullName | fullName set to: %s -> after set: %s", fullNameWeapon, result); + + // assert + TEST_ASSERT_EQUAL(fullNameWeapon, result); +} + +void test_getTypeID(void) +{ + // arrange + int type = 1, result; + Weapon test; + test.typeID = type; + + /* act */ + // Die Funktion wird ausgeführt + result = getTypeID(&test); + + // output + printf("getTypeID | typeID should be: %d -> is: %d", type, result); + + // assert + TEST_ASSERT_EQUAL(type, result); +} + +void test_setTypeID(void) +{ + // arrange + int type = 2, result; + + // act + Weapon test; + setTypeID(&test, type); + result = test.typeID; + + // output + printf("setTypeID | typeID set to: %d -> after set: %d", type, result); + + // assert + TEST_ASSERT_EQUAL(type, result); +} + +void test_getDamageModifier(void) +{ + // arrange + int damageModifier = 2, result; + Weapon test; + test.damageModifier = damageModifier; + + /* act */ + // Die Funktion wird ausgeführt + result = getDamageModifier(&test); + + // output + printf("getDamageModifier | damageModifier should be: %d -> is: %d", damageModifier, result); + + // assert + TEST_ASSERT_EQUAL(damageModifier, result); +} + +void test_setDamageModifier(void) +{ + // arrange + int damageModifier = 5, result; + + // act + Weapon test; + setDamageModifier(&test, damageModifier); + result = test.damageModifier; + + // output + printf("setDamageModifier | damageModifier set to: %d -> after set: %d", damageModifier, result); + + // assert + TEST_ASSERT_EQUAL(damageModifier, result); +} + +void test_getBaseDamage(void) +{ + // arrange + int baseDamage = 10, result; + Weapon test; + test.baseDamage = baseDamage; + + /* act */ + // Die Funktion wird ausgeführt + result = getBaseDamage(&test); + + // output + printf("getBaseDamage | baseDamage should be: %d -> is: %d", baseDamage, result); + + // assert + TEST_ASSERT_EQUAL(baseDamage, result); +} + +void test_setBaseDamage(void) +{ + // arrange + int baseDamage = 43, result; + + // act + Weapon test; + setBaseDamage(&test, baseDamage); + result = test.baseDamage; + + // output + printf("setBaseDamage | baseDamage set to: %d -> after set: %d", baseDamage, result); + + // assert + TEST_ASSERT_EQUAL(baseDamage, result); +} + +void test_getAvailable(void) +{ + // arrange + bool canBeUsed = true, result; + Weapon test; + test.canBeUsed = canBeUsed; + + /* act */ + // Die Funktion wird ausgeführt + result = getAvailable(&test); + + // output + printf("getAvailable | canBeUsed should be: %d -> is: %d", canBeUsed, result); + + // assert + TEST_ASSERT_EQUAL(canBeUsed, result); +} + +void test_setAvailable(void) +{ + // arrange + bool canBeUsed = false, result; + + // act + Weapon test; + setAvailable(&test, canBeUsed); + result = test.canBeUsed; + + // output + printf("setAvailable | canBeUsed set to: %d -> after set: %d", canBeUsed, result); + + // assert + TEST_ASSERT_EQUAL(canBeUsed, result); +} + +#endif // TEST