Skip to content

Goblin Gourger v2.0 Released

Download Release (Windows) & Source Code

Goblin Gourger is a text-based adventure game for Windows set in an endless maze of caves filled with goblins and mysteries!

Game Features Include:

  • 8 Unique Weapons
  • Turn-based Goblin Battles
  • Endless Cave System
  • A Unique Experience Each Playthrough!

The cave system is generated programmatically, so no two games will be identical. New rooms are generated “on-demand” for an endless experience.

There are a number of weapons, items, and special rooms to be discovered.

The goal of the game is to achieve the highest score possible by exploring the caves and slaying goblins!

Involvement: This is my first full game; it took me about a week to program and polish and helped me learn C++ (I had previous experience with JavaScript).

For now, the game is only for Windows but if anyone is interested, I am sure I could port it to Linux or Mac, and it would probably be a great learning experience. So, let me know if interested!

If you find bugs, please report them with as much detail as possible.

Please share any feedback or new feature requests!

No installation required; just unzip and open “goblin_gourger.exe” to play.

goblin_gourger.cpp (Main Code)

#include <iostream> // For basic input and output
#include <vector> // To use dynamic rather than static arrays
#include <cstdlib> // For random number processing
#include <ctime> // To seed random number with time
#include <algorithm> // To use 'find' on vectors
#include <windows.h> // Header for Windows-specific stuff
#include <mmsystem.h> // Multimedia system for sound (PlaySound())
#include "gg_sounds.h" // Goblin Gourger Sounds!

// Using namespace standard for this simple project
using namespace std;

string versionNumber = "2.0";

// Is the player starting a new game?
bool startNewGame = true;

int encounterRate;

// Integer used to count how many times the no dead-end loop runs
int deadEndCounter = 0;

// Adjacent room cantor values
long long int adjacentNorthRoom;
long long int adjacentEastRoom;
long long int adjacentSouthRoom;
long long int adjacentWestRoom;

// This variable holds the player's last movement direction
// This is used to ensure there is a path in the new room
// that is generated, which corresponds with the direction the
// player previously traveled.
// EXAMPLE: If the player moved North and is now in a new room,
// there should be a path South, back to the previous room
char lastMove;

int goblinsKilled = 0;

// Player Variables
int playerHealth = 100;
int playerPotions = 0;
int playerKeys = 0;
int playerBombs = 0;
string playerWeapon = "Fists";
int playerAttack = 2;

int goblinAttack = 0;

// Variable for storing random numbers
int randomNum;

// Array to hold all possible types of weapons the player can find
string weapons[] = {"Stick", "Branch", "Knife", "Dagger", "Spear", "Sword"};

// String text to be added at the beginning of the display
// I'm using this because I'm clearing the command line display after each loop
// This allows me to pass a message through cleanly to the display
// NOTE: When assigning values to 'appendMsg,' be sure to include a space
// at the end of the message.
// EXAMPLE: appendMsg = "Check out this space at the end! ";
string appendMsg = "";

string postMsg = "";

// Arrays to hold descriptions and contents of rooms
vector<string> descripText;
vector<string> roomItem;
vector<string> roomWeapon;
vector<int> roomNorthPath;
vector<int> roomEastPath;
vector<int> roomSouthPath;
vector<int> roomWestPath;
vector<int> goblinHealth;

string tempWeapon; // A variable to use when switching weapons in a room

// Array to hold possible room contents
// 0 = empty | 1 = potion | 2 = key | 3 = weapon | 4 = lockbox | 5 = goblin
string roomContent[] = {"empty", "potion", "key", "weapon", "lockbox", "goblin", "shrine", "bomb"};

int playerX = 999; // Start X and Y values high to avoid negative integers
int playerY = 999; // Cantor pairing function takes non-negatives as input

// Variable which hold the element ID of the current room
// This number will be used with roomMap to find and process
// the unique ID number of the room (the value stored inside
// the roomMap array. Whereas, the currentRoom number is
// merely the element ID for the roomMap array.
int currentRoom = 0;

// Variable to hold user input - a single character for simplicity
char userInput;

// Using a vector rather than static array for dynamic sizing
// long long int should be sufficient for large Cantor values
vector<long long int> roomMap;

// Custom function to calculate the unique Cantor value
// of two given input. Typically 'playerX' and 'playerY'
long long int cantor(int x, int y) {

    return (((x + y) * (x + y + 1)) / 2) + y;

}

// This is a function be called when the player changes weapons
// It will update the 'playerAttack' value depending on the value
// of 'playerWeapon'
void updateAttack() {

    if (playerWeapon == "Fists") { playerAttack = 2; }
    if (playerWeapon == "Stick") { playerAttack = 3; }
    if (playerWeapon == "Branch") { playerAttack = 4; }
    if (playerWeapon == "Knife") { playerAttack = 5; }
    if (playerWeapon == "Dagger") { playerAttack = 6; }
    if (playerWeapon == "Spear") { playerAttack = 7; }
    if (playerWeapon == "Sword") { playerAttack = 10; }

}

// A FUNction for displaying a cool Title at the start of the game
void displayTitle() {

    cout << "============================================================\n";
    cout << "                      Cody Ray Miller &                     \n";
    cout << "                  Dude Fuel Games Presents...               \n";
    cout << "============================================================\n";
    cout << "         ____                  ____                         \n";
    cout << "        /                     /                             \n";
    cout << "       |    ___ _  |_ | * __ |    ___ _     _ _  _  _       \n"; 
    cout << "        \\____/ |_| |_|| | | | \\____/ |_||_|| |_||=\"|     \n";
    cout << "                                              _|            \n";
    cout << "                         Version " << versionNumber << "                        \n";
    cout << "============================================================\n";
}

void playRoomSound() {

    if (roomItem[currentRoom] == "goblin") {
        playGoblinSound();
    } else if (roomItem[currentRoom] == "shrine") {
        playShrineSound();
    } else if (roomItem[currentRoom] == "weapon") {
        //playFoundWeaponSound();
    }

}

void playAttackSound() {
    if (playerWeapon == "Fists") {
        playFistsAttackSound();
    } else if (playerWeapon == "Stick" || playerWeapon == "Branch") {
        playStickAttackSound();
    } else if (playerWeapon == "Knife" || playerWeapon == "Dagger") {
        playKnifeAttackSound();
    } else if (playerWeapon == "Spear") {
        playSpearAttackSound();
    } else if (playerWeapon == "Sword") {
        playSwordAttackSound();
    }
}

