3
\$\begingroup\$

I am looking for general critique of my code and notice of any bugs or errors. I have included the main file and the class files. Also, I'm wondering where would I need comments. Sorry it is such a monster ;).



#include <iostream>
#include <string>
#include <fstream>
#include "rooms.h"
#include "characters.h"
#include<bits/stdc++.h>

using namespace std;

struct Coord {
    int x;
    int y;
};

void save(vector<vector<Rooms>>& map, Characters& player, int numTurns);
void createOriginalSave(); // Creates original.txt
int load(string filename, vector<vector<Rooms>>& map, Characters& player, vector<Characters>& npcs); // Loads object data from save file
Coord move(string in, vector<vector<Rooms>> map, int x, int y, Characters& player, int moves);
int score (double moves, Characters& player);
void help();
void take(string in, vector<vector<Rooms>>& map, Characters& player);
void end(double moves);

int main() {
    createOriginalSave();

    int numberRows = 18;
    int numberCols = 18;

    int numTurns = 0;

    Characters player("player");
    vector<vector<Rooms>> map;
    vector<Characters> npcs;

    map.resize(numberRows, vector<Rooms>(numberCols));


    string input;
    int num;
    string out;

    cout << "   _                        _           _     _       _                 _                  \n"
            "  /_\\     /\\/\\   __ _  __ _(_) ___ __ _| |   /_\\   __| |_   _____ _ __ | |_ _   _ _ __ ___ \n"
            " //_\\\\   /    \\ / _` |/ _` | |/ __/ _` | |  //_\\\\ / _` \\ \\ / / _ \\ '_ \\| __| | | | '__/ _ \\\n"
            "/  _  \\ / /\\/\\ \\ (_| | (_| | | (_| (_| | | /  _  \\ (_| |\\ V /  __/ | | | |_| |_| | | |  __/\n"
            "\\_/ \\_/ \\/    \\/\\__,_|\\__, |_|\\___\\__,_|_| \\_/ \\_/\\__,_| \\_/ \\___|_| |_|\\__|\\__,_|_|  \\___|\n"
            "                      |___/                                           " << endl;

    cout << "By Ian Herman" << endl;

    help();



    cout << endl;

    cout << "What save would you like to load from? Type original to start a new game." << endl;
    cin >> input;
    numTurns = load(input, map, player, npcs);

    out = map[player.getX()][player.getY()].getDescription();
    while (out.find('.') != -1) {
        num = out.find('.');
        if (num != -1) {
            out.replace(num, 1, "\n");
        }
    }

    cout << out << endl;



    for (int i = 0; true; i++){

        cin >> input;
        Coord newPlayerCoords;

        transform(input.begin(), input.end(), input.begin(), ::tolower);

        if (input == "north") input = "n";
        else if (input == "south") input = "s";
        else if (input == "east") input = "e";
        else if (input == "west") input = "w";
        else if (input == "u") input = "up";
        else if (input == "d") input = "down";


        if (input == "up" || input == "down" || input == "n" || input == "s" || input == "w" || input == "e") {
            newPlayerCoords = move(input, map, player.getX(), player.getY(), player, i);
            player.setLocation(newPlayerCoords.x, newPlayerCoords.y);
        }

        else if (input == "look") {
            out = map[player.getX()][player.getY()].getDescription();
            while (out.find('.') != -1) {
                num = out.find('.');
                if (num != -1) {
                    out.replace(num, 1, "\n");
                }
            }

            cout << out << endl;
        }

        else if (input == "hint") {
            cout << map[player.getX()][player.getY()].getHint() << endl;
        }

        else if (input == "quit") {
            return 0;
        }

        else if (input == "inventory") {
            if (player.getInventory().size() != 0) {

                cout << "Your inventory contains the following:" << endl;

                for (int j = 0; j < player.getInventory().size(); j++) {

                    cout << player.getInventory()[j] << endl;
                }
            } else {
                cout << "You have nothing." << endl;
            }
        }

        else if (input == "help") {
            help();
        }

        else if (input == "save") {
            save(map, player, i);
        }

        else if (input == "take") {
            cin >> input;
            take(input, map, player);
        }

        else if (input == "score") {
            cout << "Your score is " << score(static_cast<double >(i), player) << "%" << endl;
            i--;
        }

        else {
            cout << "¿Hablas Inglés?" << endl;
        }


        map[player.getX()][player.getY()].incrementActionCount();

    }
}

int score (double moves, Characters& player) {
    static int scr = 100;
    if (player.getX() == 1 && player.getX() == 1) {
        scr = 100/moves;
    } else if (player.getX() == 6 && player.getY() == 1) {
        scr = (4.0/moves) * 100.0;
    } else if (player.getX() == 10 && player.getY() == 1) {
        scr = (8.0/moves) * 100.0;
    } else if (player.getX() == 13 && player.getY() == 3) {
        scr = (12.0/moves) * 100.0;
    } else if (player.getX() == 14 && player.getY() == 6) {
        scr = (18.0/moves) * 100.0;
    } else if (player.getX() == 11 && player.getY() == 4) {
        scr = (23.0/moves) * 100.0;
    }
    return scr;
}


