c ++ - текстовая RPG - проверка правильности входных данных с помощью функций - PullRequest
0 голосов
/ 25 сентября 2018

Добрый вечер.

В настоящее время я разрабатываю текстовую RPG.Я пытался работать над функцией, чтобы проверить все мои входные данные, чтобы человек не смог сломать мою программу (или ничего не произошло), когда он вводит строку за пределами «принятых» для моей игры.У меня пока есть это, но он автоматически печатает «Это неверный ввод» для всех трех моих тестовых случаев, даже если он действителен.Действительная функция по-прежнему выполняется из строки поверх отпечатков «Неправильный ввод» ...

Отказ от ответственности: Я изучаю C ++ только около месяца, поэтому я уверенкод для этого очень процедурный и не соответствует ООП.В моем классе мы не покрывали объекты / классы или даже векторы / массивы (я изучил их самостоятельно).Так что мой код может быть очень избыточным ...

Я включил весь свой код, чтобы получить полное представление о моей программе.

Мой код выглядит следующим образом:

#include <iostream>
#include <cmath>
#include <vector>
#include <boost/algorithm/string.hpp>
#include <string>
using namespace std;

// This prints all commands used in-game upon input.
void userHelp(string action) {
    if (action == "HELP") {
        cout << endl;
        cout << "Type 'look' to check your surroundings." << endl;
        cout << "Type 'location' to print current area and map." << endl;
        cout << "Type 'check [item]' to interact with items." << endl;
        cout << "Type 'inventory' to check your inventory." << endl;
        cout << "Type 'move [north, west, south, east]' to move." << endl;
        cout << "Type 'talk [person type]' to begin conversation." << endl;
        cout << "Type 'pick up [item]' to pick up items." << endl;
        cout << endl;
    }
}
void inputVetting(string action) {
    while (action = true) {
        if (action != "HELP" || action != "LOOK" || action != "LOCATION" || action != "PICK UP BRASS KEY") {
            cout << endl;
            cout << "That is not a valid input." << endl;
            cout << endl;
        }

        if (action != "CHECK TABLE" || action != "INVENTORY" || action != "TALK GHOUL" || action != "PICK UP KEY") {
            cout << endl;
            cout << "That is not a valid input." << endl;
            cout << endl;
        }

        if (action != "MOVE NORTH" || action != "MOVE SOUTH" || action != "MOVE EAST" || action != "MOVE WEST") {
            cout << endl;
            cout << "That is not a valid input." << endl;
            cout << endl;
        }
    }
}

// This prints description lines for the player to check their surroundings of each room upon input.
// This makes it easy to add & change description lines for each room.
void look(string action, int currentRoom) {
    if (action == "LOOK") {
        if (currentRoom == 1) {
            cout << endl;
            cout << "There is a table and lamp in the room." << endl;
            cout << "There is a ghoulish creature standing in the corner." << endl;
            cout << "He seems friendly." << endl;
            cout << "There is a door to the north." << endl;
            cout << endl;
        }
        if (currentRoom == 2) {
            cout << endl;
            cout << "Description line 1." << endl;
            cout << "Description line 2." << endl;
            cout << "Description line 3." << endl;
            cout << "Description line 4." << endl;
            cout << endl;
        }
    }
}

// This prints current player area, and gives visual map of game zone upon input.
void location(string action, int currentRoom) {
    if (action == "LOCATION") {
        if (currentRoom == 1) {
            cout << endl;
            cout << "You are currently in room one." << endl;
            cout << "|-----------------------------|" << endl;
            cout << "|                             |" << endl;
            cout << "|                             |" << endl;
            cout << "|                             |" << endl;
            cout << "|          T E S T 1          |" << endl;
            cout << "|                             |" << endl;
            cout << "|                             |" << endl;
            cout << "|                             |" << endl;
            cout << "|-----------------------------|" << endl;
            cout << endl;
        }

        if (currentRoom == 2) {
            cout << endl;
            cout << "You are currently in room two." << endl;
            cout << "|-----------------------------|" << endl;
            cout << "|                             |" << endl;
            cout << "|                             |" << endl;
            cout << "|                             |" << endl;
            cout << "|          T E S T 2          |" << endl;
            cout << "|                             |" << endl;
            cout << "|                             |" << endl;
            cout << "|                             |" << endl;
            cout << "|-----------------------------|" << endl;
            cout << endl;
        }
    }
}

