首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于C++文本的RPG

基于C++文本的RPG
EN

Code Review用户
提问于 2015-02-14 16:36:28
回答 2查看 18.1K关注 0票数 7

我在C++中制作了这个基于文本的RPG,它是基于一个任务的。我这么做是为了实践到目前为止学到的东西。我怎样才能改进呢?你想怎么挑剔就怎么挑剔。

代码语言:javascript
复制
#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;

void riverstead();
void aragornHouse();
void stage1();
void stage2();
void stage3();
void stage4(int &sword, int &gold);
void ratCave();
void attackThief(int &pHealth, int &tHealth);
void thiefDead();
void searchBody();
void questUpdate();
void end();

int input;
int stages[5] = {1, 0, 0, 0, 0};
string qUpdates;
string qStages;

int main() {

    srand (time(NULL));

    system("cls");
    cout << "\n Welcome to RPG!" << endl;
    cout << "\n 1. Play" << endl;
    cout << "\n 2. Exit" << endl;
    cout << "\n> ";
    cin >> input;
    switch (input) {

        case 1:
        qUpdates = "Quest begun";
        qStages = "Talk to Aragorn in his house";
        questUpdate();

        riverstead();

        case 2:
        exit(0);

    }
}

void riverstead() {

    system("cls");
    cout << "\n You are in the town of Riverstead. Where would you like to go?" << endl;
    cout << "\n 1. Aragorn's House" << endl;
    cout << "\n 2. Rat Cave" << endl;
    cout << "\n> ";
    cin >> input;
    switch (input) {

        case 1:
        aragornHouse();

        case 2:
        ratCave();

    }   
}

void aragornHouse() {

    if (stages[0] == 1) {
        system("cls");
        cout << "\n Aragorn: You interested in doing something for me? There's gold in it for you." << endl;
        cout << "\n 1. What do you need?" << endl;
        cout << "\n 2. I'm kind of busy at the moment." << endl;
        cout << "\n> ";
        cin >> input;
        switch (input) {

            case 1:
            stage1();

            case 2:
            system("cls");
            cout << "\n If you find the time, I'll be here." << endl;
            cout << "\n ";
            system("pause");
            riverstead();

        }
    }

    if (stages[1] == 1) {
        stage2();
    }

    if (stages[2] == 1) {
        stage3();
    }

    else {
        stage4(sword, gold);
    }
}

void stage1() {

    system("cls");
    cout << "\n There's a sword that has been in my family for generations and it was recently" << endl;
    cout << "\n passed down to me from my father. " << endl;
    cout << "\n ";
    system("pause");

    system("cls");
    cout << "\n I was walking back from the market the other day and I saw this thief sneaking" << endl;
    cout << "\n out of my house with the sword! " << endl;
    cout << "\n ";
    system("pause");

    system("cls");
    cout << "\n He ran and I followed him to a nearby cave, it's called Rat Cave." << endl;
    cout << "\n ";
    system("pause");

    system("cls");
    cout << "\n I didn't go inside because I had no way to defend myself." << endl;
    cout << "\n 1. I could get that sword for you." << endl;
    cout << "\n 2. I don't think I'm the right person for the job." << endl;
    cout << "\n> ";
    cin >> input;
    switch (input) {

        case 1:
        stages[0] = 0;
        stages[2] = 1;
        system("cls");
        cout << "\n That's great! I'll be waiting right here." << endl;
        cout << "\n ";
        system("pause");

        qUpdates = "Quest updated";
        qStages = "Kill the thief in Rat Cave";
        questUpdate();

        riverstead();

        case 2:
        stages[0] = 0;
        stages[1] = 1;
        system("cls");
        cout << "\n Maybe I could find someone else to do this for me." << endl;
        cout << "\n ";
        system("pause");
        riverstead();

    }
}

void stage2() {

    system("cls");
    cout << "\n Have you changed your mind? Will you retrieve my sword?" << endl;
    cout << "\n 1. Yes, I'm ready to retrieve the sword." << endl;
    cout << "\n 2. I still don't feel like retrieving it." << endl;
    cout << "\n> ";
    cin >> input;
    switch (input) {

        case 1:
        stages[0] = 0;
        stages[1] = 0;
        stages[2] = 1;
        system("cls");
        cout << "\n That's great! I'll be waiting right here." << endl;
        cout << "\n ";
        system("pause");

        qUpdates = "Quest updated";
        qStages = "Kill the thief in Rat Cave";
        questUpdate();

        riverstead();

        case 2:
        system("cls");
        cout << "\n That's a shame. Talk to me if you change your mind." << endl;
        cout << "\n ";
        system("pause");
        riverstead();

    }
}

