Welcome guest. Before posting on our computer help forum, you must register. Click here it's easy and free.

Author Topic: House Escape -- an old-style Adventure Game  (Read 8606 times)

0 Members and 1 Guest are viewing this topic.

Dilbert

    Topic Starter
  • Moderator


  • Egghead

  • Welcome to ComputerHope!
  • Thanked: 44
    House Escape -- an old-style Adventure Game
    « on: February 19, 2007, 08:45:55 PM »
    Hello,

    one of my big projects while trying to learn C++ is to create a command-line driven game. It didn't have to be huge; it just had to encompass a good deal of what I know about C++ as an OOP language. This project is nearing completion, and when it does, since I feel I must share something of the scale it's become, I'll release it for play. It probably won't get much attention, but I really don't care.

    The main reason I'm going to do this is to get advice on how to improve. I know that online tutorials and instruction books are no match for formal training and, of course, experience. I can't do the first until college, but the second I can get now.

    So, the first order of business is to head off this kind of comment: "Why did you use ABC to accomplish this? XYZ would be much more efficient."

    Chances are, I haven't seen it before. So if there's an easier way to do something, let me know, but don't ask why I didn't use the most efficient method. My blanket answer is that "I didn't know you could do that..."

    *ahem* That aside, next thing is to say what the program basically is and how far I am in completion. The basic premise is that the player is in my house, and for reasons that are disclosed in-game, has to escape it. The geography of my house perfectly matches the one in the game, but in order to make the game challenging, I've had to delve into complete and utter fantasy to keep this from being a 5-move game. It's just one abnormal... entity... of sorts, but it dramatically alters the game. (In retrospect, I wish it was that easy now... this is getting big...)

    The game is command-line driven because I don't know how to GUI program yet, and because I can't think of a use for a GUI in this game.

    As for writing the game, I am about 80% complete. The commands, their consequences and how they interlink is set up. The big portion of the remainder is writing the command parser. There are only 11 items, but writing every way the player interacts with them and the environment is a pain in the *censored*.

    Another hurdle is writing a tutorial. I'm not about to allow my command parser to grow to the point that I have 10 different commands that boil down to the same thing, so I'm having specific commands -- and ONLY these specific commands -- work. To compensate, I'm going to write a tutorial that should make it easy to know how to do something in this game.

    In summary: I'm writing a game, it's not done, watch this thread so you can play(test for bugs) and give me coding advice when it is done.

    Est. Completion time: 1 week
    Accuracy of completion time estimate: Microsoft
    Size of project: 48 KB (source code)
    « Last Edit: February 19, 2007, 08:50:00 PM by Timothy_Bennett »
    "The geek shall inherit the Earth."

    fffreak



      Adviser

    • That's right I am a final fantasy freak.
    • Thanked: 3
      • Yes
      • JSPCRepair
    • Certifications: List
    • Experience: Guru
    • OS: Windows 7
    Re: House Escape -- an old-style Adventure Game
    « Reply #1 on: February 20, 2007, 12:38:45 AM »
    I hope all goes well, as I look forward to seeing this. By the way, are you teaching your self C++, or are you taking a class?

    8-)fffreak
    Computers are the future, not us. Learn everything you can about them while you still can, soon they will be learning about us... Every bit of advice that I give you is best guess, it is your choice whether or not you listen to it.

    Dilbert

      Topic Starter
    • Moderator


    • Egghead

    • Welcome to ComputerHope!
    • Thanked: 44
      Re: House Escape -- an old-style Adventure Game
      « Reply #2 on: February 20, 2007, 05:44:56 PM »
      I plan on going to a class in college, but for now all I've got is a C++ for beginners book and whatever I can find on the Internet (which is a lot!).

      Hopefully, the source code will not look like I'm such a beginner (I plan to release it). As it is, the project is getting big.

      I'm writing the parser right now, which is adding several hundred lines to the code. I'm up to 1656 in escape.cpp and 371 in escape.hpp. The parser isn't even half done. And I still haven't written int main() yet. Though quite frankly, that won't have much purpose other than to get the player started. :D

      More fun facts:
      Classes: 12
      Functions: 119


      UPDATE 7:00 PM GMT-8: The parser is done, using 592 lines of code to parse 72 commands, not counting the fact that I have several different ways programmed to do the same command (I shouldn't, for example, penalize someone for trying "turn on light" rather than "turn light on").

      UPDATE 7:52 PM: int main() has been written. The length of escape.cpp is now 2110 lines, with more to come as I add more functions, fix problems I know exist, and do a final code check before I let the compiler spew errors at me. ;D (Come on, how can a project this big not have code errors?)

      Items left on to-do list: 11
      Expected time to do next item: 2 hours
      Sanity: 0%
      « Last Edit: February 20, 2007, 08:55:40 PM by Timothy_Bennett »
      "The geek shall inherit the Earth."

      Sidewinder



        Guru

        Thanked: 139
      • Experience: Familiar
      • OS: Windows 10
      Re: House Escape -- an old-style Adventure Game
      « Reply #3 on: February 21, 2007, 05:34:01 AM »
      Quote
      with more to come as I add more functions, fix problems I know exist, and do a final code check before I let the compiler spew errors at me.

      Waiting until the end for a compile can be overwhelming and very disheartening. If you write your program modularly, I suggest you compile after each function is complete and fix the errors as you go. One advantage is you can concentrate on the logic more and not the syntax so much.

      Just a thought.  8-)

      The true sign of intelligence is not knowledge but imagination.

      -- Albert Einstein

      Dilbert

        Topic Starter
      • Moderator


      • Egghead

      • Welcome to ComputerHope!
      • Thanked: 44
        Re: House Escape -- an old-style Adventure Game
        « Reply #4 on: February 21, 2007, 08:18:38 AM »
        Trouble is, the only code I'm actually concerned about is the code that links up with other classes and their member functions. I'd have to make a mock class system just like the one I'm making, and that would be equally time-consuming.

        In a normal program I couldn't agree more. But a game, the way I have it, won't work with that very well. I wish it did. :( Oh well, good to know for next time. :)
        "The geek shall inherit the Earth."

        Neil



          Expert
        • Fear me Track. Noone can escape my wrath.
        • Thanked: 3
          Re: House Escape -- an old-style Adventure Game
          « Reply #5 on: February 21, 2007, 09:18:45 AM »
          OK the impression I get is that you're writing code but have yet to test if it works? Please tell me that is not true...

          Also that seems like a very large amount of functions. I don't want to rain on your parade (I've never used that phrase before) but I have a feeling your code is too specific and not very modular :P Ask yourself this question: after completion, how easy would it be to add a new possible command, or a new room? If it would take hours of function writing and modification..... well at least you have learnt for next time ;D

          I look forward to seeing your code!
          « Last Edit: February 21, 2007, 09:19:26 AM by Neil »

          Dilbert

            Topic Starter
          • Moderator


          • Egghead

          • Welcome to ComputerHope!
          • Thanked: 44
            Re: House Escape -- an old-style Adventure Game
            « Reply #6 on: February 21, 2007, 06:21:16 PM »
            It is true, I'm afraid. :(

            As for adding new commands, or a new room, that would be easy enough. In fact, that's next on the agenda; a couple of new commands that hopefully add a little to the game.

            However, adding a new room is just a tad more time-consuming. Erring on the side of allotting too much time per task, setting up the class in the header with all the needed function prototypes would take about 15-30 minutes, depending on the number of objects. Implementing the room would take about 5 minutes per function. Getting other rooms to "hook up" to the room would take about 30 seconds per room that needs connection (copy-paste, change the target room).

            Assuming an average of two objects in a room, and one way to implement each, creating a new room should take, at most, an hour.

            Addressing the large number of functions: It's not as much as it seems. I can break it down:

            The first obstacle is leaving my room. The player needs to collect two items, after doing one thing, and use them, in order to leave it. There's also a function designated to an action that seems reasonable, but won't, in this game, work. That's two items to put in inventory (one func each), one func for the first action needed, one for the action that doesn't work, and two each to implement the items. That's 6 functions right there. Then, there's the one to leave my room, making 7. Finally, there's a "description" function for a "look around" command, private variable accessors, and the constructor and destructor. That makes 14 in the first room.

            However, not all the rooms are this intensive. The Guest Bathroom, for example, has only 7, including constructor, destructor, and all item or room-related functions. I think that one's got the fewest functions.

            Actually, I think [game detail hidden] is the room with the fewest functions; it's actually got 12 total, but 4 or 5 are, like any command-line game, red herrings. ;D

            On average, I have about 9 functions per room, including every way to use an item, the constructors, etc.. However, I've got 11 rooms going, here. That makes appx. 99 functions, and let's not forget the parser which is the backbone of the whole thing. In the interest of making the code easier to read, it's one parser/room. No big deal, it just takes more space that way. (And also solves the problem of a command doing one thing in one room, and a totally different one in another room.)

            Sorry to rant, I got carried away. Anyway, I'm getting to it again. :)
            "The geek shall inherit the Earth."

            Neil



              Expert
            • Fear me Track. Noone can escape my wrath.
            • Thanked: 3
              Re: House Escape -- an old-style Adventure Game
              « Reply #7 on: February 21, 2007, 07:31:15 PM »
              Oh dear.... I hate to break it to you, but your design sucks :P You have basically hard-coded all your rooms and actions and now you face the consquences. Never mind a function for each item, you should have one function for all items....

              Dilbert

                Topic Starter
              • Moderator


              • Egghead

              • Welcome to ComputerHope!
              • Thanked: 44
                Re: House Escape -- an old-style Adventure Game
                « Reply #8 on: February 21, 2007, 10:52:32 PM »
                I'm not quite following you, here. :-?
                "The geek shall inherit the Earth."

                Neil



                  Expert
                • Fear me Track. Noone can escape my wrath.
                • Thanked: 3
                  Re: House Escape -- an old-style Adventure Game
                  « Reply #9 on: February 22, 2007, 08:31:51 AM »
                  I'll wait til I see your code, then see what I can suggest ;D

                  Dilbert

                    Topic Starter
                  • Moderator


                  • Egghead

                  • Welcome to ComputerHope!
                  • Thanked: 44
                    Re: House Escape -- an old-style Adventure Game
                    « Reply #10 on: February 22, 2007, 08:49:14 AM »
                    Sounds good. I am looking for help, here, so as soon as it's done I'll take all the help I can get. It probably does suck, though. :P ;D
                    "The geek shall inherit the Earth."

                    Dilbert

                      Topic Starter
                    • Moderator


                    • Egghead

                    • Welcome to ComputerHope!
                    • Thanked: 44
                      Re: House Escape -- an old-style Adventure Game
                      « Reply #11 on: February 22, 2007, 03:45:15 PM »
                      Oookay, I knew that my code sucked, but this is ridiculous. I got a thousand errors, and I'm rewriting.

                      EDIT: Before I go on, I should ask: If I have a member function of class X, how can I access the member variables of class Y? That seems to be a place it was hanging up the compiler.
                      « Last Edit: February 22, 2007, 03:50:11 PM by Timothy_Bennett »
                      "The geek shall inherit the Earth."

                      fffreak



                        Adviser

                      • That's right I am a final fantasy freak.
                      • Thanked: 3
                        • Yes
                        • JSPCRepair
                      • Certifications: List
                      • Experience: Guru
                      • OS: Windows 7
                      Re: House Escape -- an old-style Adventure Game
                      « Reply #12 on: February 22, 2007, 04:15:04 PM »
                      Neil is right Dilbert, when writing a program, you should perodically compile it, to make sure there are no errors, then fix any errors as you go along. Sorry I am a noob at C++ so I couldn't really help you with that, now Java on the other hand I could help you with.
                      « Last Edit: February 22, 2007, 04:15:59 PM by fffreak »
                      Computers are the future, not us. Learn everything you can about them while you still can, soon they will be learning about us... Every bit of advice that I give you is best guess, it is your choice whether or not you listen to it.

                      Dilbert

                        Topic Starter
                      • Moderator


                      • Egghead

                      • Welcome to ComputerHope!
                      • Thanked: 44
                        Re: House Escape -- an old-style Adventure Game
                        « Reply #13 on: February 22, 2007, 11:07:40 PM »
                        I found out one of the big problems. A little late, but I did.

                        As it happens, I needed to access an accessor in another function in an if statement. Trouble is, I was doing this:

                        Code: [Select]
                        class X
                        {
                        public:
                           //Other member functions
                           bool getVar() const { return theVar; }
                           //More stuff
                        private:
                           bool theVar;
                        };

                        class Y
                        {
                           //Stuff
                           void myFunc(); //Obviously, I wouldn't ever use these classes and function names.
                        };

                        ...

                        void Y::myFunc()
                        {
                           if(Ben.getVar())
                           {
                              //Stuff
                           }
                        }

                        ...

                        int main()
                        {
                           X Ben;
                           Y George;
                           George.myFunc();
                           ...
                        }

                        Imagine my frustration when I found out that I only needed to do this:

                        Code: [Select]
                        class X
                        {
                        public:
                           //Other member functions
                           bool getVar() const { return theVar; }
                           //More stuff
                        private:
                           bool theVar;
                        };

                        class Y
                        {
                           //Stuff
                           void myFunc(); //Obviously, I wouldn't ever use these classes and function names.
                        };

                        ...

                        void Y::myFunc(X Ben)
                        {
                           if(Ben.getVar())
                           {
                              //Stuff
                           }
                        }

                        ...

                        int main()
                        {
                           X Ben;
                           Y George;
                           George.myFunc(Ben);
                           ...
                        }

                        I was doing that originally, but I forgot why after a week-long break, so I removed them as I couldn't find a reference on it.

                        However, I discovered this a little late: I'm sick and I was upset, so I ended up using Shift-Delete on the hpp and cpp. Smooth move, Dil-man. :-[

                        I have a backup from my flash drive (yay!) and I will have about 70% of what I wrote back. But I'm isolating and testing the tBedroom sequence now in a separate hpp/cpp combo. I think this one will compile. As it were, I lost a good chunk of my parser and int main().

                        This supports Scott Adams' theory:

                        "People are idiots. That's everyone, not just the people with low SAT scores . . . idiocy is a condition that people slip into and out of every day.

                        --Scott Adams, The Dilbert Principle


                        As it were, I've got the cold and the flu, so debugging my bedroom will wait for a while. I've got all day tomorrow... I'm staying home sick. :(
                        "The geek shall inherit the Earth."

                        Neil



                          Expert
                        • Fear me Track. Noone can escape my wrath.
                        • Thanked: 3
                          Re: House Escape -- an old-style Adventure Game
                          « Reply #14 on: February 23, 2007, 12:29:47 PM »

                          Dilbert

                            Topic Starter
                          • Moderator


                          • Egghead

                          • Welcome to ComputerHope!
                          • Thanked: 44
                            Re: House Escape -- an old-style Adventure Game
                            « Reply #15 on: February 23, 2007, 01:22:15 PM »
                            Thanks for the info. I'm rewriting the first class now, and will be sure to test them before I go on. I can avoid embarrassing mistakes this way. ;)

                            EDIT: Okay, this is annoying. I've got this in my class:

                            Code: [Select]
                            class game
                            {
                                . . .
                                void inventory(tBedroom tBed);
                                . . .
                            };

                            And it's giving me the error:

                            error C2061: syntax error : identifier 'tBedroom' escape.cpp(14) : error C2511: 'void game::inventory(tBedroom)' : overloaded member function not found in 'game'

                            Among a slew of other errors. I don't get it; I'm following syntax of member functions to the letter, so why is the compiler spitting errors at me?

                            EDIT: I've managed to get the number of errors down by a factor of 10. The remaining 3 errors are all surrounding the game::inventory function. For some odd reason, the compiler doesn't like me using tBedroom as an identifier. I'm trying to pass tBedroom tBed as a parameter, like so:

                            void inventory(tBedroom tBed);

                            However, the compiler doesn't like that. Later, in the tBedroom class, I am able to use "game engine" as a parameter with no problems. Is this because class game appears before class tBedroom? If so, how can I correct this? I can't just rearrange the two classes, because if the problem lies with the order they are in, then tBedroom::getDoorLocked(game engine) and tBedroom openDoor(game engine) are going to have problems.
                            « Last Edit: February 23, 2007, 07:04:30 PM by Timothy_Bennett »
                            "The geek shall inherit the Earth."

                            Dilbert

                              Topic Starter
                            • Moderator


                            • Egghead

                            • Welcome to ComputerHope!
                            • Thanked: 44
                              Re: House Escape -- an old-style Adventure Game
                              « Reply #16 on: February 23, 2007, 10:43:20 PM »
                              Fixed the above problem; I made a prototype of class tBedroom above game. However, I'm having other trouble, and I can't explain this.

                              I'm testing the first two classes, as you know. However, I'm having an interesting problem: A public variables refuses to change value. Or rather, it does, then it goes back. I'm testing all my commands for how well they work. First, I try to do all the commands before it should be possible to see the items. Then, make it so they can be seen but no items are taken. Then, get the items and try to get out the room. It all passes the tests, until the last part: Opening the door with the proper tools.

                              The variable I'm trying to modify is in class game, called gamestate. It is a USHORT (typedef'd as Unsigned Short Integer). The chain of functions is as follows for the last test:

                              1. int main calls tBed.openDoor, passing engine (the game class) as a parameter.

                              2. tBed.openDoor sees that tbed.DoorLocked, a bool variable, is false, so it calls engine.win().

                              3. engine.win sets gamestate to 1, then cout's the variable's value. (It changed to 1, as expected)

                              4. int main() does an if-then to check engine.gamestate's value. If it's 0, the test fails.

                              5. As it happens, gamestate is 0, and the game fails the test.

                              WHAT!?! Here's the code, in order of how it's called:

                              In int main():
                              Code: [Select]
                              tBed.openDoor(engine);
                              Code: [Select]
                              void tBedroom::openDoor(game engine)
                              {
                                    if(doorLocked == true)
                                    {
                                          cout << "LOCKED.\n";
                                    }
                                    else
                                    {
                                          engine.win();
                                    }
                              }


                              Code: [Select]
                              void game::win()
                              {
                                    cout << "GAMESTATE IS " << gamestate << endl;
                                    gamestate = 1;
                                    cout << "GAMESTATE IS NOW " << gamestate << endl;
                              }

                              Back to int main():
                              Code: [Select]
                                   if(engine.gamestate == 0)
                                    {
                                          cout << "TEST FAILED. DOOR CLOSED.\n";
                                      cout << "GAMESTATE IS " << engine.gamestate << endl;
                                    }
                                    else
                                    {
                                          cout << "SUCCESS. ALL TESTS PASSED.\n"; //Passed final test
                                          system("pause");
                                    }

                              My output is:

                              Quote
                              SUCCESS. DOOR UNLOCKED.
                              GAMESTATE IS 0
                              GAMESTATE IS NOW 1
                              TEST FAILED. DOOR CLOSED.
                              GAMESTATE IS 0

                              WHAT THE *censored*???
                              « Last Edit: February 23, 2007, 11:02:44 PM by Timothy_Bennett »
                              "The geek shall inherit the Earth."

                              Neil



                                Expert
                              • Fear me Track. Noone can escape my wrath.
                              • Thanked: 3
                                Re: House Escape -- an old-style Adventure Game
                                « Reply #17 on: February 24, 2007, 09:17:14 AM »
                                This is why you should avoid changing public variables directly as much as possible. You should set it to private and create a public function to change its value, eg

                                private: int blah;
                                public: void changeblah(int newvalue);

                                At first glance that might seem silly and pointless but if you used this way you could simply add into the changeblah function some kind of output of when it is being changed so you know exactly when it's changed and to what value in all cases.

                                I suggest you use the search feature to go through all instances of this variable and make a note of when it is being changed and by what. You seem to have some rouge code changing the variable when it shouldn't be.

                                Dilbert

                                  Topic Starter
                                • Moderator


                                • Egghead

                                • Welcome to ComputerHope!
                                • Thanked: 44
                                  Re: House Escape -- an old-style Adventure Game
                                  « Reply #18 on: February 24, 2007, 06:10:19 PM »
                                  Thanks. I did that, but it got no change. Then I figured it out. I was passing "engine" by value! I changed it to a reference and it worked fine. :)
                                  "The geek shall inherit the Earth."