Roguelike Game in C/C++
This project was a semester-long assignment during my Advanced Programming Techniques class at Iowa State University (ComS 229). I took it during my Junior year as a Computer Science elective with Jeremy Sheaffer and thoroughly enjoyed it. The class was taught in C and C++ and was designed to help students develop:
- an intimate understanding of the C/C++ programming languages and programming practices
- skills in large project management
- ability to interpret and apply written requirements
- ability to maintain and modify existing code
Throughout the semester, each member of the class was to implement their own version of a roguelike game, similar to Nethack, structured around the weekly assignments.
We were given weekly assignments that consisted of a short description of the desired end-result and a couple of examples to aide in understanding. Each assignment required the completion of last week’s assignment and typically built upon the existing code. We were never given the exact details of future plans and were free to fulfill the weekly specifications in any way we desired. This forced us to develop code that could be easily utilized or modified for future use.
My version of the game can be broken down into 6 main parts:
- Event generation/abilities
- Playable and Non-Playable characters
- Description parser
Dungeon is a structure that contains the entire game. It keeps track of the individual characters and objects, along with access points to other layers in the dungeon. It is always randomly generated, unless an existing save_file can be located. When a character moves from one level to another (via stairs), the previous dungeon is destroyed and replaced by a new dungeon, randomly populated with freshly generated objects and monsters. All items within the player’s inventory, as well ad the player’s stats, are preserved.
Each player in the game has a set of abilities that are defined with regard to the dungeon’s internal “dice”. Similar to board games which utilize dice, a players have properties that increase the chance of certain events occurring. During each “turn”, a player moves at a certain speed which is decided by each “turn’s” rolled di(c)e. This system is also in play when two players enter combat.
The player is allowed to save his/her progress at any time, which can be resumed at a later time, provided the player is not destroyed by an enemy figure. The save file will preserve the current dungeon state, along with enemy and player positions and characteristics.
The game consists of the main, playable, character ‘@’ which can equip items in the dungeon and must defeat the monsters in a given dungeon in order to win. The monsters are non-playable and have characteristics that are determined by a character file that is read at runtime. Monsters may either be telepathic or non-telepathic and may be either smart or dumb.
Objects, or power ups, are randomly scattered throughout the dungeon and can be picked up by the main player to help him/her on his/her quest. These objects are created in a similar manner to the monsters, in that they take on characteristics defined in a character file that is also read at runtime. The objects either add or subtract from the chance of certain actions happening.
As mentioned above, a file parser reads characteristic files on startup, so that the dungeon can be populated with monsters and objects with characteristics to the players liking. This was a great feature, in that it allows customization of the game, without requiring recompiling. My parser was written in C++ (the rest of the game was written in C) and is quite robust, in that it skips erroneous characteristic entries without causing undesired game behavior.
As a result, the game was an excellent opportunity to learn more about the GNU toolchain, debugging in C/C++, implementation of requirements, and code modularization. My final product was able to work very well on linux machines, and reasonably well on Mac systems. As of now, I am currently in the process of re-writing most of the code to improve modularity and to add additional features.
- Modular design
- Familiarity with Ncurses
- GNU toolchain
- File parsing
- Usage of basic data structures
- Generic priority queue
- Generic linked list
The current source code can be found on my public git Here. Keep in mind - this was a younger me. Don’t judge too harshly :-)