Do Loop Error...

NFOBoy

Active Member
Licensed User
Longtime User
So while doing a check for conditions using a Do While Loop, I came upon something that put me into a tailspin.

My goal is to analyze a users input and compare their character to a reference character, so I use a CharacterMap to store all their input.

(The commented out code below is the Do While Loop)

CharacterMap is a list of points that I am evaluating to see if they cross each other. I iterate through the points, and if the points match, I add markers (the .hasCross). This code then takes the start of a .hasCross situation and puts all the points in-between into a smaller list, so I can analyze the properties of those points. (to see if the shape is round enough to qualify as a loop)

Was working great, and then on one character I started getting some very strange behavior in my program.

You can see that I added q=638, so that I could freeze the program there during a debug session. While watching the code line by line, when q = 648 (I added the 649 to see if 648 was the problem), and EndPoint clearly not meeting the parameters for the Do While Loop, code continued OUT of the Do While Loop. (size of this particular Map was 1440 or so)

Eventually, I changed it to the If.. Next instead, and the code works great again.

But, why would this have happened? Is there a memory issue that Do While Loops have? Is there something basic in the code comparison I'm missing? (I don't think so, as it worked for many test cases before, including loops within that test character)

Anyone else have this kind of error?

Ross

(sorry about the bad variable names (CrossPointMPOrder and OriginalMaOrder, this is because when reading a Map back in from a file, I put it back into the order that it was saved, and I discoverd that I can't parse out MapOrder by itself when looking for it as a string inside each element... changing the name for each of the other two fixed that! Poor I know, but too much time invested in creating the original character files!)


B4X:
For q = i + 1 To CharacterMap.Size - 1

            If  StartPoint.CrossPointMpOrder = EndPoint.originalMaOrder AND StartPoint.originalMaOrder = EndPoint.CrossPointMpOrder _
               AND EndPoint.hasCross = True Then
                  j = q
                  q = CharacterMap.Size-1
                  Exit
               Else
                  If EndPoint.hasCross AND Not(boolLoopExists) Then
                     startmarker = q
                     boolLoopExists = True
                  End If
                  TestCharacter.Put(TestCharacter.Size, EndPoint)
               End If
               EndPoint= CharacterMap.GetValueAt(q)
            Next
            
'            Do While StartPoint.CrossPointMpOrder <> EndPoint.originalMaOrder AND StartPoint.originalMaOrder <> EndPoint.CrossPointMpOrder _
'                  AND EndPoint.hasCross <> True
'               TestCharacter.Put(TestCharacter.Size, EndPoint)
'               If q = 638 Then
'                  Dim answer
'                  q = 649
'               End If
'               q = q+1
'               If q > CharacterMap.Size -1 Then
'                  Exit
'               Else
'                  EndPoint = CharacterMap.GetValueAt(q)
'               End If
'            Loop
            'put a box around the test character
 

NFOBoy

Active Member
Licensed User
Longtime User
Erel, I have added in some more comment lines below... concur on many ways to skin the cat, but have never encountered a Do while loop that exited out of the loop, unless conditions were met. dangerous when you never reach the condition (infinite loop) but this case, it exited BEFORE the condition was met... Definitely not my cleanest code, so hoepfully comments now make more sense. I really just want to know if anyone else has had a Do While loop exit Before the condition is met. Without an Exit of course! :)

So while doing a check for conditions using a Do While Loop, I came upon something that put me into a tailspin.

My goal is to analyze a users input and compare their character to a reference character, so I use a CharacterMap to store all their input.

(The commented out code below is the Do While Loop)

CharacterMap is a list of points that I am evaluating to see if they cross each other. I iterate through the points, and if the points match, I add markers (the .hasCross). This code then takes the start of a .hasCross situation and puts all the points in-between into a smaller list, so I can analyze the properties of those points. (to see if the shape is round enough to qualify as a loop)

Was working great, and then on one character I started getting some very strange behavior in my program.

You can see that I added q=638, so that I could freeze the program there during a debug session. While watching the code line by line, when q = 648 (I added the 649 to see if 648 was the problem), and EndPoint clearly not meeting the parameters for the Do While Loop, code continued OUT of the Do While Loop. (size of this particular Map was 1440 or so)

Eventually, I changed it to the If.. Next instead, and the code works great again.

But, why would this have happened? Is there a memory issue that Do While Loops have? Is there something basic in the code comparison I'm missing? (I don't think so, as it worked for many test cases before, including loops within that test character)

Anyone else have this kind of error?

Ross

