Qbasicnews.com

Full Version: Recursive Stuff Is Recursive Is Recursive is...
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3 4
Code:
SUB MakeRecursiveFunction(kind)
    code(kind)
    if AllKindsDone THEN RETURN -1
    FUNCTION=MakeRecursiveFunction(NewKind)
END SUB

Needless to say, I have found out the magic of recursive functions and am still learning, lol. As well as that Koch Curve, I made two filling functions, one of which works on only circles and the other which doesn't like large areas.

Keep this one in a small shape Wink
Code:
screenres 640,480
declare sub fill(x AS INTEGER, y AS INTEGER,c AS INTEGER)
circle (320,240),92,1
fill(320,240,1)
sleep
sub fill(x AS INTEGER, y AS INTEGER,c)
    if point(x,y)<>0 THEN EXIT SUB  
    PSET(x,y),c
    fill(x-1,y,c)
    fill(x,y+1,c)
    fill(x+1,y,c)
    fill(x,y-1,c)
end sub

Fill a Circle
Code:
DECLARE SUB CircleFilled(x AS INTEGER, y AS INTEGER, r AS INTEGER, c AS INTEGER)
DECLARE SUB Fill(x AS INTEGER, y AS INTEGER, c AS INTEGER)
DECLARE FUNCTION FindEdge(x AS INTEGER, y AS INTEGER, d AS INTEGER)
SCREENRES 640,480,8
CircleFilled(320,240,250,2)
SLEEP

SUB CircleFilled(x AS INTEGER, y AS INTEGER, r AS INTEGER, c AS INTEGER)
    CIRCLE (x,y),r,c
    Fill(x,y,c)
END SUB

SUB Fill(x AS INTEGER, y AS INTEGER, c AS INTEGER)
    IF y < 0 OR y > 479 THEN EXIT SUB
    IF POINT(x,y) <> 0 THEN EXIT SUB  
    LINE (findedge(x,y,-1),y)-(findedge(x,y,1),y),c
    Fill(x,y-1,c)
    Fill(x,y+1,c)
END SUB

FUNCTION FindEdge(x AS INTEGER, y AS INTEGER, d AS INTEGER)
    IF POINT(x,y) <> 0 THEN RETURN x  
    FUNCTION=FindEdge(x+d,y,d)
END FUNCTION
Code:
'Hilbert curve
DECLARE SUB Hilbert (r1%, r2%, level%)
SCREEN 12
PSET (0, 0)
clr% = 12

Hilbert 2, 0, 8
sleep
END

SUB Hilbert (r1%, r2%, level%)
SHARED clr%
IF level% THEN
  Hilbert r2%, r1%, level% - 1

  LINE -STEP(r1%, r2%), clr%

  Hilbert r1%, r2%, level% - 1

  LINE -STEP(r2%, r1%), clr%

  Hilbert r1%, r2%, level% - 1

  LINE -STEP(-r1%, -r2%), clr%

  Hilbert -r2%, -r1%, level% - 1

END IF
END SUB
Just be aware that recursion is usually SLOW. It's only used when there is no straight function. It has to initialize and deinitialize every SUB call
@Antoni Cool 8) Though I had to change the "shared clr%" to "dim shared clr%" and put it outside the sub. Dunno why you put it inside :???: .
@Wallace, they may be slower, but they are simpler to look at and are more elegant imo. Obviously whatever is better for the code is what I will use in my programs.
Deleter: It's common practice in QB, FB does not allow it.

Wallace: Recursion may be slow, but it saves a lot of arrays and indexes and is perfect for problems with a tree structure, where speed is not critical. Each method has its application.
hmm, never saw that when I coded in qb. out of curiosity, is that a global variable still? If it is, whats the point of putting the dim inside the sub?
The SHARED inside subs/functions makes a "less global" variable shared only by the functions/subs that have the SHARED declaration. It's a QB quirk not found in any other language I'm aware of.

I like it because it makes the subs/functions more self-documented, and makes global vars less prone to be modified inadvertently. However, I would have preferred to have OPTION EXPLICIT.

Anonymous

here's an 8-way linear flood fill that i translated from an example from c# =) i use it in my map editor to 'paint' tiles within other tiles' boundaries. itll stop when another tile besides the starting tile is reached. theres a bit more code than this, but its something to play with i guess.

