# 5.x — Chapter 5 comprehensive quiz

Quick review

If statements allow us to execute a statement based on whether some condition is true. Else statements execute if the associated if statement is false. You can chain together multiple if and else statements.

Switch statements provide a cleaner and faster method for selecting between a number of discrete items. Switch statements pair great with enumerations.

Goto statements allow the program to jump to somewhere else in the code. Don’t use these.

While loops allow the program to loop as long as a given condition is true. The condition is evaluated before the loop executes.

Do while loops are the same as while loops, but the condition is evaluated after the loop execution. They’re great for menus or things that need to execute at least once.

For loops are the most used loop, and are perfect when you need to loop a specific number of times.

Break statements allow us to break out of a `switch`, `while`, `do while`, or `for` loop. Or a range-based `for` loop, which we haven’t covered yet.

Continue statements allow us to move immediately to the next loop iteration. Be careful when using these with while and do while loops, as your loop counter may not get incremented properly.

And finally, random numbers give us a way to make our programs behave different each time they are run. We’ll see an example of this in the quiz below!

Quiz time

Warning: The quizzes start getting harder from this point forward, but you can do it. Let’s rock these quizzes!

Question #1

In the chapter 2 comprehensive quiz, we wrote a program to simulate a ball falling off of a tower. Because we didn’t have loops yet, the ball could only fall for 5 seconds.

Take the program below and modify it so that the ball falls for as many seconds as needed until it reaches the ground.

In constants.h:

Show Solution

Question #2

a) Implement a game of hi-lo. First, your program should pick a random integer between 1 and 100. The user is given 7 tries to guess the number.

If the user does not guess the correct number, the program should tell them whether they guessed too high or too low. If the user guesses the right number, the program should tell them they won. If they run out of guesses, the program should tell them they lost, and what the correct number is. At the end of the game, the user should be asked if they want to play again. If the user doesn’t enter ‘y’ or ‘n’, ask them again.

Note: You do not need to implement error handling for the user’s guess.

Here’s what your output should look like:

```Let's play a game.  I'm thinking of a number.  You have 7 tries to guess what it is.
Guess #1: 64
Guess #2: 32
Guess #3: 54
Guess #4: 51
Correct! You win!
Would you like to play again (y/n)? y
Let's play a game.  I'm thinking of a number.  You have 7 tries to guess what it is.
Guess #1: 64
Guess #2: 32
Guess #3: 54
Guess #4: 51
Guess #5: 36
Guess #6: 45
Guess #7: 48
Sorry, you lose.  The correct number was 49.
Would you like to play again (y/n)? q
Would you like to play again (y/n)? f
Would you like to play again (y/n)? n
Thank you for playing.
```

Hints:
* Use the Mersenne Twister algorithm from chapter 5.9 -- Random number generation to pick a random number.
* Write a function that allows the user to play a single game of hi-lo.
* Write a function that asks the user if they want to play again and handles the looping logic for an incorrect input.
* Avoid magic numbers by defining constants for the minimum/maximum random range and the number of guesses.
* In an if-statement, if you already checked 2 numbers for equality and compared them with either the < or > operator, but all checks failed, the relation between the numbers must be the one you didn’t check. For example, if `guess` is neither equal to nor less than `number`, it must be greater than `number`.

Show Solution

b) Update your previous solution to handle invalid input (e.g. ‘x’) or valid input with extraneous characters (e.g. “43x”) when the user is guessing a number.

Hint: Write a separate function to handle the user inputting their guess (along with the associated error handling).

Show Solution

 6.1 -- Arrays (Part I) Index 5.11 -- Introduction to testing your code

### 743 comments to 5.x — Chapter 5 comprehensive quiz

• Jo

Is it bad if I have to look at the solution for the quizzes most of the time? (probably around 60% of the time if I had to guess)

From the comments, it seems like people innately understand C++ and dump out solutions of some kind even if they aren't the perfect or exact solution. I can't even get to that point.

