Reputation: 55
I am trying to make a text based fighter in C++, this is one of the first things that I have done. So far I have this:
//Text Based Fighter
#include <iostream>
#include <stdlib.h> //srand, rand
#include <string>
using namespace std;
int main() {
//Player
int playerHealth = 100;
int attack1;
int attack2;
int attack3;
string attack;
int npc1;
int npc2;
cout << "Do you want to attack " << rand()[npc1,npc2];
//varname = rand() % 10 + 1;
return 0;
}
What I am wanting it to do is randomly pick between npc1 and npc2, thank you.
Also any comments on how I am writing my code would be appreciated, I have only started a couple of days ago thank you, if you need any more detail please feel free to ask, thank you.
Upvotes: 1
Views: 4330
Reputation: 158469
If you have just two choices in C++11 you can use std::bernoulli_distribution and here is an overly simplified sample:
#include <iostream>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
// give "true"1/2 of the time
// give "false" 1/2 of the time
std::bernoulli_distribution d(0.5);
int npcs[2] = {100, 101};
int index = d(gen) ? 0 : 1;
std::cout << "Do you want to attack " << npcs[index] ;
}
using an array is more flexible since it expands easily to more than two choices and then you would need to use std::uniform_int_distribution to choose between [0,N]
.
In the long run using rand() is not a good idea, although in many simple cases it may work fine. As Pete mentions as long you understand the limitations of rand()
you can use it and the C FAQ has a good section on it, How can I get random integers in a certain range?.
Upvotes: 0
Reputation: 19030
It’s easy to make mistakes when generating pseudo-random numbers. For example, in some cases using rand() % RANGE
can lead to a subtly-wrong distribution of numbers. (See this reference for examples of the problem.)
This may not matter if what you are doing is trivial.
If you want high-quality pseudo-random numbers, there are ways to fix rand()
(see above reference), but modern C++ also provides <random>
and uniform_int_distribution
.
Here’s an example, simulating throwing a 6-sided die, adapted from examples in Boost and the C++ Reference:
#include <iostream>
#include <random>
std::random_device rd;
std::mt19937 gen(rd());
int roll_die() {
std::uniform_int_distribution<> dist(1, 6);
return dist(gen);
}
int main() {
std::cout << roll_die() << std::endl;
}
The part that says dist(1, 6)
could be changed to dist(0, 1)
to produce output in the range [0, 1] (inclusive) with a uniform distribution.
Upvotes: 0
Reputation: 308138
For just 2 choices you can take the remainder from 2 with a ternary expression:
int choice = rand() % 2 == 0 ? npc1 : npc2;
If you have more than 2 choices, or even if you don't, you can make an array with those and index into it.
int npc_choices[2];
int choice = npc_choices[rand() % 2];
If the number of choices is not a power of 2 you will likely introduce a very small bias into the selection with the modulo %
operator. If you're not working on anything with statistical significance or with a huge number of choices I wouldn't worry about it.
Upvotes: 1
Reputation: 50053
You can just use an array of an arbitrary number of variables to choose from:
int attack[n]; //For some int-constant n
attack[rand() % n]; //choose a random attack-variable, use it
Upvotes: 1