[Update 3/3/2012: I’ve uploaded all the source code, as well as the executable so you can download and play here(9/9/2012: The file is no longer available due to lack of interest)] Shortly after my first semester of college-level CPS coursework, I felt confident enough with C++ to start making my own game. After all, I’ve always loved everything about games, the making of them, the playing of them, and the analysis of them. I decided to make a little text-based game where the user would enter in commands from the prompt to explore a virtual haunted house. It turned out to be a lot more work than I anticipated.
The game would be simple. After a short opening story where the player and his or her friends are out on Halloween vandalizing decorations, they find themselves running from the police. Thinking quickly, the player steps inside an old abandoned home to hide. Well, the old abandoned home turned out to be haunted!
The player could type in a variety of commands to explore the house, fight the monsters inside, and eventually find a key to open the locked front door to freedom. I found out real quick that my rudimentary knowledge of programming and algorithms wasn’t sufficient to do this project. So I had to learn.
First of all, string parsing, string parsing, string parsing. C++ didn’t have the string functions like I was used to in Java so I built my own. I started with a basic function, cleanString that would take a string the user gave me and parse it into the elements I could be interested in. (Don’t bother mentioning the strtok function! I was young and naive!) So I went through the string removing anything that wasn’t a letter or a number, and then capitalized all the letters and placed each ‘block’ of text into a queue in order so I could process them. I also removed articles like ‘a’ ‘an’ ‘the’. (so a user command like opEn _ the – Door became OPEN DOOR)
Then I had to process the commands. What I did was manually create a big, messy if-else if-else block that tested all possible commands. There was some serious nesting going on to process more complex commands. What I was essentially doing was explicitly making a series of decision trees. For example, take a look at the simplified tree for a command like ‘ATTACK’:
The actual structure is a little more complicated, but you get the gist. There were more than a handful of trees/flowcharts like this one, and writing them all out was a long and painstaking process.
Thinking about it three years later, I don’t think it would be that much simpler. I might create a COMMAND object that accepted a player object and a world state object. The command object would probably be some sort of dynamic tree that would make it easier to test the validity of a command. Each node in the tree could have something like a command string to match, a test to perform using attributes from the player object (as well as any updating of player state and world state), and paths to valid next commands. A testCommand function would pass the user’s cleaned command to the tree and return true if success and false if failure. All updating would be done automatically.
There’s probably other ways to make the simpler, this was just an example off the top of my head.
Anyways, I digress. Here are some other notable points about the project:
- I did not know what the C++ STL was, and as such built all data structures by hand, including Queue, Linked List, and Stack
- After you beat the game you get a cheat code so that next time you can breeze though it. The code was originally intended for debugging purposes.
- The game tracks your inventory and can display a little ASCII map:
- I sprinkled all sorts of easter eggs inside the game for fun. There’s a sleep command to take a little nap. There’s also an OBSERVE MYSELF command that prints out the description of yourself you entered at game start.
- The entire project lasted me four weeks or so when I think I could do it in a day or two now, as well as make it many times better and efficient.
- A big motivating force behind the project was to get better at C++ and become more familiar with it. To that end I would say I succeeded.
- Another note about getting familiar with C++: I spent hours and hours trying to figure out why my game state wouldn’t update when I finally remembered the difference between pass-by-value and pass-by-reference.
- I was so enamored with completing my first C++ self-motivated project that I even made a little icon for the .exe in MSoft Paint:
Who knows? Maybe one day I’ll make a Haunted House 2.