• Hi Jo!

Try to solve it yourself. See what you're stuck with, have another look at the lesson about that topic.
If you still can't solve it, look at Alex' or someone else's solution. Fix the part of your code that you were stuck at and continue from there. If you can't solve it altogether, use the solution as much as you need to get your code to do the task. Wait a day or 2 and try it again without looking at your old code or a solution.
It's normal to get stuck, but at the end of the tutorials (When you leave learncpp), you should be able to code on your own.

• Jon

Hello, I wanted to ask, for the last question, is it not advisable to place the error handling directly in the for-loop of the playGame() function? Just curious why you recommend creating a whole new function for this purpose? Also, do we still need to remove extraneous input when asking for char input in the playAgain() function? Thanks very much for everything!!! Here's my solution for reference:

• Hi Jon!

> is it not advisable to place the error handling directly in the for-loop of the playGame() function?
It's not. For one, your error handling doesn't work, because line 22ff will be executed even if the input is erroneous. You're missing a loop.
Validating input is a often a repeated task, so it should be in it's own function.
If you can split one function into more than one, doing so will most likely make your code easier to read and maintain.

> do we still need to remove extraneous input when asking for char input
Should not be necessary. Anything you can type can be stored in a char.

* Line 8: Initialize your variables with uniform initialization. You used copy initialization.
* Line 54, 55: Initialize your variables with uniform initialization. You used direct initialization.
* Line 11, 38: Initialize your variables with uniform initialization.
* Line 32, 62: Limit your lines to 80 characters in length for better readability on small displays.
* Line 17, 20, 43: Don't pass 32767 to @std::cin.ignore. Pass @std::numeric_limits<std::streamsize>::max().
* Line 26: Unnecessary comparison.
* Line 45, 46: Double comparison of @yesOrNo to 'y'
* Line 46-49: There's no need for an if-statement
* Line 65: Don't compare booleans to false/true

• Jon

Thank you! Sorry, one more quick one:

You mentioned "Don't compare booleans to false/true", is that a style thing or will that cause problems with a program that I can't see yet?

• It's a style thing

• beginnerCoder

I'll post my admittedly horrible solution to the second exercise just in case anyone has time to check it. Please forgive the use of goto statements, I know I could have done the same with do-while loops.

I tried to do everything outside of main but I ended up having the two functions call each other, and I'm not really sure it's a positive thing. Anyway, here we go:

• Hi!

> two functions call each other
That's bad. Recursion is covered later. You using recursion and goto shows that you didn't understand loops enough. Give it another try. If you have to, look at other submissions or the quiz' solution.

* Initialize your variables with uniform initialization
* Seed RNGs only once. You're seeding @mersenne with every call to @twister
* Magic numbers: 1, 7, 100
* Don't use goto
* You don't have to return from voids
* Line 27: Unnecessary comparison

• Ajalle Perfej

The following code compiled without errors...but when the application was run, it rotated my screen 90 degrees clockwise! I can't stop laughing about that undefined behaviour.

random.cpp

main.cpp

• I don't see anything in you code that could create the described behavior. I suspect you pressed ctrl + alt + arrow key.

Suggestions:
random.cpp
* Line 15, 17: Uniform initialization
* @twister: You're seeding the mersenne twister with every call to @twister

main.cpp
* Line 19: Unnecessary
* Line 36: Should be break to avoid the duplicate return (line 36, 44)

• Ajalle Perfej

I reproduced the undefined behaviour under entirely different conditions.

Original condition:
- Fedora 28
- had Firefox ESR, Gedit, and Terminal open.
- hit enter in Terminal following some text
- display rotated 90 degrees clockwise

Repeating condition:
- Debian 9.5
- Had only LibreOffice Writer open
- hit enter at the end of a paragraph of text in LibreOffice Writer
- display rotated 90 degrees clockwise

In addition the mouse pointer is implicated as it moves erratically in response to mouse movement.

