Program 4 Dordal Due: April 22, 2005 You are to modify the game program presented in class, adding the features below. Every new command should have a "generic" response; ie be recognized by Room::response(). That is, TURN VALVE in a non-ValveRoom should say "There is nothing to turn here!" Also be aware that in order to get the dynamic_cast operator to work, you have to enable the run-time type information with the "/GR" option. Go to Project (on main menubar) => Properties (menu item) => C/C++ (folder) => Language => Enable Run-Time Type Info (set to Yes) 1. Add a second Lantern, of class Lantern. The second Lantern should **have the same name**, LANTERN. When the user invokes the command LIGHT LANTERN you look on the Inventory for the first such object and light() it. Note that you will need to downcast from Carryable* to Lightable* to do this. Similarly, in the dark rooms, you will need to check whether there is any Lightable on Inventory (it also has to be lit!). The function haslight() may be useful here, though notice that it doesn't check whether the lantern is lit. Notice also that, as written, it returns only the first Lightable, which may be the "wrong" one! Your program, for example, should work properly even when both LANTERNs are on the Inventory list and only the second one is lit. The two Lantern objects are different instances of the class Lightable. You are to arrange for there to be some *material* difference, even when both are lit. In other words, you are to have some puzzle where it makes a difference which of the two (identically named!) LANTERNs the user has. For example, ... There is a magic inscription at the base, but you'll need to shine the light on it to read it. SHINE LANTERN // added room-specific verb SHINE I'm sorry! You seem to have the dim lantern; somewhere there is the bright lantern though. Note that if the user has both the dim LANTERN and bright LANTERN on Inventory, in that order, then LIGHT LANTERN will light only the first, dim, LANTERN. To light the second lantern, one can do DROP LANTERN // drops first lantern LIGHT LANTERN // lights remaining lantern TAKE LANTERN // picks first lantern back up It is not forbidden to have an upfront distinction made between the two lanterns, but they *are* required to have the same name and so this would make printing bright/dim descriptions rather complicated. The right way to do this, should you decide to implement this, would probably to give Carryables both name and description, equal by default but settable in some cases to different strings. Personally, I wouldn't bother. 2. If you eat the chocolate, it should go away after 2-3 bites. Keep the number of bites left as an attribute of the chocolate itself. To do this, you will need to create a class Eatable : public Carryable { private: int _bitesleft; public: bool eat() { if (!_bitesleft) return false; else _bitesleft --; } or something like that. You don't need downcasting if there is only one Eatable thing in the game (CHOCOLATE), although downcasting is still a very reasonable way to implement this. 3. Introduce a puzzle room where you cannot *leave* the room until some action occurs. Possibilities are: You have to FIGHT the dragon (with a SWORD?) You have to GIVE the dragon a PRESENT or COOKIE. There is a cave-in and you have to DIG (with SHOVEL?) 4. Make the StoneRoom (or whatever room in your game comes after "Passage1") be "dark"; that is, if the user gets that far without a Lantern then they cannot see anything except the way back out (to the north). They cannot "move stone", or TAKE anything. StoneRoom::response() should attempt to prohibit much of anything. While it is possible to check for the lantern in on_entry, it is much better to check as well in each call to response(), in case the user did DROP LANTERN. In principle you want every deep cave room to be "dark", but handling things like DROP LANTERN make this a little complicated. 5. You are to add one additional puzzle of your own. Your puzzle should, at a minimum, involve the following: one new CarryObj one new verb one new derived room class, with special behavior for at least one verb (new or existing). some kind of state change to the room or to an object (like the stone being moved or valve being turned) You will be graded in part on the inventiveness of your puzzle. Here are a few possibilities. UNLOCK CHEST with a KEY found elsewhere; once the chest is unlocked, something should be inside. Cross a rickety two-move bridge over a bottomless pit; if you carry too much the bridge will break; you can only carry two things at a time. You need to CAST SPELL in the WizardsChamber, but in order to do this you must first find in the game a BELL, BOOK, and CANDLE. (And maybe LIGHT CANDLE? Or maybe, in the simpler direction, just find NEWTEYE and BATWING. If you try to CAST SPELL and don't have the ingredients, the game should tell you what you're missing.) The different-Lanterns issue in #1 can be a part of one of the puzzles required in parts 3 and 5. The puzzles in 3 and 5 should be relatively independent of one another, though.