(sorry about the bad variable names (CrossPointMPOrder and OriginalMaOrder, this is because when reading a Map back in from a file, I put it back into the order that it was saved, and I discoverd that I can't parse out MapOrder by itself when looking for it as a string inside each element... changing the name for each of the other two fixed that! Poor I know, but too much time invested in creating the original character files!)


B4X:
Dim StartPoint, EndPoint As Point
Dim q As Double 'changed this to double as I was seeing if because q was int, that was the problem
Dim j As Int
   Dim TestCharacter As Map
   TestCharacter.Initialize
   
   Dim startmarker As Int 'used to look for loops within loop ends
   Dim boolLoopExists As Boolean
'   
   For i = 0 To CharacterMap.Size - 1 'start at beginning of the drawn character, analyzing point by point in the touch map
      StartPoint = CharacterMap.GetValueAt(i) 'iterate through the map
      If StartPoint.hasCross Then 'found a point with .hasCross... now need to fill up a new CharacterMap with this point and all succeeding points until the point where it crossed is reached
         If i+1 > CharacterMap.Size - 1 Then 'this will handle the case that for some reason the last point has a .hasCross and no more points after it.
            StartPoint.hasCross=False 'since no match for the last point.. reset it to False
            Exit
         Else
            EndPoint = CharacterMap.GetValueAt(i+1) 'look at each successive character to find the match
            q = i 'used to track thru the character map FROM the point that has the .hasCross
            TestCharacter.Put(TestCharacter.Size, StartPoint) 'add the Start Point to the front of the character map
            For q = i + 1 To CharacterMap.Size - 1 'will go thru from StartPoint and add all successive non-cross points
               If  StartPoint.CrossPointMpOrder = EndPoint.originalMaOrder AND StartPoint.originalMaOrder = EndPoint.CrossPointMpOrder _
                  AND EndPoint.hasCross = True Then
                  j = q 'inside this test means that there is a match.. so the EndPoint has been found
                  q = CharacterMap.Size-1 'forces the exit from the loop
                  Exit 'again forces the exit'' double redundant.. hey I was tired!
               Else
                  If EndPoint.hasCross AND Not(boolLoopExists) Then
                     startmarker = q 'if in here, then a point exists in-between that MAY be another loop, so mark it so not forget to start looking from here next iteration
                     boolLoopExists = True 'so know if to use startMarker...
                  End If
               TestCharacter.Put(TestCharacter.Size, EndPoint) 'this add the current EndPoint, which is not the TRUE endpoint to the map
               End If
               EndPoint= CharacterMap.GetValueAt(q)'to to next point and evaluate
            Next
            
'            Do While StartPoint.CrossPointMpOrder <> EndPoint.originalMaOrder AND StartPoint.originalMaOrder <> EndPoint.CrossPointMpOrder _
'                  AND EndPoint.hasCross <> True 'same thing as up top except in a do.. while loop
'               TestCharacter.Put(TestCharacter.Size, EndPoint) 'condition not met, put in the map
'               If q > CharacterMap.Size -1 Then 'force out of this do while loop, as the end of the map has been reached
'                  Exit
'               Else
'                  EndPoint = CharacterMap.GetValueAt(q) 'go to next endpoint
'               End If
'            Loop
            'put a box around the test character

            If checkLoopShape(TestCharacter) = False Then
               'do stuff to get rid of startpoint and endpoint
               StartPoint.hasCross = False
               EndPoint.hasCross = False
            Else
               'if there was a loop.. then no double loops!
               boolLoopExists = False
            End If
            
            TestCharacter.Initialize 'reset the CharaterMap
            If boolLoopExists Then 'no need to look at all the points in between again.. unless another loop possibily exists inside this one
               i = startmarker - 2
               boolLoopExists = False
            Else
               i = j+1 'start looking at the main map from where we already looked in q loop, 
            End If
         End If
      End If
   Next[/QUOTE]
 
Upvote 0

NFOBoy

Active Member
Licensed User
Longtime User
Hrmmm,

I must admit, I do see the OR/AND thing getting me behind the axle (in fact, I still am! ;) ), but how it worked for all the other points I tested... and exiting out early on that one character... grrrrr

My thought was, and still is, the While loop would generate a 1 (and exit the loop) when ALL conditions were equal (since testing for inequality against all 3, if any one was still inequal... then the AND forces a 0.

The If loop generates a 1 when all three conditions are equal (same premise, except it tests directly for equality in all 3, and if not, then AND to 0)

The IF loop is asking is A1=A2 and B1=B2 and C1 =C2 , if so, then exit, if not then continue.

The While Loop is asking: A1 <> A2 AND B1<>B2 AND C1<>C2, if so, then continue, if not, then exit. (this means that I didn't want just one of them to be equal, all have to be, because if I used an OR, then the Loop would end too soon)

double grrrrr...


:)

Fun stuff.

Thanks much Erel
 
Upvote 0
Top