Search

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 for each 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!

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:

In your main code file:

Show Solution

2a) 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
Your guess is too high.
Guess #2: 32
Your guess is too low.
Guess #3: 54
Your guess is too high.
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
Your guess is too high.
Guess #2: 32
Your guess is too low.
Guess #3: 54
Your guess is too high.
Guess #4: 51
Your guess is too high.
Guess #5: 36
Your guess is too low.
Guess #6: 45
Your guess is too low.
Guess #7: 48
Your guess is too low.
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:
* If your compiler is C++11 capable, use the Mersenne Twister algorithm from chapter 5.9 -- Random number generation to pick a random number.
* If your compiler is not C++11 capable, you can use rand() (also presented in 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.

Show Solution

2b) 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

599 comments to 5.x — Chapter 5 comprehensive quiz

  • learning

    Hey, this is my solution for 2a & 2b. Is there anything which I can do better? Thanks in advance!

    • - Initialize your variables with brace initializers.
      - Limit your lines to 80 characters in length for better readability on small displays.
      - Line 61, 62: Duplicate comparison.
      - Line 62: `return (cSelection == 'y');`.
      - Line 78+: Should be a do-while loop.
      - If your program prints anything, the last thing it prints should be a line feed.

  • Avijit Pandey

    Here's my approach to the solution for the hi-lo game. I wanted to ask for feedback, like what mistakes I've made that I'm not noticing, or bad practices that I'm still used to, or if I'm doing something that can be done in 2 lines, in 10 lines.

    • Hello!

      - Line 18, 20: Duplicate comparison.
      - Avoid abbreviations. Use descriptive variable names.
      - `noOfTries` should be `constexpr`, because it's compile-time constant.
      - Line 25: Magic string: 7
      - Line 39 always compares true.
      - Line 42 is unreachable.
      - `getRandomNumber` is unused and should be removed (Or re-implemented by using the mersenne twister).
      - Line 51, 52: Initialize with brace initializers.

      • Avijit Pandey

        Thanks for the feedback, much appreciated!
        I'm new to programming so I didn't completely understand these two points, can you explain in a little more detail please?
        -Line 39 always compares true.
        -Line 18, 20: Duplicate comparison.

        • > always compares true
          You already know that `userGuess` is not less than or equal to `answer` because of the two preceding checks. The only relation between the numbers that's left is that `userGuess` is larger than `answer`.

          > Duplicate comparison
          You're comparing `choice` to 'y' twice without modifying `choice` in-between. The two comparisons will yield the same result. That's a waste of processing power (Negligible for `char`, but it can be a lot for other types).
          You would use a `while (true)` loop and `switch` inside the loop. When it's `y` or `n`, you return from inside the loop.

  • Jan

    Hello,

    could you give me some feedback on my code (2a).
    I'm not sure if I took the right approach here by using the mersenne algorithm with the static keyword in an own function instead of the main function.

    (main.cpp)

    • - Don't pass 32767 to @std::cin.ignore. Pass @std::numeric_limits<std::streamsize>::max().
      - Don't use `std::system`, it won't work on other operating systems.
      - Line 31: Magic string: 7.
      - `maxGuesses` should be `constexpr`.
      - Line 50 always compares true.
      - Line 38: You know how often the loop will run. Use a `for`-loop.
      - Initialize your variables with brace initializers.

      > I'm not sure if I took the right approach here
      It's fine.

  • potterman28wxcv

    Hello, I wrote the answer to 2a) in a different style than the one you used. I would be curious to hear your thoughts about it. Thanks a lot for these very in-depth tutorials!

    • Hello,

      - Initialize your variables with brace initializers.
      - Line 69: Use `while (askPlayAgain());` and remove `playAgain`.
      - You're using the same name style for variables and functions, this can lead to confusion.
      - Magic number: 20000. Pass `std::numeric_limits<std::streamsize>::max()`.
      - Line 59, 61: Duplicate comparison of `play` to 'y'.
      - Line 55 will fail if the stream is in a erroneous state. You need to `std::cin.clear()` first.
      - Inconsistent formatting. Use you're editor's auto-formatting feature.
      - Inconsistent namespace naming (lower case vs upper case).
      - Use --prefix unless you need postfix--.

      Good use of `constexpr` and no recursion!

      • potterman28wxcv

        Hello, thanks for your feedback!

        > - Use --prefix unless you need postfix--.

        I indeed noticed in the rest of the tutorial that this form was privileged.

        Is there any particular reason for this? Or is it more of a coding style?

        • If you don't remember the differences, re-read lesson 5.4.
          Postfix-- has to create a copy of the variable, which takes time and memory.
          --Prefix modifies the variable in-place and doesn't need any copies.

        • Alex

          I'm in the process of revamping all of the lessons and bringing them up to the latest best practices, as well as integrating new material. This is taking a while, so the later lessons haven't been retrofit yet. If you see an inconsistency, that's why.

  • ratlab

    How can I improve this?

    (Main.cpp)

    (InputHandler.h)

    (InputHandler.cpp)

    (GameLogic.h)

    (GameLogic.cpp)

    (Randomizer.h)

    • - Initialize your variables with brace initializers.
      - Limit your lines to 80 characters in length for better readability on small displays.
      - If you use something, include its header. <utility> for `std::pair` in "main.cpp".
      - `while` wants a `bool`. Use `while (true)`.
      - `getNumber`, `getTries` and `getRange` are mostly duplicate code and should be merged.
      - GameLogic.cpp:13+ should be a `switch`.

      You're one of the very few who seeded their rng only once and didn't use magic numbers, good job!

  • Sam

    Here is my updated solution with a struct and various other fixes (Question #2)

  • Sam

    Here is my solution for Question #2 with full error checking/restart module. Any feedback is appreciated (nascardriver ;))

    I feel like this can definitely be refactored a ton, and the entire logic/structure of the program can be improved/re-written.

    • - Initialize your variables with brace initializers.
      - Use std::time instead of its global-namespaced counterpart.
      - `streammax` should be constexpr.
      - `std::tolower` doesn't modify its argument. You're not detecting an upper case 'N'.
      - `playAgain` should return a `bool`.
      - Put line breaks at the end of lines, not the beginning.
      - Line 52, 56: Repetition. Use the conditional operator to print "lives" or "life".
      - Magic number: 1, 100
      - Use braces for initialization only. Using them for assignments looks like initializer lists (Covered later).
      - `main`: Missing return statement.

  • Joe

    Hi @nascardriver if you're reading this could you review my code to please, this is what I had for the solution

    (Main.cpp)

    (HiLoGame.h)

    (HiLoGame.cpp)

    • Hi Joe!

      - Main.cpp:12: Initialize your variables with brace initializers.
      - Main.cpp:25, 27: Duplicate comparison. Move line 19-27 into its own function that returns a bool. Use that function as `main`'s loop's condition.
      - Use `constexpr` for compile-time constants.
      - HiLoGame.cpp:11: Magic number: 7.
      - `struct`s shouldn't contain functions. You'll learn about `class` later. It's the same thing, but classes are assumed to provide operations on their data. `struct` is usually used for storage alone. It's fine for now.
      - HiLoGame.cpp:29-35 should be checked before asking the user for another input.
      - HiLoGame.cpp:36-41: Should be moved to HiLoGame.cpp:51 and the condition removed.
      - `HiLoGame::checkStatus` would be better implemented as returning a `bool` and without `isDone`.

Leave a Comment

Put all code inside code tags: [code]your code here[/code]