Reputation: 1
I'm trying to code a version of the picolo mobile drinking game app for me and my friends to play (it seemed simple enough and we were sick of the questions in the app so we wanted to be able to write our own). The way that it is supposed to work is by prompting for the number of players, randomizing the order of the questions, and then asking them one by one. I tried to use cin.ignore() to wait to ask the next question until the user presses enter, and it works for every iteration except the first. Here's the source code:
#include<iostream>
using std::cin;
using std::cout;
using std::endl;
#include<algorithm>
using std::random_shuffle;
#include<fstream>
using std::ifstream;
#include<cstdlib>
#include<string>
using std::string;
#include<time.h>
const int numQuestions = 19;
int vir6rounds;
bool activeVir6 = false;
int v6counter = 0;
void getQuestion(int questionNumber, string players[], int numPlayers);
int getRandom();
int main()
{
srand(time(0));
// Create array of player names based on entered size
cout << "Enter \"quit\" to end game" << endl;
cout << "How many players?" << endl;
int numPlayers;
cin >> numPlayers;
cout << "Enter players' names: " << endl;
string players[numPlayers];
for (int i = 0; i < numPlayers; i++)
cin >> players[i];
bool loop = true;
int qArray[numQuestions];
// Populate array
for (int i = 0; i < numQuestions; i++)
{
qArray[i] = i;
}
while (loop)
{
// Reshuffle array each time game is looped
random_shuffle(qArray, qArray + numQuestions);
for (int i = 0; i < numQuestions; i++)
{
// Choose 3 random player names from array
// Changes each time a new question is generated
random_shuffle(players, players + numPlayers);
getQuestion(qArray[i], players, numPlayers);
cin.ignore(); // Problem here
}
cout << "Game over; press enter to play again" << endl;
cin.ignore();
}
}
void getQuestion(int questionNumber, string players[], int numPlayers)
{
if (activeVir6 == true)
{
v6counter++;
if (v6counter == vir6rounds)
{
cout << "Pong loser can speak again." << endl;
cin.ignore();
activeVir6 = false;
v6counter = 0;
}
}
string player1 = players[0];
string player2 = players[1];
string player3 = players[2];
switch (questionNumber)
{
case 0:
cout << "Going around, Play rock paper scissors with the player to your left." << endl;
cout << "Losers take two drinks." << endl;
break;
case 1:
cout << player1 << ", who would win in a fight? " << player2 << " or " << player3 << "?";
cin.ignore();
cout << "Loser takes two drinks." << endl;;
break;
case 2:
cout << player1 << " chooses the next song" << endl;
break;
case 3:
cout << "Whoever took a shower the least recently has to take a drink" << endl;
break;
case 4:
cout << player1 << ", take as many penalties as you want.";
cin.ignore();
cout << "However many you took, " << player2 << " has to take double." << endl;
break;
case 5:
cout << "Everyone switch drinks to the left" << endl;
break;
case 6:
cout << "virus: " << player1 << " versus " << player2 << " in pong." << endl;
cout << "loser can't speak until otherwise" << endl;
activeVir6 = true;
vir6rounds = getRandom();
break;
case 7:
cout << player1 << " take as many penalties as the youngest players age.\nIf you're the youngest, everyone else take 2." << endl;
break;
case 8:
cout << player1 << ", buy " << player2 << " a red bull or take 15 penalties" << endl;
break;
case 9:
cout << player1 << ", let " << player2 << " look through your snap memories or take 8 penalties" << endl;
break;
case 10:
cout << player1 << " has to say yes to " << player2 << " for 5 minutes or take 8 penalties" << endl;
break;
case 11:
cout << player1 << ", show off ur best cartwheel" << endl;
break;
case 12:
cout << player1 << ", change clothes with " << player2 << " or they pick how many penalties you take" << endl;
break;
case 13:
cout << player1 << ", pick someone new to go on aux or they take 5 penalties" << endl;
break;
case 14:
cout << player1 << ", cook " << player2 << " a meal or take 9 penalties" << endl;
break;
case 15:
cout << player1 << ", pick two people to shotgun" << endl;
break;
case 16:
cout << player1 << ", let " << player2 << " paint ur nails or take 10 penalties" << endl;
break;
case 17:
cout << player1 << ", every time you talk to " << player2 << " take 3 penalties until otherwise" << endl;
break;
case 18:
cout << player1 << ", kill yourself or take a penalty." << endl;
break;
default:
cout << "question has not been defined yet" << endl;
}
return;
}
Here is some example input. Everything else seems to run fine; the only problem I've come across is that after entering the names, the program prints the first two lines (in this case, "helen, buy john a red bull or take 15 penalties" and "dylan chooses the next song") at the same time before working correctly.
/*
Enter "quit" to end game
How many players?
7
Enter players' names:
john
kevin
mark
stacy
helen
jenna
dylan
helen, buy john a red bull or take 15 penalties
dylan chooses the next song
mark, let stacy look through your snap memories or take 8 penalties
helen has to say yes to mark for 5 minutes or take 8 penalties
Everyone switch drinks to the left
*/
I'm not all too concerned with the efficiency of the code or the typical pitfalls of the rand() function due to the low-stakes nature of the game, mostly just with getting it to print out each line one at a time as intended. However, as a new and admittedly shabby programmer, all advice would be welcomed and appreciated.
Upvotes: 0
Views: 95
Reputation: 598414
The first iteration doesn't wait on cin.ignore()
(which BTW is not a good way to wait for an ENTER press) because there is still a line break present in the input buffer that was left over after the last player's name was read in.
Try using std::getline()
instead of operator>>
to read in each player's name, it will and automatically discard the trailing line break for you. Just watch out for this gotcha:
Why does std::getline() skip input after a formatted extraction?
Also, string players[numPlayers];
is not standard C++:
Why aren't variable-length arrays part of the C++ standard?
Use std::vector
instead.
Upvotes: 2