Code:
Function flood_fill( x As Integer, y As Integer, c As Integer )

  
  

  If start_color = c Then Return -1


  Dim As Integer l_fill_loc = x
  Dim As Integer r_fill_loc = x
  
  Dim As Integer Ptr index_pointer

  index_pointer = @m->room[ll_current_room].layout[ll_current_layer][y * m->room[ll_current_room].x + x]

  Do
  
    index_pointer[0] = c
    
    indices_checked( l_fill_loc, y ) = Not 0
    
    l_fill_loc -= 1
    index_pointer -= 1
    
    If l_fill_loc < 0 Or _
       index_pointer[0] <> start_color Or _
       indices_checked( l_fill_loc, y) Then
        
      Exit Do
      
    End If  
  
  
  Loop

  l_fill_loc += 1

  index_pointer = @m->room[ll_current_room].layout[ll_current_layer][y * m->room[ll_current_room].x + x]
  
  
  Do
  
    index_pointer[0] = c
    
    indices_checked( r_fill_loc, y ) = Not 0
    
    r_fill_loc += 1
    index_pointer += 1
    
    If r_fill_loc >= m->room[ll_current_room].x Or _
       index_pointer[0] <> start_color Or _
       indices_checked( r_fill_loc, y) Then
        
      Exit Do
      
    End If  
  
  
  Loop
  
  r_fill_loc -= 1

  Dim As Integer crawl

  For crawl = l_fill_loc To r_fill_loc  
  
  
      If ( y > 0 ) Then
        If ( m->room[ll_current_room].layout[ll_current_layer][ ( y - 1 ) * m->room[ll_current_room].x + crawl] = start_color ) And _
           ( Not ( indices_checked( crawl, y - 1 ) ) ) Then
        
        flood_fill( crawl, y - 1, c )       
        
      End If
  
        If ( m->room[ll_current_room].layout[ll_current_layer][ ( y - 1 ) * m->room[ll_current_room].x + crawl - 1] = start_color ) And _
           ( x > 0 ) And _
           ( Not ( indices_checked( crawl - 1, y - 1 ) ) ) Then
        
        flood_fill( crawl - 1, y - 1, c )       
        
      End If
  
        If ( m->room[ll_current_room].layout[ll_current_layer][ ( y - 1 ) * m->room[ll_current_room].x + crawl + 1] = start_color ) And _
           ( x < m->room[ll_current_room].x ) And _
           ( Not ( indices_checked( crawl + 1, y - 1 ) ) ) Then
        
        flood_fill( crawl + 1, y - 1, c )       
        
      End If



    End If



      If ( y < m->room[ll_current_room].y ) Then  
      
        If ( m->room[ll_current_room].layout[ll_current_layer][ ( y + 1 ) * m->room[ll_current_room].x + crawl] = start_color ) And _
           ( Not ( indices_checked( crawl, y + 1 ) ) ) Then
        
        flood_fill( crawl, y + 1, c )       
        
      End If
  
        If ( m->room[ll_current_room].layout[ll_current_layer][ ( y + 1 ) * m->room[ll_current_room].x + crawl - 1] = start_color ) And _
           ( x > 0 ) And _
           ( Not ( indices_checked( crawl - 1, y + 1 ) ) ) Then
        
        flood_fill( crawl - 1, y + 1, c )       
        
      End If
  
        If ( m->room[ll_current_room].layout[ll_current_layer][ ( y + 1 ) * m->room[ll_current_room].x + crawl + 1] = start_color ) And _
           ( x < m->room[ll_current_room].x ) And _
           ( Not ( indices_checked( crawl + 1, y + 1 ) ) ) Then
        
        flood_fill( crawl + 1, y + 1, c )       
        
      End If
    
    End If


  Next

End Function
I never said it wasn't the easiest way to do things. I'm just pointing out that it is slower. Being a game programmer whos worried about FPS I just thought I'd mention it. I use it all the time for things that have nothing faster (Radix sort)
recursion won't hurt your programm that badly unless you are on a 386 ( which i guess you are not ). even doom used recursion to traverse the 2d bsp-tree it used for culling and collision so go figure :p, besides, you can translate any recursive function into a non recursive function with a stack. all you will gain by this is the loss of the function call itself.
Pages: 1 2 3 4