The next step Ray Elder gives hints on developing your programming with the aid of a program by Steven Bridge of Bristol. OK. So you've done the really hard work, thought of something to write, sat down and produced a working, debugged program. You are pleased. The rest of the family make approving sounds and you decide that you will send your brain-child to be published. Some weeks later an envelope drops through the door and you rush to open it to find out just how many of those blue notes they are offering. Shock! Horror! They are so unaware of real talent that they have rejected your masterpiece. Obviously they're pretty stupid so you cancel your subscription and look for another, more appreciative magazine. Probably 75% or more of the programs submitted to ZX Computing are rejected because I already have a similar program awaiting publication. The new one may have differ- ent features or been programmed differently, but once I have accepted (or if the previous editor has accepted) a program then sooner or later we will publish it. Most of the other rejections are because the program has been left in an unrefined state. What do I mean by that? Steven Bridge has very generously has very generously given me permission to use his program to try and demon- strate how you can refine a program. I do appreciate how difficult it is to accept criticism and to allow your work to be criticised in print must be twice as bad, so my most heartfelt thanks to him for taking the hot seat! Steve's Program Take a look at Program 1. [On the TZX, this is the called "Quiz Steve".] This is Steve's original program, it has no drastic bugs (there is one very minor one that is not fatal - can you spot it?), and it works fine, performing the task intended. So what's wrong with it? Answer, nothing! But let's take what I call "the next step". The first thing I noticed was the system of producing the superb music. Obviously Steve had developed this note by note in the DATA statement and used a system where 999 was the "rogue value" which signalled the end of that section. However, now that the music was completely developed it is no longer essential. Also it seems a shame to only use it once. With this in mind I created a subroutine at 8000- 8020 in my program (program 2 [a.k.a. "Quiz Ray"]). The RESTORE allows me to call it more than once and find the correct starting point of the data each time, knowing the exact length allowed a FOR/NEXT loop to be used, vari- ables a and b can both be READ in one go and the whole lot fits in one line. The next thing I noticed was the frequent use of PAUSE 100: CLS and so I thought another subroutine would be in order. On my listing I created this subroutine at line 8100. Notice I used an empty loop instead of PAUSE. This is partly a leftover technique from my ZX81 days when PAUSE caused a screen flicker and an occasional crash. However I still used it on the Spectrum because on occasions a player may be slow to remove his finger from a key and cause the pause to be ignored. Remember that a pause is cut short by a key being pressed! Variable qu is initialised in Steve's program but never used. He was probably going to use it as a question counter then developed his program in another way. As it is redun- dant we ought to remove it for neatness' sake. Steve owns a 16K Spectrum so, for the sake of memory saving, I reduced variable "score" to "sc". It would have been even better to have used "s" but I wanted to keep a balance between eco- nomy and legibility. For the latter Steve's name is the ideal! The Big Step So much for the simple, nit picking modifications. TO get a good overall view of his program, and in fact any program, it is essential to get a print out of the listing. For this purpose the sadly defunct ZX Printer or the Alphacom 32 is ideal. With a listing available the pattern of the program emerged and I traced it through looking for repetitive actions, initially in order to create subroutines but soon I became aware that it could be summarised in a simple form as follows: * 1 Print at the same position the question number. * 2 Print at the same position the questions and 3 options. * 3 Get an input. * 4 Beep. * 5 Check answer, if wrong print this at the same pos. and give correct answer. * 6 Check answer, if correct print this, add 10 to score. * 7 Next question. The only things that changed were the questions, the options and the position the correct answer was in. As so much was repeated I looked for a way to set up a format and use DATA for the different questions each time. The obvious one was the one I used. Each question was set up as a DATA line starting from line 9000, and each line consists of: * The question - a string variable * The 3 options - numeric variables * The position of the answer in the options - a numeric variable This makes it simplicity itself to amend, alter, increase or replace any of the questions as they all follow the same layout. To store the three options I used a DIMensioned array. This would prove easier to find when printing the correct answer. Also while I was about it I thought it might be nice to give the correct answer even if the player had chosen correctly, a confirmation of his choice. Finally I used variable a (for answer) to hold the posi- tion in the options of the correct answer. The Final Step Line 150 RESTOREd the data pointer to the start of the questions and line 200 set up a loop counter i. I decided that as we knew how many questions were to be asked a main loop was suitable. Using the value of "i" it was straightforward to print up the question number as Steve had in his original. The data was read into q$, each element of c() and "a" then the pause, cls subroutine was called. All in the one line. Line 210 prints out all the information. Notice the loop "j" to print each c() element, and how I utilised its value to provide suitable spacing and the numbering. This was found by trial and error. Quite often a fair bit of time needs to be spent on just formatting the screen to give a balanced, effective display. Of course, each person has his own preferences for the way a screen is laid out, this only happens to be mine. Line 212 gets the input. Here I used INKEY$. My reason was that the less key-pressing the user did the more he could concentrate on the questions. The fact that only a single number from one to three was required made it most appropriate. I also introduced a simple but effective check that a suitable key was pressed, all other keys (except BREAK of course) are ignored. Line 215 provides the BEEP then goes on to check for the correct answer by comparing the VALue of the input a$ to variable "a" read from the DATA. The variable "a" is also used to identify the correct element of c() for printing in both "correct" and "wrong" messages. The line then increases the score and jumps over line 216 to line 220. Line 216 is the "wrong" message and is only reached if VAL a$ is not equal to "a" when checked by line 215. Lines 600 to 701 follow Steve's format of presenting the messages and line 701 uses PAUSE 0 to wait for a key. At this stage there has been a lengthy gap since the last required key press so there should not be much chance of lingering fingers. Further Steps Well, Steve agreed with me that this program was much more efficient and easily adaptable than before, and we talked about other modifications it was now possible to make with the extra memory available. Most of these we'll leave for you to experiment with. The first one was that, for the sake of user friendliness, a prompt to "Press 1,2 or 3" would be nice after each question, the prompt removed on a valid input. The we thought that we could increase the number of questions. A possible idea - especially with a 48K machine - would be to have twice the number of questions in memory as were required to be asked and choose them at random. his would make for tremendous variation each time the game was played. A system of checking that a question wasn't repeated would need devising for this! We even mused on a way to present the options in a different order so that the date had to be remembered and not the position in the options. For this one we created these lines [also on the TZX as "shuffle", to be merged with "Quiz Ray"]: 205 FOR j=1 TO 4 206 LET x=INT(RND*3)+1: LET y=INT (RND*3)+1: IF x=y THEN GO TO 206 207 IF x=a THEN LET a=y: GO TO 209 208 IF y=a THEN LET a=x 209 LET z=c(x): LET c(x)=c(y):LET c(y)=z: NEXT j This swaps two elements of c() at random, four times. Lines 207/208 keep track of the position of the correct answer. Another idea was that the option data could be made into strings so that some answers could be words as well as numbers and open up a whole new range of questions. All that would be necessary would be to DIMension c$(3,4) and use c$() instead of c(), the number 4 would be altered to the length of the longest word in the answer. As it was now getting to 12.30am and I had to write this lot up, we parted. And so, here endeth the lesson...