void stage3() {

    system("cls");
    cout << "\n Have you retrieved the sword yet?" << endl;
    cout << "\n 1. I'm working on it." << endl;
    cout << "\n> ";
    cin >> input;
    switch (input) {

        case 1:
        system("cls");
        cout << "\n Let's hope the thief is still there by the time you get round to doing it." << endl;
        cout << "\n ";
        system("pause");
        riverstead();

    }
}

void stage4(int &gold, int &sword) {

    system("cls");
    cout << "\n Have you retrieved the sword yet?" << endl;
    cout << "\n 1. Yup. Was a piece of cake." << endl;
    cout << "\n 2. Yes, at the price of almost getting killed." << endl;
    cout << "\n> ";
    cin >> input;

    system("cls");
    cout << "\n That's brilliant! I knew you were the right man for the job. Here is the gold," << endl;
    cout << "\n as promised." << endl;
    cout << "\n ";
    system("pause");

    sword = 0;
    system("cls");
    cout << "\n Item removed - Aragorn's Sword" << endl;
    cout << "\n ";
    system("pause");

    gold = gold + 100;
    system("cls");
    cout << "\n Item added - 100 Gold" << endl;
    cout << "\n ";
    system("pause");

    qUpdates = "Quest complete";
    qStages = " ";
    questUpdate();

    end();

}

void ratCave() {

    int pHealth;
    int pDamage;
    int tHealth;
    int tDamage;
    int turn;

    if (stages[0] == 1 || stages[1] == 1) {
        system("cls");
        cout << "\n I haven't really got a good reason to go here." << endl;
        cout << "\n ";
        system("pause");
        riverstead();
    }

    system("cls");
    cout << "\n Thief: I'm warning you, stranger. Leave now!" << endl;
    cout << "\n 1. I've come for my friend's sword." << endl;
    cout << "\n 2. Okay, okay, I'm leaving!" << endl;
    cout << "\n> ";
    cin >> input;
    switch (input) {

        case 1:
        system("cls");
        cout << "\n Ha! You won't be leaving with it!" << endl;
        cout << "\n ";
        system("pause");

        pHealth = rand() % 40 + 80;
        tHealth = rand() % 20 + 40;

        turn = rand() % 2;

        if (turn == 1) {
            system("cls");
            cout << "\n The thief has the first turn." << endl;
            cout << "\n ";
            system("pause");

            tDamage = rand() % 5 + 10;

            pHealth = pHealth - tDamage;
            system("cls");
            cout << "\n The thief attacks you for " << tDamage << " damage!" << endl;
            cout << "\n ";
            system("pause");

        }

        else {
            system("cls");
            cout << "\n You have the first turn." << endl;
            cout << "\n ";
            system("pause");
        }

        attackThief(pHealth, tHealth);

        case 2:
        system("cls");
        cout << "\n That's what I thought." << endl;
        cout << "\n ";
        system("pause");
        riverstead();

    }
}

void attackThief(int &pHealth, int &tHealth) {

    int pDamage;
    int tDamage;

    pDamage = rand() % 10 + 10;
    tDamage = rand() % 5 + 10;

    system("cls");
    cout << "\n Your health: " << pHealth << endl;
    cout << "\n Thief's health:  " << tHealth << endl;
    cout << "\n What would you like to do?" << endl;
    cout << "\n 1. Attack the thief" << endl;
    cout << "\n 2. Attempt to flee" << endl;
    cout << "\n> ";
    cin >> input;
    switch (input) {

        case 1:
        tHealth = tHealth - pDamage;
        system("cls");
        cout << "\n You attack the thief for " << pDamage << " damage!" << endl;
        cout << "\n ";
        system("pause");

        if (tHealth < 1) {
            system("cls");
            cout << "\n You have killed the thief!" << endl;
            cout << "\n ";
            system("pause");
            thiefDead();
        }

        pHealth = pHealth - tDamage;
        system("cls");
        cout << "\n The thief attacks you for " << tDamage << " damage!" << endl;
        cout << "\n ";
        system("pause");

        if (pHealth < 1) {
            system("cls");
            cout << "\n You have been killed by the thief!" << endl;
            cout << "\n ";
            system("pause");
            exit(0);
        }

        attackThief(pHealth, tHealth);

        case 2:
        system("cls");
        cout << "\n Your attempt to flee is unsuccessful." << endl;
        cout << "\n ";
        system("pause");
        attackThief(pHealth, tHealth);

    }
}

void thiefDead() {

    qUpdates = "Quest updated";
    qStages = "Retrieve Aragorn's Sword";   
    questUpdate();

    system("cls");
    cout << "\n What would you like to do?" << endl;
    cout << "\n 1. Search the thief's body" << endl;
    cout << "\n 2. Leave the cave" << endl;
    cout << "\n> ";
    cin >> input;
    switch (input) {

        case 1:
        searchBody();

        case 2:
        riverstead();

    }
}

