Can I pick a random element from an array in C++?

Viewed 786

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.

4 Answers

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;
    }
}

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];

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));
    ....
}

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];

    ...
}
Related