1. ## Glass Rod Problem

I'm working on a project, and can't seem to get the project to get the triangle variable to increase when the conditions are met. I need this number to be accurate so I can work out the probability. Below you'll find the project, and my amateurish code. Any help is appreciated.

Problem
Experiments that are either too expensive or too dangerous to perform are often simulated on a computer when the computer is able to provide a good representation of the experiment. Find out how to call the random-number generator (usually a function returning a floating point value in the range 0 to 1) for your C++ system. (Look up the functions rand and srand in the library cstdlib on the website cplusplus.com). Write a program that uses the random-number generator to simulate the dropping of glass rods that break into three pieces. The purpose of the experiment is to estimate the probability that the lengths of the three pieces are such that they might form the sides of a triangle.
For the purposes of this experiment, you may assume that the glass rod always breaks into three pieces. If you use the line segment 0 to 1 (on the real number line) as a mathematical model of the glass rod, a random-number generator (function) can be used to generate two numbers between 0 and 1 representing the coordinates of the breaks. The triangle inequality (the sum of the lengths of two sides of a triangle are always greater than the length of the third side) may be used to test the length of each piece against the lengths of the other two pieces.
To estimate the probability that the pieces of the rod form a triangle, you’ll need to repeat the experiment many times and count the number of times a triangle can be formed from the pieces. The probability estimate is the number of successes divided by the total number of rods dropped. Your program should prompt the user for the number of rods to drop and allow the experiment to be repeated. Use a sentinel value of 21 to hale execution of the program.

Code:
Code:
```#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cfloat>
#include <iomanip>
#include <stdlib.h>
#include <time.h>

using namespace std;

float doBreak (float, float);
float doProbability (float, float);

const int SENTINEL = 21;        //sentinal value

int main()
{
float break1;
float break2;
float side1;
float side2;
float side3;
float count;
float tests;
float triangle;
float probability;

const int SENTINEL = 21;
count = 1;
srand (time (NULL));

cout << "Enter number of glassrods to demolish (Enter 21 to end program): ";
cin >> tests;

if
(tests != SENTINEL)
{
do
{
doBreak(break1, break2);
count++;
}while (count <= tests);

doProbability(triangle, tests);
cout << "The probability that the broken glass rods will form a triangle is: " << probability << "%" << endl;
}
else
{
cout << "Aww, I was hoping to break stuff..." << endl;
}
return 0;
}

float doBreak
(float break1,
float break2)
{
float side1;
float side2;
float side3;
float triangle;
triangle = 0;

break1 = (float)rand()/RAND_MAX;
break2 = (float)rand()/RAND_MAX;

if (break1 < break2)
{
side1 = break1;
side2 = (break2 - break1);
side3 = 1 - break2;
}
else if (break2 < break1)
{
side1 = break2;
side2 = (break1 - break2);
side3 = 1 - break1;
}
else
{
side1 = break1;
side2 = break1;
side3 = break1;
}
if
((side1 + side2) > side3 &&
(side1 + side3) > side2 &&
(side2 + side3) > side1)
{
triangle += 1;
cout << triangle << endl;
}
return side1;
return side2;
return side3;
return triangle;
}

float doProbability
(float triangle,
float tests)
{
float probability;

probability = (triangle / tests) * 100;
return probability;
}```

2. A couple problems at least:

1) you are not looking at the returned value from the doBreak() function at all;

2) you can't return a sequence of values like that in doBreak(). The 'return side1' statement ends the function right there
at that point. 'side1' is the only value returned.

The variables declared in main() and the variables declared in doBreak() are independant, they are local to those functions
and have scope only in those functions.

One solution is to make those variables global; declare them once, before main().
then the function can assign values to any and all of them,
and the values are available in main().

3. Thank you, I moved the variable though and am still having the issue. I also cleaned up the returns in doBreak.

Code:
```
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cfloat>
#include <iomanip>
#include <stdlib.h>
#include <time.h>

using namespace std;

float doBreak ();
float doProbability (float, float);

const int SENTINEL = 21;		//sentinal value
float triangle;

int main()
{
float count;
float tests;
float probability;

count = 1;
srand (time (NULL));

cout << "Enter number of glassrods to demolish (Enter " << SENTINEL << " to end program): ";
cin >> tests;

if
(tests != SENTINEL)
{
do
{
doBreak();
count++;
}while (count <= tests);

doProbability(triangle, tests);
cout << "The probability that the broken glass rods will form a triangle is: " << probability << "%" << endl;
}
else
{
cout << "Aww, I was hoping to break stuff..." << endl;
}
return 0;
}

float doBreak()
{
float break1;
float break2;
float side1;
float side2;
float side3;
triangle = 0;

break1 = (float)rand()/RAND_MAX;
break2 = (float)rand()/RAND_MAX;

if (break1 < break2)
{
side1 = break1;
side2 = (break2 - break1);
side3 = 1 - break2;
}
else
{
side1 = break2;
side2 = (break1 - break2);
side3 = 1 - break1;
}
if
((side1 + side2) > side3 &&
(side1 + side3) > side2 &&
(side2 + side3) > side1)
{
triangle += 1;
cout << triangle << endl;
}
return triangle;
}

float doProbability
(float triangle,
float tests)

{
float probability;

probability = (triangle / tests) * 100;
return probability;
}```

4. Your doBreak() function returns 'triangle', so you need to look at it when you call doBreak().

like this:

triangle = doBreak();

Also same for doProbability(triangle, tests);
should be:

probability = doProbability(triangle, tests);

5. I feel dumb, I should have known that. That being said, I'm still getting off percentages because the triangle variable is not increasing.

Code:
```#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cfloat>
#include <iomanip>
#include <stdlib.h>
#include <time.h>

using namespace std;

float doBreak ();
float doProbability (float, float);

const int SENTINEL = 21;		//sentinal value
float triangle;

int main()
{
float count;
float tests;
float probability;

count = 1;
srand (time (NULL));

cout << "Enter number of glassrods to demolish (Enter " << SENTINEL << " to end program): ";
cin >> tests;

if
(tests != SENTINEL)
{
do
{
triangle = doBreak();
count++;
}while (count <= tests);

probability = doProbability(triangle, tests);
cout << "The probability that the broken glass rods will form a triangle is: " << probability << "%" << endl;
}
else
{
cout << "Aww, I was hoping to break stuff..." << endl;
}
return 0;
}

float doBreak()
{
float break1;
float break2;
float side1;
float side2;
float side3;
triangle = 0;

break1 = (float)rand()/RAND_MAX;
break2 = (float)rand()/RAND_MAX;

if (break1 < break2)
{
side1 = break1;
side2 = (break2 - break1);
side3 = 1 - break2;
}
else
{
side1 = break2;
side2 = (break1 - break2);
side3 = 1 - break1;
}
if
((side1 + side2) > side3 &&
(side1 + side3) > side2 &&
(side2 + side3) > side1)
{
triangle += 1;
cout << triangle << endl;
}
return triangle;
}

float doProbability
(float triangle,
float tests)

{
float probability;

probability = (triangle / tests) * 100;
return probability;
}```

6. Looks like 'triangle' is being reset to zero each time doBreak is called. Then if a triangle is formed,
it gets incremented to 1. So doBreak() always returns a 0 or 1, and in main(), triangle is always 0 or 1.

Couple ways to fix:

In main(), change

triangle = doBreak();

to

triangle = triangle + doBreak();

or

in the doBreak() function, change

triangle = 0;

to

static triangle = 0;

7. Will moving triangle = 0 to int main before calling doBreak also work?

Originally Posted by megafiddle
Looks like 'triangle' is being reset to zero each time doBreak is called. Then if a triangle is formed,
it gets incremented to 1. So doBreak() always returns a 0 or 1, and in main(), triangle is always 0 or 1.

Couple ways to fix:

In main(), change

triangle = doBreak();

to

triangle = triangle + doBreak();

or

in the doBreak() function, change

triangle = 0;

to

static triangle = 0;

8. I should also ask if there's an 'easy' way to avoid using triangle as a global variable, and just pass it back and forth. I get points off for global variables.

9. This seems to work, but I'm curious for the future how it could be better.

Code:
```#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cfloat>
#include <iomanip>
#include <stdlib.h>
#include <time.h>

using namespace std;

float doBreak ();
float doProbability (float, float);

const int SENTINEL = 21;		//sentinal value

int main()
{
float count;
float tests;
float probability;
float triangle;
triangle = 0;

count = 1;
srand (time (NULL));

cout << "Enter number of glassrods to demolish (Enter " << SENTINEL << " to end program): ";
cin >> tests;

if
(tests != SENTINEL)
{
do
{
triangle = doBreak();
count++;
}while (count <= tests);

probability = doProbability(triangle, tests);
cout << "The probability that the broken glass rods will form a triangle is: " << probability << "%" << endl;
}
else
{
cout << "Aww, I was hoping to break stuff..." << endl;
}
return 0;
}

float doBreak()
{
float break1;
float break2;
float side1;
float side2;
float side3;
float triangle;

break1 = (float)rand()/RAND_MAX;
break2 = (float)rand()/RAND_MAX;

if (break1 < break2)
{
side1 = break1;
side2 = (break2 - break1);
side3 = 1 - break2;
}
else
{
side1 = break2;
side2 = (break1 - break2);
side3 = 1 - break1;
}
if
((side1 + side2) > side3 &&
(side1 + side3) > side2 &&
(side2 + side3) > side1)
{
triangle += 1;
}
return triangle;
}

float doProbability
(float triangle,
float tests)

{
float probability;

probability = (triangle / tests) * 100;
return probability;
}```

10. Yes you can move triangle into main(). As now written, globals are not necessary;
global variables just would have been one solution as originally written.

Actually though, you are not passing it back and forth. main() will have it's own variable 'triangle'
and doBreak() will have it's own also. What you are doing is retrieving the value of 'triangle' as
it exists in doBreak() and assigning it to the variable 'triangle' in main. These two 'triangle' variables
could just as easily have two different names; they are different variables.

Still though, you need to accumulate the count value of 'triangle' like in the examples just above.

Using a static declaration will do two things:
first it will initialize 'triangle' to zero only once, at the beginning of program execution,
and second, it will preserve the value of 'triangle' from one function call to the next, so
it will accumulate the count.

Or as in the very first example,

triangle = triangle + doBreak();

it accumulates the count right there in main().

11. I'd like to interject to say that I really like this thread, and that it sets a good example. The problem is clearly described by the poster (not just copy-paste from the problem statement). The problem statement itself is included. You posted code, and it was properly indented. People made observations and suggestions, and you implemented them, posting the changed code. You are listening to what people are saying and making progress. This is something we do not see enough of on this board. Thanks, and keep it up.

12. I am going to attempt that new idea in my own time, though not tonight when I'm close doing it the long way! <g>

This is where I'm at, and I'm very happy, thanks for the help. I'm taking it apart in my head to figure out a way to get around the triangle being declared in two places. Global would make sense, but as I said, the teacher dislikes them.

Code:
```#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cfloat>
#include <iomanip>
#include <stdlib.h>
#include <time.h>

using namespace std;

float doBreak ();
float doProbability (float, float);

const int SENTINEL = 21;		//sentinal value

int main()
{
float count;
float tests;
float probability;
float triangle;

count = 1;
srand (time (NULL));

cout << "Enter number of glassrods to demolish (Enter " << SENTINEL << " to end program): ";
cin >> tests;

if
(tests != SENTINEL)
{
do
{
triangle = doBreak();
count++;
}while (count <= tests);

probability = doProbability(triangle, tests);
cout << "The probability that the broken glass rods will form a triangle is: " << probability << "%" << endl;
}
else
{
cout << "Aww, I was hoping to break stuff..." << endl;
}
return 0;
}

float doBreak()
{
float break1;
float break2;
float side1;
float side2;
float side3;
float static triangle = 0;

break1 = (float)rand()/RAND_MAX;
break2 = (float)rand()/RAND_MAX;

if (break1 < break2)
{
side1 = break1;
side2 = (break2 - break1);
side3 = 1 - break2;
}
else
{
side1 = break2;
side2 = (break1 - break2);
side3 = 1 - break1;
}
if
((side1 + side2) > side3 &&
(side1 + side3) > side2 &&
(side2 + side3) > side1)
{
triangle += 1;
}
return triangle;
}

float doProbability
(float triangle,
float tests)

{
float probability;

probability = (triangle / tests) * 100;
return probability;
}```

13. Originally Posted by CoryMore
This seems to work, but I'm curious for the future how it could be better.
I would change this:

const int SENTINEL = 21; //sentinal value

to this:

#define SENTINEL 21 //sentinal value

as it doesn't need to be a variable.

Also, you want:

static float triangle = 0;

14. I believe it is, after adding a print out:
Code:
```if
((side1 + side2) > side3 &&
(side1 + side3) > side2 &&
(side2 + side3) > side1)
{
triangle += 1;
cout << triangle << endl;
}
return triangle;
}```
I get:

\$ ./rods
Enter number of glassrods to demolish (Enter 21 to end program): 100
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
The probability that the broken glass rods will form a triangle is: 30%

15. Originally Posted by brewbuck
I'd like to interject to say that I really like this thread, and that it sets a good example. The problem is clearly described by the poster (not just copy-paste from the problem statement). The problem statement itself is included. You posted code, and it was properly indented. People made observations and suggestions, and you implemented them, posting the changed code. You are listening to what people are saying and making progress. This is something we do not see enough of on this board. Thanks, and keep it up.
I agree, it was a pleasure to help.