// Function to update the description text based on room contents
void updateDescripText() {
    if (roomItem[currentRoom] == "empty" && currentRoom != 0) {
        descripText[currentRoom] = "The room is empty.";
    } else if (roomItem[currentRoom] == "potion") {
        descripText[currentRoom] = "There is a \033[1;32mPotion\033[0;33m here.\033[0;0m";
    } else if (roomItem[currentRoom] == "key") {
        descripText[currentRoom] = "There is a \033[0;35mKey\033[0;33m here.\033[0;0m";
    } else if (roomItem[currentRoom] == "weapon") {
        descripText[currentRoom] = "There is a \033[0;36m" + roomWeapon[currentRoom] + "\033[0;33m here.\033[0;0m";
    } else if (roomItem[currentRoom] == "lockbox") {
        descripText[currentRoom] = "There is a \033[0;35mLocked Box\033[0;33m here.\033[0;0m";
    } else if (roomItem[currentRoom] == "goblin") {
        descripText[currentRoom] = "There is a \033[0;31mGoblin\033[0;33m here.\033[0;0m";
    } else if (roomItem[currentRoom] == "shrine") {
        descripText[currentRoom] = "There is a Shrine here.";
    } else if (roomItem[currentRoom] == "bomb") {
        descripText[currentRoom] = "There is a \033[0;31mBomb\033[33m here.\033[0;0m";
    }
}

// This function runs when the player uses a bomb in a dead-end room.
// It will open a new random path in the room - N, E, S, or W.
void deadEndBomb() {

    // Initialize the iterator
    auto it = roomMap.end();

    // Regardless of room contents, if the room is a dead-end, blow open a new random path
    // If the current room is a dead-end room (only 1 path)...
    if (roomNorthPath[currentRoom] + roomEastPath[currentRoom] + roomSouthPath[currentRoom] + roomWestPath[currentRoom] < 2) {

        // Add this message to the end of any existing append Msg from previous if clauses
        appendMsg = appendMsg + "A new path opens! ";

        // Generate a random number to pick a random direction for the new path
        randomNum = rand() % 4;
        if (randomNum == 0) {
            // NORTH
            // If the north path of the current room is currently inaccessible...
            if (roomNorthPath[currentRoom] == 0) {
                // Open the North path of the current room
                roomNorthPath[currentRoom] = 1;

                // NORTH ADJACENT ROOM CHECK
                // Calculate the cantor value of the room to the North of the current room
                adjacentNorthRoom = cantor(playerX, playerY + 1);

                // Check to see if this cantor value exists already.
                it = find(roomMap.begin(), roomMap.end(), adjacentNorthRoom);

                // If the end is not reached, the value has been found and the room exists.
                if (it != roomMap.end()) {
                    // Set the adjacent room's corresponding path to be open
                    roomSouthPath[distance(roomMap.begin(), it)] = 1;
                } else {
                    // The player has never been inside the adjacent room before.
                    // Do nothing.
                }

            } else {
                // If the north path is already open, blow open the South path instead
                roomSouthPath[currentRoom] = 1;

                // SOUTH ADJACENT ROOM CHECK
                // Calculate the cantor value of the room to the North of the current room
                adjacentSouthRoom = cantor(playerX, playerY - 1);

                // Check to see if this cantor value exists already.
                it = find(roomMap.begin(), roomMap.end(), adjacentSouthRoom);

                // If the end is not reached, the value has been found and the room exists.
                if (it != roomMap.end()) {
                    // Set the adjacent room's corresponding path to be open
                    roomNorthPath[distance(roomMap.begin(), it)] = 1;
                } else {
                    // The player has never been inside the adjacent room before.
                    // Do nothing.
                }

            }
        }
        if (randomNum == 1) {
            // SOUTH
            // If the south path of the current room is currently inaccessible...
            if (roomSouthPath[currentRoom] == 0) {
                // Open the South path of the current room
                roomSouthPath[currentRoom] = 1;

                // SOUTH ADJACENT ROOM CHECK
                // Calculate the cantor value of the room to the North of the current room
                adjacentSouthRoom = cantor(playerX, playerY - 1);

                // Check to see if this cantor value exists already.
                it = find(roomMap.begin(), roomMap.end(), adjacentSouthRoom);

                // If the end is not reached, the value has been found and the room exists.
                if (it != roomMap.end()) {
                    // Set the adjacent room's corresponding path to be open
                    roomNorthPath[distance(roomMap.begin(), it)] = 1;
                } else {
                    // The player has never been inside the adjacent room before.
                    // Do nothing.
                }

            } else {
                // If the south path is already open, blow open the North path instead
                roomNorthPath[currentRoom] = 1;

                // NORTH ADJACENT ROOM CHECK
                // Calculate the cantor value of the room to the North of the current room
                adjacentNorthRoom = cantor(playerX, playerY + 1);

                // Check to see if this cantor value exists already.
                it = find(roomMap.begin(), roomMap.end(), adjacentNorthRoom);

                // If the end is not reached, the value has been found and the room exists.
                if (it != roomMap.end()) {
                    // Set the adjacent room's corresponding path to be open
                    roomSouthPath[distance(roomMap.begin(), it)] = 1;
                } else {
                    // The player has never been inside the adjacent room before.
                    // Do nothing.
                }

            }
        }
        if (randomNum == 2) {
            // EAST
            // If the east path of the current room is currently inaccessible...
            if (roomEastPath[currentRoom] == 0) {
                // Open the East path of the current room
                roomEastPath[currentRoom] = 1;

                // EAST ADJACENT ROOM CHECK
                // Calculate the cantor value of the room to the East of the current room
                adjacentEastRoom = cantor(playerX + 1, playerY);

                // Check to see if this cantor value exists already.
                it = find(roomMap.begin(), roomMap.end(), adjacentEastRoom);

                // If the end is not reached, the value has been found and the room exists.
                if (it != roomMap.end()) {
                    // Set the adjacent room's corresponding path to be open
                    roomWestPath[distance(roomMap.begin(), it)] = 1;
                } else {
                    // The player has never been inside the adjacent room before.
                    // Do nothing.
                }

            } else {
                // If the east path is already open, blow open the west path instead
                roomWestPath[currentRoom] = 1;

                // WEST ADJACENT ROOM CHECK
                // Calculate the cantor value of the room to the West of the current room
                adjacentWestRoom = cantor(playerX - 1, playerY);

                // Check to see if this cantor value exists already.
                it = find(roomMap.begin(), roomMap.end(), adjacentWestRoom);

                // If the end is not reached, the value has been found and the room exists.
                if (it != roomMap.end()) {
                    // Set the adjacent room's corresponding path to be open
                    roomEastPath[distance(roomMap.begin(), it)] = 1;
                } else {
                    // The player has never been inside the adjacent room before.
                    // Do nothing.
                }

            }
        }
        if (randomNum == 3) {
            // WEST
            // If the west path of the current room is currently inaccessible...
            if (roomWestPath[currentRoom] == 0) {
                // Open the West path of the current room
                roomWestPath[currentRoom] = 1;

                                // WEST ADJACENT ROOM CHECK
                // Calculate the cantor value of the room to the West of the current room
                adjacentWestRoom = cantor(playerX - 1, playerY);

                // Check to see if this cantor value exists already.
                it = find(roomMap.begin(), roomMap.end(), adjacentWestRoom);

                // If the end is not reached, the value has been found and the room exists.
                if (it != roomMap.end()) {
                    // Set the adjacent room's corresponding path to be open
                    roomEastPath[distance(roomMap.begin(), it)] = 1;
                } else {
                    // The player has never been inside the adjacent room before.
                    // Do nothing.
                }

            } else {
                // If the west path is already open, blow open the east path instead
                roomEastPath[currentRoom] = 1;

                // EAST ADJACENT ROOM CHECK
                // Calculate the cantor value of the room to the East of the current room
                adjacentEastRoom = cantor(playerX + 1, playerY);

                // Check to see if this cantor value exists already.
                it = find(roomMap.begin(), roomMap.end(), adjacentEastRoom);

                // If the end is not reached, the value has been found and the room exists.
                if (it != roomMap.end()) {
                    // Set the adjacent room's corresponding path to be open
                    roomWestPath[distance(roomMap.begin(), it)] = 1;
                } else {
                    // The player has never been inside the adjacent room before.
                    // Do nothing.
                }

            }
        }

    }

}