void searchBody() {

    int gold;
    int sword;

    gold = gold + 20;
    sword = 1;
    stages[2] = 0;
    stages[3] = 1;

    system("cls");
    cout << "\n You found 20 gold and Aragorn's Sword!" << endl;
    cout << "\n ";
    system("pause");

    qUpdates = "Quest updated";
    qStages = "Return to Aragorn";  
    questUpdate();

    return;

}

void questUpdate() {

    system("cls");
    cout << "\n " << qUpdates << " - Aragorn's Sword" << endl;
    cout << "\n ";
    system("pause");

    if (qStages != " ") {
        system("cls");
        cout << "\n " << qStages << endl;
        cout << "\n ";
        system("pause");
    }

    return; 

}

void end() {

    system("cls");
    cout << "\n Thank you for playing RPG! A game made by Elliot Morgan." << endl;
    cout << "\n ";
    system("pause");
    main();

}
EN

回答 2

Code Review用户

回答已采纳

发布于 2015-02-14 18:19:24

不要在全局范围内执行using namespace std,而是在函数中使用它,甚至只在您正在使用的东西上使用它:

代码语言:javascript
复制
int main()
{
  using std::cout;
  ...
}

在您的主目录中,您有一个exit(0),相反,您应该执行一个返回语句。

代码语言:javascript
复制
return EXIT_SUCCESS;

您的switch语句中没有默认的大小写,所以如果用户输入了错误的号码,什么都不会发生,程序会在没有通知的情况下结束。最好有某种错误处理。您还应该执行一个函数,该函数显示多个选项,并允许用户输入一个如果正确的话返回的值,这样您就可以保存一些类型。

例如:

代码语言:javascript
复制
/**
 * show a number choices and lets the user choose one
 * @returns 1-n
 */
int promptUser( const std::vector<std::string>& options );

您的程序具有C程序的结构,您应该使用类来封装功能。识别故事中的对象并创建适当的类。

阿拉贡,小偷,玩家都有一些共同的特点

代码语言:javascript
复制
system("pause"); 

调用这样的外部程序不是件好事,它在应用程序中打开了一个安全漏洞,而使用std::getline或类似的。

你忘了初始化一些变量。

代码语言:javascript
复制
int gold;   <---
int sword;

gold = gold + 20;

在声明变量时,一定要养成初始化变量的习惯。

不要打电话给main()。它使程序流难以跟踪,相反,如果您希望重新启动游戏,则在main()中有一个循环。

票数 9
EN

Code Review用户

发布于 2015-02-14 17:32:56

这里还有很多需要改进的地方。首先,在处理整个移动的超级方法中有大量的代码块。为了便于阅读、调试、维护和添加,您应该将其分成更小的逻辑组。我注意到的一个例子是,您有很多这样的东西:

代码语言:javascript
复制
cout << "\n 1. Attack the thief" << endl;
cout << "\n 2. Attempt to flee" << endl;

也许您应该创建一个打印选项的方法:

代码语言:javascript
复制
void printOptions(std::vector<std::string> ops)
{
    for(const auto& opt : ops) {
        std::cout << &elem - &v[0] << opt << std::endl;
    }
}

然后,你可以称之为:

代码语言:javascript
复制
printOptions({"Attack the thief", "Attempt to flee"});

这比其他版本更干净,而且是可重用的,因此它将缩短您的代码。你也可以有很多你想要的论点,所以如果你想有三个选择的时候,没有问题。

你的另一个问题是你是using namespace std;。这很糟糕,因为稍后您可能会定义自己的名称空间,或者使用不同的名称空间,其中有一些方法名为这可能会引起问题

您的switch语句不应该像这样:

代码语言:javascript
复制
switch (input) {

    case 1:
    searchBody();

    case 2:
    riverstead();

}

相反,应该缩进case语句,如下所示:

代码语言:javascript
复制
switch (input) {
    case 1:
        searchBody();

    case 2:
        riverstead();
}

而且,我相信你在这里有一个错误。在C++和大多数其他语言中,一旦到达匹配的case语句,您将继续执行所有较低的case语句。如果匹配了case 1:并执行了searchBody();,这意味着riverstead();也会被执行。应该在每个break;块的末尾添加一个case语句:

代码语言:javascript
复制
switch (input) {
    case 1:
        searchBody();
        break;

    case 2:
        riverstead();
        break;        // unnecessary here because it is the last statement, but good practice.
}

我更喜欢if/else语句而不是switch语句,但是switch语句有时是有用的。

同样,您有大量的方法应该被分割成更小的块。我相信还有其他的事情你可以清理,但这将是一个好的开始

票数 5
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/80531

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档