Help with a coin flip program

I have a coin flip program that flips a coin 1000 times and tells you each time if it's heads or tails. But it seems that sometimes it doesn't spit out either of those outcomes.

For example, in my program below, the numbers of times that heads and tails pop up should equal 1000, yes? But it only adds up to a number considerably less than that, usually around 600-700.

Also, if there is a simpler, more efficient way to make a coin flip program, then I would like to know.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <ctime>
#include <cstdlib>
#include <iostream>
using namespace std;
int randRange ()
{
    
return rand() % 3 ;

}

int main ()
{
int h=0;
int t=0;
int i;

srand( time( NULL ) );

  cout << "Coin flip!" <<'\n';
  
for (i=0;i<1000;i++)
{
    randRange();

if (randRange() ==1 || randRange() ==3 || randRange() ==5 || randRange() ==7 || randRange() ==9)
{
    cout << "Heads." << '\n';
    h++;
}

else if (randRange() ==2 || randRange() ==4 || randRange() ==6 || randRange() ==8 || randRange() ==0  )
{
    cout << "Tails." << '\n';
    t++;
}

}

cout << '\n' << "Heads: " << h << '\n';
cout << "Tails: " << t;

}

Line 24 is pretty much pointless. An integer is returned but is never used.
Within your if conditions, you call randRange() over and over again, which will provide different results for each test.
This could happen:

line 26:
Is 0 == 1? No.
Is 2 == 3? No.
...Rest of condition will always be false...
line 32
Is 1 == 2? No.
...Most of condition will always be false...
Is 2 == 0? No.

As you can see, there is a chance for none of the conditions to be true. Maybe you meant to store the result of rangRange() in a variable and test that.

Why do you test the result of randRange() against values greater than 2? randRange() will always return a result from 0 to 2. Maybe you forgot to change that 3 in your randRange() function?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <ctime>
#include <cstdlib>
#include <iostream>

enum Face { Head, Tail } ;

Face coinFlip()
{
    return Face(rand()%2) ;
}

int main ()
{
    std::srand(std::time(0)) ;

    unsigned flips[2] = { 0, 0 } ;

    const unsigned nFlips = 1000 ;

    for ( unsigned i=0; i<nFlips; ++i )
        ++flips[coinFlip()] ;

    std::cout << "Heads: " << flips[Head] << " (" << (double(flips[Head]) / nFlips) * 100 << "%)\n" ;
    std::cout << "Tails: " << flips[Tail] << " (" << (double(flips[Tail]) / nFlips) * 100 << "%)\n" ;
}
I wanted line 24 to be within the for loop so that the random number would be different each time. I wanted the heads or tails output to be as close to 50/50 as possible, but not predictable.

I thought the || would cover all possible values though? (You are right, I only need numbers between 0-2). For example, if 0!=1 or if =!=3, etc. etc, then it would go to the else if, so it would have to equal at least one of those values, right?
Line 24 does nothing. Sure, you conjured up a random number but nothing happens to it. You don't use it in the rest of the program. It's like:
1
2
3
4
5
int main(){
   2+3; //Nothing happens with the value returned here.
   int var = 2+3; //Now you can use the result
   return 0;
}


You call randRange() again and again within the if conditions; there will be different results each time the function's result is tested against another number. So no, randRange() does not have to be equal to one of the conditions.

What you probably meant is this:
1
2
3
int result = randRange();
if(result == 0 || result == 2)
//... 



(You are right, I only need numbers between 0-2).

If you are doing something like if x is even be tails or if x is odd be heads, then having a range larger than [0,1] would seem reasonable. However, if you just want a straight up heads or tails, just use 0 to 1. 0 to 2 makes no sense in a coin flip unless the coin can land on its side. In fact, your program above favors tails over heads.


Final Note:
I like cire's program. It is very elegant and better than anything I would have come up with. But then again, I've only been programming for a few months...
Ah, okay. So this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <ctime>
#include <cstdlib>
#include <iostream>
using namespace std;
int randRange ()
{

return rand() % 2 ;

}

int main ()
{
int h=0;
int t=0;
int i;

srand(time (NULL));

  cout << "Coin flip!" <<'\n';

for (i=0;i<1000;i++)
{
//randRange() becomes an integer

    int coin=randRange();
    if (coin==0)
    {
        cout << "Heads." << '\n';
        h++;
    }

    else if (coin ==1)
    {
        cout << "Tails." << '\n';
        t++;
    }

}

cout << '\n' << "Heads: " << h << '\n';
cout << "Tails: " << t;

}


Actually worked much better than my first one. But I still don't quite understand why. Why does setting randRange() to an integer make it work versus just stating it? Isn't it an integer already?
> Try to use all the bits of the pseudo random number returned by std::rand()

1
2
3
4
5
6
enum Face { Head, Tail } ;

Face coin_flip()
{
    return ( rand() / double(RAND_MAX) ) < 0.5 ? Head : Tail ;
}

Actually worked much better than my first one. But I still don't quite understand why. Why does setting randRange() to an integer make it work versus just stating it? Isn't it an integer already?


Well, let's change your first program a little to illustrate what's happening.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <ctime>
#include <cstdlib>
#include <iostream>

using namespace std ;

// change randRange so we can see what's happening:
int randRange ()
{
    int num = rand() % 3 ;
    cout << "randRange returning " << num << '\n' ;
    return num ;
}

int main ()
{
    int h=0;
    int t=0;
    int i;

    srand( time( NULL ) );

    cout << "Coin flip!" <<'\n';

    // make it one flip for clarity:
    for (i=0;i<1;i++)
    {
        randRange();

        if (randRange() ==1 || randRange() ==3 || randRange() ==5 || 
            randRange() ==7 || randRange() ==9)
        {
            // cout << "Heads." << '\n';
            h++;
        }

        else if (randRange() ==2 || randRange() ==4 || randRange() ==6 ||
                 randRange() ==8 || randRange() ==0  )
        {
            // cout << "Tails." << '\n';
            t++;
        }

    }

    cout << '\n' << "Heads: " << h << '\n';
    cout << "Tails: " << t << '\n' ;
}


Sample output:
Coin flip!
randRange returning 1
randRange returning 2
randRange returning 0
randRange returning 1
randRange returning 0
randRange returning 0
randRange returning 0
randRange returning 0
randRange returning 2
randRange returning 1
randRange returning 2

Heads: 0
Tails: 0


Match up the return values with the calls to randRange in the code.
Last edited on
hey,
randrange() would always return 0,1 or 2.why test for other values like 3 or 9?. also, you can change randrange() to rand()%2, which will return 0 or 1.
if randrange()==0,its heads and if randrange()==1 its tails.
the sum up of all outcomes has to be 1000.!@
Thank you all for the help :)
Topic archived. No new replies allowed.