Programming Techniques 01: Program Design

By Dominic Ford

Originally published in EUG #35

In this series, I shall be showing you how to use your programming skill to achieve the best results that you can. I will assume that you can already program, at least in BASIC. If you cannot do so, you need to read either the Acorn Electron User Guide's BASIC tutorial or, even better, a book such as The Electron Book, which provides an excellent tutorial. Similarly, if you want to learn Assembly Language, you need a book such as Electron Assembly Language (Shiva) which provides a much better tutorial than EUG even could, simply because no reader has enough time to write such a detailed tutorial and besides, there is not enough room on EUG to publish such a long article.

If you have any ideas for subjects that you want me to cover in Programming Techniques, please write into EUG and tell me about them. I already have plans for articles on graphics, sound and memory management. Do you want details about writing any specific type of program?

So, you have an idea for a program that you want to write. The first thing to do, before you start writing the code, is to visualise what the user will see and do when they use the program. If it is a game, imagine what the user will have to do, and what they will see on screen as they do it. Forget the title screen and introduction: these are fun to write, and although the user will see them first, before the actual program, you should program them last. Concentrate on the heart of the program first. You may have some important decisions to make. For example, in an arcade adventure such as Shipwrecked, you must decide whether it is to scroll or whether it is to be a flick-screen game (like the original Shipwrecked).

Next, you should start to plan out how the computer will achieve these results. Sketches are often a good idea, to show the flow of the program from one routine to another. One great decision which you must make is whether to use BASIC or Machine code. If speed is important, Machine code is useful, but if readability or ease of writing the code is important, BASIC is a good choice. A mixture can also be good in some circumstances. You may want to do the main body of the code in BASIC, where it is easily readable and quick to write, and have the slower routines in machine code. Animation routines, for example, may need Machine code for speed. Laser Darts is an example of such a program. I wrote the main loop in BASIC, but the animation of the laser is too slow for BASIC so I did it in Machine code. When the player fires a laser, I simply execute CALLlaser.

But do not start any coding yet - your routines should stay simply as names in boxes for the moment. Your plans do not have to be that clear - in fact if they are too clear-cut you may have problems if you cannot achieve quite the effect you want. You should leave room to make alterations if you cannot get the computer to produce the right effect, or simply if you discover a much better effect than the one you originally planned! Often an effect which you think will be really good in fact looks or sounds dreadful in practice. On the other hand, often the best effects are stumbled upon quite by accident.

Now is the time to start programming. Pick one, and only one, of the routines on your diagram, and then write the code for that routine. It is very important that you do not code too much at any one go. Your program should start out very simple, and slowly work up to being something complex. You may even want to start with only half a routine, but whatever it is you need to be able to test it to ensure that it works faultlessly.

When you start testing your routine, make sure that you save the program or source code first - the computer may well crash, in which case you could very easily lose your work. Do not be afraid to risk crashing the computer - test the routine as vigorously as possible. For example, if you are writing a routine to find the square root of a number, ask it what the root of -2 is (there is not one). Is the result acceptable? If not, fix it. Remember, if you ask for a number between 1 and 10, some user is bound to type 11, and your program should be prepared to deal with this. Even internal routines should check to see if they are called illegal parameters. If a routine is called with the wrong parameters, it is much easier to trace the problem is your program says "Error at 100" than if it simply does not operate in the way it should.

Whenever I test a routine, I always make the following checks:

  • What happens if an illegal value is passed to a routine. e.g. if 11 is given as input for a routine which only accepts values from 1 to 10?
  • What happens if a decimal, such as 2.5 is given when only whole numbers are allowed?
  • What happens if the user types a string for a numeric input?

Your program should be able to deal with all of these situations.

When you are totally satisfied that one routine is working, build on it and add on another routine. Then test it again. Generally, I get worried if I write code for more than about half an hour without testing to see if it works. We all make mistakes, and there are bound to be bugs in your code. If you test your software and it does not work, you know that there is a problem with the code which you added since the previous test. The smaller the amount of code that this is, the easier your bug will be to find. Just as in a scientific experiment you only ever change one variable at any one time, you should only change one aspect of your program at any one time. That way there is only one possible source of problems. When you make a small alteration, never fall into the trap of thinking "It was only a small alteration: it's bound to work, so I won't bother to test it." You will regret it if you do.

Shipwrecked (EUG #30) was developed in this way, in very small steps. To illustrate my point, these were the steps in which I developed the code:

  1. I wrote a routine to read the type of block in any given square on the Shipwrecked map. For example, I could ask it the value of the block in square (5,8), and it would report block type 3.
  2. I added onto this a routine to read the graphic data for the reported block type, in the example this would be block 3, and then plot it onto the relevant square on the screen. That way I could ask for block (5,8) to be drawn on the screen, and a block would appear.

    Naturally, I had to test it to ensure that the right block was drawn, and that it was drawn in the right place on the screen.
  3. Next I added a simple loop to display all of the blocks in a ten by ten square. This meant it displayed the whole screen. This also had to be tested. I could now ask for the second screen across in the third row down, and get this screen drawn on the screen.
  4. Then I added a white square onto the screen, which could be moved around with the keyboard. If the square went off the side of the screen the program moved onto the next screen across. This was quite a large step forward, and took a lot of testing to get working.
  5. I added gravity, so that if there was no solid ground below the square it fell downwards.
  6. I drew several pictures of a man, and replaced the white square with them. I made the program just display the same one of them all the time at first, so you always got the same frame, and the man looked very stiff. When I had tested this, I made the program select the relevant frame to display, and so animate the man and make his legs seem to move.

When testing a program, make good use of trial and error. If an effect doesn't look quite right, fiddle around with the code until it looks better. Even if an effect looks okay, it is still often a bit of fun to fiddle with the variables to see what strange effects you can get. Sometimes you get something better than what you had originally!

Make good use of your friends in testing your software. If you are not sure which of two effects looks better, ask around. Get your friends to test your programs for you as well. Invite them over to play your new game and see how long it takes them to crash it! That is the method I used to test Shipwrecked to the limits. Vigorous testing is undoubtedly the key to successful programming.

My next Programming Techniques article will be about Graphics.

Dominic Ford, EUG #35