3

This has been bugging me for days:

#include <iostream>
using namespace std;

string words[] = {"cake", "cookie", "carrot", "cauliflower", "cherries", "celery"};
string word = words[rand() % 6];
string guess;
int lives = 3;

int main()
{
    std::cout << "Can you guess what word I'm thinking of? I'll give you a hint: it's a food that starts with the letter C. You have three tries. Good luck!" << std::endl;

    while(lives > 0)
    {
        std::cin >> guess;
        std::cout << std::endl;

        if(guess == word)
        {
            std::cout << "Wow, That's actually correct! Good job!" << std::endl;
            break;
        }
        else
        {
            lives--;

            std::cout << "Nope! You now have " << lives << " lives left." << std::endl;
        }
    }

    if(lives <= 0)
    {
        std::cout << "And... you lose!" << std::endl;
    }

    return 0;
}

I'm currently working on a word-guessing game, but when I try to pick a random element from my words array, it gets stuck on element 1 (i.e "cookie"). I used:

string words[] = {"cake", "cookie", "carrot", "cauliflower", "cherries", "celery"};
string word = words[rand() % 6];

Help would be appreciated.

Bluegenic
  • 163
  • 3
  • 11
  • 1
    you haven't initialised `rand` with `srand` so it will always return the same number which I guess on your platform is a multiple of 6 + 1 – Alan Birtles Sep 02 '21 at 07:21
  • 1
    You need to seed the random number ganerator - "_...std::srand() seeds the pseudo-random number generator used by rand(). If rand() is used before any calls to srand(), rand() behaves as if it was seeded with srand(1)...."_ see https://en.cppreference.com/w/cpp/numeric/random/rand – Richard Critten Sep 02 '21 at 07:21
  • 1
    Does this answer your question? [How to generate a random number in C++?](https://stackoverflow.com/questions/13445688/how-to-generate-a-random-number-in-c) – prehistoricpenguin Sep 02 '21 at 07:24
  • Why declare anything outside of `main`? For `words` I kind of see why you're doing it but for anything else it makes little sense and in fact makes distributes the logic across a larger area of the code than necessary making it a bit harder to understand. – fabian Sep 02 '21 at 07:27

4 Answers4

4

If you want to do it C++ style, use , and for maintenance I think std::vector of std::string is a good choice too.

#include <iostream>
#include <vector>
#include <string>
#include <random>

int main()
{
    std::vector<std::string> words{ "cake", "cookie", "carrot", "cauliflower", "cherries", "celery" };

    // gets 'entropy' from device that generates random numbers itself
    // to seed a mersenne twister (pseudo) random generator
    std::mt19937 generator(std::random_device{}());

    // make sure all numbers have an equal chance. 
    // range is inclusive (so we need -1 for vector index)
    std::uniform_int_distribution<std::size_t> distribution(0, words.size() - 1);

    for (std::size_t n = 0; n < 40; ++n)
    {
        std::size_t number = distribution(generator);
        std::cout << words[number] << std::endl;
    }
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19
  • I suggest not using `std::random_device` to generate random numbers. It'll empty the entropy pool and be very slow. Instead, just use it once to seed a pseudo random generator, like. `std::mt19937 rd(std::random_device{}());` - Other than that, good answer. It actually generates the words in random order using the modern C++ `random` library. – Ted Lyngmo Sep 02 '21 at 19:38
  • 1
    Didn't know about the performance hit on using random device. So I've updated the code. I hope C++11 and later examples will become the norm one day :) – Pepijn Kramer Sep 02 '21 at 19:52
2

rand() is a pseudo random number generator. That means, given the same starting conditions (seed), it will generate the same pseudo random sequence of numbers every time.

So, change the seed for the random number generator (e.g. use the current time as a starting condition for the random number generator).

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;

static const string words[] = {"cake", "cookie", "carrot", "cauliflower", "cherries", "celery"};

int main() {
   //variables moved to inside main()
   string guess;
   int lives = 3;

   srand(time(NULL));
   string word = words[rand() % 6];
nos
  • 223,662
  • 58
  • 417
  • 506
0

if u didnt generate using a srand() function

ur programm will automatic generate for you with the seed 1

so you can proceed it like this:

#include<cstdlib>
#include<ctime>
...
int main()
{
    srand(time(NULL));
    ....
}
Charles chen
  • 131
  • 4
0

You shouldn't use rand in C++, there are far better random engines.

#include <iostream>
#include <array>
#include <random>

using namespace std;

// use std::array as a better alternative to C arrays
array words {"cake", "cookie", "carrot", "cauliflower", "cherries", "celery"};
string guess;
int lives = 3;

int main()
{
    std::mt19937 gen{std::random_device{}()}; // generates random numbers
    std::uniform_int_distribution<std::size_t> dist(0, words.size() - 1); // maps the random number to [0..number of words]
    
    int index = dist(gen);
    string word = words[index];

    ...
}
Timo
  • 9,269
  • 2
  • 28
  • 58
  • You want to seed `gen` or else you'd get the same sequence of words every time you start the program. Also, the template argument deduction for `uniform_int_distribution` will likely fail since you are mixing types for _min_ and _max_. – Ted Lyngmo Sep 02 '21 at 19:31