// This function will be used with a bomb to open a four-way path.
// It first opens a four-way path in the current room and then checks
// all adjacent rooms to see if they already exist or not. If they
// do, it ensures that a corresponding path is opened there also.
void fourWayBomb() {

    // Open all four paths in the current room
    roomNorthPath[currentRoom] = 1;
    roomEastPath[currentRoom] = 1;
    roomSouthPath[currentRoom] = 1;
    roomWestPath[currentRoom] = 1;

    // Check adjacent rooms
    // If they exist, open a corresponding path
    // If no adjacent room exists, there is
    // nothing needing to be done

    // Initialize the iterator
    auto it = roomMap.end();

        // NORTH

        // Calculate the cantor value of the room to the North of the current room
        adjacentNorthRoom = cantor(playerX, playerY + 1);

        // Check to see if this cantor value exists already.
        it = find(roomMap.begin(), roomMap.end(), adjacentNorthRoom);

        // If the end is not reached, the value has been found and the room exists.
        if (it != roomMap.end()) {
            // Set the adjacent room's corresponding path to be open
            roomSouthPath[distance(roomMap.begin(), it)] = 1;
        } else {
            // The player has never been inside the adjacent room before.
            // Do nothing.
        }

        // EAST

        // Calculate the cantor value of the room to the East of the current room
        adjacentEastRoom = cantor(playerX + 1, playerY);

        // Check to see if this cantor value exists already.
        it = find(roomMap.begin(), roomMap.end(), adjacentEastRoom);

        // If the end is not reached, the value has been found and the room exists.
        if (it != roomMap.end()) {
            // Set the adjacent room's corresponding path to be open
            roomWestPath[distance(roomMap.begin(), it)] = 1;
        } else {
            // The player has never been inside the adjacent room before.
            // Do nothing.
        }

        // SOUTH

        // Calculate the cantor value of the room to the South of the current room
        adjacentSouthRoom = cantor(playerX, playerY - 1);

        // Check to see if this cantor value exists already.
        it = find(roomMap.begin(), roomMap.end(), adjacentSouthRoom);

        // If the end is not reached, the value has been found and the room exists.
        if (it != roomMap.end()) {
            // Set the adjacent room's corresponding path to be open
            roomNorthPath[distance(roomMap.begin(), it)] = 1;
        } else {
            // The player has never been inside the adjacent room before.
            // Do nothing.
        }

        // WEST

        // Calculate the cantor value of the room to the West of the current room
        adjacentWestRoom = cantor(playerX - 1, playerY);

        // Check to see if this cantor value exists already.
        it = find(roomMap.begin(), roomMap.end(), adjacentWestRoom);

        // If the end is not reached, the value has been found and the room exists.
        if (it != roomMap.end()) {
            // Set the adjacent room's corresponding path to be open
            roomEastPath[distance(roomMap.begin(), it)] = 1;
        } else {
            // The player has never been inside the adjacent room before.
            // Do nothing.
        }

}

void checkAdjacentNorthPath() {

        auto it = roomMap.end();

        // Calculate the cantor value of the room to the North of the current room
        adjacentNorthRoom = cantor(playerX, playerY + 1);

        // Check to see if this cantor value exists already.
        it = find(roomMap.begin(), roomMap.end(), adjacentNorthRoom);

        // If the end is not reached, the value has been found and the room exists.
        if (it != roomMap.end()) {
            // Set the current room's path value to correspond with the already explored room
            roomNorthPath[currentRoom] = roomSouthPath[distance(roomMap.begin(), it)];
        } else {
            // The player has never been inside the adjacent room before.
            // Do nothing.
        }
}

void checkAdjacentEastPath() {

        auto it = roomMap.end();

        // Calculate the cantor value of the room to the East of the current room
        adjacentEastRoom = cantor(playerX + 1, playerY);

        // Check to see if this cantor value exists already.
        it = find(roomMap.begin(), roomMap.end(), adjacentEastRoom);

        // If the end is not reached, the value has been found and the room exists.
        if (it != roomMap.end()) {
            // Set the current room's path value to correspond with the already explored room
            roomEastPath[currentRoom] = roomWestPath[distance(roomMap.begin(), it)];
        } else {
            // The player has never been inside the adjacent room before.
            // Do nothing.
        }
}

void checkAdjacentSouthPath() {

        auto it = roomMap.end();

        // Calculate the cantor value of the room to the South of the current room
        adjacentSouthRoom = cantor(playerX, playerY - 1);

        // Check to see if this cantor value exists already.
        it = find(roomMap.begin(), roomMap.end(), adjacentSouthRoom);

        // If the end is not reached, the value has been found and the room exists.
        if (it != roomMap.end()) {
            // Set the current room's path value to correspond with the already explored room
            roomSouthPath[currentRoom] = roomNorthPath[distance(roomMap.begin(), it)];
        } else {
            // The player has never been inside the adjacent room before.
            // Do nothing.
        }
}

