RPG战斗系统无法正常运行

时间:2018-12-17 10:41:25

标签: c++

我正在尝试制作一个RPG战斗系统,让您与地精战斗。不幸的是,我用来制作一个运气系统的随机发生器不能像我想要的那样工作。由于某种原因,当我希望每次随机变量都是不同的值时,每个循环中的随机变量总是相同的。我尝试了很多事情,但没有成功。同样在将其发布到这里之前,我意识到当满足停止条件时,while循环不会停止。

#include <iostream>
#include <random>
#include <ctime>

using namespace std;

int main(){
    std::mt19937 generator;
    generator.seed(std::time(0));

    std::uniform_int_distribution<uint32_t> d100(0, 100);

    int random = d100(generator);

    std::mt19937 generator2;
    generator2.seed(std::time(0));

    std::uniform_int_distribution<uint32_t> d20(1, 20);

    int random2 = d20(generator2);

    string action;
    int enmyHP = 100;
    int plyrHP = 120;

    while(enmyHP >= 1 || plyrHP >= 1){
        cout << "You are fighting a goblin. What will you do?"<< endl;
        cout << "|| ATTACK ||       || SPELL ||      || RUN ||"<< endl;
        cin >> action;

        if(action == "attack" || action == "Attack" || action == "ATTACK"){
            if(random >= 95){
                cout << "CRITICAL HIT!" << endl;
                cout << "You did 50 damage!" << endl;
                enmyHP - 50;
            } else if(random < 95 && random > 15){
                cout << "You did " << random2 << " damage" << endl;
                enmyHP = enmyHP - random2;
                cout <<"The goblin has: "<< enmyHP << " HP left" << endl;

            } else if(random > 15 && random < 1){
                cout << "You miss" << endl;
            } else {
                cout << "You hit yourself" << endl;
                plyrHP = plyrHP - 20;
                cout << "You have: " << plyrHP << " HP" << endl;
            }
        }
    }
    return 0;
}

1 个答案:

答案 0 :(得分:2)

在这里,您实际上是在生成随机数,不是在创建具有不同分布的两个 dice ,因此,每次使用randomrandom2时,您都会得到相同的数字:

int random = d100(generator);
int random2 = d20(generator2); // only one generator per thread should usually be used

如果您想创建一组可以使用的骰子,则可以将发行版与生成器的引用绑定在一起,以创建函子(可调用),可以像函数一样使用。示例:

#include <iostream>
#include <random>
#include <iomanip>    // std::setw
#include <functional> // std::bind

int main() {
    std::random_device rd;
    std::mt19937 generator(rd());

    auto d6 = std::bind(std::uniform_int_distribution<uint16_t>(1, 6), std::ref(generator));
    auto d20 = std::bind(std::uniform_int_distribution<uint16_t>(1, 20), std::ref(generator));
    auto d100 = std::bind(std::uniform_int_distribution<uint16_t>(1, 100), std::ref(generator));    
}

或者,您可以创建lambda来达到相同的效果:

std::uniform_int_distribution<uint16_t> dist6(1, 6);
std::uniform_int_distribution<uint16_t> dist20(1, 20);
std::uniform_int_distribution<uint16_t> dist100(1, 100);

// capture the distributions and generator by reference
auto d6 = [&](){ return dist6(generator); };
auto d20 = [&](){ return dist20(generator); };
auto d100 = [&](){ return dist100(generator); };

编辑:根据建议,您还可以制作Dice类:

class Dice {
    // static is implied below but added to make it clear: one instance
    // is created and shared between instances of Dice.
    //
    // thread_local makes one instance of the variable per thread
    // in case you add mutithreading later.
    static thread_local std::random_device rd;
    static thread_local std::mt19937 generator;

    std::uniform_int_distribution<uint32_t> dist;
public:    
    Dice(uint32_t low, uint32_t high) : dist(low, high) {}

    // make instances of the class callable:
    uint32_t operator()() {
        return dist(generator);
    }
};

thread_local std::random_device Dice::rd;
thread_local std::mt19937 Dice::generator = std::mt19937(Dice::rd());

Dice d6(1, 6);
Dice d20(1, 20);
Dice d100(1, 100);

可以使用以下任何版本:

while(true) {
    std::cout << d6() << std::setw(3) << d20() << std::setw(4) << d100() << "\n";
}