Software Design Case Study - Fireball Logic Game
The game board is 10 x 10. The cannonball deflects off the posts in this fashion:
The player has a fixed number of shots, but repeating a previous shot does not count. Also, the player has to be able to click on a cannon to fire it, and to click on a game cell to guess if there is a post there.
First, Functional Decomposition was applied to decompose the game board into its components.
This gives five arrays of objects:
Treating them all as two dimensional arrays allowed me to use the same drawing function for all five objects. Since the board is always square, I only have to define one dimension.
Rather than create a separate control for each cannon and game cell, I chose to draw them on screen and use the above map to calculate where a mouse occurred. Everything was normalized to the logical origin of (0,0).
Each of the (X, Y) coordinates in the game map are defined in CONSTANTS.H. In addition, the entire board is offset in the dialog box window, so that it appears centered. The offset is defined as an (OFFSETX, OFFSETY) offset in CONSTANTS.H and is added to the objectís position when drawing, and subtracted from the mouse coordinate when the mouse is clicked. That allows all game board operations to operate on the logical coordinates, rather than the physical coordinates. The entire game board can then be moved anywhere in the main window by simply changing the values of OFFSETX and OFFSETY.
There is only one board and only one cannonball, so those were both made as Singletons.
Decoupling the User Interface
The board and cannonball often had to send information to, or get information from, the user interface. Because I do not like to tightly couple objects with their on-screen representation any more than is necessary, I created the CUserInterface object as a Bridge between the UI and the rest of the program. This object provides the interface to the UI, allowing the game objects to communicate with the UI in a safe manner. The object is a Singleton, so that only one will exist.
Click here for the source code in C++. The classes CMyBitmap, CAboutDialog, and CDice are reusable as-is. The class CSound is reusable with modification to the sound definition array.
To facilitate unit testing, I created a Tutorial mode that shows the path of the cannonball as it travels. Initially, the position of the posts were hard-coded by using a stub function for the random number generator. It simply returned a hard-coded sequence of positions. That allowed me to debug the ball navigation code, especially for multiple bounces..