But this appears to be an issue with recent versions of Linux in association with the Enter key rather than anything to do with C++. I just wanted to reassure you of that.

• I did mine a little differently than the solution. I would love to have some feedback or any advice to improve my programming please.

• * Initialize your variables with uniform initialization
* Don't pass 32767 to @std::cin.ignore. Pass @std::numeric_limits<std::streamsize>::max()
* Seed the rng only once
* Line 18, 35, 40: Double comparison of @input to 'y'/'n'
* Line 56: You have a constant for 7, use it
* Don't use @system. @pause only exists on Windows. Use @std::cin.get()

• Thank you so much!

• Faruk Hodzic

Hi,
I coded the number guessing game.My result is different from the solution.I would really like some feedback, opinions or just some advice or maybe some improvements i could make in the code.

main.cpp

• Hi!

* Initialize your variables with uniform initialization. Read compiler warnings and fix them.
* Don't define constants more than once. (@error)
* Line 41, 47: Double comparison of @userGuess to @RandomNumber
* Inconsistent naming convention for variables
* @GetGuess should loop until the input is valid. Not @Game.
* If a function modifies an argument, pass it by address to make it obvious to the caller that the argument will be modified.
* Line 83: The first time the condition is checked it will always be true. Use a do-while-loop.

• Faruk Hodzic

Thanks so much.The variables userGuess and RandomNumber i forgot to take out and i whant the boolean terminate to be modified so the game can quit or play again.Thanks for the feedback and your time.

• Boteomap2

Hi Alex / nascardriver!

Since my code is a bit different to the solution, I thought I'd offer it up for any feedback (which would be much appreciated if you have time):

Function.h

function.cpp

main.cpp

• Hi!

function.cpp
* Only seed once. If @getRandomNumber is called multiple times in 1 second, it will return the same number every time. @getRandomNumber returns predictable values.
* Line 16, 17, 30, 52: Uniform intialization
* Don't pass 32767 to @std::cin.ignore. Read to relative lesson or the documentation.
* Line 56, 58: Double comparison of @check to 'y' and 'Y'
* Line 61: Don't use @system. Your code won't work on operating systems other than Windows. If you have to use @system, use @std::system.

main.cpp
* Magic number: 7
* Use ++prefix unless you need postfix++
* @main is missing a return-statement

• boteomap2

Thank you so much!

• Gaboon

I was just wondering, heres the two parts of code I changed for the first question:

I changed the calculateAndPrintHeight to return an int, height, then used that for my height, as well as time output, is this a proper way to do it? Thanks

• Why would you cast to an int? Height should be a floating point number.

• Gaboon

True, true, I was doing it late at night, I corrected that mistake, but it is good otherwise?

• Alex A

Hi again all,

I don't know why this keeps happening but once again for the first question I have got a different solution but it works... can someone point out tow things to me 1) what I can improve/correct and 2) why the solution given is specifically more advisable than mine? thanks in advance

• * Don't pass 32767 to @std::cin.ignore. Pass @std::numeric_limits<std::streamsize>::max()
* Use double literals when calculating with doubles (2.0 instead of 2)
* Line 43: Mixing variables in a for-loop makes it harder to understand

When you want to repeat code for an unknown amount of time, use a while- or do-while-loop. If you know how often your code is supposed to run, use a for-loop. There are exceptions, but this is a good rule most of the time.

• Ajalle Perfej

Any comments on this solution? It may have less flexibility for further development because I've eliminated one of the functions, but for this specific purpose it seems to work fine.

• * Initialize your variables with uniform initialization
* Use double numbers when calculating with doubles (2.0 instead of 2)
* You're using the same name style for variables and functions. This can lead to confusion.

• Clapfish

Hi Alex / nascardriver!

Since my code is a bit different to the solution, I thought I'd offer it up for any feedback (which would be much appreciated if you have time):

Many thanks and best wishes!

• Hi Clapfish!

