Search

11.x — Chapter 11 comprehensive quiz

Summary

Inheritance allows us to model an is-a relationship between two objects. The object being inherited from is called the parent class, base class, or superclass. The object doing the inheriting is called the child class, derived class, or subclass.

When a derived class inherits from a base class, the derived class acquires all of the members of the base class.

When a derived class is constructed, the base portion of the class is constructed first, and then the derived portion is constructed. In more detail:

  1. Memory for the derived class is set aside (enough for both the base and derived portions).
  2. The appropriate derived class constructor is called.
  3. The base class object is constructed first using the appropriate base class constructor. If no base class constructor is specified, the default constructor will be used.
  4. The initialization list of the derived class initializes members of the derived class.
  5. The body of the derived class constructor executes.
  6. Control is returned to the caller.

Destruction happens in the opposite order, from most-derived to most-base class.

C++ has 3 access specifiers: public, private, and protected. The protected access specifier allows the class the member belongs to, friends, and derived classes to access the protected member, but not the public.

Classes can inherit from another class publicly, privately, or protectedly. Classes almost always inherit publicly.

Here’s a table of all of the access specifier and inheritance types combinations:

Access specifier in base class Access specifier when inherited publicly Access specifier when inherited privately Access specifier when inherited protectedly
Public Public Private Protected
Private Inaccessible Inaccessible Inaccessible
Protected Protected Private Protected

Derived classes can add new functions, change the way functions that exist in the base class work in the derived class, change an inherited member’s access level, or hide functionality.

Multiple inheritance enables a derived class to inherit members from more than one parent. You should avoid multiple inheritance as much as possible.

Quiz Time

1) For each of the following programs, determine what they output, or if they would not compile, indicate why. This exercise is meant to be done by inspection, so do not compile these (otherwise the answers are trivial).

1a)

Show Solution

1b) Hint: Local variables are destroyed in the opposite order of definition.

Show Solution

1c)

Show Solution

1d)

Show Solution

1e)

Show Solution

2a) Write an Apple class and a Banana class that are derived from a common Fruit class. Fruit should have two members: a name, and a color.

The following program should run:

And produce the result:

My apple is red.
My banana is yellow.

Show Solution

2b) Add a new class to the previous program called GrannySmith that inherits from Apple.

The following program should run:

And produce the result:

My apple is red.
My banana is yellow.
My granny smith apple is green.

Show Solution

3) Challenge time! The following quiz question is more difficult and lengthy. We're going to write a simple game where you fight monsters. The goal of the game is to collect as much gold as you can before you die or get to level 20.

Our program is going to consist of 3 classes: A Creature class, a Player class, and a Monster class. Player and Monster both inherit from Creature.

3a) First create the Creature class. Creatures have 5 attributes: A name (std::string), a symbol (a char), an amount of health (int), the amount of damage they do per attack (int), and the amount of gold they are carrying (int). Implement these as class members. Write a full set of getters (a get function for each member). Add three other functions: void reduceHealth(int) reduces the Creature's health by an integer amount. bool isDead() returns true when the Creature's health is 0 or less. void addGold(int) adds gold to the Creature.

The following program should run:

And produce the result:

The orc has 3 health and is carrying 15 gold.

Show Solution

3b) Now we're going to create the Player class. The Player class inherits from Creature. Player has one additional member, the player's level, which starts at 1. The player has a custom name (entered by the user), uses symbol '@', has 10 health, does 1 damage to start, and has no gold. Write a function called levelUp() that increases the player's level and damage by 1. Also write a getter for the level member. Finally, write a function called hasWon() that returns true if the player has reached level 20.

Write a new main() function that asks the user for their name and produces the output as follows:

Enter your name: Alex
Welcome, Alex.
You have 10 health and are carrying 0 gold.

Show Solution

3c) Next up is the Monster class. Monster also inherits from Creature. Monsters have no non-inherited member variables.

First, write an empty Monster class inheriting from Creature, and then add an enum inside the Monster class named Type that contains enumerators for the 3 monsters that we'll have in this game: DRAGON, ORC, and SLIME (you'll also want a MAX_TYPES enumerator, as that will come in handy in a bit).

Show Solution

3d) Each Monster type will have a different name, symbol, starting health, gold, and damage. Here is a table of stats for each monster Type:

Type Name Symbol Health Damage Gold
DRAGON dragon D 20 4 100
ORC orc o 4 2 25
SLIME slime s 1 1 10