void save(vector<vector<Rooms>>& map, Characters& player, int numTurns) {
    string name;
    ofstream outfile;
    cout << "WARNING: DO NOT SAVE DURING COMBAT, CURRENT  COMBAT PROGRESS WILL NOT BE SAVED" << endl;
    cout << "Enter save name, enter same name of pre-existing save to overwrite it, save name original will not work." << endl;
    cin >> name;
    name = name + ".txt";
    outfile.open(name.c_str());
    for (int i = 0; i < 17; i++) {
        for (int j = 0; j < 17; ++j) {
            if (!map[i][j].getEmpty()) {
                outfile << "Room:" << endl;
                outfile << i << " " << j << endl;
                outfile << map[i][j].getName() << endl;
                outfile << map[i][j].getDescription() << endl;



                for (int k = 0; i < map[i][j].getInventory().size(); i++) {
                    outfile << map[i][j].getInventory()[k] << " ";
                }
                outfile << "null";
                outfile << endl;
                outfile << map[i][j].getHint() << endl;
                outfile << map[i][j].getActions() << endl;
            }
        }
    }
    outfile << "Player:" << endl;
    outfile << player.getX() << " " << player.getY() << endl;
    outfile << player.getHealth() << " " << player.getMaxHealth() << endl;
    outfile << player.getMana() << " " << player.getMaxMana() << endl;

    for(int i = 0; i < player.getInventory().size(); i++) {
        outfile << player.getInventory()[i] << " ";
    }
    outfile << "null" << endl;

    outfile << numTurns;
    outfile.close();
    cout << "Save Completed." << endl << endl;
}

int load(string filename, vector<vector<Rooms>>& map, Characters& player, vector<Characters>& npcs) {
    string in;
    string in2 = " ";

    filename = filename + ".txt";


    ifstream infile;
    int x, y;
    int numIn;
    infile.open(filename.c_str());

    while(!infile.good()) {
        infile.close();
        cout << "Save does not exist, please enter valid save." << endl;
        cin >> filename;
        filename += ".txt";
        infile.open(filename.c_str());
    }


    infile >> in;
    while (in != "Player:") {
        infile >> x >> y;
        infile >> in;
        map[x][y].setName(in);
        infile.ignore(1000, '\n');
        getline(infile, in);
        map[x][y].setDescription(in);
        while (true) {
            if (infile.peek() == '\n') break;
            else {
                infile >> in2;
                if (in2 == "null") break;
                map[x][y].addItem(in2);
            }
        }
        infile.ignore(1000, '\n');
        getline(infile, in);
        map[x][y].setHint(in);
        infile >> numIn;
        map[x][y].setActions(numIn);
        infile >> in;
        map[x][y].setEmpty(false);
    }

    //Load player data
    infile >> x >> y;
    player.setLocation(x,y);
    infile >> numIn;
    player.setHealth(numIn);
    infile >> numIn;
    player.setMaxHealth(numIn);
    infile >> numIn;
    player.setMana(numIn);
    infile >> numIn;
    player.setMaxMana(numIn);



    while (true) {

        infile >> in2;
        if (in2 == "null") break;
        player.addItem(in2);

    }


    infile >> numIn; // Takes in number of turns

    infile.close();
    return numIn;
}