void checkAdjacentWestPath() {

        auto it = roomMap.end();

        // Calculate the cantor value of the room to the West of the current room
        adjacentWestRoom = cantor(playerX - 1, playerY);

        // Check to see if this cantor value exists already.
        it = find(roomMap.begin(), roomMap.end(), adjacentWestRoom);

        // If the end is not reached, the value has been found and the room exists.
        if (it != roomMap.end()) {
            // Set the current room's path value to correspond with the already explored room
            roomWestPath[currentRoom] = roomEastPath[distance(roomMap.begin(), it)];
        } else {
            // The player has never been inside the adjacent room before.
            // Do nothing.
        }
}

void updatePostMsg() {

        // Clear post message
        postMsg = "";

        // If the room contains a goblin, have it attack the player!
        if (roomItem[currentRoom] == "goblin" && goblinHealth[currentRoom] > 0) {

            // Goblin counterattacks, dealing between 1 and 10 damage
            goblinAttack = rand() % 10 + 1;
            playerHealth -= goblinAttack;
            postMsg = "\033[0;31m It attacks!!";

        }

        // Calculate whether or not the current room is a dead end. Display dead end post message if it is.
        if ((roomNorthPath[currentRoom] + roomEastPath[currentRoom] + roomSouthPath[currentRoom] + roomWestPath[currentRoom]) < 2) { postMsg = "\033[0;31m It's a Dead End.\033[0;0m"; }

        // If the room contains a shrine, have it heal the player
        if (roomItem[currentRoom] == "shrine") {

            if (playerHealth < 100) { postMsg = " \033[0;32mHealth restored!\033[0;0m"; playerHealth = 100; }

        }
}

void spawnGoblin() {

    roomItem.push_back("goblin");
    descripText.push_back("There is a goblin here.");
    roomWeapon.push_back(weapons[0]);
    goblinHealth.push_back(rand() % 10 + 1);
    if (roomMap.size() > 150) { goblinHealth[currentRoom] += 4; }

}

// Function to create a new room
void makeNewRoom() {

    // 'Push' a new value (0) to the 'back' (end) of the array
    roomMap.push_back(0);

    // Push new room path values to initialize arrays
    roomNorthPath.push_back(0);
    roomEastPath.push_back(0);
    roomSouthPath.push_back(0);
    roomWestPath.push_back(0);

    // While loop to avoid dead-ends
    while ((roomNorthPath[currentRoom] + roomEastPath[currentRoom] + roomSouthPath[currentRoom] + roomWestPath[currentRoom]) < 2) {
    
    // Set random paths for the room
    randomNum = rand() % 2; // Generate random number between 0 and 1
    roomNorthPath[currentRoom] = randomNum;
    randomNum = rand() % 2; // Generate random number between 0 and 1
    roomEastPath[currentRoom] = randomNum;
    randomNum = rand() % 2; // Generate random number between 0 and 1
    roomSouthPath[currentRoom] = randomNum;
    randomNum = rand() % 2; // Generate random number between 0 and 1
    roomWestPath[currentRoom] = randomNum;

    // Ensure that there is a path back to wherever the player came form
    if (lastMove == 'N') { roomSouthPath[currentRoom] = 1; }
    if (lastMove == 'E') { roomWestPath[currentRoom] = 1; }
    if (lastMove == 'S') { roomNorthPath[currentRoom] = 1; }
    if (lastMove == 'W') { roomEastPath[currentRoom] = 1; }

    // Ensure that paths are not created into existing rooms without corresponding paths.
    // For example, do not create a West path if the existing room to the West has no East path.

    // If player came from the South, check W, N, E
    if (lastMove == 'N') {

        checkAdjacentWestPath();
        checkAdjacentNorthPath();
        checkAdjacentEastPath();

    }

    // If player came from the South, check N, E, S
    if (lastMove == 'E') {

        checkAdjacentNorthPath();
        checkAdjacentEastPath();
        checkAdjacentSouthPath();

    }

    // If player came from the South, check E, S, W
    if (lastMove == 'S') {
        
        checkAdjacentEastPath();
        checkAdjacentSouthPath();
        checkAdjacentWestPath();

    }

    // If player came from the South, check N, W, S
    if (lastMove == 'W') {

        checkAdjacentNorthPath();
        checkAdjacentWestPath();
        checkAdjacentSouthPath();

    }

    // OPTIONAL: This code would permit the creation of dead ends
    // Break out of the loop if player has explored 100 rooms or more

    // I'm still really not sure about adding dead ends. It provides an
    // interesting challenge but the possibility of a closed cave system.

    //if (roomMap.size() >= 100) { break; }

    // This loop can get stuck because a dead-end is simply unavoidable sometimes. This counter helps to ensure
    // that the loop is canceled after a certain amount of tries, so that the game can simply generate the
    // dead-end and move on. Otherwise, the game will hang on a black screen.
    deadEndCounter++;

    if (deadEndCounter > 10) {

        deadEndCounter = 0;
        break;

    }

    }

    // Use RNG to determine new room contents
    // Make a certain percentage of rooms empty by default (prevents too many items, etc.)
    randomNum = rand() % 2; // Pick a random number between 0 and 1

    // If random number is 1, determine contents with a chance for items
    if (randomNum == 1) {
        randomNum = rand() % 8;
        switch (randomNum) {
            case 0:
            roomItem.push_back("empty");
            descripText.push_back("The room is empty.");
            roomWeapon.push_back(weapons[0]);
            goblinHealth.push_back(0);
            break;
            case 1:
            roomItem.push_back("potion");
            descripText.push_back("There is a potion here.");
            roomWeapon.push_back(weapons[0]);
            goblinHealth.push_back(0);
            break;
            case 2:
            randomNum = rand() % 2;
            if (randomNum == 0) {
                roomItem.push_back("key");
                descripText.push_back("There is a key here.");
                roomWeapon.push_back(weapons[0]);
                goblinHealth.push_back(0);
            } else {
                roomItem.push_back("empty");
                descripText.push_back("The room is empty.");
                roomWeapon.push_back(weapons[0]);
                goblinHealth.push_back(0);
            }
            break;
            case 3:
            roomItem.push_back("weapon");
            randomNum = rand() % 5; // Generate a random number between 0 and 5.
            // cout << "Random number generated: " << randomNum << "\n\n"; // DEBUG CODE ONLY
            roomWeapon.push_back(weapons[randomNum]);
            descripText.push_back("There is a " + roomWeapon[currentRoom] + " here.");
            goblinHealth.push_back(0);
            break;
            case 4:
            roomItem.push_back("lockbox");
            descripText.push_back("There is a locked box here.");
            roomWeapon.push_back(weapons[0]);
            goblinHealth.push_back(0);
            break;
            case 5:
            spawnGoblin();
            break;
            case 6:
            // Shrine room - needs to be rare, so adding RNG to prevent it from
            // showing up too often...
            randomNum = rand() % 4;
            if (randomNum == 0) {
                roomItem.push_back("shrine");
                descripText.push_back("There is a shrine here.");
                roomWeapon.push_back(weapons[0]);
                goblinHealth.push_back(0);
            } else {
                roomItem.push_back("empty");
                descripText.push_back("The room is empty.");
                roomWeapon.push_back(weapons[0]);
                goblinHealth.push_back(0);
            }
            break;
            case 7:
            // Bomb room!
            randomNum = rand() % 2; // Generate a random number between 0 and 1
            if (randomNum == 0) {
                roomItem.push_back("bomb");
                descripText.push_back("There is a Bomb here.");
                roomWeapon.push_back(weapons[0]);
                goblinHealth.push_back(0);
            } else {
                roomItem.push_back("empty");
                descripText.push_back("The room is empty.");
                roomWeapon.push_back(weapons[0]);
                goblinHealth.push_back(0);
            }
            break;
            default:
            // This is just a goofy "in case something goes wrong case"
            roomItem.push_back("empty");
            descripText.push_back("Something went wrong!!!!");
            roomWeapon.push_back(weapons[0]);
            goblinHealth.push_back(0);
            break;
        }

    // Otherwise, if random number is 0, always make the room empty
    // OR filled with a GOBLIN!
    } else {

        // Determine encounter rate - lower encounter rate number means MORE encounters
        if (roomMap.size() >= 30) { encounterRate = 4; }
        if (roomMap.size() >= 70) { encounterRate = 3; }
        if (roomMap.size() >= 120) { encounterRate = 2; }
        else { encounterRate = 5; }
        
        // Pick a random number
        randomNum = rand() % encounterRate;

        // If the number is...
        if (randomNum == 0) {

            spawnGoblin();
        
        } else {

            roomItem.push_back("empty");
            descripText.push_back("The room is empty.");
            roomWeapon.push_back(weapons[0]);
            goblinHealth.push_back(0);

        }

    }

    updateDescripText(); // Update description text for the room

    // cout << "\a"; could be used for a mostly-cross-platform "bell" sound here, if desired
    // For now, I have chosen to disable it.

    // Calculate the unique Cantor value for the current playerX and playerY values
    // and assign that value to the array.
    // Example: In the first room... roomMap[0] = 0, where '0' is the calculated
    // Cantor value for the pairing, '0,0'
    // This modifies the initialized value of the current roomMap element, which was
    // previously set to '0' (see code in 'if' clause, above)
    roomMap[currentRoom] = cantor(playerX, playerY);

}

