-1

Started to try c++ again with a simple card game. I made a class for each card with two constructors, one with no values creates the card randomly and one that takes in values.

#include <string>
#include <iostream>
#include <stdlib.h>     /* srand, rand */
#include <ctime>
#include <sstream>

class Card
{

private:

char suit;
int value;
public:

Card();
Card(char suit, int value);


void SetSuit(char suit);
void SetValue(int value);

...

std::string GetCard() ;

};

Card::Card(char suit, int value)
{
suit= toupper(suit);
this -> suit=suit;
this -> value=value;
}
Card::Card() //create random card
{   

srand (time(0));
char suits [4] = {'D','S','H','C'};
int randNum = (rand() % 4);
SetSuit(suits[randNum]);
randNum = (rand() % 12)+2;
SetValue(randNum);


...

std::string Card::GetCard(){

...

return card.str();

}

If I create an array of card objects and then output it every card in the array has the same suit and value. I'm not sure how to get each card to be random the array.

Matthew
  • 432
  • 4
  • 17
  • 2
    **Wall of code, shrug!** Could you narrow that and get more specific about your actual problems please. – πάντα ῥεῖ Jul 04 '14 at 01:05
  • You just get the same value generated. See [this answer.](http://stackoverflow.com/a/7343853/115272) – Jacob Seleznev Jul 04 '14 at 01:10
  • This class at first seems to work, if you use the class without an array, it creates random values, i think when he creates a regular array (`Card card[5]`) and loops through it, the constructor for the class Card is for some reason making every card have the same value in the array. – James Jul 04 '14 at 01:17
  • Ive seen that before. The way I understand it working is that everytime a new object is created srand is called again which should create new random numbers so I don't understand why if I create an array of 50 it is creating 50 of the same values and not generating a new random number each time? – Matthew Jul 04 '14 at 01:20
  • 2
    @user3803703: It's simple, don't call `srand()` in a loop. Only use it ONCE in your program to set the start of the sequence generated by `rand()`. If you repeatedly reset the random number state you will get the same stream of numbers. – Blastfurnace Jul 04 '14 at 01:22
  • @user3803703 This is actually a rather decent question, if you corrected it to a good, minimal code example those downvotes should reverse and you'll see the question reopened. – Brad Koch Jul 04 '14 at 02:43

2 Answers2

5

The problem is with:

srand (time(0));
int randNum = (rand() % 4);

Probably on your system, time(0) returns the number of seconds this epoch. So when you call this code multiple times without a second elapsing, it gets the same value. Therefore you get the same random number every time.

You're supposed to do srand just once per program run. And if you need any serious sort of randomness then you need more entropy than just time(0). Even if you fix this, you could still execute your program several times and get the same card sequence every time, if all the runs begin within the same second.

The way that rand() typically works is to generate a long sequence of numbers which is predictable if you know the seed, but hard to predict just from a subset of the number. The srand function says "start the sequence at this point". If you start at the same point each time , you get the same random numbers each time. Further reading

M.M
  • 138,810
  • 21
  • 208
  • 365
  • Ok. I think I get get that. srand is being called to quickly that it keeps giving the same seed. I took srand out of the class and added it to main then created the array and looped through it and it still creates every card as the same card. Maybe I'm misunderstanding how rand works? – Matthew Jul 04 '14 at 01:36
  • maybe you added it inside a loop in `main` or something.. or you're doing something else wrong, hard to say without being able to see the code. Try to post a [MVCE](http://stackoverflow.com/help/mcve). – M.M Jul 04 '14 at 01:42
  • I'm pretty sure what Matt said is right, I just removed srand() from your class and put it at the start of main and these are the last three runs `D - 9D - 10S - 5D - 5D - 4` & `H - 6S - 8H- JackS - 6D - 8` & `S - 10S - 7C - 8H - 8C - 7`, assumming that's what is expected, i just looped the array and called GetCard() – James Jul 04 '14 at 01:47
  • Oh yeah it is working correctly with an array now. I was using vector at first, that's still not working but I guess that's a different issue. – Matthew Jul 04 '14 at 01:57
3

Call srand(time(0)) only once when your application starts, e.g., at the main() function, not whenever any card is created.

ALittleDiff
  • 1,191
  • 1
  • 7
  • 24