// This provides interactions with objects placed according to each area in the game zone upon input.
void checkItem(string action, int currentRoom) {
    if (currentRoom == 1) {
        if (action == "CHECK TABLE") {
            cout << endl;
            cout << "Description line A." << endl;
            cout << "Description line B." << endl;
            cout << "Do you want to open the drawer?" << endl;
            cout << "(1) Yes\n(2) No" << endl;
            cout << endl;

            string choice;

            cin >> choice;
            boost::to_upper(choice);

            if (choice == "1" || choice == "YES") {
                cout << endl;
                cout << "You open the drawer." << endl;
                cout << "There is a brass key inside." << endl;
                cout << endl;
            } else if (choice == "2" || choice == "NO") {
                cout << endl;
                cout << "You leave the drawer alone." << endl;
                cout << endl;
            }
        }
    }
}

//This simple function allows user to pick up the key in the first game area.
void pickUpKey(string action, int currentRoom, vector<string>& inventory) {
    if (currentRoom == 1) {
        if (action == "PICK UP KEY" || action == "PICK UP BRASS KEY") {
            cout << endl;
            cout << "You have picked up the brass key." << endl;
            cout << "It is now in your inventory." << endl;
            cout << endl;

            inventory.push_back("Brass Key");
        }
    }
}

// This prints description lines for the first game area.
void firstRoom() {
    cout << endl;
    cout << "You awake in a dark cabin-like room." << endl;
    cout << "(Type 'help' for commands)" << endl;
}

//This prints description lines for the second game area.
void secondRoom() {
    cout << "Description line 1." << endl;
    cout << "Description line 2." << endl;
    cout << "Description line 3." << endl;
    cout << "Description line 4." << endl;
}

// This helps player move around the first area upon input.
// I've split up the movements into functions per room, for easier altering/flow
void movePlayerFirstRoom(string action, int& currentRoom, vector<string>& inventory) {
    if (action == "MOVE NORTH" && currentRoom == 1) {
        std::vector<string>::iterator it;
        it = find(inventory.begin(), inventory.end(), "Brass Key");

        if (it != inventory.end()) {
            currentRoom = 2;
            cout << endl;
        } else {
            cout << endl;
            cout << "The door is locked!" << endl;
            cout << endl;
        }
    }
    if (action == "MOVE SOUTH" && currentRoom == 1) {
        cout << endl;
        cout << "You can't walk past a wall!" << endl;
        cout << endl;
    }
    if (action == "MOVE EAST" && currentRoom == 1) {
        cout << endl;
        cout << "You can't walk past a wall!" << endl;
        cout << endl;
    }
    if (action == "MOVE WEST" && currentRoom == 1) {
        cout << endl;
        cout << "You can't walk past a wall!" << endl;
        cout << endl;
    }
}

// This helps player move around the second area upon input.
void movePlayerSecondRoom(string action, int& currentRoom) {
    if (action == "MOVE NORTH" && currentRoom == 2) {
        cout << endl;
        cout << "You can't walk past a wall!" << endl;
        cout << endl;
    }
    if (action == "MOVE SOUTH" && currentRoom == 1) {
        cout << endl;
        cout << "Juub closed the door behind him." << endl;
        cout << "You can no longer go that way." << endl;
        cout << endl;
    }
    if (action == "MOVE EAST" && currentRoom == 1) {
        cout << "You can't walk past a wall!" << endl;
        cout << endl;
    }
    if (action == "MOVE WEST" && currentRoom == 1) {
        cout << "You can't walk past a wall!" << endl;
        cout << endl;
    }
}

// This provides a for loop to display the items in player's inventory, used in     checkInventory.
void listInventory(vector<string> inventory) {
    for (auto i : inventory) {
        cout << ":: " << i << endl;
    }
}

// This prints out a player's inventory upon input.
void checkInventory(string action, vector<string>& inventory) {
    if (action == "INVENTORY") {
        cout << endl;
        cout << "Your inventory contains: " << endl;

        listInventory(inventory);

        cout << endl;
    }
}

// This provides basic mechanics for combat against enemies.
// void attackEnemy;

// This is the dialogues for NPC 1.
void npcOne(string action) {
    if (action == "TALK GHOUL") {
        string choice;

        cout << endl;
        cout << "Ah, hello." << endl;
        cout << "I haven't seen anyone around here in a long time." << endl;
        cout << "Name's Juub. I've been down here trying to find treasure." << endl;
        cout << "Problem is, I haven't found anything..." << endl;
        cout << "... but I have found a monster." << endl;
        cout << "Actually, that's why I'm in this room." << endl;
        cout << "A corrupted spirit chased me into here." << endl;
        cout << "I was lucky enough to lock myself in, otherwise I'd surely be dead." << endl;
        cout << "But... now, that you're here..." << endl;
        cout << "Mind helping me out?" << endl;
        cout << endl;

        cout << "Do you want to help Juub kill the monster?" << endl;
        cout << "(1) Yes\n(2) No" << endl;
        cout << endl;

        cin >> choice;
        boost::to_upper(choice);
        cout << endl;

        if (choice == "1" || "YES") {
            cout << "Excellent." << endl;
            cout << "I wish I could be of help, but I got a bad arm." << endl;
            cout << "Got shot in the Great War by a phaser rifle." << endl;
            cout << "Come back with his essence, and I'll give you a reward." << endl;
            cout << "... oh, yeah. The key to the door is somewhere in this room." << endl;
            cout << endl;
        } else if (choice == "2" || "NO") {
            cout << "Eh, figures..." << endl;
            cout << "Can never trust humanoids, anyway." << endl;
            cout << endl;
        }
    }
}