Coord move(string in, vector<vector<Rooms>> map, int x, int y, Characters& player, int moves) {
    Coord coords;
    coords.x = x;
    coords.y = y;
    int num;
    string out;

    //This is a lot of super ugly and complex control structures that you don't want to read, please don't.

    if (x == 1 && y == 1) {
        if (in == "down") {
            coords.x = 3;
            coords.y = 1;
        } else {
            cout << "You run into a wall!" << endl;
        }
    } else if (x == 3 && y == 1 && in == "up") {
        coords.x = 1;
        coords.y = 1;
    } else if (x == 0 && y == 0) {
        if (in == "n") {
            coords.x = 7;
            coords.y = 4;
        } else {
            cout << "You run into a wall!" << endl;
        }
    }

    else if ((y > 5 && x > 3) || (x >= 10 && y >= 3)) {
        if (in == "n") {
            if (y == 3 && x == 13) {
                coords.x = 13;
                coords.y = 1;
            }
            else if (map[x][y - 1].getEmpty()){
                cout << "You run into a wall!" << endl;
            } else {
                coords.y--;
            }
        } else if (in == "s") {

            if (y == 6  && x == 15) {
                coords.x = 13;
                coords.y = 4;
                if(find(map[13][4].getInventory().begin(), map[13][4].getInventory().end(), "straw") == map[13][4].getInventory().end()) {
                    player.setHealth(player.getHealth()-2);
                    cout << "You slide down the chute spiraling deeper into the earth." << endl;
                    cout << "Suddenly, you are ejected into the air in another chamber, you fall down to the ground and hit the cold, hard floor. You take 2 damage." << endl;
                } else {
                    cout << "You slide down the chute spiraling deeper into the earth." << endl;
                    cout << "Suddenly, you are ejected into the air in another chamber, you fall down on to a soft pile of straw, cushioning your fall." << endl;
                }
            } else if (x == 11 && y == 5) {
                cout << "The sphinx blocks the door and says \" You may pass and enter my room of treasure if you solve my riddle, it goes like this\n "
                        "\'Six letters long\n"
                        "Guess if you choose\n"
                        "I am all but everything\n"
                        "I have nothing to lose\'\"  " << endl;
                cin >> out;
                if (out == "vacuum") {
                    cout << "Alas, you have beaten me, go forth and take what you must."  << endl;
                    coords.y++;
                } else {
                    cout << "Wrong! You can try again if you so choose." <<  endl;
                }
            }
            else if (map[x][y + 1].getEmpty()){
                cout << "You run into a wall!" << endl;
            }
            else if (y == 8 && x == 5) {
                end(static_cast<double > (moves));
            }
            else {
                coords.y++;
            }
        } else if (in == "e") {
            if (x == 5 && y == 7) {
                coords.x = 10;
                coords.y = 4;
            }
            else if (map[x + 1][y].getEmpty()){
                cout << "You run into a wall!" << endl;
            }
            else if (x == 12 && y==4) {
                if (find(player.getInventory().begin(), player.getInventory().end(), "amulet") != player.getInventory().end()) {
                    cout << " The amulet picks you up and flies you across the fissure." << endl;
                    coords.x = 13;
                    coords.y = 4;
                }
                else {
                    coords.x = 13;
                    coords.y = 4;
                }
            }
            else {
                coords.x++;
            }
        } else if ( in == "w") {
            if (x == 10 && y==4) {
                coords.x = 5;
                coords.y = 7;
            }
            else if (map[x - 1][y].getEmpty()){
                cout << "You run into a wall!" << endl;
            }
            else if (x == 12 && y==4) {
                if (find(player.getInventory().begin(), player.getInventory().end(), "amulet") != player.getInventory().end()) {
                    cout << " The amulet picks you up and flies you across the fissure." << endl;
                    coords.x = 11;
                    coords.y = 4;
                }
                else {
                    cout << " Falling hundreds of feet may cause death." << endl;
                }
            }
            else {
                coords.x--;
            }
        }
    }
    else   {
        if (in == "n") {
            if (y==1 && x < 10){
                cout << "Are you TRYING to DIE?" << endl;
            } else if (map[x][y].getName() == "apothecary") {
                coords.x = 10;
                coords.y  = 1;
            } else if (map[x][y].getName() == "blacksmith") {
                coords.x = 11;
                coords.y  = 1;
            }
            else {
                coords.y--;
            }
        } else if (in == "s") {
            if (y==5 || (x == 12 && y == 1) || (x == 9 && y == 1)) {
                cout << "You cannot cross the river on foot, but there may be another way." << endl;
            }
            else if (map[x][y].getName() == "library") {
                coords.x = 10;
                coords.y  = 1;
            }
            else if (map[x][y].getName() == "tavern") {
                coords.x = 11;
                coords.y  = 1;
            }
            else if (x == 13 && y == 1) {
                coords.x = 13;
                coords.y = 3;
            }

            else{
                coords.y++;
            }
        } else if (in == "e") {
            if (x == 13 && y <3) {
                cout << "If you enter the forest it is likely you will be mutilated by a bear." << endl;
            } else if (x == 8 && y < 6 && y > 1) {
                cout << "You cannot cross the river on foot, but there may be another way." << endl;
            } else if (x == 10 && y == 4) {
                coords.x = 5;
                coords.y = 7;
            }  else {
                coords.x++;
            }
        } else if ( in == "w") {
            if (x == 3) {
                cout << "If you enter the forest it is likely you will be eaten by a Grue" << endl;
            } else {
                coords.x--;
            }
        }

    }

    if (coords.x == 7 && coords.y == 5) {
        if(in == "s") {
            coords.x = 0;
            coords.y = 0;
        } else {
            cout << "You run into the side of the shack!" << endl;
            coords.x = x;
            coords.y = y;
        }
    } else if (coords.x == 11 && coords.y == 0) {
        if (in == "n") {
            coords.x = 0;
            coords.y = 3;
        } else {
            cout << "You run into a wall!" << endl;
        }
    } else if (coords.x == 10 && coords.y == 0) {
            if (in == "n") {
                coords.x = 1;
                coords.y = 4;
            } else {
                cout << "You run into a wall!" << endl;
            }
    } else if (coords.x == 10 && coords.y == 2) {
        if (in == "s") {
            coords.x = 0;
            coords.y = 5;
        } else {
            cout << "You run into a wall!" << endl;
        }
    } else if (coords.x == 11 && coords.y == 2) {
        if (in == "s") {
            coords.x = 1;
            coords.y = 6;
        } else {
            cout << "You run into a wall!" << endl;
        }
    }


    out = map[coords.x][coords.y].getDescription();
    while (out.find('.') != -1) {
        num = out.find('.');
        if (num != -1) {
            out.replace(num, 1, "\n");
        }
    }


    cout << out << endl;

    return coords;
}



