XNA Game-Themed CS1 Examples (XGC1) Release 2.0 (XNA V3.1) 2/8/2010
Topic: Topic.3.ModulesAndFunctions
Example: Ex_5.DescribeAlgorithm

Functions As A Way To Describe An Algorithm

References:

• Pre-requisite: it is assumed that you have read through the prior tutorials, and are familiar with the concepts covered in those tutorials.

Goals:

• In this tutorial, we will:
• Examine how to use functions to clarify the steps of an algorithm

1. Obtain the example code

Download and unzip the zip file and you will see an ExampleProgram folder. Open the ExampleProgram folder, the EXE folder contains the compiled program and you can double click on the .sln file to work with the source code.

When the game starts, you'll see a screen that looks similar to this:

As you can see, there is a single soccer ball on the screen.  Using the right thumbstick, you can move the soccer ball around (if you want, you can even move it off the screen).  The program prints out a simple, purely textual message at the top of the screen, and the current location of the soccer ball at the bottom of the screen (along with the ball's radius).  As you move the ball around on the screen, you'll notice that the size of the ball changes in proportion to the height of the ball - as you move the ball upwards, it gets bigger, and as you move it downwards, it gets smaller.  You'll also notice that the ball gradually sinks towards the bottom of the screen.

2. Clarifying The Algorithm Using Functions.

Since the source code to this program is nearly identical to the program used in the previous tutorial, we will only examine the code that's new, or different.

The term "algorithm" is basically a fancy word for "a series of steps that you do in order to achieve some goal".  One could say that there's an algorithm for driving from your house to the grocery store (which might look something like: (1) go north on the street you live for 5 blocks, (2) take a left onto Grocery St, (3) go 3 blocks on Grocery St, (4) turn right into the grocery store's parking lot), that there's an algorithm for assembling a peanut butter and jelly sandwich, etc, etc.  In some ways, "algorithm" is very similar to "recipe", except that "algorithm" is usually used to describe a series of steps that are specific to calculating or computing something.  Let's look at how functions can help clarify an algorithm by examining the UpdateWorld routine:

• UpdateWorld():  protected override void UpdateWorld(){     if (GamePad.ButtonBackClicked())         this.Exit();     // Step 1: move the soccer     MoveSoccerByThumbStick();     // Step 2: Drop the ball gradually     DropSoccerGradually();     // Step 3: Compute soccer size based on current height     ComputeSoccerSize();     // Step 4: Print message for the user     PrintMessageForUser(); }
• As you can see from the code, above, UpdateWorld starts by doing the standard "Does the player want to exit the program?" check, and then proceeds on through 4 distinct steps.
• While the comments make it very clear what the steps are, each of the steps would be clear even without the comments.  Since each step is done by a function, what we see here is a list of function names, in the order in which the functions will be called.  Since we've chosen good, descriptive function names, it's very clear what will happen, and in what order.
• Contrast this with a version of the UpdateWorld that simply takes all the code from the functions, and pastes the function code into here: protected override void UpdateWorld(){     if (GamePad.ButtonBackClicked())         this.Exit();     // Step 1: move the soccer     // Change Ball position with Right Thumb Stick     m_TheSoccer.CenterX += GamePad.ThumbSticks.Right.X;     m_TheSoccer.CenterY += GamePad.ThumbSticks.Right.Y;     // Step 2: Drop the ball gradually     const float DROP_RATE = 0.1f;     m_TheSoccer.CenterY -= DROP_RATE;     // Step 3: Compute soccer size     float yPos = m_TheSoccer.CenterY;     const float RADIUS_SCALE_FACTOR = 0.16f;     m_TheSoccer.Radius = BALL_INIT_RADIUS + (RADIUS_SCALE_FACTOR * yPos);     // Step 4: Print message for the user     EchoToTopStatus("Simple 4-step instruction for this program!");     EchoToBottomStatus("Soccer Ball position: " + m_TheSoccer.Center + " Radius:" + m_TheSoccer.Radius); }
• While you can figure out what the program is doing, using the function names makes it substantially easier to know what the intent of each block of code is.  Indeed, with this version, the comments describing each step are much more important - removing them would make this version much more jumbled, confusing, and harder to understand.
• In terms of the functions themselves, the only really new function is DropSoccerGradually().  Before examining that, we will briefly look at PrintMessageForUser, which now handles echoing messages to both the top and bottom status bars, and along with MoveSoccerByThumbStick, which handles moving the soccer ball in response to user input.
• You'll notice that each function has one, primary purpose.  This is a good rule of thumb to follow when creating your own functions - while each function may do many different steps in order to accomplish it's task, each function still has one, primary task that it accomplishes.  Not only does this help to make it clear what the algorithm is, but it will make the program easier to understand and maintain.
• MoveSoccerByThumbstick():  /// /// Change the center of the soccer ball by right thumb stick movements. /// private void MoveSoccerByThumbStick() {     // Change Ball position with Right Thumb Stick     m_TheSoccer.CenterX += GamePad.ThumbSticks.Right.X;     m_TheSoccer.CenterY += GamePad.ThumbSticks.Right.Y; }
• This function does the exact same thing as UpdateWorld was doing in the previous tutorial, except that that logic has now been moved to this separate function.
 /// /// decrease soccer's Y position by some constant value /// private void DropSoccerGradually() {     const float DROP_RATE = 0.1f;     m_TheSoccer.CenterY -= DROP_RATE; }
• This is the only, genuinely new function for this tutorial.  It has responsibility for making the soccer ball slowly move towards the bottom of the screen.
• In order to do that, we declare a local, named constant, and subtract that value from the soccer ball's Y value.
• Much like the way in which
m_TheSoccer.CenterY += DROP_RATE;

is equivalent to:

m_TheSoccer.CenterY = m_TheSoccer.CenterY + DROP_RATE;

You'll notice that
m_TheSoccer.CenterY -= DROP_RATE;

is equivalent to:

m_TheSoccer.CenterY = m_TheSoccer.CenterY - DROP_RATE;

• ComputeSoccerSize():
• This is unchanged from the prior tutorial.
• PrintMessageForUser(): /// /// This is the "comment area" for the function. You should /// use this area to explain the details of what your function does. /// In this case: /// /// This function prints a simple message to the /// TopStatus area in the application window. /// private void PrintMessageForUser() {     EchoToTopStatus("Simple 4-step instruction for this program!");     EchoToBottomStatus("Soccer Ball position: " + m_TheSoccer.Center + " Radius:" + m_TheSoccer.Radius); }
• This function puts all the 'EchoTo...' logic in one place, which is convenient, and helps make it clear what step 4 is doing, back in UpdateWorld
• In addition to changing the top message, we have removed the random number from the bottom message, and replaced that with the soccer ball's current radius.

FURTHER EXERCISES::

1. Start from a blank starter project (1000.201, if you need it), and re-do the code from memory as much as possible.  On your first try, do what you can, and keep the above code open so that when you get stuck, you can quickly look up what you forgot (and that after you finish a line, so that you can compare your line to the 'correct' line).  On the next try, do the same thing, but try to use the finished code less.  Repeat this until you can type everything, without refering the tutorial's code.
• Repeat this exercise daily for several days, so that you really get the hang of this.  As you go on, periodically review this by re-doing this exercise.