3
#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];
4
  • 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 Commented Sep 2, 2021 at 7: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 en.cppreference.com/w/cpp/numeric/random/rand Commented Sep 2, 2021 at 7:21
  • 1
    Does this answer your question? How to generate a random number in C++? Commented Sep 2, 2021 at 7: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. Commented Sep 2, 2021 at 7:27

4 Answers 4

8

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;
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

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.
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 :)
3

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

2 Comments

I up-voted this (and also the answer by @Pepijn Kramer). Two caveats: (1) My compiler emits a "narrowing" warning when I use std::time(NULL) as an argument for std::srand. That is because std::time returns a 64-bit value, and std::srand expects type unsigned, which is only 32-bits (on my compiler). In the rare cases where I use std::rand, I usually seed it by calling std::srand(std::random_device{}()).
(cont.) (2) In applications where std::srand is called more than once—which does not happen here—there is a danger that the values returned by std::time could be closely correlated, or even identical. See item 2 in this Stack Overflow answer, which compares std::srand(std::time(NULL)) with std::srand(std::random_device{}()). See also the discussion by M.E. O'Neill, in her article Simple Portable C++ Seed Entropy.
1

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

    ...
}

1 Comment

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

2 Comments

He uses global variable, which initialization is performed before main is executed, so your fix will not work until other part of code is fixed too. So your answer in best case is incomplete.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.