void help() {
    cout << "This is a text based adventure game, you type commands into the terminal and the game will respond accordingly." << endl;
    cout << "All commands MUST be lower-case AND MUST spelled correctly." << endl;
    cout << "By using north, south, east, and west commands you can navigate through the game." << endl;
    cout << "These commands  can be shortened to their one letter variants: n, s, e, & w." << endl;
    cout << "Sometimes you may have to move by using the up & down commands; they can also be shortened." << endl;
    cout << "Use the inventory command to get a list of all the items contained within your inventory." << endl;
    cout << "Use the save command to save the game state to a save file." << endl;
    cout << "Use the take command to take items" << endl;
    cout << "Use the help command to view these instructions and the quit command to exit the game." << endl;
    cout << "Cave passages are twisty, the tunnels may not always behave the way you assume." << endl;
    cout << "Any questions, comments, or concerns may be emailed to iankherman@gmail.com" << endl;
    cout << "WARNING: We are not responsible for any serious injury or death caused by the playing of this game." << endl;
    cout << "Thank you and enjoy!" << endl;
    cout << endl;
}

void take(string in, vector<vector<Rooms>>& map, Characters& player) {
    int x = player.getX();
    int y = player.getY();

    if (map[x][y].getName() == "library" || map[x][y].getName() == "tavern" || map[x][y].getName() == "apothecary" || map[x][y].getName() == "blacksmith") {
        cout << "You decide against taking anything from this town, you feel as though a great amount has already been taken from it." << endl;
    } else if (map[x][y].getName() == "sphinx_treasure" && in == "gold") {
        cout << "You pick up some gold and put it in your knapsack." << endl;
        player.addItem("gold");
    } else if (map[x][y].getName() == "sphinx_treasure" && in == "jewels") {
        cout << "You pick up some gems and put them in your knapsack." << endl;
        player.addItem("gems");
    }   else if (map[x][y].getName() == "pit" && in == "amulet") {
        cout << "As you place the amulet around your neck, suddenly it picks you up by the neck and flies you out over the pit, then it safely returns you to the platform." << endl;
        map[x][y].setDescription("You are on a large stone platform over a MASSIVE pit, it seems to span on for miles!");
        player.addItem("amulet");
        map[x][y].removeItem("amulet");
    }  else if (map[x][y].getName() == "cave_branch" && in == "straw") {
        cout << "You take the straw and stuff it into your knapsack." << endl;
        map[x][y].removeItem("straw");
        map[x][y].setDescription("Here the tunnel heads south, a small crack in the wall leads east, in front of you there is a chute high above the ground.");
        player.addItem("straw");
    } else if (map[x][y].getName() == "fork_room" && in == "fork") {
        cout << "hah, you pick up the fork lol"<< endl;
    }
}

void end(double moves) {
    cout << "As you enter the room, you are splashed with confetti, and loud horns blare a melody. In front of you are many people, in the middle of them is a tall man, cloaked in wizards garb. \n He shouts \" Congradulations! You have passed my test, this marks your first day as the ruling wizard of this land. "
            "\nAll these trials were to test your problem solving ability, so I could be sure I had a worthy heir, I knew you could do it! \n After this everyone made there way back up to the surface, where two pavillions were pitched, you all had a great feast and lived happily ever after!  " << endl;
    cout << "Your final score was " << ((27.0/moves) * 100);
    exit(1);
}