* Line 8, 9, 36, 60: Initialize your variables with uniform initialization to a specific (0) value. chars can be initialized to 0, '\0', '\x00'.
* Line 20, 25: Don't pass 32767 to @std::cin.ignore. Pass @std::numeric_limits<std::streamsize>::max()
* Magic numbers: 1, 7, 100
* Line 78, 70: Double comparison of @c to 'y'
* Sorting your includes alphabetically can help you to see if you've already included something. For when you get errors and don't know why.

Structure looks good, keep it up!

• Clapfish

Hi nascardriver!

Many thanks for your useful feedback. I wasn't entirely sure what you meant by "* Line 78, 70: Double comparison of @c to 'y'" though (and I assume you meant lines 68 and 70). Could you elaborate?

I did, however, re-write that function to see if you'd approve of the alternative, along with the other suggested alterations (further criticism / feedback would again be much appreciated!):

• > I wasn't entirely sure what you meant by [...]
Yep, I meant 68, not 78.
First, you compared @c to 'y' in line 68. If @c is 'y', the loop stops and @c is compared to 'y' again in line 70. You compared a variable twice to the same value without the variable changing in-between. This is unnecessary. For chars the performance impact is negligible, but it's still there. Your new solution doesn't have this problem.

> further criticism / feedback would again be much appreciated
* Line 9, 10 still use direct initialization
* I can't say this with certainty, but it looks like you're using the same name style for both variable and functions. This can lead to confusion.

• Clapfish

Thanks again nascardriver!

You're right, I'd missed (and/or not read your line numbers closely enough) the getRandomInt() function initialisations - I assume this is the correct solution:

And thanks for the explanation of the char comparison; I want to focus on fostering optimal efficiency habits from the start, so that's always important to me! Good to know my new solution is better (I prefer it in general, too).

I'm really interested in your final comment though - how did you come to that conclusion looking through this code, and what would you personally change (and why)? I've been using the following conventions so far:

- functionName()
- variable_name

Cheers!

• You didn't have any variable names composed of two words, that's why I couldn't be certain.
I expected you to use

- functionName
- variableName

> what would you personally change
I use (a modified version of) hungarian notation

> (and why)?
Because there's no chance of a mix-up happening

• Clapfish

I'll look it up! Thank you again for all your feedback.

• Jason

why does mine keep on printing "you have 5 tries left"
or "you have 6 tries left"

• Jason

My new version

• * Use "else if"
* Use @std::srand, @std::rand and @std::time
* Pass nullptr to @std::time
* Line 37, 39: Uniform initialization
* Magic numbers

• dsg vrghsefggf aegfr

yes, because i skipped multiple lessons

• dsg vrghsefggf aegfr

