Oh and Did I Mention It Will Save You Time? Lots of Time

Oh and Did I Mention It Will Save You Time? Lots of Time

Programming Lesson 8–Subs and Functions

Everything we’ve done so far involves writing one long stream of code, inside one button, to complete all of the tasks we’ve been set. Whist this works, it isn’t a good idea for any program which has any kind of complexity (read – your coursework will be more complicated and therefore you need a better way of working)

The answer to this problem is to spend some time designing your code before you even think of writing anything in VB. Why would you waste your life with a pencil and paper? Simple – it will save you hours of misery later and will result in you writing code which is elegant, easy to read and above all – REALLY easy to debug. Now that’s got to be worth something, right?

Oh and did I mention it will save you time? Lots of time.

Lots.

Task 1

The first step is to break your problem down in to steps. Once you’ve done this, you ask the question:

“What are the significant parts/stages of my program?”

And

“Which parts of my program will happen/run/be used more than once?”

The task then is to take these parts of your program and split them in to Subs and Functions.

Key point - By doing this, you will be able to build your program/coursework in stages – making anapparently complex task just a set of small, simple problems to solve!

In this first example, the program will already have been broken down for you and all you have to do is fill in the missing bits, just so you can get used to how this works.

Open the “SubsandFunctions” project from the shared area. I suggest you copy the entire folder to your area to avoid access rights issues.

You are going to complete a project which simulates a really simple slot machine type game. It will do the following things:

  1. Give the user £1 starting money and take 20p off per go
  2. Spin the reels
  3. Display the result of the spin – win or loss depending on some simple rules
  4. Allow the user to select if they want another go or to take their winnings.

Clearly here we have several distinct parts to our program and each one will be used over and over again. Let’s have a look at an outline algorithm for this game:

Start

Money = £1

reel1 = 0

reel2 = 0

reel3 = 0

Loop while money is > 0 and user wants to play again

Reduce money by 20p

Do spin

Show outcome of spin

Update money based on outcome

Exit loop if no money left

Ask user if they want to proceed

Exit loop if they don’t want to

End loop

End

This will form the basis of our “main” code, however each of the other tasks can be broken down further in to sub tasks – these will be our “Subs” which are re-usable code blocks in our program.

Have a look at the code you’ve opened:

These are the subs you are going to fill in. Simply by splitting our program like this, we have instantly reduced the complexity of our task. We can now approach each as a separate problem and then bolt them all together.

The next task is to describe what each sub will do in some detail:

Main()

  • Create the game variables
  • Loop round, allowing the user to play until no more money or no more turns required
  • Call DoSpin()
  • Call CompareReels()
  • Display outcomes
  • Call UpdateMoney()
  • Ask if the player wants another turn.

DoSpin()

  • Generate three random numbers – one for each reel
  • Return these numbers

CompareReels()

  • Compare the three random numbers to the rules:
  • Return any winnings or losses this combination will cause

UpdateMoney()

  • Reduce the player’s available money by 0.2
  • Increase or decrease the player’s money according to any winnings they may have earned or losses they have made
  • Display the players current balance

And now we program them…!

I’ll hold your hand with the main routine, you are going to do the code for the rest.

Let’s start with the Main routine.

Step 1: Create the variables we need. Note there are no global variables!

Step 2: Create the game loop:

Notice the lines after the loop – when the game ends (after the loop) it is a good idea to provide some kind of end game text. In this case we tell them how much they finished with and pause the program with console.read() so they can read the message before quitting.

Step 3: Fill in the game loop

We will come back and slightly alter this code later. For now, note how we call another sub – simply put its name and some brackets. This has a lot of advantages when reading and organising our code. Imagine if we simply put it all in one place, the loop would be massive. Later, one of your challenges will be to remove the “another turn” code and turn it in to a function.

Calling Sub Routines – Passing variables

There is a reason for the pair of brackets after the name of a sub routine…!

It is possible that a sub routine doesn’t need any information in order to perform its job, but this is unusual. Most sub routines will need some variables to work on and may also want to send the result of their calculations back out as well.

Take the “doSpin()” sub routine. In order to work, this routine will need to manipulate the three reel variables and when it finishes, we would expect it to give us back three random numbers.

To complicate matters further, there are two methods of passing variables to a sub routine:

  • ByRef
  • ByVal

ByVal takes a copy of the variable and gives it to the sub routine. Any changes to that value are lost when the sub routine has finished.

ByRef sends the value of the variable to the subroutine, BUT any changes that are made to the variables are KEPT.

Confused? You should be! Let’s fix this with some code.

First, change the call so that the three reels are sent to the doSpin() routine:

Clearly, this code now gives the three reel variables to the DoSpin() routine.

Now, change the DoSpin routine itself so it can accept the variables “ByRef”:

Note that we don’t have to specify the expected data type, but it really does help. Note also the fact that these variables will be referred to as r1, r2 and r3 in this sub ONLY, as these are the names we’ve declared here in the sub definition.

Finally, add the code that performs the spin. The rule will be that each reel can have a value from 1 – 6.

The Randomize() function call is necessary to ensure you get different random numbers. If you don’t do this, every time you spin the same numbers will be generated.

Try running your program, you should get something like this:

Pretty good so far, right?

Now you’re on your own…

Task – finish the game code

Here are the changes you should make to the sub routine calls and definitions for the rest of the program. Change your code.

Notice some are ByRef and others ByVal – it is good practise to protect values that won’t change by sending the as ByVal.

You will now be given the explanation/definition for each routine and your challenge is to implement the code. It shouldn’t be difficult!

Note – your code should output a message telling the user how much they won or lost.

Functions

Sub routines are blocks of code that can take in values, do something to them and pass out the answer.

Functions are similar, but they tend to perform a specific task and they RETURN a single value.

For example, in our game we have a section of code which asks the user whether they want another turn. This happens repeatedly in the loop and it would be nice to remove this code and move it elsewhere. All we really need to know is whether it is true or false that the user wants another turn.

Change your game loop code:

Now add a new bit of code to the bottom of our program:

Notice the difference between a sub and a function:

  • The word “sub” is replaced with “function”
  • A function has a data type – in this case Boolean.
  • A function will usually always be assigned to a variable – variableName = Function()

Functions are assigned a data type, as they will return a single value, of that type. Nothing else comes OUT of a function. Because of this, we can assign the result of a function to a variable, as we have done in the game loop. In other words oneMoreGo() will either be True or False.

Add the code below:

A function contains one other thing that a sub routine does not – a RETURN statement. A function must have one or more of these so that it can send a value back to the place where it was called. Try out the code now to see that it works, step through using a break point and the debugger if you still don’t understand how it works.

Now it’s your turn. Both compareReels() and UpdateMoney() should, in fact, be functions.

You will need to change the code in the game loop:

Quick extension for super people – you could turn this in to one single line of code and remove the “result” variable…

The sub routine definitions would change to look like this:

See if you can do it…! It should require only minor changes to your code.