void createOriginalSave() {
    ofstream outfile;
    outfile.open("original.txt");
    outfile << "Room:\n";
    outfile << "1 1\n";
    outfile << "start\n";
    outfile << "You are standing in a wizards tower, to your left and right are stained glass windows. On nearby shelves are various jars with strange pickled things, unfortunately these things are out of your reach. There is a staircase leading down from the tower.\n";
    outfile << "null\n";
    outfile << "GO DOWN GENIUS!!\n";
    outfile << "1\n";

    outfile << "Room:\n";
    outfile << "3 1" << endl;
    outfile << "tower_outside" << endl;
    outfile << "You are outside a tall tower, ahead of you is a long dirt road. To the north is a deep ravine and to your the south is endless countryside. To your west is a dark, thick forest." << endl;
    outfile << "null" << endl;
    outfile << "Take THE ROAD *facepalms*" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "3 2" << endl;
    outfile << "country_1" << endl;
    outfile << "You are in the countryside, the forest is to your west & the wizard's tower is to the north." << endl;
    outfile << "null" << endl;
    outfile << "Maybe go back to the road?" << endl;
    outfile << "0" << endl;


    outfile << "Room:" << endl;
    outfile << "3 3" << endl;
    outfile << "country_2" << endl;
    outfile << "You are in the countryside, the forest is to your west." << endl;
    outfile << "null" << endl;
    outfile << "Maybe go back to the road?" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "3 4" << endl;
    outfile << "country_3" << endl;
    outfile << "You are in the countryside, the forest is to your west." << endl;
    outfile << "null" << endl;
    outfile << "Maybe go back to the road?" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "3 5" << endl;
    outfile << "country_4"<< endl;
    outfile << "You are in countryside, the forest is to your west, also, there is a large, fast moving river to the south." << endl;
    outfile << "null" << endl;
    outfile << "Maybe go back to the road?" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "4 5" << endl;
    outfile << "country_5"<< endl;
    outfile << "You are in countryside, there is a large, fast moving river to the south." << endl;
    outfile << "null" << endl;
    outfile << "Maybe go back to the road?" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "4 4" << endl;
    outfile << "country_6" << endl;
    outfile << "You are in the countryside." << endl;
    outfile << "null" << endl;
    outfile << "Maybe go back to the road?" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "4 3" << endl;
    outfile << "country_8" << endl;
    outfile << "You are in the countryside, to the east is a large hill." << endl;
    outfile << "null" << endl;
    outfile << "Maybe go back to the road?" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "4 2" << endl;
    outfile << "country_9" << endl;
    outfile << "You are in the countryside, to the north is the road." << endl;
    outfile << "null" << endl;
    outfile << "Maybe go back to the road?" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "5 2" << endl;
    outfile << "country_10" << endl;
    outfile << "You are in the countryside, to the north is the road & to the south is a large hill." << endl;
    outfile << "null" << endl;
    outfile << "Maybe go back to the road?" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "5 3" << endl;
    outfile << "hill" << endl;
    outfile << "After a brisk climb to the top of the hill, you finally look around you. On the top of the hill is a tall oak tree, providing much needed shade from the summer heat. From the tree you can see a town to the north-east and a hut to the south-east. There is also a path leading to the hut from the road, it passes by right at the foot of the hill." << endl;
    outfile << "null" << endl;
    outfile << "Head for the town" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "5 4" << endl;
    outfile << "country_7" << endl;
    outfile << "You are in the countryside, to the north is a large hill." << endl;
    outfile << "null" << endl;
    outfile << "Maybe go back to the road?" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "5 5" << endl;
    outfile << "country_11" << endl;
    outfile << "You are in the countryside, to the south is a large, fast moving river." << endl;
    outfile << "null" << endl;
    outfile << "Maybe go back to the road?" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "4 1" << endl;
    outfile << "road_1" << endl;
    outfile << "You are on the road, and it is a beautiful day :)." << endl;
    outfile << "null" << endl;
    outfile << "Onwards!!" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "5 1" << endl;
    outfile << "road_2" << endl;
    outfile << "You continue on the flat dirt road, not paying attention to anything else." << endl;
    outfile << "null" << endl;
    outfile << "Onwards!!" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "6 1" << endl;
    outfile << "road_3" << endl;
    outfile << "Here there is a a small dirt path leading away from the road to the south." << endl;
    outfile << "null" << endl;
    outfile << "Onwards!!" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "6 2" << endl;
    outfile << "path_1" << endl;
    outfile << "You are on a little, windy dirt path. To the north is the road." << endl;
    outfile << "null" << endl;
    outfile << "Go back!" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "6 3" << endl;
    outfile << "path_2" << endl;
    outfile << "You are on a little, windy dirt path. To the west is a large hill." << endl;
    outfile << "null" << endl;
    outfile << "Go back!" << endl;
    outfile << "0" << endl;


    outfile << "Room:" << endl;
    outfile << "6 4" << endl;
    outfile << "path_4" << endl;
    outfile << "You are on a little, windy dirt path, here it turns eastward." << endl;
    outfile << "null" << endl;
    outfile << "Go back!" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "7 4" << endl;
    outfile << "witch_out_1" << endl;
    outfile << "You are on the north side of a small wooden shack, on this side, there is a door. To the west a small dirt path winds away." << endl;
    outfile << "null" << endl;
    outfile << "Go south to enter the house dummy!" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "6 5" << endl;
    outfile << "witch_out_2" << endl;
    outfile << "You are on the west side of a small wooden shack. To the north a small dirt path winds away, and to the south is a large, fast moving river." << endl;
    outfile << "null" << endl;
    outfile << "Enter the house dummy!" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "8 5" << endl;
    outfile << "witch_out_3" << endl;
    outfile << "You are on the east side of a small wooden shack. To the south is a large, fast moving river. Here, the river turns to the north blocking you from traveling east." << endl;
    outfile << "null" << endl;
    outfile << "Enter the house dummy!" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "0 0" << endl;
    outfile << "witch" << endl;
    outfile << "When you enter the shack you immediately notice how dark it is. There is a small bed in the corner and a long counter spanning the other wall. There are various herbs hanging from the ceiling. In the middle of the room is a large cauldron with a strange potion brewing in it." << endl;
    outfile << "null" << endl;
    outfile << "TALK to the witch." << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "8 4" << endl;
    outfile << "outhouse" << endl;
    outfile << "You are in the countryside, there is an outhouse here. To the east is a large, fast moving river." << endl;
    outfile << "null" << endl;
    outfile << "Go back!" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "8 3" << endl;
    outfile << "countryside_12" << endl;
    outfile << "You are in the countryside, to the east is a large, fast moving river." << endl;
    outfile << "null" << endl;
    outfile << "Go back to the road." << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "8 2" << endl;
    outfile << "countryside_13" << endl;
    outfile << "You are in the countryside, to the east is a large, fast moving river. To the north is the road." << endl;
    outfile << "null" << endl;
    outfile << "Go back to the road." << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "7 1" << endl;
    outfile << "road_4" << endl;
    outfile << "You are on yet another segment of road." << endl;
    outfile << "null" << endl;
    outfile << "Continue." << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "7 2" << endl;
    outfile << "countryside_14" << endl;
    outfile << "You are in the countryside, to the north is the road." << endl;
    outfile << "null" << endl;
    outfile << "Go back to the road." << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "7 3" << endl;
    outfile << "countryside_15" << endl;
    outfile << "You are in the deep countryside." << endl;
    outfile << "null" << endl;
    outfile << "Go back to the road." << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "8 1" << endl;
    outfile << "bandits" << endl;
    outfile << "The road continues." << endl;
    outfile << "null" << endl;
    outfile << "Continue." << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "9 1" << endl;
    outfile << "gate_1" << endl;
    outfile << "To your east is the gate to a walled town, the gate is open and there are no guards. To the north there is a ravine and to the south is the river." << endl;
    outfile << "null" << endl;
    outfile << "Enter the town." << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "10 1" << endl;
    outfile << "mainstreet_1" << endl;
    outfile << "You are in the main street of the town, all the buildings of the town are boarded up, and some of the doors hang wide open. Everything is in disarray; on the street, trash skitters around in the wind. To the north is the library & to the south is the apothecary." << endl;
    outfile << "null" << endl;
    outfile << "Explore the town." << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "11 1" << endl;
    outfile << "mainstreet_2" << endl;
    outfile << "You are in the main street of the town,  to the north is the tavern & to the south is the blacksmith." << endl;
    outfile << "null" << endl;
    outfile << "Explore the town." << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "0 3" << endl;
    outfile << "tavern" << endl;
    outfile << "You enter the tavern and immediately you are hit with the smell of stale beer, the smell seems to be wafting over from behind the counter, there is a beer keg here. The emptiness of the tavern gives you the shivers." << endl;
    outfile << "beer null" << endl;
    outfile << "Explore the town." << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "1 4" << endl;
    outfile << "library" << endl;
    outfile << "Some of the bookshelves have collapsed here, books are strewn all over the floor." << endl;
    outfile << "null" << endl;
    outfile << "Explore the town." << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "0 5" << endl;
    outfile << "apothecary" << endl;
    outfile << "Here, there are strange items scattered all around. There are strange animal horns placed on a rack along with large pieces of wood, some of which, have fallen onto the floor. Shattered vials and jars cover the floor. " << endl;
    outfile << "null" << endl;
    outfile << "Explore the town." << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "1 6" << endl;
    outfile << "blacksmith" << endl;
    outfile << "The blacksmiths walls and floor are made of wood, the store is empty except for a counter on the far wall. "<< endl;
    outfile << "null" << endl;
    outfile << "Explore the town." << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "12 1" << endl;
    outfile << "gate_2" << endl;
    outfile << "To your west is the gate to a walled town, the gate is open and there are no guards. To the north there is a ravine and to the south is the river." << endl;
    outfile << "null" << endl;
    outfile << "Enter the town." << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "13 1" << endl;
    outfile << "road_end" << endl;
    outfile << "The road comes to a halt just before a massive cave entrance to the south. It appears that the river runs right over the cave. To the north is the ravine and to the east is the forest." << endl;
    outfile << "null" << endl;
    outfile << "Onwards!!" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "13 3" << endl;
    outfile << "cave_enter" << endl;
    outfile << "The cave is dark and moist, there is a small crack in the ceiling through which water trickles in." << endl;
    outfile << "null" << endl;
    outfile << "Onwards!!" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "13 4" << endl;
    outfile << "cave_branch" << endl;
    outfile << "Here the tunnel heads west, a small crack in the wall leads east, in front of you there is a chute high above the ground, under which is a pile of straw." << endl;
    outfile << "straw" << endl;
    outfile << "Onwards!!" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "11 4" << endl;
    outfile << "cave_huge" << endl;
    outfile << "You are in a massive chamber from which you suspect many tunnels lead from.The darkness is thick enough to prevent your light from reaching the far ends of the chamber." << endl;
    outfile << "null" << endl;
    outfile << "Onwards!!" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "12 4" << endl;
    outfile << "fissure" << endl;
    outfile << "You are on a ledge facing a deep fissure, you see the outline of what could be a doorway on the other side of the fissure." << endl;
    outfile << "null" << endl;
    outfile << "Onwards!!" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "11 5" << endl;
    outfile << "sphinx" << endl;
    outfile << "You are in a small room, there is a large sphinx here guarding a wooden door." << endl;
    outfile << "null" << endl;
    outfile << "Onwards!!" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "11 6" << endl;
    outfile << "sphinx_treasure" << endl;
    outfile << "There are piles and piles of the spinx's gold and jewels filling the room, there is too much to carry!. " << endl;
    outfile << "gold jewels null" << endl;
    outfile << "Hooray!" << endl;
    outfile << "0" << endl;



    outfile << "Room:" << endl;
    outfile << "10 4" << endl;
    outfile << "statue" << endl;
    outfile << "Here there is a tall statue of a king, he is guarding a tunnel leading downwards, deeper into the cave." << endl;
    outfile << "null" << endl;
    outfile << "Deeper." << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "5 7" << endl;
    outfile << "deep" << endl;
    outfile << "There is no sound here, you can only hear the sound of your own heartbeat. There is a tunnel leading east, at a steep incline; to the south is a large opening leads into another chamber." << endl;
    outfile << "null" << endl;
    outfile << "Explore" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "5 8" << endl;
    outfile << "antechamber" << endl;
    outfile << "There is a massive door to the south, it seems to be made of the stone that makes up the rest of the cave. On the door is inscribed 'Mors propius' the rest of the door is covered with runes of an unknown nature." << endl;
    outfile << "null" << endl;
    outfile << "Darker" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "5 9" << endl;
    outfile << "cult_room" << endl;
    outfile << "" << endl;
    outfile << "null" << endl;
    outfile << "Darker" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "14 4" << endl;
    outfile << "crack" << endl;
    outfile << "You are in an east-west crack, on both sides the crack opens up into larger chambers." << endl;
    outfile << "null" << endl;
    outfile << "Onwards!!" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "15 4" << endl;
    outfile << "chamber_2" << endl;
    outfile << "You are in a large chamber, the walls seem to have been built with great masonry. There is a crack in the wall to the east, it seems to have been formed after this chamber was constructed. To the north and south are two arched passage ways." << endl;
    outfile << "null" << endl;
    outfile << "Onwards!!" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "15 3" << endl;
    outfile << "mana" << endl;
    outfile << "On the far side of this small room, there is a carving of an angel, out of its mouth spills a dark liquid which is then collected in a basin beneath the carving." << endl;
    outfile << "null" << endl;
    outfile << "Drink it" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "15 5" << endl;
    outfile << "corridor" << endl;
    outfile << "You are in a long hallway." << endl;
    outfile << "null" << endl;
    outfile << "Forward" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "15 6" << endl;
    outfile << "fork_room" << endl;
    outfile << "There is a fork in the corridor. Ahead of you, in the middle of the fork is a arched chute that spirals down, deeper into the cave, if you were to enter it, you would slide down." << endl;
    outfile << "fork null" << endl;
    outfile << "Go south to enter the chute" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "16 6" << endl;
    outfile << "shrine" << endl;
    outfile << "This is the first room that has its own lighting, on the walls are two lanterns burning with a green flame of magical origin. In the center of the room is a large altar, it is carved in the shape of a twenty sided die." << endl;
    outfile << "null" << endl;
    outfile << "WORSHIP it" << endl;
    outfile << "0" << endl;

    outfile << "Room:" << endl;
    outfile << "14 6" << endl;
    outfile << "pit" << endl;
    outfile << "You are on a large stone platform over a MASSIVE pit, it seems to span on for miles! There is a amulet hanging from a pedestal in front of you, it has a black gem set in the middle, also, set behind the gem is a pair of wings." << endl;
    outfile << "amulet null" << endl;
    outfile << "Take the amulet" << endl;
    outfile << "0" << endl;


    outfile << "Player:" << endl;
    outfile << "1 1" << endl;
    outfile << "10 10" << endl;
    outfile << "10 10" << endl;
    outfile << "null" << endl;
    outfile.close();
}