Next step is to write a Monster constructor, so we can create monsters. The Monster constructor should take a Type enum as a parameter, and then create a Monster with the appropriate stats for that kind of monster.

There are a number of different ways to implement this (some better, some worse). However in this case, because all of our monster attributes are predefined (not random), we'll use a lookup table. A lookup table is an array that holds all of the predefined attributes. We can use the lookup table to look up the attributes for a given monster as needed.

So how do we implement this lookup table? It's not hard. We just need two things. First, we need an array that contains an element for each monster Type. Each array element will contain a struct that contains all of the predefined attribute values for that Type of Monster.

Since all the properties of monsters are known at compile-time, we can declare make the lookup a static constexpr member of Monster. The definition of the lookup table is as follows:

A reminder

If you get an error in the declaration of monsterData, make sure your compiler is C++17 capable by trying to compiling the example in lesson 0.12 -- Configuring your compiler: Choosing a language standard.

Now we can index this array to lookup any values we need! For example, to get a Dragon's gold, we can access monsterData[Type::DRAGON].gold.

Use this lookup table to implement your constructor:

The following program should compile:

and print:

A orc (o) was created.

Show Solution

3e) Finally, add a static function to Monster named getRandomMonster(). This function should pick a random number from 0 to MAX_TYPES-1 and return a monster (by value) with that Type (you'll need to static_cast the int to a Type to pass it to the Monster constructor).

Lesson 5.9 -- Random number generation contains code you can use to pick a random number.

The following main function should run:

The results of this program should be randomized.

Show Solution

3f) We're finally set to write our game logic!

Here are the rules for the game:

  • The player encounters one randomly generated monster at a time.
  • For each monster, the player has two choices: (R)un or (F)ight.
  • If the player decides to Run, they have a 50% chance of escaping.
  • If the player escapes, they move to the next encounter with no ill effects.
  • If the player does not escape, the monster gets a free attack, and the player chooses their next action.
  • If the player chooses to fight, the player attacks first. The monster's health is reduced by the player's damage.
  • If the monster dies, the player takes any gold the monster is carrying. The player also levels up, increasing their level and damage by 1.
  • If the monster does not die, the monster attacks the player back. The player's health is reduced by the monster's damage.
  • The game ends when the player has died (loss) or reached level 20 (win)
  • If the player dies, the game should tell the player what level they were and how much gold they had.
  • If the player wins, the game should tell the player they won, and how much gold they had

Here's a sample game session:

Enter your name: Alex
Welcome, Alex
You have encountered a slime (s).
(R)un or (F)ight: f
You hit the slime for 1 damage.
You killed the slime.
You are now level 2.
You found 10 gold.
You have encountered a dragon (D).
(R)un or (F)ight: r
You failed to flee.
The dragon hit you for 4 damage.
(R)un or (F)ight: r
You successfully fled.
You have encountered a orc (o).
(R)un or (F)ight: f
You hit the orc for 2 damage.
The orc hit you for 2 damage.
(R)un or (F)ight: f
You hit the orc for 2 damage.
You killed the orc.
You are now level 3.
You found 25 gold.
You have encountered a dragon (D).
(R)un or (F)ight: r
You failed to flee.
The dragon hit you for 4 damage.
You died at level 3 and with 35 gold.
Too bad you can't take it with you!

Hint: Create 4 functions:

  1. The main() function should handle game setup (creating the Player) and the main game loop.
  2. fightMonster() handles the fight between the Player and a single Monster, including asking the player what they want to do, handling the run or fight cases.
  3. attackMonster() handles the player attacking the monster, including leveling up.
  4. attackPlayer() handles the monster attacking the player.

Show Solution


12.1 -- Pointers and references to the base class of derived objects
Index
11.7 -- Multiple inheritance