This does what it is supposed to do, with winning, 7 guesses, etc.
but it repeatedly prints "you have 6 guesses left"
or "you have 5 guesses left"
whats wrong?
(don't mind the bottom, I was too lazy to think of a for loop)

• Hi there!

You set @guesses to 7 every time you call @guesses. Notice the duplicate name here? Change you naming convention to avoid confusion.
Initialize your variables with uniform initialization.
Use a loop. Even without a loop you'd only need one variable to store the guess.
Use "else if".
Line 15, 20: Duplicate code.
Seed @std::rand.

I advice you to post your quiz solutions more often, because if you continue writing code like this you'll get into bad habits.

• jaasdsfae rgegraewr

thanks! I improved it a little.
Can I do this without the global variable?
(the code you see here may be a little different from my actual code)

• Your code doesn't compile. Line 9, 19.
You still have a duplicate name.
Yes you can do it without a global variable.
Initialize your variables with uniform initialization.
Line 35 is still using magic numbers.
Line 25 is unnecessary.
The loop in @main doesn't terminate once the correct answer was given.
You're still using @rand (and now also @srand and @time) and passing a wrong type to @time. Use their @std::* counterparts.

I feel like you skipped several lessons. If so, read them, you'll have a hard time without the basics. If you have read the preceding lessons, try to fix your code as good as you can, post a version that compiles, and I'll again point out what's wrong, assuming you fix what I wrote so far.

• jaasdsfae rgegraewr

some of these bad habits i get from sololearn.com

• C++guy

My attempt for quiz 2. A tough one. Everything works perfectly fine and fulfill all the conditions. I was just wondering if all these loops weren't misleading for someone who didn't make the code (since basically all my program is condensed into a single function).

• * Initialize your variables with uniform initialization
* Don't pass 32767 to @std::cin.ignore. Pass @std::numeric_limits<std::streamsize>::max()
* Re-read lessons 5.5, 5.6 and 5.7. Line 29 and 50 don't make sense. They do the job, but they're the wrong choice and wrong implementation.
* Line 41: Unnecessary comparison
* Magic numbers: 1, 7, 100. Declare constants
* Line 60: Unnecessary comparison
* You're using the same name style for variables and functions. This can lead to confusion

• C++guy

* Uniform initialization done
* Done
* I got it I think, tell me if yes.
* Comparisons checked.
* No more magic numbers.

• > Uniform initialization done
Line 7, 9, 11, 19, 27, 34, 57

> I got it I think, tell me if yes
You did!

> Comparisons checked
Line 37, 75: Double comparison to 'y'. You can avoid this by returning a bool from @tryAgain

> No more magic numbers
Line 9. Pass @minNumber and @maxNumber to @randomNumber.
Declaring those and @numberTriesMax const makes it easier for a reader to understand your code. The way it is set up now could cause a reader (who has partially read your code) to think that those values are variable and might be set by the end-user via console input for example.

What I forgot before:
* Line 57: Use ++prefix unless you need postfix++

What you did now:
* Line 77: You don't need to manually return from a void. return in voids is only used to prematurely exit the function.

• C++guy

> Checked

> Comparisons re-checked and added bool userSaysYes{tryAgain() == 'y'}

> No more magic numbers.

> I deleted return in the void function.

Here I am making a lot of mistakes on a 80 lines code, how nightmarish it must be to check a whole massive game like GTA V. Thanks for the correction.

• > added bool userSaysYes{tryAgain() == 'y'}
That doesn't get rid of the double comparison. Also, you don't need two char variables in @tryAgain.

> how nightmarish it must be to check a whole massive game like GTA V
The mistakes you're making are beginner mistakes everybody makes. If you've been coding for a long time, there shouldn't be a need to check the code after writing it. Unless there is a bug of course.

• hoon

I tried quiz 1 and it worked
I want to know if there is anything fixed
[code]
#include "pch.h"
#include <iostream>
#include "constants.h"

// gets initial height from user and returns it
double getInitialHeight()
{
std::cout << "Enter the height of the tower in meters: ";
double initialHeight;
std::cin >> initialHeight;
return initialHeight;
}

// Returns height from ground after "secondsPassed" seconds
double calculateHeight(double initialHeight, int secondsPassed)
{
// Using formula: [ s = u * t + (a * t^2) / 2 ], here u(initial velocity) = 0
double distanceFallen = (myConstants::gravity * secondsPassed * secondsPassed) / 2;
double currentHeight = initialHeight - distanceFallen;

return currentHeight;
}

// Prints height every second till ball has reached the ground
void printHeight(double height, int secondsPassed)
{
if (height > 0.0)
{
std::cout << "At " << secondsPassed << " seconds, the ball is at height:\t" << height <<
" meters\n";
}
else
std::cout << "At " << secondsPassed << " seconds, the ball is on the ground.\n";
}

void calculateAndPrintHeight(double initialHeight)
{
int secondsPassed = 0;
while (true)
{
double height = calculateHeight(initialHeight, secondsPassed);
printHeight(height, secondsPassed);
if (height <= 0)
break;
secondsPassed++;
}
}

int main()
{
const double initialHeight = getInitialHeight();

calculateAndPrintHeight(initialHeight);

return 0;
}
[/cold]

• * Use double numbers when calculating with doubles (2.0 instead of 2 etc.)
* Initialize your variables with uniform initialization
* Use ++prefix unless you need postfix++
* If you're using curly brackets for one part of an if-statement, use them for all parts

• ChilaKiller

My attempt at quiz 2 (the result its just what the quiz asked, but i feel there are many bad practices and senseless lines of code, i would appreciate corrections and/or feedback)

• Hi ChilaKiller!

* Inconsistent formatting. Use the auto-formatting feature of your editor.
* Initialize your variables with uniform initialization
* @getRandomNumber returns the same number every time it is called in the same second. Declare @mersenne static.
* Magic numbers: 1, 100, 7, 32767
* @userNumber should be declared inside the loop.
* Use a for-loop
* Line 65: Initialize to 0, '\0' or '\x00'
* Line 70, 72: Double comparison of @ch to 'y'

• George

So here is my code for the 2nd to last solution of this quiz.

Other than small mistakes (like 7 being a magic number), the one in my interest now is the fact that the attempt counter takes two "guess" calls to get incremented! How do I fix this?

• Hi George!

* Initialize your variables with uniform initialization
* @mersenneRNG will return the same number every time it's called in the same second. Declare @mersenne static so it's only initialized once.
* Line 28: Unreachable code

Good code structure.

> counter takes two "guess" calls to get incremented!
You're calling @guess twice (Line 57, 58). Remove line 57.

• George

Hi nascardriver! Thanks for the response!
Oof, I forgot that function calls as conditional statements are still function calls. Thanks for pointing it out!
As for what you said about uniform initialization, I thought I had initialized all my variables that way...? Which one escaped me?

• > Which one escaped me?
Line 9, 12, 35

Line 18 should be initialized to 0, '\0' or '\x00'

• George

Oh, I straight up copied the mersenne PRNG from the RNG chapter, so that's why. No excuse for line 35 tho, I guess.

• For quiz 2

• Hi!

* void-functions don't need a return statement at the end
* Line 9, 11, 14, 41: Uniform initialization
* Use a do-while-loop to avoid the duplicate call to @playGame
* Use @std::numeric_limits<std::streamsize>::max() instead of 32767
* @std::srand should only be called once. You're calling it every time @playGame is called

• Thanks nascardriver

• Gizmo

I'm having an issue where my RNG generates the same number every time I run it. This is the section of code that runs my RNG:

Every time I run it, it generates the number 57. I'm thinking that it keeps generating the same seed over and over again. Am I doing something wrong, or is there an issue with std::random_device? If it is something with std::random_device, should I use std::srand(static_cast<unsigned int>(std::time(nullptr))) instead? (#including the appropriate headers, of course.)

• Hi Gizmo!

Does this code produce the same output every time you run it?

If so, your system/compiler is using a deterministic rng for @std::random_device. This means that it generates the same sequence every time.
You can seed the mersenne twister with other values. Preferably a value generated by the hardware to get it as random as possible. The easier solution being the system time.

@Alex
It might be worth mentioning that @std::random_device isn't guaranteed to be seeded properly. Checking @std::random_device::entropy should work, I haven't tried it though.

• Alex

It appears that std::random_device::entropy isn't reliable either. I've updated lesson 5.9 to avoid std::random_device and seed using the clock instead, at least for now. I've also flagged the article for further investigation to see if I can find a more robust solution that isn't overly complicated.

• Gizmo

@Alex I tried the updated seed for the Mersenne Twister Algorithm in your example in lesson 5.9. It works, but I had to tweak a few things to get it to compile.

1.) I had to add "std::" in front of time(nullptr) to make it std::time(nullptr).
2.) I had to #include <ctime>.