Character Class:



#ifndef CHARACTERS_H
#define CHARACTERS_H

#include <string>
#include <vector>

using namespace std;

class Characters {
public:
    Characters(string nm);
    int getHealth();
    int getMana();
    void setMana(int mn);
    void setHealth(int hp);
    void setMaxMana(int mn);
    void setMaxHealth(int hp);
    int getXp();
    string getName();
    string getDescription();
    void setDescription(string disc);
    vector<string> getInventory();
    void addItem(string nm);
    void removeItem (string nm);
    int getX();
    int getY();
    void setLocation(int ex, int why);

    int getMaxHealth() const;

    int getMaxMana() const;

private:
    string name;
    string description;
    int health;
    int mana; //Magic energy
    int maxHealth;
    int maxMana;
    int xp; //Xp gained from kill
    vector<string> inventory;
    int x, y;
};


#endif //CHARACTERS_H

Implementation:



#include "characters.h"

string Characters::getName() {
    return name;
}

vector<string> Characters::getInventory() {
    return inventory;
}

string Characters::getDescription() {
    return description;
}

void Characters::addItem(string nm) {
    inventory.push_back(nm);
}

int Characters::getHealth() {
    return health;
}

int Characters::getXp() {
    return xp;
}

int Characters::getMana() {
    return mana;
}