310 comments to 11.x — Chapter 11 comprehensive quiz

  • sito

    hello! could you give an example of how you would build a normal array? for this qui<? I have tried doing it the way you should in the quiz but with a normal array but i can't get it to work. thanks
    Something worth mentioning is that I didn't make the array static and const. In order for this to work in the qquiz does the array need to be const and static?

    • nascardriver

      Change the array definition to

      The rest stays the same.

      • Alan

        I got the same problem, but i don't get what is wrong with the "std::array" version. Is there something in the definition of "std::array" that doesn't allow it or it has something to do with the complier?

        • nascardriver

          There's nothing wrong with `std::array`. I don't know why @site wanted to use a built-in array. Do you have a problem with `std::array`?

  • sito

    Hello! i have some questions for quizz 3 d
    first, why can't you make a normal array like this? something like this MonsterData array[Monster::max_types]{{"dragon", "test"}}; I tried creating an array like that to use instead of the quiz suggestion but I couldn't get it to work. When debugging the program it exited with code 3 and I don't understand why it does that because from what i have found exiting with code 3 is related to memmory Also why do yu have so many brases when you make the array in the quiz suggestion?
    I also wonder why you make the array static? in my opinion there is no need to do it because you are later going to create the monster object and the monster object won't get destroyed until the program is done so why do this?
    thanks.

    • nascardriver

      > why can't you make a normal array like this?
      Normal arrays aren't as convenient as `std::array`. `std::array` has several member functions that make it easier to use and safer than built-in arrays.
      This quiz is totally possible with built-in arrays, you must be doing something else wrong.

      > why do yu have so many brases
      We explain this here https://www.learncpp.com/cpp-tutorial/6-15-an-introduction-to-stdarray/#struct

      > why you make the array static?
      If you don't make it static, every instance of the `Monster` class will get its own copy of `monsterData`. That's very wasteful. We only need one `monsterData` in the entire program.

  • kavin

    For quiz 2b) instead of adding extra protected class , i did like this.

    Is it ok to do this or using a protected class with a new constructor is a must ?

    • nascardriver

      You're now allowing the public to choose a name, which is not supposed to happen.

      "My orange is orange"
      But `kavin` is an apple.

      If you're ok with letting the public choose a name, then your solution is alright.

      • kavin

        Thanks for the clarification. I will make it a rule not to depend on the user/public to give correct values.
        And for quiz 3d) its mentioned,

        If we define the array outside the class, how could we access MonsterData since it has private access inside the class?

        • nascardriver

          Define `MonsterData` outside, but still declare it as a member inside.

          It doesn't matter if we defined members inside or outside of the class, they have access to other members.

  • Attila

    Hey Alex and Nascardriver,

    Could you please add in a lesson about circular dependency? I ran into it head-first with a practice project, and I would like to spare my fellow beginners from doing the same.

    • Alex

      It's referenced in several lessons, but I've added a to-do to cover it more explicitly as part of the ongoing site updates. Thanks for the suggestion!

  • Zhang

    Hello! I have a small question that why there is a "continue" in line 174 in the last code 3f?

    • nascardriver

      Without the `continue`, to code would keep running to line 178 and on, but that's not necessary, because that condition can never be true if we reached line 174.

  • Wayseeker

    Nascardriver,

    First, I can't thank you enough for the tutorials you have presented here.  They are generally very complete and clear, especially given that I come to learning C++ with basically NO training in coding or programming except for a tiny bit of self-training in Basic Programming back in the early 90's when I was a teenager.  

    My goal--eventually--is to create my own roguelike game, which I know is a long way down the line, as I have a lot to learn.  Quiz 3d here has given me my first real frustration (other than the usual that comes with learning coding).  It may suggest a possible change that would help your tutorial.

    I wrote my code, then tried to compile it, and I got errors.  After researching through the tutorials and online for awhile, I decided to just look at the solution.  I was immediately struck by "#include <string_view>", which I felt reasonably sure I'd never seen before.  

    Eventually, I was able to resolve the issue by searching for string_view in the comments and finding the comment by arcad on December 30, 2019 at 5:56 pm.  Setting my project on Visual Studio to C++17 standards helped me solve the problem, but I wouldn't have known to do this without referring to this comment.  Also, it appeared to be a discussion among people who are already familiar with std::string vs std::string_view, so, even though the code now compiles without error, I still don't understand why.

    In pursuit of this, I then searched for discussions of std::string_view in your tutorials, and all I found was this reference from lesson 6.8b: "C-style strings are used in a lot of old or low-level code, because they have a very small memory footprint. Modern code should favor the use std::string and std::string_view, as those provide safe and easy access to the string."

    My suggestion would be to either add a note about std::string_view to this quiz point, as you do with some other things here, or add some section prior in which you explain the difference between the two. For myself, at this point, I am still unclear what the difference between the two is, other than the fact that one works and one doesn't.

    All that said, thank you again for the exceptional gift you have provided for so many people here with this work.  It is my hope that this might help a bit to make it even better.

    Best,

    Wayseeker

    • nascardriver

      Hi!

      There's a lesson dedicated to `std::string_view`. If you've been around for a while, you might have read the chapter before the lesson was added. Check the overview regularly to see if new lessons were added, you don't need to read the "Updated" ones, their content is mainly the same as before.

      Unless you have a reason to use an old standard, you should always use the latest version (Currently C++17, soon C++20).

      When you're having issues with a standard function or type not working, cppreference is a great reference. When you open up the std::string_view reference, you'll see that it requires C++17 (green text). Until you learn about templates, most of the references will seem cryptic, but you should get the most important information from reading the descriptions. A lesson about using standard references is pending.

      We're aware of the `std::string` vs `std::string_view` issue in this lesson, which is caused by `constexpr`. We'll updated lessons that introduce new types to say whether or not they work with `constexpr` until we have a lesson that covers `constexpr` in detail. I added notes about `std::string_view` to the first example that uses it in this lesson.

      Most of the lessons, including this one, are Alex' work. I only started writing recently.

      Thanks a lot for your feedback! If there's anything else you think could be improved, please say so.

      • Wayseeker

        Thank you so much for the reply!  You are correct.  I've been working through the lessons since early October, so I missed both of the lessons you mentioned above as I went through them prior to the updates.  I will check that regularly as I move forward.  I am very impressed by both how clear and articulate these lessons all are and by how careful the authors are in maintaining it, updating it, and responding to questions and comments.  

        This is fine work.  Bravo!

        Thanks again.

    • Wayseeker

      I received an email letting me know that you replied, but I can't see it here.  Where might I find that?

      Thanks,

  • cnoob

    Here is my shot at the quiz, with one last question: Lets say I have class. In said class I have a local variable inside a static function. The variable is also explicitly declared as a static variable. Is the variable supposed to be accessible "globally", or still only if I call the function?
    Since the game is pretty hard,(if you are not lucky enough to catch a wave of slimes and be able the flee everything else on the first couple of levels you have no chance to win) I have added a possibility to play again after the player dies (or wins).

    • nascardriver

      - Member functions that don't modify their object should be `const`.
      - You're using `mersenne` in multiple places. Add a new class for random number generation.
      - Use comments for documentation. What do your return values mean?
      - Avoid recursion.
      - Line 217-220: Add a `reset` member function that calls all these functions. If you want to reset at several points, you'll forget to call something.

      > Is the variable supposed to be accessible "globally", or still only if I call the function?
      The variable is only accessible inside the function and possibly by callers of the function if the function returns the variable.

      • cnoob

        Thanks a lot! Ive applied recursion, because it seems to be the easiest way to handle the 3 possible outcomes of the fightMonster() function inside a while loop. (Ive added the comments for the sake of clarity as you suggested.) I think it is also quite straightforward and safe in this case. Here is the code:

        • nascardriver

          The documentation comments should be placed at the function that they document, not at a call to the function. With your updated code, a reader of `fightMonster` still doesn't know what the return value means until they find a place where you're using the function and wrote a comment.

          You have only 2 returns values, use a `bool` or an `enum`. An `int` might make a reader search for more return values.

          `RandNum::mersenne` should be private, you're not using it outside of the class.

          The recursion may have seemed like an easy solution, but it makes it very hard to follow the control flow of your program, as well as decreasing reusability. Make sure your understand the quiz's solution or someone else's solution that uses loops.

          • cnoob

            All right, I got rid of the recursions. fightMonster() handles the control flow by calling attackPlayer(), or attackMonster(). And indeed, main() is much more comprehensible like this, it almost reads like a normal text.
            I used nested loops though, I hope thats legit.

            • nascardriver

              That's looking a lot better, good job!

              The nested loops can be avoided by adding more functions.
              Line 152-155 and 218-225 and be reduced to 1 line each, that'll save you typing.

  • I keep getting two errors: first at constexpr (error message: "a constexpr must have a literal or const type)
    2nd error at the opening curly brace (error message: "a member of type "const std::array <Monster::MonsterData,3U>" cannot have an in-class initializer.
    Note that this error shows even though I copied the exact code from the lesson.

    • nascardriver

      Did you enable the latest standard in your compiler settings? You need at least C++17.
      Which compiler are you using?

      • cnoob

        Im getting the same error message in VS 2019, with the latest standard enabled. (It works though, if I change constexpr to const.)

        • cnoob

          O.K., I got it! In the solution you are using std::string_view in the MonsterData struct. Ive used std::string, thats why I got the error. Why does it have to be std::string_view btw? (I mean for this specific purpose. Why cant we use an std::string?)

          • Alex

            I was able to compile the example on Visual Studio 2017 and 2019 using both the C++17 and latest standards. So not sure what's going on here.

            A couple of thoughts:
            1) The examples were missing some string and string_view #includes. I've added them. See if that fixes the issue.
            2) In a prior update, nascardriver moved the initialization for monsterData into the class. If you move it back outside the class, do you still get the same error?

            std::string_view is more efficient than std::string when working with string literal data (std::string makes a copy, std::string_view doesn't).

            • cnoob

              I can initialize monsterData outside without any problem, I guess it doesnt even need to be static then.
              I only get the error if I try to initialize it inside the class AND I use std::string instead of std::string_view. I understand that it is not efficient, but why doesnt it work at all?
              At the same time, if I declare the array like this:

              Then it compiles with std::string.

              I suppose the array MUST be static or global because otherwise it doesnt get initialized before the constructor, right?
              It seems that std::string needs the declaration to be inline, while std::string_view needs it to be constexpr. Why is that?

          • nascardriver

            Yes that's right. In C++20 it might work with `std::string`, not sure. Before that, it can't work. `constexpr` is a compile-time value, but `std::string` uses dynamic allocation, a feature that requires the program to be running. `std::string_view` on the other hand is just a view at a string literal, it can be used at compile-time.

            You can initialize `monsterData` outside, because then you're not using `constexpr` anymore. If you were using `constexpr`, you'd have to initialize it inside.
            `static` `constexpr` member variables are `inline` by default, which allows you to initialize the member inside the class. Without `inline`, you're not allowed to initialize `static` members inside the class.

  • HurricaneHarry

    Greetings,

    Thanks for the tutorials again!
    But... I've hit a wall again. When I tried to do the third quiz I always get an error message, so I simply copy pasted in your solution. I get the exact same error there.

    Making it not static constexpr compiles but crashes when running at constructing:

    with the debug error:

    So far it only worked if I took the struct and array out of the class in some form.
    Just reread the static, const and container lessons, but still missing the forest for the trees it seems...
    What am I doing wrong?

    • nascardriver

      This looks like you have a user-provided destructor in `MonsterData`. The code in the solution compiles with

      If you need a destructor, you can't use a `constexpr` array. Define `monsterData` outside of the class or mark it `inline`.

      • HurricaneHarry

        Hi nascardriver,

        sorry for answering with such a delay. But a day after writing that comment my machine died. And getting a replacement around christmas and new year... easier said than done, especially if the parcel-service also loses your shipment on the first try...

        BTT
        I went for the definition outside of the class in the end, as explained in the earlier lessons, and that worked like a charm. But I did actually not write a destructor at all. (I even copy pasted in the provided solution to be shure)
        Is it possible it's a change from c++17? As the version of g++ delivered with Code::Blocks doesn't seem to be fully compatible with the '17 standard. So far I wanted to stay as true to the recommendations listed in the beginning of the tutorials as possible, but maybe it's time to update.

        best regards

        • nascardriver

          The code requires C++17. You should always use the latest standard available.

          • HurricaneHarry

            Finally found the solution.
            It was related to std::string_view.
            What got me in the end, was that there was no "undefined type" (or something like that) error with the string_view line with the (partial/experimental..?) c++17 standard in vanilla CB g++ version.

            Maybe add a line in the lesson, that the (as it seems still latest) build of Code::Blocks doesn't come with a sufficient g++ version for this quiz?
            Or, maybe it was already added in one of the lessons.
            Works with g++ 9.2.

            best regards

            • nascardriver

              Thank you for sharing what your issue was!
              Different versions of CB ship with different compilers which support different standards.
              Because old standard selections/compiler incapabilities have caused many errors since we started updating the lessons, I emphasized that learncpp uses C++17 and I added an example to test the compiler in lesson 0.12. Additionally, I added a note to this lesson, the array snippet in particular, reminding readers to use C++17. This makes it easy to figure out errors that are caused by old compilers or wrong compiler settings before they occur in the quiz.

  • Wilibert

    Hello Alex and nascardriver, first of all, thanks a lot for the tutorial.

    I'm getting a weird issue with quiz 3)d, even if I copy paste the code from the solution. Here's a sample of what I tried:

    The first normal array compiles just fine and my code runs with it. The second array is an std::array and gives me an "incomplete type is not allowed" error. I spent quite a bit of time looking around on the internet to figure out what was wrong, and it seems like I just can't initialize a static constexpr std::array inside a class... even if I change the data type to int, I still get the same error.
    The code sample provided for the quiz says to place the std::array as a private member of Monster, but it doesn't seem to work in Visual Studio 2019. I also tried putting another set of braces like the solution code does, but it doesn't remove my incomplete type error.
    Am I missing something?
    Here's the error code:
    ...\Wilibert's stuff\Chapter 11 Quiz 3\Monster.h(30,68): error C2027: use of undefined type 'std::array<Monster::MonsterData,3>'
    ...\Wilibert's stuff\Chapter 11 Quiz 3\Monster.h(30): message : see declaration of 'std::array<Monster::MonsterData,3>'

    • nascardriver

      `std::array` requires an extra set of curly braces, because it uses aggregate initialization to initialize the C-style array member. The extra braces are in the examples of this lesson.

      • Wilibert

        Yup, and I just realized I forgot to #include array... That was what I was missing. It occurred to me when I went to sleep last night. Well, thanks for the answer. Adding the braces and the #include fixed it

  • Ryan

    Just a trivial question. What is the best random generator? I use this:

    I googled this many times but everyone gives different answers.

    Also there are so many green text in the final solution, it makes it harder to read the code.

    • nascardriver

      I can't tell you which one is best. I doubt there is a best once. Different generators have different pros and cons depending on how you use them. If you need a lot of random numbers, eg. for graphics, speed will be more important to you than randomness. If you use your rng very rarely, eg. for password generation, speed won't matter to you and you might want more randomness.
      There are flaws in your code.
      Seed random number generators only once. `rd` should be `static` because it's expensive. `mersenne` should be `static` so it doesn't get re-seeded.
      When they're static, your code can still fail if the system it runs on doesn't provide a random source, which is used by `std::random_device`. Without a random-source, `std::random_device` doesn't generate random numbers, making your generator predictable. Call `rd.entropy()` once and check if it's non-zero to make sure it can generate random numbers. If it can't, fall back to another source (eg. `std::time`, that's predicable too, but better than a constant seed).

  • Tompouce

    Hi!
    So in the Fruit exercise, I defined the apple class as such:

    But when initializing Apple a {"red"}; in main(), eventhough one Apple constructor is protected and the other public, I get a compiler error telling me that more than one compiler matches the arguments given.
    I realise that I have given default parameter values for the protected constructor, but since it's not supposed to be accessible from main() shouldn't that be enough for the compiler to know which constructor to use?

    • nascardriver

      Hi!

      The compiler searches for a matching function before it takes access modifiers into account. You can't have ambiguous functions even if the have different access modifiers.

  • ErwanDL

    Hey,

    Wouldn't it be cleaner to pass the "name" and "color" string parameters as const references to the constructors for Fruit/Apple/etc. ? I thought that non-fundamental type parameters should be passed as const ref.

    Which would typically look like :

    • nascardriver

      Absolutely, lesson updated. Thanks for pointing it out!

      • ErwanDL

        I also noticed that at line 66 of the solution to question 3.d), you could perhaps replace the C-style

        with what I believe to more idiomatic to C++

        • nascardriver

          Thanks again! I updated the lesson to use `std::array` and `std::string_view`. In case you missed the lesson about `std::string_view` (Added Nov. 02): https://www.learncpp.com/cpp-tutorial/6-6a-an-introduction-to-stdstring_view/

  • Alexsander

    Guess the solution for question 2b can't be compiled. GrannySmith constructor calls an Apple constructor that doesn't exist - the only one found has only one argument, not two.

  • Slash

    I really like the implementation of the console-style RPG.
    However, I noticed at the end, where you show the sample game session, that orc is still alive after being hit by the player (LVL 2) 2 times.
    Orc's health should be 0 by then and therefore it should not hit back, shouldn't it?

  • Parsa

    In the table shown at the top, the row for private, shouldn't it be private, inaccessible, private?

  • Anastasia

    @Alex, when you have a bit of time - the return statement in main() is missing in all the quiz 1 examples (1a, 1b, ...) and in the last snippet in 3d.

Leave a Comment

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