// Main function
int main() {

    // Set output to UTF-8 - for special character use
    //SetConsoleOutputCP(CP_UTF8);

    updateAttack();

    // Seed random number generation with current time
    srand(time(0));

    startNewGame = true;

    while (true) {

    if (startNewGame) {
    // Set up description, etc. for the initial room
    descripText.push_back("You are in a dark cave.");
    roomItem.push_back("empty");
    roomWeapon.push_back(weapons[0]);
    roomMap.push_back(0);
    goblinHealth.push_back(0);
    roomMap[currentRoom] = cantor(playerX, playerY);
    roomNorthPath.push_back(1);
    roomEastPath.push_back(1);
    roomSouthPath.push_back(1);
    roomWestPath.push_back(1);
    startNewGame = false;
    }

    while (playerHealth > 0) {

        // Clear the command window display - works on Windows!
        system("CLS");
        
        // Adjust the size of the roomMap array if needed
        if (currentRoom >= roomMap.size()) {

            // Function to generate a new room
            makeNewRoom();
            //DEBUG: appendMsg = "MAKING NEW ROOM... ";

        }

        updateDescripText(); // Update description text before displaying!

        updatePostMsg();

        // Check to see if the player has died. If so, exit the game loop.
        if (playerHealth < 1) { break; }

        // DEBUG DISPLAY ONLY BELOW
        //cout << "Size of roomMap: " << roomMap.size() << endl;
        //cout << "Size of roomItem: " << roomItem.size() << endl;
        //cout << "Size of descripText: " << descripText.size() << endl;
        //cout << "Size of roomWeapon: " << roomWeapon.size() << endl;
        //cout << "Size of goblinHealth: " << goblinHealth.size() << endl;
        //cout << "Player Attack: " << playerAttack << " | Goblin Health: " << goblinHealth[currentRoom] << " | Goblin Attack: " << goblinAttack << "\n\n";

        displayTitle();

        playRoomSound();

        int playerScore = ((roomMap.size() * 10) + (goblinsKilled * 20)) - 10;
        // Display game stats
        cout << "SCORE: " << playerScore << " | Rooms Explored: " << roomMap.size() << " | Goblins Slain: " << goblinsKilled << "\n\n";

        // Display Description Text for current room
        cout << appendMsg << "\033[0;33m" << descripText[currentRoom] << postMsg << "\033[0;0m\n\n";

        // If the room contains a goblin with more than zero hp, display Goblin HP
        if (roomItem[currentRoom] == "goblin" && goblinHealth[currentRoom] > 0) { cout << "Goblin HP: " << goblinHealth[currentRoom] << "\n\n"; }

        // Display the currentRoom value
        //cout << "You are currently in room " << currentRoom << ".\n\n";

        // Display current room's unique Cantor value
        //cout << "The Cantor value of the current room is: " << roomMap[currentRoom] << "\n\n";

        // Display player health - if clause changes player health color to red if low health!
        if (playerHealth <= 20) { cout << "\033[0;31mHealth: " << playerHealth; }
        else { cout << "\033[0;32mHealth: " << playerHealth; }
        cout << "\033[0;0m - Weapon: " << playerWeapon << " (" << playerAttack << " dmg)";
        cout << "\n";
        // Display player inventory status
        cout << "\033[0;0mPotions: " << playerPotions << " | Keys: " << playerKeys << " | Bombs: " << playerBombs << "\n\n";

        // Display available paths to player
        cout << "You see paths ";
        if (roomNorthPath[currentRoom] == 1) { cout << "North "; }
        if (roomEastPath[currentRoom] == 1) { cout << "East "; }
        if (roomSouthPath[currentRoom] == 1) { cout << "South "; }
        if (roomWestPath[currentRoom] == 1) { cout << "West "; }
        cout << "\n\n";

        // Display player current X and Y position and explain navigation
        //cout << "You are in a room at " << playerX << "," << playerY << ".\n\n";

        cout << "\033[0;36mAction Commands:\033[0;0m\nMovement: \033[0;36mN\033[0;0m - Go North | \033[0;36mE\033[0;0m - Go East | \033[0;36mS\033[0;0m - Go South | \033[0;36mW\033[0;0m - Go West\n";
        cout << "\033[0;36mF\033[0;0m - Fight! | \033[0;36mT\033[0;0m - Take Item | \033[0;36mO\033[0;0m - Open Lock | \033[0;36mP\033[0;0m - Use Potion\n\033[0;36mB\033[0;0m - Use Bomb\033[0;0m";

        cout << "\n\n>>>>";

        // Get user input
        cin.get(userInput);

        // Convert user input to uppercase
        userInput = toupper(userInput); // This avoids case sensitivity issues between input 'n' and 'N', for example

        // Create a variable to hold temporary Cantor values in switch case below
        long long int tempCant;

        // Iterator to be used inside switch case
        auto it = roomMap.end(); // Declare iterator here to avoid scope issues!

        // Determine what to do based on user input
        switch (userInput) {
            case 'O':
            // If there is a lockbox in the current room and the player has at least 1 key...
            if (roomItem[currentRoom] == "lockbox" && playerKeys > 0) {

                playerKeys--;
                playKeyUnlockSound();

                randomNum = rand() % 6; // Generate a random number between 0 and 3
                // If number generated is 0, 1, or 2... (less than 3)

                // If number generated is...
                if (randomNum == 5) {

                    // The player finds a sword. Logic below handles
                    // what to do whether the player is barehanded
                    // or else already has an existing weapon

                    // What to do if player has no existing weapon...
                    if (playerWeapon == "Fists") {

                        playerWeapon = "Sword";
                        updateAttack();
                        playFoundSwordSound();
                        roomItem[currentRoom] = "empty";
                        appendMsg = "You found a Sword! You take it. ";

                    } else if (playerWeapon == "Sword") {

                        // Give player a potion
                        playerPotions ++;
                        playFoundPotionSound();
                        appendMsg = "You found a Potion! You take it. ";
                        roomItem[currentRoom] = "empty";

                    // What to do if player has an existing weapon...
                    } else {

                    // Store player's current weapon temporarily
                    tempWeapon = playerWeapon;
                    // Change player's weapon to sword
                    playerWeapon = "Sword";
                    // Update player attack value
                    updateAttack();
                    playFoundSwordSound();
                    // Change the room item to weapon
                    roomItem[currentRoom] = "weapon";
                    // Store the player's old weapon inside the room
                    roomWeapon[currentRoom] = tempWeapon;
                    // Let the player know they found a sword!
                    appendMsg = "You found a Sword! You take it. ";
                    
                    }
                
                // In every other case, do the following...
                } else {

                    // Give player a potion
                    playerPotions ++;
                    playFoundPotionSound();
                    appendMsg = "You found a Potion! You take it. ";
                    roomItem[currentRoom] = "empty";

                }


            } else if (roomItem[currentRoom] == "lockbox" && playerKeys < 1) {

                appendMsg = "You need a key to open the locked box. ";

            } else {

                appendMsg = "There is nothing to open here. ";

            }
            break;
            case 'B':
            if (playerBombs > 0) {

                playerBombs--;
                playBombSound();

                if (roomItem[currentRoom] == "goblin") {

                    // Set goblinHealth to zero. Bombs kill goblins. LOL
                    goblinHealth[currentRoom] = 0;

                    // Increment goblin kill-counter variable
                    goblinsKilled++;

                    // Let the player know they've killed the goblin
                    appendMsg = "The bomb explodes! You defeat the goblin! ";
                    // Determine whether to set the room to empty or potion
                    randomNum = rand() % 7; // Generate random number between 0 and 6
                    if (randomNum == 1) { roomItem[currentRoom] = "potion"; }
                    else if (randomNum == 2) { roomItem[currentRoom] = "key"; }
                    else { roomItem[currentRoom] = "empty"; }

                } else if (roomItem[currentRoom] == "shrine") {

                    appendMsg = "The bomb explodes! The shrine crumbles. ";
                    roomItem[currentRoom] = "empty";


                } else if (roomItem[currentRoom] == "lockbox") {

                randomNum = rand() % 6; // Generate a random number

                // If number generated is...
                if (randomNum == 5) {

                    // The player finds a sword. Logic below handles
                    // what to do whether the player is barehanded
                    // or else already has an existing weapon

                    // What to do if player has no existing weapon...
                    if (playerWeapon == "Fists") {

                        playerWeapon = "Sword";
                        updateAttack();
                        roomItem[currentRoom] = "empty";
                        appendMsg = "The bomb explodes! You found a Sword! You take it. ";

                    } else if (playerWeapon == "Sword") {

                        // Give player a potion
                        playerPotions ++;
                        appendMsg = "The bomb explodes! You found a Potion! You take it. ";
                        roomItem[currentRoom] = "empty";

                    // What to do if player has an existing weapon...
                    } else {

                    // Store player's current weapon temporarily
                    tempWeapon = playerWeapon;
                    // Change player's weapon to sword
                    playerWeapon = "Sword";
                    // Update player attack value
                    updateAttack();
                    // Change the room item to weapon
                    roomItem[currentRoom] = "weapon";
                    // Store the player's old weapon inside the room
                    roomWeapon[currentRoom] = tempWeapon;
                    // Let the player know they found a sword!
                    appendMsg = "The bomb explodes! You found a Sword! You take it. ";
                    
                    }
                
                // In every other case, do the following...
                } else {

                    // Give player a potion
                    playerPotions ++;
                    appendMsg = "The bomb explodes! You found a Potion! You take it. ";
                    roomItem[currentRoom] = "empty";

                }

                } else if (roomItem[currentRoom] == "bomb") {

                    if (roomNorthPath[currentRoom] + roomEastPath[currentRoom] + roomSouthPath[currentRoom] + roomWestPath[currentRoom] < 4) {

                    appendMsg = "The bombs explode! New paths open!! ";
                    fourWayBomb();
                    roomItem[currentRoom] = "empty";

                    } else {

                        appendMsg = "The bombs explode! ";
                        roomItem[currentRoom] = "empty";

                    }

                } else { appendMsg = "The bomb explodes! "; }

                deadEndBomb(); // Run the function to see if the room is a dead-end and blow open a random path if it is

            } else {

                // Let the player know they have no bombs
                appendMsg = "You don't have any bombs. ";

            }
            break;
            case 'F':
            if (roomItem[currentRoom] == "goblin") {

                goblinHealth[currentRoom] -= playerAttack;
                playAttackSound();

                // If, after attacking, the goblin's health is 0 or lower...
                if (goblinHealth[currentRoom] < 1) {

                    // Set goblinHealth to zero; there is really no need for this
                    // but it bothers me to think of negative enemy health...
                    goblinHealth[currentRoom] = 0;

                    // Increment goblin kill-counter variable
                    goblinsKilled++;

                    // Let the player know they've killed the goblin
                    appendMsg = "You defeat the goblin! ";
                    // Determine whether to set the room to empty or potion
                    randomNum = rand() % 7; // Generate random number between 0 and 6
                    if (randomNum == 1) { roomItem[currentRoom] = "potion"; }
                    else if (randomNum == 2) { roomItem[currentRoom] = "key"; }
                    else { roomItem[currentRoom] = "empty"; }

                } else {

                    // Let the player know that they've damaged the goblin and also been damaged themselves
                    appendMsg = "Goblin takes " + to_string(playerAttack) + " dmg! ";

                }
                

            } else { appendMsg = "There is nothing to fight here. "; }
            break;

            case 'T':
            if (roomItem[currentRoom] == "empty") {

                appendMsg = "There is nothing to take here. ";

            }
            
            if (roomItem[currentRoom] == "potion") {

                playerPotions++; // Increase number of potions held by player
                playTakeItemSound();
                roomItem[currentRoom] = "empty"; // Make the room empty now
                appendMsg = "You take the potion. ";

            }

            if (roomItem[currentRoom] == "bomb") {

                playerBombs++; // Increase number of potions held by player
                playTakeItemSound();
                roomItem[currentRoom] = "empty"; // Make the room empty now
                appendMsg = "You take the bomb. ";

            }
            
            if (roomItem[currentRoom] == "key") {

                playerKeys++; // Increase number of keys held by player
                playTakeItemSound();
                roomItem[currentRoom] = "empty"; // Make the room empty now
                appendMsg = "You take the key. ";

            }
            
            if (roomItem[currentRoom] == "lockbox") {

                appendMsg = "The locked box is too big to take. ";
            
            }
            
            if (roomItem[currentRoom] == "weapon") {

                randomNum = rand() % 6; // Pick a random number between 0 and 5
                if (playerWeapon == "Fists") {

                    playerWeapon = roomWeapon[currentRoom];
                    playTakeItemSound();
                    roomItem[currentRoom] = "empty";

                    updateAttack();

                    appendMsg = "You take the " + playerWeapon + ". ";

                } else {

                    tempWeapon = playerWeapon; // Save the player's existing weapon in a temp variable
                    playerWeapon = roomWeapon[currentRoom]; // Assign the room's weapon to the player
                    playTakeItemSound();
                    roomWeapon[currentRoom] = tempWeapon; // Assign player's old weapon to the room

                    updateAttack();
                    
                    appendMsg = "You take the " + playerWeapon + ". "; 

                }

            }
            
            if (roomItem[currentRoom] == "goblin") {

                appendMsg = "You pick up the goblin. \033[1;31mIt attacks!! \033[0;0m"; // LOL
                playerHealth -= 10; // Have the goblin damage the player

            }
            break;
            case 'P':
            if (playerPotions > 0 && playerHealth < 100) {

                // Reduce player potions by 1
                playerPotions--;
                playUsePotionSound();
                // Increase player health by 10
                playerHealth += 10;
                // Ensure that player health cannot exceed 100
                if (playerHealth > 100) { playerHealth = 100; }
                // Let the player know what happened
                appendMsg = "You use a potion. \033[0;32mHealth restored! \033[0;0m";

            } else if (playerPotions > 0 && playerHealth == 100) {

                // Let the player know they're being silly...
                appendMsg = "Your health is already full. ";

            } else {

                // Let the player know they have no potions
                appendMsg = "You don't have any potions. ";

            }
            break;
            case 'N':
            if (roomNorthPath[currentRoom] == 1) {
            lastMove = 'N';
            // Increase player Y position by 1. (increment)
            playerY++;
            playWalkSound();
            // Calculate Cantor value of new position
            tempCant = cantor(playerX, playerY);
            // Search to see if the unique Cantor value for the room entered already exists
            it = find(roomMap.begin(), roomMap.end(), tempCant);

            // If the end is not reached, the value has been found and the room
            // has been previously entered by the player.
            // Else, it is a room the player has never entered before.
            if (it != roomMap.end()) {
                // The player has been inside this room before. Set 'currentRoom' to the index
                // of the roomMap array containing the found Cantor value
                currentRoom = distance(roomMap.begin(), it);
            } else {
                // The player has never been inside this room before. Set the 'currentRoom'
                // value to the next available index of the roomMap array.
                currentRoom = roomMap.size();
            }
            appendMsg = "You go North. ";
            } else { appendMsg = "\033[1;31mYou can't go that way. \033[0;0m"; }
            break;
            case 'E':
            if (roomEastPath[currentRoom] == 1) {
            lastMove = 'E';
            // Increase player Y position by 1. (increment)
            playerX++;
            playWalkSound();
            // Calculate Cantor value of new position
            tempCant = cantor(playerX, playerY);
            // Search to see if the unique Cantor value for the room entered already exists
            it = find(roomMap.begin(), roomMap.end(), tempCant);

            // If the end is not reached, the value has been found and the room
            // has been previously entered by the player.
            // Else, it is a room the player has never entered before.
            if (it != roomMap.end()) {
                // The player has been inside this room before. Set 'currentRoom' to the index
                // of the roomMap array containing the found Cantor value
                currentRoom = distance(roomMap.begin(), it);
            } else {
                // The player has never been inside this room before. Set the 'currentRoom'
                // value to the next available index of the roomMap array.
                currentRoom = roomMap.size();
            }
            appendMsg = "You go East. ";
            } else { appendMsg = "\033[1;31mYou can't go that way. \033[0;0m"; }
            break;
            case 'S':
            if (roomSouthPath[currentRoom] == 1) {
            lastMove = 'S';
            // Increase player Y position by 1. (increment)
            playerY--;
            playWalkSound();
            // Check to make sure the player has not gone 'out of bounds'
            // (into a negative integer player position).
            if (playerY < 0) {
                // If decrement goes negative, return to '0'
                playerY = 0;
                appendMsg = "\033[1;31mYou can't go that way; a wall blocks your path.\n\n\033[0;0m";
                break; // Exit the switch, doing nothing else.
            }
            // Calculate Cantor value of new position
            tempCant = cantor(playerX, playerY);
            // Search to see if the unique Cantor value for the room entered already exists
            it = find(roomMap.begin(), roomMap.end(), tempCant);

            // If the end is not reached, the value has been found and the room
            // has been previously entered by the player.
            // Else, it is a room the player has never entered before.
            if (it != roomMap.end()) {
                // The player has been inside this room before. Set 'currentRoom' to the index
                // of the roomMap array containing the found Cantor value
                currentRoom = distance(roomMap.begin(), it);
            } else {
                // The player has never been inside this room before. Set the 'currentRoom'
                // value to the next available index of the roomMap array.
                currentRoom = roomMap.size();
            }
            appendMsg = "You go South. ";
            } else { appendMsg = "\033[1;31mYou can't go that way. \033[0;0m"; }
            break;
            case 'W':
            if (roomWestPath[currentRoom] == 1) {
            lastMove = 'W';
            // Increase player Y position by 1. (increment)
            playerX--;
            playWalkSound();
            // Check to make sure the player has not gone 'out of bounds'
            // (into a negative integer player position).
            if (playerX < 0) {
                // If decrement goes negative, return to '0'
                playerX = 0;
                appendMsg = "\033[1;31mYou can't go that way; a wall blocks your path.\n\n\033[0;0m";
                break; // Exit the switch, doing nothing else.
            }
            // Calculate Cantor value of new position
            tempCant = cantor(playerX, playerY);
            // Search to see if the unique Cantor value for the room entered already exists
            it = find(roomMap.begin(), roomMap.end(), tempCant);

            // If the end is not reached, the value has been found and the room
            // has been previously entered by the player.
            // Else, it is a room the player has never entered before.
            if (it != roomMap.end()) {
                // The player has been inside this room before. Set 'currentRoom' to the index
                // of the roomMap array containing the found Cantor value
                currentRoom = distance(roomMap.begin(), it);
            } else {
                // The player has never been inside this room before. Set the 'currentRoom'
                // value to the next available index of the roomMap array.
                currentRoom = roomMap.size();
            }
            appendMsg = "You go West. ";
            } else { appendMsg = "\033[1;31mYou can't go that way. \033[0;0m"; }
            break;

            case '\n':
            continue;
            break;

            default:
            appendMsg = "\033[1;31mInvalid input. Please try again.\n\n\033[0;0m";
            break;

        }

            cin.clear(); // Clear cin state/error flags
            cin.ignore(1000, '\n'); // Removes extraneous user inputs. For example, if the
            // player types 'north' instead of just 'n' for North.

    }

    // GAME OVER code here
    system("CLS");

    displayTitle();

    playGameOverSound();

    int playerScore = ((roomMap.size() * 10) + (goblinsKilled * 20)) - 10;
    // Display game stats
    cout << "SCORE: " << playerScore << " | Rooms Explored: " << roomMap.size() << " | Goblins Slain: " << goblinsKilled << "\n\n";
    cout << "\033[1;31mYou have died.\033[0;0m\n\nGAME OVER\n\nDo you want to play again? (Y/N)\n\n>>>>";

    // Get user input
    cin.get(userInput);

    // Convert user input to uppercase
    userInput = toupper(userInput); // This avoids case sensitivity issues between input 'n' and 'N', for example

    switch (userInput) {

        case 'Y':

        startNewGame = true;
        // Clear all arrays
        descripText.clear();
        roomItem.clear();
        roomWeapon.clear();
        goblinHealth.clear();
        tempWeapon.clear();
        roomMap.clear();
        roomNorthPath.clear();
        roomEastPath.clear();
        roomSouthPath.clear();
        roomWestPath.clear();

        // Reset variables
        playerScore = 0;
        goblinsKilled = 0;
        playerX = 999;
        playerY = 999;
        playerPotions = 0;
        playerKeys = 0;
        playerHealth = 100;

        playerWeapon = "Fists";
        playerAttack = 2;
        goblinAttack = 0;
        currentRoom = 0;
        randomNum = 0;

        appendMsg = "";
        postMsg = "";

        cin.clear(); // Clear cin state/error flags
        cin.ignore(1000, '\n');

        break;

        case 'N':
        exit(0);
        break;

        default:
        // Do nothing
        break;

    }

    }

}