void Characters::setMana(int mn) {
    if (mn > maxMana) {
        mana = maxMana;
    } else {
        mana = mn;
    }
}

void Characters::setMaxHealth(int hp) {
    maxHealth = hp;
}

void Characters::setDescription(string disc) {
    description = disc;
}

void Characters::removeItem(string nm) {
    for (int i = 0; i < inventory.size(); ++i) {
        if (inventory[i] == nm) {
            inventory.erase(inventory.begin() + i);
            break;
        }
    }
}

void Characters::setHealth(int hp) {
    if (hp > maxHealth) {
        health = maxHealth;
    } else {
        health = hp;
    }
}

void Characters::setMaxMana(int mn) {
    maxMana = mn;
}

Characters::Characters(string nm) {
    name = nm;
    maxMana = 10;
    maxHealth = 10;
    health = 10;
    mana = 10;
    description = "You are you, you dummy!";
    xp = 0;
    x = 1;
    y = 1;
}

int Characters::getY() {
    return y;
}

int Characters::getX() {
    return x;
}

void Characters::setLocation(int ex, int why) {
    x = ex;
    y = why;
}

int Characters::getMaxHealth() const {
    return maxHealth;
}

int Characters::getMaxMana() const {
    return maxMana;
}

Room class:



#ifndef ROOMS_H
#define ROOMS_H

