Typing Quiz

Write your question here.
I am recently trying to create a program that requires this:

The user is required to type in list of at least 5 animals.
The program then takes those inputs and selects from 1 to 3 animals and it shuffles(scrambles) their words and then gives it as an output.

The user must be able to figure out which animals are in it.
The program must be able to ignore spaces in user input.

When succeeding to answer in two consecutive rounds, the computer's challenge becomes harder by striking out a character one by one. The position to strike out is chosen at random. So, succeeding 4 consecutive times, the random word has two strikes out shown by underscore "_" characters. On the other hand, failing to answer in two consecutive rounds, the computer's challenge becomes easier by reducing the count of strikes out. The sample session follows.

This is an example:

Enter at least five animal names, e.g., cat, dog, etc...
> dog cat
> snake zebra
> tiger
>
1: dog
2: cat
3: snake
4: zebra
5: tiger

What are 2 animals in "gbzeoard" ? zebra dog
Yes!

What are 2 animals in "dgaoct" ? dog cat
Yes!
Succeeded two consecutive times, challenge goes up!

What are 1 animal in "ezar_" ? zebra
Yes!

So far this is my code, I need help in what I should do next.
I need to take an input of string and vectorize it. I must also use random_shuffle.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>
#include <ctime>
#include <algorithm>
#include <cstdlib>
#include <fstream>

using namespace std;

int main () {
cout<<"Enter a List of Animals:"<<endl;
string animal;
while (cin){
	getline(cin, animal);
	
}

	return 0;
}
You don't need a lot of those unnecessary headers, an example being fstream.
This is not a particularly simple thing that you are being asked to do -- It requires you to think in much more complex ways than you have previously.

The trick is to break the problem down into individual tasks that you can do simply. This is most easily done by using functions.

Here's a skeleton that can get you started:

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <algorithm>
#include <chrono>
#include <iostream>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

// (Global) variables used by the game ---------------------------------------

vector <string> animals;

int passes = 0;
int fails  = 0;

mt19937 prng( chrono::system_clock::now().time_since_epoch().count() );

int     number_of_animals_used;
string  random_word;

set <string> chosen_animals;
set <string> guesses;

// Helper functions ----------------------------------------------------------

void pass()
{
  fails = 0;
  passes += 1;
  cout << "Yes!\n";
}

void fail()
{
  passes = 0;
  fails += 1;
  cout << "No!\n";
}

int number_of_dashes_to_use()
{
  return passes / 2;
}

// Initialization ------------------------------------------------------------

void get_input()
{
  ...
}

void display_input()
{
  ...
}

// Game ----------------------------------------------------------------------

void init_play()
{
  chosen_animals.clear();
  guesses.clear();

  shuffle( animals.begin(), animals.end(), prng );
  number_of_animals_used = uniform_int_distribution <int> ( 1, 3 )( prng );

  ...
}

void play()
{
  init_play();
  
  cout << "\nWhat are " << number_of_animals_used << " animals in \"" << random_word << "\"? ";
  for (int n = 0; n < number_of_animals_used; n++)
  {
    string guess;
    cin >> guess;
    if (!cin) return;
    guesses.insert( guess );
  }
  
  if (guesses == chosen_animals) pass();
  else fail();
}

// Main ----------------------------------------------------------------------

int main()
{
  prng.discard( 10000 );
  get_input();
  display_input();
  while (cin) play();
}

Work on individual tasks.

Some notes:
You don't necessarily need to use std::set, but it helps a lot to track the animals used to make the random word and compare it to the user's input.

Don't use the srand()/rand() stuff if you can help it. Instead use the std::shuffle() and a PRNG from <random> (I used the MT19937 above). If you absolutely MUST use the old stuff, see the FAQ on how to do that: http://www.cplusplus.com/faq/beginners/random-numbers/

I've given you help with some of the trickier things. The hardest thing you must do (and you should know how to do it -- check your notes) is reading input. Use a std::stringstream to convert a string you get with std::getline() into individual words, just like you would normally cin >> s.

It is OK to use global variables.

Hope this helps.
I think understand most of this but what is the purpose of chrono and it relation to this program? Also, what does a set<> do? I have yet to learn about that.
Last edited on
closed account (E0p9LyTq)
CelestialX wrote:
what is the purpose of chrono and it relation to this program?

http://www.cplusplus.com/reference/chrono/
he elements in this header deal with time. Example: system clock.

Also, what does a set<> do?

http://www.cplusplus.com/reference/set/set/
Sets are containers that store unique elements following a specific order.

Duoas is one of the best sources of learning new C++ code tricks and ideas here, I constantly learn something from the code he posts.
What I mean to say is that I do not understand what it does and why it is needed. I would like understand the concept behind the use of chrono::system_clock::now().time_since_epoch().count()