gg_sounds.cpp (Sounds File)

#include "gg_sounds.h"
#include <windows.h>
#include <mmsystem.h>

// Miscellaneous Sounds
void playWalkSound() {

    PlaySound(TEXT("sound/walk.wav"), NULL, SND_ASYNC);

}
void playGoblinSound() {

    PlaySound(TEXT("sound/goblin.wav"), NULL, SND_ASYNC);

}
void playUsePotionSound() {

    PlaySound(TEXT("sound/use_potion.wav"), NULL, SND_ASYNC);

}
void playTakeItemSound() {

    PlaySound(TEXT("sound/take_item.wav"), NULL, SND_ASYNC);

}
void playBombSound() {

    PlaySound(TEXT("sound/bomb.wav"), NULL, SND_ASYNC);

}
void playShrineSound() {

    PlaySound(TEXT("sound/shrine.wav"), NULL, SND_ASYNC);

}

// Locked Box & Found Sounds
void playKeyUnlockSound() {

    PlaySound(TEXT("sound/key_unlock.wav"), NULL, SND_SYNC);

}
void playFoundSwordSound() {

    PlaySound(TEXT("sound/found_sword.wav"), NULL, SND_ASYNC);

}
void playFoundPotionSound() {

    PlaySound(TEXT("sound/found_potion.wav"), NULL, SND_ASYNC);

}

void playFoundWeaponSound() {

    PlaySound(TEXT("sound/found_weapon.wav"), NULL, SND_ASYNC);

}

// Weapon Attack Sounds
void playFistsAttackSound() {

    PlaySound(TEXT("sound/attack_fists.wav"), NULL, SND_SYNC);

}
void playStickAttackSound() {

    PlaySound(TEXT("sound/attack_stick.wav"), NULL, SND_SYNC);

}
void playKnifeAttackSound() {

    PlaySound(TEXT("sound/attack_knife.wav"), NULL, SND_SYNC);

}
void playSpearAttackSound() {

    PlaySound(TEXT("sound/attack_spear.wav"), NULL, SND_SYNC);

}
void playSwordAttackSound() {

    PlaySound(TEXT("sound/attack_sword.wav"), NULL, SND_SYNC);

}

// Game Over Sound
void playGameOverSound() {

    PlaySound(TEXT("sound/game_over.wav"), NULL, SND_ASYNC);

}

gg_sounds.h (Header File)

// gg_sounds.h

#ifndef GG_SOUNDS_H
#define GG_SOUNDS_H

// Miscellaneous Sounds
void playWalkSound();
void playGoblinSound();
void playUsePotionSound();
void playTakeItemSound();
void playBombSound();
void playShrineSound();

// Locked Box & Found Sounds
void playKeyUnlockSound();
void playFoundSwordSound();
void playFoundPotionSound();
void playFoundWeaponSound();

// Weapon Attack Sounds
void playFistsAttackSound();
void playStickAttackSound();
void playKnifeAttackSound();
void playSpearAttackSound();
void playSwordAttackSound();

// Game Over Sound
void playGameOverSound();

#endif

Leave a Reply

Your email address will not be published. Required fields are marked *