#include <string>
#include <vector>

using namespace std;


class Rooms {
public:
    Rooms();
    void addItem (string nm);
    string getName();
    vector<string> getInventory();
    void removeItem (string nm);
    string getDescription();
    void incrementActionCount(); //Increments number of actions from player in room
    int getActions();
    void setDescription (string disc);
    bool getEmpty();
    const string &getHint() const;
    void setName(string nm);
    void setHint(string hnt);
    void setActions(int act);
    void setEmpty (bool emp);
private:
    string name;
    bool empty;
    string description;
    string hint; // Will be displayed after a certain number of actions
    vector<string> inventory;
    int actionCount; // Number of actions player has taken in room
};



#endif //ROOMS_H

Implementation:



#include "rooms.h"

Rooms::Rooms() {
    hint = "Boy, you are taking a while to figure out this room aren't you?";
    inventory = {};
    description = "You are in a completely blank room";
    name = "";
    actionCount = 0;
    empty = true;
}

void Rooms::addItem(string nm) {
    inventory.push_back(nm);
}

void Rooms::setName(string nm) {
    name = nm;
}

void Rooms::removeItem(string nm) {
    for (int i = 0; i < inventory.size(); ++i) {
        if (inventory[i] == nm) {
            inventory.erase(inventory.begin() + i);
            break;
        }
    }
}

int Rooms::getActions() {
    return actionCount;
}

string Rooms::getDescription() {
    return description;
}

vector<string> Rooms::getInventory() {
    return inventory;
}

string Rooms::getName() {
    return name;
}

void Rooms::incrementActionCount() {
    actionCount++;
}

void Rooms::setDescription(string disc) {
    description = disc;
}

bool Rooms::getEmpty() {
    return empty;
}

void Rooms::setHint(string hnt) {
    hint = hnt;
}

void Rooms::setActions(int act) {
    actionCount = act;
}

void Rooms::setEmpty(bool emp) {
    empty = emp;
}

const string &Rooms::getHint() const {
    return hint;
}
\$\endgroup\$
0
3
\$\begingroup\$

In addition to everything mentioned in Toby Speight's review:

This program can use at least one additional class and probably more. The class that is obviously missing is Game. The class Game should be responsible for loading the game from a file, saving the game to a file and executing the game.

The function createOriginalSave() should probably be broken up into createNewGame() and then use the save() function to save the new game.

The suggested createNewGame() function should generate a map of rooms.

Each room should be responsible for printing its data to the output file.

Most of the functions in the file that contains main are too 'complex' and need to be broken up into smaller functions. You might find some reusable code this way. The code is currently very difficult to maintain and expand because it is so complex.

\$\endgroup\$
10
\$\begingroup\$

<bits/stdc++.h> is not a standard C++ header. Please use only standard headers, so your code is portable.

using namespace std; is a terrible idea - it completely removes the benefit of namespaces, meaning that all the standard library (including future types and functions not yet standardised) is mixed in with your program identifiers. Don't do that! Especially not in a header, where the harm is inflicted on every translation unit that includes that header.

There's sometimes an argument for importing a few, specific names into a smaller scope (a function, usually), but seldom for bringing in an entire namespace at the top level.


Many members are missing their const qualification. For example:

std::string getName() const;
//                    ^^^^^
// function must not modify 'this' object

Picking on a random function that just caught my eye:

void Rooms::setName(std::string nm) {
    name = nm;
}

We're making an unnecessary copy; we can avoid doing so:

void Rooms::setName(std::string nm) {
    name = std::move(nm);
}

And in Rooms::removeItem, we don't need a copy:

void Rooms::removeItem(const string& nm) {

There are many more functions that unnecessary copy their arguments.

\$\endgroup\$
2
  • \$\begingroup\$ What about comments, where would I need those? \$\endgroup\$ – anon Feb 12 '20 at 18:38
  • \$\begingroup\$ I would just add, using namespace std; is often used so that things like cout can be written without a prefix, and you can get the same benefit with using std::cout; and bringing in just the few things you are going to use, individually. (I know you know this, Toby; just adding it for the benefit of OP.) \$\endgroup\$ – David Conrad Feb 12 '20 at 22:00
2
\$\begingroup\$

In general when there is multiple options on a program like yours (on the section you manage the variable input), is desirable to make it more readable in order to avoid the multiples if statements. My recommendation is to use a map, or unordered_map with the input as first parameter and second a callback to the desire functionality. For example:

for (int i = 0; true; i++){

    cin >> input;
    Coord newPlayerCoords;

    transform(input.begin(), input.end(), input.begin(), ::tolower);

    if (input == "north") input = "n";
    else if (input == "south") input = "s";
    else if (input == "east") input = "e";
    else if (input == "west") input = "w";
    else if (input == "u") input = "up";
    else if (input == "d") input = "down";

Transform on

for (int i = 0; true; ++i){ // Check the increment here

    cin >> input;
    Coord newPlayerCoords;

    transform(input.begin(), input.end(), input.begin(), ::tolower);

    auto it = callbacks.find(input);
    if (it != callbacks.end()) {
        auto operation = it->second;

        operation(...);
     }

Hope you get the idea, just need to define statically the callbacks as your convenience.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy