while Statement breaking loop - c++

I added a while statement around my code so that the user could repeat the process as my teacher instructed, the way I did it worked on other code but for some reason it broke this one I could use help making it work please and thank you. The point of the code is to just flip 10000 coins and output the number of heads and tails. Thanks for any and all help.
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>
using namespace std;
// Keaton Graffis 12/22/2012
int coin()
{
int flip;
// assign random numbers
flip = rand() % 2 + 1;
return (flip);
}
int main()
{
char choice = 'y';
while (choice == 'y' || choice == 'Y');
{
double numFlips = 10000;
int count, face, heads = 0, tails = 0;
// initialize the random number generator
srand(static_cast<int>(time(0)));
// generate and count the number of heads and tails
for (int count = 1; count <= numFlips; count++)
{
face = coin();
if (face == 1)
heads++;
else
tails++;
}
cout << "The number flips: " << numFlips << endl;
cout << "The number of heads: " << heads << endl;
cout << "The number of tails: " << tails << endl;
// Asks user if they would like to go again(makes cod enot run, not sure why, this works on all my other code)
while (1)
{
cout << "Would you like to play again [Y]es or [N]o?\n";
cin >> choice;
if (choice == 'y' || choice == 'Y' || choice == 'n' || choice == 'N')
break;
}
}
}

Remove the semicolon after the while condition of the first loop. Only full statements are terminated by a ;.
Notes:
Since C++11, better facilities for random number generation are provided in the <random> header. Use these!

Related

Generating a random number for players in a dice game

I am writing a simple dice game where two players play against each other. The winner is the one who gets the largest number when the dice is rolled. However, when I press enter to make a random number get generated for the first player, I just get new empty lines. Here is the code:
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>
using namespace std;
int main()
{
srand(time(0));
int p1 = (rand() % 6) + 1;
cout << "Player 1: Press enter to roll your dice" << endl;
cin >> p1;
int p2 = (rand() % 6) + 1;
cout<<"Player 2: Press enter to roll your dice" << endl;
cin >> p2;
if(p1 == p2)
{
cout<<"You tied! \n";
}
else if(p1 > p2)
{
cout<<"You won! \n";
}
else
{
cout<<"You lost! \n";
}
}
You're trying to prompt the user for discardable action, but in-fact actually requesting they provide integer input to the console (which, inconveniently, will overwrite the random draws you just pulled).
When the stream is in a good state:
cin >> p1;
will attempt to read a formatted integer off the stream. During this attempt, whitespace (including newline) will be ignored. Therefore, until such time as you (a) enter a valid integer, (b) enter any non-whitespace that will fail to be parsed as an integer, or (c) the stream is already in EOF state so any further pulls without clearing are going to fail, so you're just left staring at an input prompt.
What you seem to really want is to just ignore data on the input stream until such time as a newline is entered (or EOF is encountered). One way to do that is to use the stream ignore member. For example:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
will pull all input from std::cin and discard it until such time as a newline is entered, or the stream reaches and error or eof state. Using that, what you probably really want is this:
#include <iostream>
#include <limits>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
srand(static_cast<unsigned>(time(0)));
int p1, p2;
cout << "Player 1: Press enter to roll your dice" << endl;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
p1 = (rand() % 6) + 1;
cout << "Player 2: Press enter to roll your dice" << endl;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
p2 = (rand() % 6) + 1;
cout << "Player 1: " << p1 << '\n';
cout << "Player 2: " << p2 << '\n';
if (p1 == p2)
{
cout << "You tied! \n";
}
else if (p1 > p2)
{
cout << "Player 1 won! \n";
}
else
{
cout << "Player 2 won! \n";
}
}
I'd use <random> for the actual draw, but that is unrelated to the root problems in your posted code.
To get an Enter key press you need to read the newline. In C++ that’s the rather wordy:
#include <iostream>
#include <limits>
std::cin.ignore( std::numeric_limits <std::streamsize> ::max(), '\n' );
Note that your program really does not need user input as it is written — everything that happens is independent of the user’s action.
RNG and the Pigeonhole Principle
Whatever RAND_MAX is on your system, if it isn’t 32767 it is probably a number of the form 2n-1. This doesn’t divide nicely by 6. So you are more likely to get a random number of 0 than 2 or 5, for example.
The way to fix this is to ignore numbers past some multiple of 6.
int multiples = RAND_MAX / 6;
int new_rand_max = multiples * 6;
If the value from rand() is not strictly less than new_rand_max then you can just throw it away.
while ((x = rand()) >= new_rand_max) ;
Now you can get the remainder and return that:
return x % 6;
Put all that in a function, making 6 an argument value, and you are good to go!
int random( int n )
{
int max = (RAND_MAX / n) * n;
int result;
while ((result = rand()) >= max) ;
return result % n;
}
And to use it:
int p1 = random( 6 ) + 1;

Code gives desired output but keeps on running

This code I wrote is supposed to subtract one from the number inputed, or divide by 2 based on whether it is a multiple of 3 or not. However, every time I try to run the code, It outputs the numbers I want but then doesn't stop running. I am new to coding and not sure how to fix this.
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
int main() {
int n;
cout << "Enter a positive number: " << endl;
cin >> n;
if (n < 0) {
cout << "Invalid input." << endl;
}
while (n >= 1) {
if (n % 3 == 0) {
n = n-1;
cout << n << endl;
}
else if (n % 3 != 0) {
n = n / 2;
cout << n << endl;
}
}
return 0;
}
This is a screenshot of the output I get. Instead of giving me the opportunity to run the code again it just stays like this:
I may be misunderstanding what you're asking, however, traversing through the code you can identify that nothing is being done to make the code run again. You would need add what you have inside another while loop. This new while loop would be something like while (input != 0) then run everything you have. In your input statement you could say "Please enter a positive number or enter 0 to exit". This is just an example of an approach, but the premise is that you need something to keep this loop running.

c++ program crashing. Not sure why

Your Community Supported Agriculture (CSA) farm delivers a box of fresh fruits and vegetables to your house once a week. For this programming project, define the class BoxOfProduce that contains exactly three bundles of fruits or vegetables. You can represent the fruits or vegetables as an array of type string. Add appropriate constructors and accessor/mutator functions to get or set the fruits or vegetables stored in the array. Also write an output
function that displays the complete contents of the box on the console.
Next, write a main function that creates a BoxOfProduce with three items randomly selected from this list:
• Broccoli
• Tomato
• Kiwi
• Kale
• Tomatillo
Do not worry if your program randomly selects duplicate produce for the three items. Next, the main function should display the contents of the box and allow the user to substitute any one of the five possible fruits or vegetables for any of the fruits or vegetables selected for the box. After the user is done with substitutions it should output the final contents of the box to be delivered. Then it should ask if the user wants to create another box and if
yes, it should repeat the above steps. It should keep doing so until the user chooses not to create another box of produce.
Finally, add a static variable to your class that keeps track of the total number of boxes of produce created and a static function that returns that value. Display this value in the main function at the end of each iteration of the main loop.
My program gets to the removeStuff() function after the user types Y if they want to swap out the bundle. Once it gets there and the user types what fruit/vegetable they want to remove, the program shuts down. I'm not sure why this is happening. Any help is greatly appreciated.
#include <iostream>
#include "BoxOfProduce.h"
#include <string>
#include <ctime>
#include <cstdlib>
#include <vector>
#include <memory>
#include <algorithm>
using namespace std;
int main()
{
char myChar;
string answer = "";
srand(time(0));
BoxOfProduce bo;
bo.randomize();
cout << "Your box initially starts with: " << endl;
cout << bo.random << endl;
vector<string> randomResult = bo.randomize();
for (vector<string>::const_iterator iter = randomResult.begin(), iterEnd = randomResult.end();
iter != iterEnd; ++iter){
cout << *iter << endl;
}
cout << "Would you like to swap out any of your bundles for any of the five bundles you didn't get? (Y/n) " << endl;
getline(cin, answer);
if(answer.length() == 1){
myChar = answer[0];
}
if(myChar == 'y' || myChar == 'Y'){
cout << "Okay!" << endl;
bo.removeStuff();
}else if(myChar == 'n' || myChar == 'N'){
BoxOfProduce bo1;
bo1.createBox();
}else{
cout << "That is not a valid character. Goodbye." << endl;
return 0;
}
}
---------------------------------------------------------------------
#include "BoxOfProduce.h"
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
#include <vector>
#include <memory>
#include <algorithm>
using namespace std;
BoxOfProduce::BoxOfProduce()
{
}
vector<string> BoxOfProduce::randomize()
{
srand(time(0));
string choices[] = {"Broccoli", "Tomato", "Kiwi", "Kale", "Tomatillo"};
vector<string> random;
for(int i = 0; i < 3; i++)
{
random.push_back(choices[rand() % 5]);
}
return random;
}
vector<string> BoxOfProduce::printContents(vector<string> bundles[3])
{
cout << "Your box contains these three bundles: " << endl;
cout << bundles << endl;
}
void BoxOfProduce::createBox(){
cout << "Would you like to create another box? (Y/n)" << endl;
getline(cin, answer);
if(answer.length() == 1){
myChar = answer[0];
if(myChar == 'y' || myChar == 'Y'){
vector<string> printContents();
randomize();
}
}
}
void BoxOfProduce::removeStuff()
{
cout << "Of your three bundles, what would like to remove?" << endl;
cin >> answer;
vector<string>::iterator result = find(randomResult.begin(), randomResult.end(), answer);
if(answer == "Tomato" || answer == "tomato" || answer == "broccoli" || answer == "Broccoli" || answer == "kiwi" || answer == "Kiwi" || answer == "kale" || answer == "Kale" || answer == "tomatillo" || answer == "Tomatillo"){
randomResult.erase(result);
bundles[3] = randomResult;
addStuff();
}else{
cout << "That is not a choice!" << endl;
}
}
void BoxOfProduce::addStuff()
{
cout << "Now that we have removed a bundle, what would you like to swap that out for: Tomato, Broccoli, Kiwi, Kale, or Tomatillo?" << endl;
getline(cin, answer);
if(answer == "Tomato" || answer == "tomato" || answer == "broccoli" || answer == "Broccoli" || answer == "kiwi" || answer == "Kiwi" || answer == "kale" || answer == "Kale" || answer == "tomatillo" || answer == "Tomatillo"){
randomResult.push_back(answer);
bundles[3] = randomResult;
printContents(bundles);
}else{
cout << "Sorry, you can't add that." << endl;
}
}
-----------------------------------------------------------------
#ifndef BOXOFPRODUCE_H
#define BOXOFPRODUCE_H
#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;
class BoxOfProduce
{
public:
BoxOfProduce();
string getBundles();
void setBundles(string b);
vector<string> randomize();
string bundleOfFruit();
vector<string> printContents(vector<string> bundles[3]);
string random;
void createBox();
void removeStuff();
void addStuff();
private:
vector<string> bundles[3];
vector<string> choices[5];
char myChar;
string answer = "";
vector<string> randomResult;
};
#endif // BOXOFPRODUCE_H
This is still very much a work in progress, so please go easy on me.
You are accessing out of bounds, e.g.
bundles[3] = randomResult;
as you have the declaration
vector<string> bundles[3]; // 3 elements, last one is indexed by 2
and in C or C++ the indexing starts from 0, so the last element of the array bundles should be bundles[2].
In any case, are you sure you need an array of vector of strings? It seems a bit odd.

C++ Writing simple coin flip game

I'm writing a code for a game that prompts the user to pick how many times they want to flip a coin and guess how many times it will land on heads. I wrote most of, just need help finishing it up. I tried to include a count of the heads but ran into problems.
#include <iostream>
#include <cmath>
#include <ctime>
using namespace std;
int myRandNumGen(){
int num = rand();
return num;
}
char coinTossFunction( ){
char coinToss;
int coinTossValue = (myRandNumGen()%2); // 0 or 1
switch (coinTossValue) {
case 0:
coinToss = 'H';
break;
case 1:
coinToss = 'T';
break;
default:
break;
}
return coinToss;
}
int calcCoin(int n){
int cout_heads=0;
for(int i=0;i<=n;i++){
if(coinTossFunction() == 'H')
++cout_heads;
}
return (cout_heads/n);
}
int main(){
int coinflips, guess;
cout << "How many times do you want to flip the coin? " << endl;
cin >> coinflips;
cout << "Guess how many times a coin will land on heads if flipped: " << endl;
cin >> guess;
if (guess>coinflips) {
cout << "Guess Error";
}
for(int i=1;i<=coinflips;i++){
cout << calcCoin;
}
Here are a few problems with your code:
for(int i=0;i<=n;i++)
This will make i take the values from 0 to n, which means you will enter in the loop n+1 times, instead of n times.
return (cout_heads/n);
Since both variables cout_headsand n are integers, this will perform an integer division, and not a floating point division. The result will always be 0 or 1 in this case.
cout << calcCoin;
When you call a function you need to put parenthesis. Also your calCoin function takes a parameter.

Why are my if statements not working consistently?

I'm making a coin toss program for my c++ class and we are required to make a function that flips a coin and prints out if it is heads or tails, and print 10 per line. When I ran the program though the if statements I used to detect if the coin was heads or tails weren't enough to pick from the two.
#include <iostream>
#include <ctime>
using namespace std;
void coinToss(int times);
int main()
{
srand(time(0));
int times;
cout << "How many times would you like to toss the coin?" << endl;
cin >> times;
coinToss(times);
return 0;
}
void coinToss(int times)
{
int toss = 0, count = 0;
for(int i = 0; i < times;i++)
{
toss = rand()%2;
if(toss == 1)//Detects if coin is heads.
{
cout << "H";
}
if(toss == 0)//Detects if coin is tails.
{
cout << "T";
}
else //I had to include this for the program to run, further explanation below the code.
{
cout << "Ya done goofed.";
}
count++; //Counts to ten
if(count == 10) //Skips to the next line if the coin has been tossed ten times.
{
cout << endl;
count = 0;
}
}
}
At one point I replaced the heads or tails with "cout << toss;" and the only numbers returned were 1 and 0. I don't understand how if I'm getting only the two numbers I'm checking for some of them aren't being caught by my if statements.
To complete the assignment I've changed the second if statement into an else statement and everything seems peachy, but I'd really like to understand what's going on here.
What happens with your code is:
Is the result 1 ? Then print H. Keep going. Is the result 0 ? Then print T. Else, if it's not 0, print "Ya done goofed.".
You need to keep your if statements linked together:
if (toss == 1) {
cout << "H";
} else if (toss == 0) {
cout << "T";
} else {
cout << "Ya done goofed.";
}
You won't fall in the else case anymore and will be able to remove it.
As a sidenote, regarding your overall program structure: your coinToss function shouldn't do everything. Your code should be more splitted: a function which returns H or T, a function which calls this function X times as requested by the user and formatting the output would be a good start.
Another small note: your count variable, allowing you to add a new line every 10 flips, could be removed. i % 10 will give you the same result: every ten increments, i % 10 would be equal to 0.
You're probably printing the output properly, then terminating without writing a newline on the last line, and your shell prompts clearing back to the left margin and overwriting your output (clearing the rest of the line to boot). If you have less than 10 tosses, your only line of output may appear lost, otherwise it'll be the last line.
Try adding an extra std::cout << '\n'; before main returns.
(Separately, you can say std::cout << "HT"[rand() % 2];, or std::cout << (rand() % 2 ? 'H' : 'T'); and do away with the ifs, but it's no big deal... whatever's clearest for you at this stage)
Well, rand()%2 will produce only two numbers: 1 and 0, this seems to be in line with your task as a coin is a boolean number generator, isn't it? :)
Therefore this seems to do the job you are looking for:
#include <iostream>
#include <ctime>
using namespace std;
void coinToss(int times);
int main()
{
srand(time(0));
int times;
cout << "How many times would you like to toss the coin?" << endl;
cin >> times;
coinToss(times);
return 0;
}
void coinToss(int times)
{
int toss = 0, Count = 0;
for(int i = 0; i < times;i++)
{
toss = rand() % 2;
// Choose:
cout << ((toss) ? "H" : "T"); // if you want a character
// or
cout << toss; // if you want the number
Count++; //Counts to ten
if(Count == 10) //Skips to the next line if the coin has been tossed ten times.
{
cout << endl;
Count = 0;
}
}
}
if(toss == 1)//Detects if coin is heads.
{
cout << "H";
}
else if(toss == 0)//Detects if coin is tails.
{
cout << "T";
}
You need to use else-if statement. You also need not use else after the toss==0 because rand()%2 will either be 0 or 1. There is no third option.
rand() returns a pseudo-random integral number in the range between 0 and RAND_MAX. And, rand() % 2 will be 0 or 1. So, there would be:
if(toss == 1)//Detects if head
{
cout << "H";
}
else // tail
{
cout << "T";
}
I don't think there is anything wrong with this. Well not that I can see... If I add some debug then I see what I think you're expecting...
#include <iostream>
#include <ctime>
using namespace std;
void coinToss(int times);
int main() {
srand(time(0));
int times;
cout << "How many times would you like to toss the coin?" << endl;
cin >> times;
coinToss(times);
return 0;
}
void coinToss(int times) {
int toss = 0, count = 0;
for(int i = 0; i < times;i++) {
toss = rand() % 2;
cout << "Toss: " << toss << endl;
if(toss == 1)//Detects if coin is heads.
{
cout << "H (" << toss << ")" << endl;
}
if(toss == 0)//Detects if coin is tails.
{
cout << "T (" << toss << ")" << endl;
}
count++; //Counts to ten
if(count == 10) //Skips to the next line if the coin has been tossed ten times.
{
//cout << endl; count = 0;
}
}
}
And compile it
g++ coin_toss.cc
And run it
./a.out
How many times would you like to toss the coin?
4
Toss: 1
H (1)
Toss: 0
T (0)
Toss: 0
T (0)
Toss: 0
T (0)
Then this is exactly what I expect or am I missing something?
You don't need an "if else if" statement.
You can also use a switch:
switch( rand() % 2 )
{
case 0:
cout << "T";
break;
case 1:
cout << "H";
break;
default:
cout << "oops you goofed!;
}
// continue within for loop
If you "forgot" the break after case 1 you would again get the "oops you goofed!" message after each head toss.