// This is a small function to get the user's name, used in gameIntro.
void getName() {
    cout << "Please enter your name." << endl;
    cout << endl;

    string name;
    cin >> name;

    cout << endl;
    cout << "Welcome, " << name << ". Enjoy the game!" << endl;
}

// This is the introduction prompt of the game.
// This gives players the option to play or quit the game, then sets player's name.
void gameIntro() {
    cout << endl;
    cout << "==============================" << endl;
    cout << "Welcome to *Love Pits*" << endl;
    cout << "==============================" << endl;
    cout << endl;

    getName();

    cout << endl;
    cout << "..." << endl;
    cout << "..." << endl;
    cout << "..." << endl;
    //  cout << string(60, '\n'); <-- This is an attempt to try and clear screen, not sure if I want to do this.
}

int main() {
    vector<string> inventory;
    int currentRoom;
    string action;

    inventory.push_back("Rusted Dagger");

    while (true) {
        gameIntro();
        currentRoom = 1;
        firstRoom();
        cout << endl;
        // All possible actions/interactions within room one.
        while (currentRoom == 1) {
            if (currentRoom != 1) {
                break;
            }

            getline(cin, action);
            boost::to_upper(action);

            //Provides all possible actions for player.
            checkInventory(action, inventory);
            checkItem(action, currentRoom);
            userHelp(action);
            look(action, currentRoom);
            location(action, currentRoom);
            movePlayerFirstRoom(action, currentRoom, inventory);
            npcOne(action);
            pickUpKey(action, currentRoom, inventory);
            inputVetting(action);
        }
        secondRoom();
        cout << endl;
        // All possible actions/interactions in game area two.
        while (currentRoom == 2) {
            if (currentRoom != 2) {
                break;
            }
            getline(cin, action);
            boost::to_upper(action);

            // Provides all possible actions for player.
            checkInventory(action, inventory);
            checkItem(action, currentRoom);
            userHelp(action);
            look(action, currentRoom);
            movePlayerSecondRoom(action, currentRoom);
            location(action, currentRoom);
        }
    }
}

Может кто-нибудь помочь мне понять, почему моя функция проверки не работает?Или, если лучше, каковы некоторые вещи и места, где я могу их выполнять, где я могу правильно проверить ввод, чтобы пользователь мог вводить только те команды, которые будут работать в программе, в противном случае я распечатываю что-то вроде «Это недопустимо»вход "?Спасибо за любую помощь!Я просто пытаюсь улучшить как можно больше.

1 Ответ

0 голосов
/ 25 сентября 2018

Проверьте свою логику.То, как мы говорим по-английски, не означает, как мы применяем логическую логику к выражению if.

if (action != "HELP" || action != "LOOK" || action != "LOCATION" || action != "PICK UP BRASS KEY")

Допустим, вы ввели "LOOK".Вот то, на что разбивается весь этот if:

 if (action != "HELP" || // true
     action != "LOOK" || // false
     action != "LOCATION" || // true
     action != "PICK UP BRASS KEY") // true

Поскольку вы применяете || (or) ко всем этим тестам, все, что требуется, это то, что один из этих тестов становится true для всего этого, чтобы быть true.Таким образом, весь if становится true и таким образом входит в блок ошибок if.

Исправление заключается в использовании && (и):

if (action != "HELP" && action != "LOOK" && action != "LOCATION" && action != "PICK UP BRASS KEY")

Теперь давайтеПосмотрите, как это происходит, если введено "LOOK":

 if (action != "HELP" && // true
     action != "LOOK" && // false
     action != "LOCATION" && // true
     action != "PICK UP BRASS KEY") // true

Теперь, если какое-либо из этих условий равно false, тогда все if становится false, таким образом, не входит в блок ошибок,

Сравнить сейчас, если введено "ABC":

 if (action != "HELP" && // true
     action != "LOOK" && // true
     action != "LOCATION" && // true
     action != "PICK UP BRASS KEY") // true

Таким образом, "ABC" не соответствует ни одному из вариантов, поэтому if становится истинным и входит в блок ошибок.


Еще один момент - если вам нужно проверить больше записей, бесконечный оператор if не очень хорошо масштабируется.Подумайте о том, чтобы поместить слова в таблицу и выполнить поиск, например, unordered_set или аналогичный, и просто используйте find(), чтобы увидеть, есть ли запись в таблице.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...