c ++-文本RPG-使用功能检查有效输入

时间:2018-09-25 03:00:39

标签: c++ function

晚上好。

我目前正在开发文本RPG。我一直在尝试研究所有输入的函数,这样,当一个人在我的游戏的“可接受”范围之外键入字符串时,一个人将无法破坏我的程序(或什么也没有发生)。到目前为止,我已经知道了这一点,但是即使我的测试用例有效,它也会自动为所有三个测试用例输出“那不是有效的输入”。有效功能仍从“无效输入”打印顶部的字符串开始执行...

免责声明:我只学习C ++大约一个月,所以我确定此代码非常程序化,并且与OOP不符。在我的课堂上,我们没有涉及对象/类,甚至没有向量/数组(我自己学过)。所以我的代码可能非常多余...

我已包含所有代码,以全面了解我的程序。

我的代码如下:

#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 :(得分:0)

检查您的逻辑。我们的英语口语并不能转化为将布尔逻辑应用于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,整个事情变成{{1} }。这样整个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"变为true,并进入错误块。


还有一点-如果要检查的条目更多,那么无休止的if语句的伸缩性就不太好。考虑将单词放在表中并进行查询,即if或类似内容,然后使用unordered_set来查看条目是否在表中。