Other than these two things, it works like a charm. I get a different random number each time. Thank you @Alex and @nascardriver for solving my problem.

• Alex

Thanks for sharing that it worked for you. I've updated the sample code in lesson 5.9 in accordance with your modifications.

• Clapfish

Hi Alex!

Just to reiterate this point (since I was about to write a new comment until I saw this had already been covered here), I wondered the same as Gizmo.

Initially I used the std::time(nullptr) seed in my RNG code, since that was covered well in lesson 5.9. When I checked your solution to the quiz, I was surprised to see the std::random_device method (which hadn't yet been covered in the lessons). Naturally I tried using your solution instead, and, like Gizmo, found that it generates the same sequence of numbers each time (starting with 57!).

As such, like nascardriver mentioned, I would suggest that either random_device is covered in the lessons prior to this quiz, or the quiz solution be amended to use only what has been previously covered (such as std::time(nullptr)) to avoid confusion.

Best wishes!

• Alex

My bad. When I migrated away from using std::random_device, I forgot to update the quiz solutions accordingly. I've now updated them, and all traces of std::random_device have been abolished (hopefully).

• DAT

Quiz 2:
#include"stdafx.h"
#include<cstdlib>
#include<iostream>
#include<ctime>

void playGame()
{
std::srand(static_cast<unsigned int>(std::time(nullptr)));

int randomNumber = 1 + (std::rand() % 100);

for (int i = 1; i <= 7; i++)
{
std::cout << "Guess #" << i << ": ";
int number;
std::cin >> number;
if(std::cin.fail())
{
std::cin.clear();
std::cin.ignore(32767, '\n');
}
if (number == randomNumber)
{
std::cout << "Correct! You win!" << "\n";
return ;
}
else if (number < randomNumber)
std::cout << "Your guess is too low" << "\n";
else
std::cout << "Your guess is too high" << "\n";
}
std::cout << "Sorry, you lose. The correct number was " << randomNumber << "\n";
return ;
}

void playAgain()
{
playGame();
while (true)
{
std::cout << "Would you like to play again (y/n)? ";
char play_again;
std::cin >> play_again;
std::cin.ignore(32767, '\n');
if (play_again == 'y')
playGame();
else if (play_again == 'n')
return;
}
}

int main()
{
std::cout << "Let's play a game. ";
std::cout << "I'm thinking of a number. You have 7 tries to guess what it is" << "\n";
playAgain();

return 0;

}

• Kio

For Quiz 2.

It's not the best code, but some alternative work to @Alex

@nascardriver hit me with improvements :) Much appreciated. And thank you for your work and comments :)

