3-Lib banner

The Absolute Beginners Guide to OPL

Part 7 - Time for a sort out


We're going to take a step sideways this week and ignore the interface itself. Instead, I'll show you how to sort the generated numbers and thus present them in a more conventional fashion. TV shows always list lottery numbers in numerical order and it would be very nice if we did the same in "Milo".

Before we get going, several people have gotten confused with all the changes so far and so I thought it a good idea to put up my code in downloadable form. If you think you would benefit from a fresh copy of the code, it's here as milo7start.txt, just merge/import it into your OPL editor as appropriate.

You'll remember from last time that we've now split our code down into several different procedures, each performing a different function. In particular, the generate: procedure is responsible for calling the picknum:() routine and displaying the results. At the moment it prints out each number as it generates it but we'll need to change the order of things slightly in order to sort the numbers prior to display.

What we'll aim to do is sort the numbers with a new procedure, sort:, and then create a new loop to do the actual displaying. The easiest way to do all this is first of all to copy a section of code: move to the generate: procedure and highlight the whole loop as shown in the screen shot:

Screen shot

Copy it to the clipboard, press the downarrow key to move the cursor to just in front of the RETURN statement and press Enter a few times to put in some blank lines. Now paste the copied code in again. We've now got two loops, both identical. Move inside the first loop and remove the three graphics lines. Similarly, remove the picknum: line from the second loop. Your code should now look something like this:

Screen shot

Translate the code, run it (remember to press Menu once inside the running program!) and you'll see that so far nothing's really changed. Having separated out the number-picking code from the number-displaying code, we are now at liberty to add in a sort: procedure to rearrange the numbers prior to display.

Add in a line between the two loops as follows:

sort: rem Sort the numbers into numerical order

Screen shot

So how are we going to actually perform the sorting process? There are many different ways of doing sorting on computers, with fancy names (QuickSort, HeapSort, CombSort etc.), but as speed isn't really an issue here, I'll use the simplest type of sort possible. Consider the following logic and try to understand it:

While we're still making changes to the number order
  For each of the 5 pairs of numbers in our array
    If the first of each pair is higher in value than the second, swap them over
  End of the For loop
End of main while loop

Note especially that for a list of 6 numbers, there are only 5 comparisons to be made, i.e. compare no.1 with no.2, 2 with 3, 3 with 4, 4 with 5 and 5 with 6. (In general, for 'n' array elements, the number of comparisons needed each time will be 'n-1'). Let's try and put this into practice in our OPL.

Move right to the bottom of the program code and enter a new procedure. Sorry for the amount of typing, I guess you could always cut and paste from your web browser from this page?

PROC sort:
LOCAL i%,flag%,temp%

flag%=1 rem set Non-zero to make sure loop starts!

WHILE flag%<>0
  flag%=0 rem reset the flag
  i%=1 :WHILE i%<=5 rem 5 possible comparisons between the 6 ball numbers
    if numbers%(i%)>numbers%(i%+1)
      temp%=numbers%(i%)
      numbers%(i%)=numbers%(i%+1)
      numbers%(i%+1)=temp%
      flag%=1
    endif
    i%=i%+1
  ENDWH
ENDWH
RETURN
ENDP

Screen shot

Can you see how I've implemented our sorting logic in OPL? The flag% variable is set to 1 to make sure the loop gets started properly and thereafter flag% gets zeroed at the start of each main loop and only set to 1 if any swapping goes on. Thus, once a loop has completed with flag% set to 0 still, we know that no more swapping was needed and that the numbers are now in correct numerical order.

Note also the way in which I've done the swapping. I use another temporary variable, temp% as a go-between. If one number is higher than the next one in line, I set temp% to the first number, then move the second number up into the space the first number occupied and finally set the second number to equal temp%. This sort of number-shuffling is what computers are particularly good at and as a consequence they manage to do it very quickly indeed!

Translate the code and run it. If all is well, when you generate the numbers you'll see something like this:

Screen shot

We've done it! The numbers are all neatly in the right order. If you don't believe me, generate a few more sets of numbers and watch the Series 5 shuffle them neatly into line!

This sorting technique can be very handy whenever you've got a small number of array elements which need re-ordering. If you've got over 100 elements, it would be worth looking into using a more efficient method, but that's a session for another day!

Next week we'll get to grips with a 'splash' screen to impress your users. See you then!


Go to next lesson | Programming index