Also, since I am still relatively new (barely 2 weeks) into C++ and programing, I would like to understand why "." are used and what they do.

And why do we have to clear (chosen_animals.clear();guesses.clear();)?
chrono and time

<chrono> is a replacement for <ctime>.
Don't worry about it. Use <ctime> and seed things with srand(time(0));.
Then get random numbers using one of the methods in the FAQ article I linked for you.


set

A 'set' is a "has a" container. You can answer questions like: does animals "have a" penguin?

This "has a" functionality is necessary for your program to function correctly. Without it you cannot determine whether or not the user entered the correct collection of animal names.


For example, suppose the user gave you the list of animals: dog, cat, snake, zebra, and tiger.
But the scrambled word uses only two of those animals.

For example, suppose that dog and cat were chosen from the list and scrambled together to form the word "codgta".

If the user thinks that the two animals represented are dog and zebra he would be wrong: Zebra is not one of the animal names used to create the scramble.


So every iteration of your program must do several things:

    1 - select N animals from the list
      - remember which animals were selected!
    2 - scramble their names together
    3 - ask the user to try to unscramble them
    4 - get the user's response(s)
    5 - compare the user's response to the names selected in step 1

Notice that there multiple lists of animal names:

    - the list obtained at the beginning of the program
    - the sublist the program chooses randomly from the first list
    - the sublist obtained from the user when he guesses what animals are in the second list


The trick, of course, is that the second list may be (dog, cat) and the user may enter (cat, dog). The two list the same animals, of course; hence the choice of using a set.


You don't really need the std::set to do this.
You could write a function that compares two lists to see if they contain the same animals in any order. A set is just a convenient Standard Library object.

1
2
3
4
5
6
7
bool is_subset( const vector<string>& set, const vector<string>& subset )
{
  for each element in subset:
    if element not found in set:
      return false
  return true
}



clearing previous loops

What would happen if you didn't start with an empty set of randomly chosen animals (and user responses) each time you play the game? Consider:

The first game: computer chooses (cat, dog) the first time. User correctly answers (cat, dog).

Then the computer chooses (zebra, dog) the second time. User correctly answers (zebra, dog), but computer is trying to look for (cat, dog, zebra).

Similar logical issues occur with the user response.


Hope this helps.
Is it okay if I replace prng with rand() and mt19937 prng( chrono::system_clock::now().time_since_epoch().count() ); with srand(time(0))

and I do not understand what prng.discard(1000) does so I am having a trouble finding a replacement.
Can I use the rand()%(size of vector or set by using .size)

Also, in the user_input section and display input what exactly am I supposed to do.

this is what I have for the first one:

void get_input()
{
string input;
cout<<"Please Enter Animals:"<<endl;
getline(cin,input);
animals.push_back(input);
}

void display_input()
{
cout<<"These are the Animals you have entered: "<<animals<<endl;
}
Last edited on
So my final code looked like this:

#include <iostream>
#include <cstdlib>
#include <random>
#include <string>
#include <vector>
#include <sstream>
#include <chrono>
#include <ctime>
#include <set>

using namespace std;

//Global Variables used.
vector<string>animals;

int passes=0;
int fails=0;
string scrambled_words;

mt19937 prng( chrono::system_clock::now().time_since_epoch().count() );

int number_of_animals;

vector <string> chosen_animals;
vector <string> answers;

//Score Functions

void pass()
{
fails = 0;
passes += 1;
cout << "Correct!\n";
}

void fail()
{
passes = 0;
fails += 1;
cout << "Incorrect!\n";
}

//Function that decides level, this is an algorithm.

int dash_level()
{
return passes / 2;
}

//Functions that are used to begin game

void get_input()
{
string input;
cout<<"Type Quit to End Game."<<"Otherwise, Please Enter Animals:"<<endl;
getline(cin,input);
animals.push_back(input);
}


void begin()
{
chosen_animals.clear();
answers.clear();

shuffle( animals.begin(), animals.end(), prng );
int number_of_animals = uniform_int_distribution <int> ( 1, 3 )( prng );
for (int i=0; i< number_of_animals; ++i) chosen_animals.push_back(i);
shuffle(chosen_animals.begin(), chosen_animals.end(), prng);
for (int j=0; j < chosen_animals.size(); j++) scrambled_words.push_back(j);
}

//The Actual Game Function

void game()
{
begin();

cout << "\nWhat are " << number_of_animals << " animals in \"" << scrambled_words << "\"? ";
for (int n = 0; n < number_of_animals; n++)
{
string answer;
cin >> answer;
if (!cin||answer=="Quit") return;
answers.push_back( answer );
}

if (answers == chosen_animals) pass();
else fail();
}

//The Game
int main()
{
prng.discard( 10000 );
get_input();
while (cin) game();
}

I would very much appreciate if someone can debug this so that it can work well.
Topic archived. No new replies allowed.