• Hi Kio!

* Initialize your variables with uniform initialization
* Use @std::numeric_limits<std::streamsize>::max() instead of 32767
* The random device and mersenne twister should be static
* @validateInput: Unused parameter
* Use @std::size_t instead of @size_t. Since you're not using @i for a function that requires an @std::size_t, use an int.
* Use ++prefix unless you need postfix++
* Line 76: Use while (true)
* @main: Use a do-while-loop to prevent the duplicate call to @playGame

• Kio

You are the machine :)

Can you provide an example of "do - while" loop for my current example, I'm bit tired so, any boost would help?

• Kio

Nice alternative to Quiz 1. I've just pasted code that was modified

• Terra'Navis

If anyone could advise I was wondering if someone could tell me if there is anything wrong or poorly made about my version of quiz 2a), also am i committing any bad practices.

• Hi Terra!

* Initialize your variables with uniform initialization
* Avoid abbreviations unless their meaning is obvious
* Use ++prefix unless you need postfix++
* @getRandomNumber shouldn't create a new mersenne twister every time it is called.
* Line 53: Unnecessary. You only need to return from non-void functions.
* Line 65: Unnecessary
* Line 75 should be merged with @repeatPlay to avoid to duplicate call in line 75 and 64

• Terra'Navis

Hi thank you for your comments they are very useful, just a few questions on some of them if you have the time:
*am i not using uniform initialisation for every variable except uChoice?, also why is uniform initialisation important?
*why is it better to use ++prefix over postfix++
*"line 75 should be merged with @repeatPlay", why is the duplicate call bad? also is this a good solution:

• > am i not using uniform initialisation for every variable except uChoice?
Line 19, 20, 21, 23, 61.
Line 35 and 36 should be one line.

> why is uniform initialisation important?
It disallows implicit casts which would go unnoticed with other initializations and could cause undesired behavior. There are more reasons, but this is why I use it.

> why is it better to use ++prefix over postfix++
If it wasn't for compiler optimization, ++prefix would be faster, because postfix++ needs to store the unmodified value of the variable

> why is the duplicate call bad?
Duplicates are always bad, because they mean extra work when updating something.
Imagine the call wouldn't be as simple as it is now. If there were a lot of arguments and maybe calculations you'd need to perform before you call @playGame. Those would be needed in both places and they'd always need to be the same. Why do it twice when you can do it once?

> is this a better solution
It is. Try using a do-while-loop to avoid the comparison in line 5 on the first run, because it will always be true.

• Terra'Navis

• Sam

My solutions, any feedback is welcome:

Question 1:

Question 2:

• Hi Sam!

General
* Initialize your variables with uniform initialization

1
* Inconsistent variable name style
* Line 5: Use -= for better readability
* Use double literals when calculating with doubles (2.0 instead of 2)
* If @initialHeight is 0.0, no message will be printed

2
* @PlayHiLo: Unused return value
* @main: Missing return-statement
* Don't use @exit unless there is not way around it. If you have to use it, use @std::exit
* A do-while-loop is better suited in @main to avoid the duplicate call to @PlayHiLo (Line 54, 63)

• Sam

Thank you so much!

I have one more question specifically in regards to

I understand that the seed generation should only be done once in a program, but currently it seems to occur every time PlayHiLo is called. Is this an issue, and if so, do you have any suggestions on how to improve there?

• Declare it static (Lesson 4.3)

• Dr.Abbas

Hello
I honestly don't know if saying thank you is enough but, THANK YOU!. I appreciate what you are doing.

well i tried to experiment with somethings while working the quiz.
1) i was wondering if i could print the time?. i tried cout with & without staticcast to int

2) can i make a function that has >2 parameters but will still function if i pass 1 without saying "not if arguments"

3) if 2 is possible can i can make the function do different statements according to which arguments i pass

4) can a function return more than one value at the same time

5) if 4 is possible can it return different types at the same time, i.e (returning int to an int variable but can also return string to string variable)

my code works as i intended but i'm sure there is many things wrong with it and my style.
so please show me whats wrong and how i can make it better or shorter or more functional.

• Hi Dr. Abbas!

1. For everything related to time, @std::chrono is your friend
2,3. Lesson 7.6 and 7.7
4,5. Lesson 4.7 or 6.10, 6.11, 7.3 and 7.4

References
std::chrono::system_clock::now - http://www.cplusplus.com/reference/chrono/system_clock/now/

* @std::srand should only be called once.
* Initialize your variables with uniform initialization. Preferably to a specific value.
* @compare: Missing return value
* Line 70: Unnecessary comparison
* Line 93: Unnecessary
* A bool is false/true
* @main: Missing return statement
* Line 121: Without code, there's nothing I can tell you

• Leo Prast

I am sure somebody must have noticed and remarked on it (apologies if so), but technically, should I not check and handle std::cin fail state before I ask for the number as well as after?

It seems the current standard answer only checks afterwards.

Sure, it would only result in a double line of input request, and in this program a failure should not be possible at that point, but that may not be guaranteed when reusing the code.

• Alex

Yes, if you're writing a reusable module, it would be good practice to ensure all of the streams are in a good state before you try to use them, just in case.

I don't tend to do that in most of these programs for conciseness reasons.

• Josh

When I tried doing the first program in the quiz, it keeps telling me there is no file in directory even though I have the file with the same name as you. Please help. Thank you

• KitsuekiDC

Here's what I came up with. It's a little different than the shown solution (and lacks sufficient commenting) but it the first solution I thought of.