| 
 Part 7Thinking about Thinking
 
 In which we'll take the player's guess, compare it to 
                    the real solution, and work out how accurate his guess was.
 Abstract ConceptsOne of the main things that people have problems with when 
                    programming is begin able to take an idea in their head, and 
                    turn that idea into computer code that does exactly what they 
                    want it to do. What I want to show you in this chapter is 
                    how we take one concept and turn it into code.
 The key (as always) is being able to break your idea into 
                    smaller and smaller rules. If you break it down far enough, 
                    then you'll have something that can easily be written in OPL. 
                    What you must remember is when writing these rules, you must 
                    mention everything you do. You can't say "compare this 
                    ball to those four," you need to say what you're comparing, 
                    to which ball, and what to do depending on the result. Checking The GuessBreaking It Down
 Before we can tell the computer what to do, we need to have 
                    a clear understanding on the thought processes that that our 
                    brain goes through. If we were making a cup of tea, it's no 
                    good having a rule that goes:
  
                    Boil Kettle You need something like:  
                    Take kettle to tap
Remove lid
Put kettle under tap
Turn on tap
DOwait a bit
UNTIL kettle is full
Put lid on kettle
Put kettle on table
Plug in power cable to kettle (it's an old fashioned one)
Switch on power at mains
Switch on kettle
DO
   wait a bit
UNTIL kettle switch moves to off position
 Of course, there's nothing to stop you calling the above 
                    PROC boil_kettle: is there. Right, so this is the level of detail we'll need to break 
                    down any computer action. Let's now look at MASTER and how 
                    I've broken it down, although you might want to have a go 
                    yourself before having a look at my solution. Again, remember there is no right or wrong way when doing 
                    routines like this. If your way works, great! Just because 
                    it's slightly different from mine, you understand it and the 
                    user gets the same end result. Checking Those BallsThe routine in Master checks to see how many balls are the 
                    right colour in the right place, and how many are the right 
                    colour but in the wrong place. These two numbers will be used 
                    to display the 'hint' to the player so he or she can make 
                    another guess to try and logically work out the solution.
 Always keep your overall goal of a procedure in mind. It 
                    helps immensely. Now
 Code BreakdownSo what we'll do here is break down exactly the thought processes 
                    that you go through when comparing a guess in Master to the 
                    correct four colour solution.
 Some CountersTo keep track of things, we'll start with two 'counters' in 
                    our heads.. the number of balls that are the right colour 
                    in the right place, and the right colour but in the wrong 
                    place. So the first thing to do is
  
                    (Right Place)=0
(Wrong Place)=0 Check all balls are guessed (if not, return)The guess button can be pressed at any time so we should check 
                    to see everything is in order before we process the guess.
  
                    (Counter)=0
DO
   (Counter) is increased by one
   IF guess position (counter) does not have a colour (ie it has a value of zero)
      Go back into game loop, print up warning message
   ENDIF
UNTIL (counter) equals four Have we won?This check is obvious. Have we got the solution correct? And 
                    as we're already thinking like a computer, we'll use a DO... 
                    UNTIL loop
  
                    (Counter)=0
DO
   (Counter) is increased by one
   IF guess position (counter) EQUALS colour in solution position (counter)
         (Right Place) is increased by one
   ENDIF
UNTIL (counter) equals four
IF (Right Place) equals four
   Then the guess is 100% correct, do the victory routine
ENDIF All the above should be pretty obvious, and easy to code 
                    (now we've bbroken it down into the small logical steps computer 
                    programming requires).  How many balls are the right colour in the right place?Well, we have the steps already don't we? We can use the code 
                    above because the (Right Place variable is going to carry 
                    the number of balls we need.
 How many balls are the right colour, but in the wrong 
                    place?Stop and think how you do this before we break it into steps. 
                    You take the first ball, and see if it matches anything in 
                    the solution (ignoring a ball if it is in the same postion 
                    (ioe the second guess compared to the second ball in the solution 
                    is something you don't do).
  
                    (Wrong Place)=0
(Counter One)=0
DO
   (Counter One) is increased by one
   (Counter Two)=0
   DO
      (Counter Two) is increased by one
      IF (Counter One) and (Counter Two) are different
         IF guess position (Counter One) equals solution position (Counter Two)
            Add one to (Wrong Place)
         ENDIF
      ENDIF
   UNTIL (Counter Two) equals four
UNTIL (Counter One) equals four So now (Wrong Place) holds the number of balls that are the 
                    right colour, but in the wrong place.Or does it?
 The 'Gotcha'
 
  PICTURE 
                    1-2-3-4 Guess  PICTURE 1-5-5-1 Solution 
 Have a look at this example. In your head, you know the correct 
                    solution is "one in the right place." But if you 
                    follow through the steps above, you 'll get "one in the 
                    right place and one in the wrong place." Why?
 Because the red ball guessed in first place is not only counted 
                    in the 'right place' code, it is also counted in the 'wrong 
                    place' code by being matched up with forth ball in the solution. One way to get round this is this simple rule that each guess 
                    ball can only be used once, as can each ball in the solution. 
                    So to facilitate this, we copy the guess and the solution 
                    into temporary arrays. When we match up balls in either the 
                    right place or the wrong place, we change the value in the 
                    array to something that wouldn't normally be there - we change 
                    a guess ball to 0, and a solution ball to 99. This way they 
                    cannot be counted again. This is one example in how 'pseudo-code' can help you pick 
                    up bugs and logical flaws before you actually sit in front 
                    of the keyboard and start typing. The Completed CodeSo, here we have all the above in OPL.
  
                    LOCAL foo%, gnu%,right_place%,wrong_place%
LOCAL foobar%(4),guessbar%(4)
rem *** Create a copy of the solution so we can remove balls
rem *** as there position is noted. Ditto with guess array
foo%=0
DO
   foo%=foo%+1
   foobar%(foo%)=solution%(foo%)
   guessbar%(foo%)=guess%(foo%)
UNTIL foo%=4
                     
rem *** check all balls are guessed
foo%=0
DO
   foo%=foo%+1
   IF guessbar%(foo%)=0 : giPRINT "Not all spaces filled..." : RETURN : ENDIF
UNTIL foo%=4
breakout%=99 : rem *** Eventull incdrement turn counter
                     
rem *** right pieces in right place
foo%=0
DO
   foo%=foo%+1
   IF guessbar%(foo%)=foobar%(foo%)
      right_place%=right_place%+1
      foobar%(foo%)=0 : rem remove from stemp solution
      guessbar%(foo%)=99 : rem remove from guess
   ENDIF
UNTIL foo%=4
IF right_place%=4 : rem Victory
   m_victory:
   RETURN
ENDIF
                     
foo%=0
DO
   foo%=foo%+1
   gnu%=0
   DO
      gnu%=gnu%+1
      IF guessbar%(foo%)=foobar%(gnu%)
         wrong_place%=wrong_place%+1
         foobar%(gnu%)=0
         gnu%=4
      ENDIF
   UNTIL gnu%=4
UNTIL foo%=4giPRINT NUM$(right_place%,1)+" in the right place, "+NUM$(wrong_place%,1)+" in the wrong place"
                     
m_showguess:(right_place%,wrong_place%,turn%) It's not called from the event loop yet (but it shouldn't 
                    be that hard to figure out how), and we haven't yet got around 
                    to displaying the generated result. All that will be covered 
                    in Part 8. But as with everything, you should be able to get down and 
                    do it yourself, so if you want a little challenge over the 
                    next fortnight... away you go! 
 Got any questions or comments arising from this tutorial. 
                    Need help with OPL. Head to the forums 
                    for help from the friendly community.  
   |