'======================================
' Parametric Flammulate/Reticulate pattern generator
'======================================
'  Cesare Brizio, 28 October 2022
'  
'  Version Porphyria_Experiment_3.30
Version="Porphyria Experiment 3.30"
'
' I am midway between a RANDOMIZE()-based activation, 
' that I would like to avoid in the future because it's an admission
' of lack of control, and an activation by a preset delay assigned to each line.
'
'  Partly inspired by:
'      Bernard Tursch & Dietmar Greifeneder
'      «Oliva Shells - The genus Oliva and the species problem»
'      L'Informatore Piceno (Italy), 2001
'   
'     Hans Meinhardt
'     «The Algirithmic Beauty of Seashells»
'     Springer, 1995
'   
'   
'======================================
 
'======================
' Activate debug by setting 
' the DEBUG variable to "True"
'======================
'DEBUG = "True"
DEBUG = "False"
'======================
 
'--------------------------------------------------------------------------------------------------------------------------------'
' Graphics Initialization:
'--------------------------------------------------------------------------------------------------------------------------------'
GeneralBackgroundColor="Wheat" ' #F5DEB3
Edge_LINE_Color="FireBrick" ' #B22222
GraphicsWindow.BackgroundColor = GeneralBackgroundColor
GraphicsWindow.BrushColor = "Black"
GraphicsWindow.CanResize="True"
GraphicsWindow.FontName="Roboto"
GraphicsWindow.FontSize = 14
GraphicsWindow.Height = 750
GraphicsWindow.Left= 0
GraphicsWindow.Title = "Shell Pattern Generator"
GraphicsWindow.Top = 0
GraphicsWindow.Width = 1200
 
'--------------- Opening
CRLF = Text.GetCharacter(13) + Text.GetCharacter(10)
Opening="This is a less over-engineered and partly successful piece of software in the same family as my previous, "
Opening= Opening+"uneffective «Oliva Shell Pattern Generator»"+CRLF
Opening= Opening+"Differently from its predecessor, this program is mostly hard-coded and doesn't provide an "
Opening= Opening+"actual user interface."+CRLF 
Opening= Opening+"I improved the similitude of the generated pattern and that of Oliva porphyria, one of my target species."+CRLF
Opening= Opening+"The initial concept is based on the «wavefront approach» avocated, among others, by Bernard Tursch & Dietmar "
Opening= Opening+"Greifeneder in their book «Oliva Shells - The genus Oliva and the species problem» "
Opening= Opening+"- L'Informatore Piceno (Italy), 2001. The incomparably better results provided by the software by Hans Meinhardt, "
Opening= Opening+"«The Algorithmic Beauty of Seashells» - Springer, 1995 "
Opening= Opening+"are obtained with an entirely different approach. "+CRLF
Opening= Opening+"This program is aimed at providing a linear array of pixel generators that 'extrudes' the pattern on its entire length: "
Opening= Opening+"just in that respect, it may reflect its natural model, the shell growing edge."+CRLF
Opening= Opening+""+CRLF 
Opening= Opening+"                                                      WARNING !!! "+CRLF 
Opening= Opening+""+CRLF 
Opening= Opening+"While taking advantage of some of the best virtues of Small Basic, this program takes also its worst defect - "
Opening= Opening+"slowness."+CRLF
Opening= Opening+" - First, some minutes are taken to initialize matrixes (you can follow the countdown on the text window);"+CRLF
Opening= Opening+" - Then, many more minutes are taken to generate the outlined pattern;"+CRLF
Opening= Opening+" - Finally, fill color is added via a «fill region» algorithm, that requires no less than five minutes, often more, to scan the whole screen."+CRLF 
Opening= Opening+"The whole process may take well above 20 minutes."
'--------------------------------------------------------------------------------------------------------------------------------'
' Show Opening message:
'--------------------------------------------------------------------------------------------------------------------------------'
Curr_Text = Opening
GraphicsWindow.ShowMessage(Curr_Text,"Oliva porphyria Pattern Experiment 3.30")
 
 
'==========================
' Cycling array of Fill Colors
'==========================
FillColor[1] = "#FFFFFF" '  "White"
FillColor[2] = "#FFF5EE" '  "Seashell"
FillColor[3] = "#FFFFE0" '  "LightYellow"
FillColor[4] = "#FFFFF0" '  "Ivory"
 
'=====================================
' Cycling Array - Inhibition by collision
' 60% of the times no line survives collision
' 20% of the times, the UPWARD line survives
' 20% of the times, the DOWNWARD line survives
'=====================================
WHO_SURVIVES[1] = "NONE" 'upon collision, no line survives
WHO_SURVIVES[2] = "NONE"   'upon collision, the line going UP survives
WHO_SURVIVES[3] = "UP" 'upon collision, the line going DOWN survives
WHO_SURVIVES[4] = "NONE"
WHO_SURVIVES[5] = "DOWN"
WHO_SURVIVES[6] = "NONE"
WHO_SURVIVES[7] = "NONE"
WHO_SURVIVES[8] = "UP"
WHO_SURVIVES[9] = "NONE"
WHO_SURVIVES[10] = "DOWN"
 
 
'=========================================
' Choose configuration
'=========================================
TextWindow.CursorLeft = 0
TextWindow.CursorTop = 0
TextWindow.WriteLine("Which configuration would you like to test (1=porphyria-like, 2=alternative)?")
ASK_CONFIG_AGAIN:
TextWindow.WriteLine("Please enter a number ( 1 or 2 ):")
CONFIG = TextWindow.Read()
If CONFIG < 1 or CONFIG > 2 Then
  TextWindow.WriteLine("You entered a value lower than 1 or higher than 2!")
  Goto ASK_CONFIG_AGAIN
EndIf
For I = 0 to 3
  TextWindow.CursorLeft = 0
  TextWindow.CursorTop = I
  TextWindow.WriteLine("                                                                                 ")
EndFor
 
'--------------------------------------------------------------------------------------------------------------------------------'
' Display Rendering Parameters
'--------------------------------------------------------------------------------------------------------------------------------'
'==================================
' Window: 1200 x 750
' Active area 1200 x 700
'==================================
GraphicsWindow.BrushColor=GraphicsWindow.BackgroundColor
GraphicsWindow.FillRectangle(0,0,1200,750)
GraphicsWindow.FontName="Roboto"
GraphicsWindow.FontSize = 14
GraphicsWindow.BrushColor = "Black"
'Current parameters will be shown above the graphics
GraphicsWindow.DrawText(0,730,Clock.Day+"/"+Clock.Month+"/"+(Clock.Year-2000)+" "+Clock.Time+" -Version "+Version+" - Configuration "+Config)
 
'--------------------------------------------------------------------------------------------------------------------------------'
' STATE VECTOR Initialization
'
'   WW  AA  RR  NN  II  NN  GG  !!!   !!!   !!!
'
' For clarity of rendering, every X position in the array corresponds to 2 (two) pixels.
' So, a 600 dots array will require 1200 pixels on the screen
'
' States are "B" (background)  and "E" (edge)
' scanning is retrograde (right to left) to simulate a clokwise creation of the pattern
'--------------------------------------------------------------------------------------------------------------------------------'
' Should be 600 to 1 !!!!
For X=600 To 1 Step -1
  For Y=1 To 700
    TextWindow.CursorLeft = 0
    TextWindow.CursorTop = 0
    TextWindow.WriteLine(" Y = "+Y+ " X = "+X+"              ")  
    STATE[X][Y]="B" 'Everything is BACKGROUND
  EndFor  
EndFor
 
 
If Config=1 Then
  '=================================================================================
  '=================================================================================
  '=================================================================================
  ' Porphyria-like pattern
  '=================================================================================
  '=================================================================================
  '=================================================================================
  '=====================================
  ' Cycling Array - Inhibition by collision
  ' 60% of the times no line survives collision
  ' 20% of the times, the UPWARD line survives
  ' 20% of the times, the DOWNWARD line survives
  '=====================================
  WHO_SURVIVES[1] = "NONE" 'upon collision, no line survives
  WHO_SURVIVES[2] = "NONE" 
  WHO_SURVIVES[3] = "UP"   'upon collision, the line going UP survives
  WHO_SURVIVES[4] = "NONE"
  WHO_SURVIVES[5] = "DOWN" 'upon collision, the line going DOWN survives
  WHO_SURVIVES[6] = "NONE"
  WHO_SURVIVES[7] = "NONE"
  WHO_SURVIVES[8] = "UP"
  WHO_SURVIVES[9] = "NONE"
  WHO_SURVIVES[10] = "DOWN"
  '=====================================
  ' Cycling Array - Each Y position is assigned a
  ' delay. This is a tentative and probably unrealistic
  ' idea: after "rapid firing" for some times, the
  ' delay abruptly increases then after some cycles
  ' abruptly decreases
  '=====================================
  TYP_DELAY[1] = 8
  TYP_DELAY[2] = 12
  TYP_DELAY[3] = 8
  TYP_DELAY[4] = 16
  TYP_DELAY[5] = 40
  TYP_DELAY[6] = 60
  TYP_DELAY[7] = 80
  TYP_DELAY[8] = 60
  TYP_DELAY[9] = 40
  TYP_DELAY[10] = 32
  '--------------------------------------------------------------
  ' Number of elements in the delay array +1
  '--------------------------------------------------------------
  MAX_COUNT_DELAY = 11
  '--------------------------------------------------------------
  ' Maximum initial delay
  '--------------------------------------------------------------
  Inital_Max_Delay = 80
  '--------------------------------------------------------------------------------------------------------------------------------'
  ' DELAY VECTOR Initialization
  '   Each Y position has a delay assigned. Once expired, the state turns to "E"
  '--------------------------------------------------------------------------------------------------------------------------------'
  For Y=1 To 700
    ' randomize initial delay up to maximum initial delay
    DELAY[Y]=Math.GetRandomNumber(Math.Round(Inital_Max_Delay))
    ' randomize expired time for activation up to half maximum initial delay
    TIME_TICK[Y]=Math.GetRandomNumber(Math.Round(Inital_Max_Delay/2))
  EndFor
  '--------------------------------------------------------------------------------------------------------------------------------'
  ' Inhibition radius (minimum distance between new activation and exisiting activations)
  '--------------------------------------------------------------------------------------------------------------------------------'
  New_Px_Inhib_Radius=2  
  '--------------------------------------------------------------------------------------------------------------------------------'
  ' New Activation Conflict Control may be enabled or disabled
  '--------------------------------------------------------------------------------------------------------------------------------'
  New_Activation_Conflict_Control="TRUE"
  '--------------------------------------------------------------------------------------------------------------------------------'
  ' Survival strategy based on cycling array
  '--------------------------------------------------------------------------------------------------------------------------------'  
  OLDER_SURVIVES = "FALSE"
  '--------------------------------------------------------------------------------------------------------------------------------'
  ' Global periodical reset disabled
  '--------------------------------------------------------------------------------------------------------------------------------'    
  Global_Periodical_Reset ="FALSE"
  Global_Periodical_Reset_Step =0
  '-----------------------------------------
  'lines may propagate indefinitely!
  '-----------------------------------------
  AGING = "FALSE"
  MAX_AGE = 10000  
Elseif Config=2 Then
  '=================================================================================
  '=================================================================================
  '=================================================================================
  ' Alternative pattern
  '=================================================================================
  '=================================================================================
  '=================================================================================
  '=====================================
  ' Cycling Array - Inhibition by collision
  ' 60% of the times no line survives collision
  ' 20% of the times, the UPWARD line survives
  ' 20% of the times, the DOWNWARD line survives
  '=====================================
  WHO_SURVIVES[1] = "UP" 'upon collision, no line survives
  WHO_SURVIVES[2] = "NONE" 
  WHO_SURVIVES[3] = "NONE" 
  WHO_SURVIVES[4] = "DOWN"
  WHO_SURVIVES[5] = "UP" 
  WHO_SURVIVES[6] = "NONE"
  WHO_SURVIVES[7] = "DOWN"
  WHO_SURVIVES[8] = "NONE" 
  WHO_SURVIVES[9] = "UP"
  WHO_SURVIVES[10] = "DOWN"  
  '=====================================
  ' Cycling Array - Each Y position is assigned a
  ' delay. 
  ' delays increase then decrease every 10 pixels
  ' delay abruptly increases then after some cycles
  ' abruptly decreases
  '=====================================
  TYP_DELAY[1] = 8
  TYP_DELAY[2] = 4
  TYP_DELAY[3] = 36
  TYP_DELAY[4] = 33
  TYP_DELAY[5] = 8
  TYP_DELAY[6] = 4
  TYP_DELAY[7] = 36
  TYP_DELAY[8] = 33
  TYP_DELAY[9] = 10
  TYP_DELAY[10] = 30
  TYP_DELAY[11] = 33
  TYP_DELAY[12] = 36
  TYP_DELAY[13] = 8
  TYP_DELAY[14] = 4
  TYP_DELAY[15] = 8
  TYP_DELAY[16] = 4
  TYP_DELAY[17] = 36
  TYP_DELAY[18] = 33
  TYP_DELAY[19] = 8
  TYP_DELAY[20] = 4
  '--------------------------------------------------------------
  ' Number of elements in the delay array +1
  '--------------------------------------------------------------
  MAX_COUNT_DELAY = 21
  '--------------------------------------------------------------
  ' Maximum initial delay
  '--------------------------------------------------------------
  ' NO! Initial delay will be assigned during Delay vector initialization  Inital_Max_Delay = 10
  '--------------------------------------------------------------------------------------------------------------------------------'
  ' DELAY VECTOR Initialization
  '   Each Y position has a delay assigned. Once expired, the state turns to "E"
  '--------------------------------------------------------------------------------------------------------------------------------'
  activation_step = 15
  For Y=1 To 700
    what=Math.Remainder(Y,20)
    Activable=Math.Remainder(Y,activation_step)
    If Activable = 1 then
      AGAIN_DELAY:
      ' randomize initial delay up to Typ_DELAY[what], so that nearby Y will activate in different moments
      DELAY[Y]=Math.GetRandomNumber(Math.Round(TYP_DELAY[what]))
      '----------random assigned delay  should not less than 80% of the reference TYP_DELAY
      If DELAY[Y] < (TYP_DELAY[what]*0.8) then
        Goto AGAIN_DELAY
      EndIf  
 
      ' randomize expired time for activation up to one third of  the reference TYP_DELAY
      TIME_TICK[Y]=Math.GetRandomNumber(Math.Round(TYP_DELAY[what]/3))
      'TIME_TICK[Y] = DELAY[Y]-1
 
    Else
      '============ Inactive "forever"
      DELAY[Y] = 10000
    EndIf    
    TextWindow.CursorLeft = 0
    TextWindow.CursorTop = 0
    TextWindow.WriteLine(" [Y] = "+Y+" DELAY[Y] = "+DELAY[Y]+ " TIME_TICK[Y] = "+TIME_TICK[Y]+"                        ")  
  EndFor  
  '--------------------------------------------------------------------------------------------------------------------------------'
  ' Inhibition radius (minimum distance between new activation and exisiting activations)
  '--------------------------------------------------------------------------------------------------------------------------------'
  New_Px_Inhib_Radius=2    
  '--------------------------------------------------------------------------------------------------------------------------------'
  ' New Activation Conflict Control may be enabled or disabled
  '--------------------------------------------------------------------------------------------------------------------------------'
  New_Activation_Conflict_Control="TRUE"  
  '--------------------------------------------------------------------------------------------------------------------------------'
  ' Survival strategy based on line age (if TRUE it disables the usage of WHO_SURVIVES[] array)
  '--------------------------------------------------------------------------------------------------------------------------------'  
  OLDER_SURVIVES = "TRUE"  
  '--------------------------------------------------------------------------------------------------------------------------------'
  ' Global periodical reset enabled
  '--------------------------------------------------------------------------------------------------------------------------------'    
  Global_Periodical_Reset ="TRUE"
  Global_Periodical_Reset_Step =60  
  '------------------------------------------------------
  ' if  AGING = "TRUE"
  ' lines may propagate up to MAX_AGE length
  '------------------------------------------------------
  AGING = "FALSE"
  '-------- Tentative quantification relative to global reset step
  MAX_AGE = 40
EndIf  
 
 
 
TextWindow.WriteLine("Riga 317                            ")
 
  ' Initialization of  the index of the cycling vector that defines
  ' survival strategies upon collision
  COUNT_SURVIVAL = 0
 
  ' For X= 600 To 1 Step -1  
  For X= 600 To 1 Step -1  
 
    '====================================================
    ' In config = 2 every Global_Periodical_Reset_Step X all the current front 
    ' is disabled and delays are reset
    '==================================================== 
    If Global_Periodical_Reset ="TRUE" then
      If X> (Global_Periodical_Reset_Step+1) and X<(600) And Math.Remainder(X,Global_Periodical_Reset_Step) = 0 Then
      TextWindow.CursorLeft = 0
      TextWindow.CursorTop = 0
      TextWindow.WriteLine(" GLOBAL PERIODICAL RESET                                                ")     
        'TextWindow.Read()
        Sound.PlayBellRing()
        For THIS_Y=1 To 700
          'reset all column to "B"
          STATE[X][THIS_Y]="B"    
          STATE[X+1][THIS_Y]="B"    
          what=Math.Remainder(THIS_Y,20)          
          Activable=Math.Remainder(THIS_Y,activation_step)          
          If Activable = 1 then  
            AGAIN_DEL:
            ' randomize initial delay up to Typ_DELAY[what], so that nearby Y will activate in different moments
            DELAY[THIS_Y]=Math.GetRandomNumber(Math.Round(TYP_DELAY[what]))
            '----------random assigned delay  should not less than 80% of the reference TYP_DELAY
            If DELAY[THIS_Y] < (TYP_DELAY[what]*0.8) then
              Goto AGAIN_DEL
            EndIf  
            TIME_TICK[THIS_Y]=Math.GetRandomNumber(Math.Round(TYP_DELAY[what]/3))
            'TIME_TICK[THIS_Y] = DELAY[THIS_Y]-1       
          Else
            '============ Inactive "forever"
            DELAY[THIS_Y] = 10000
          EndIf            
        EndFor  
      EndIf
    EndIf
 
    For Y= 2 To 700
      TextWindow.CursorLeft = 0
      TextWindow.CursorTop = 0
      TextWindow.WriteLine(" Y = "+Y+ " X = "+X+"             ")     
      '==============================================
      ' SELF ACTIVATION UPON DELAY EXPIRATION
      '==============================================
      Time_tick[Y] = Time_tick[Y] + 1
      ' Only "B" cells need activation!
      If TIME_TICK[Y] = DELAY[Y] and STATE[X][Y] = "B" Then 
        ' reset time count
        TIME_TICK[Y] = 1
        ' cycle to next delay
        WHICH_DELAY = WHICH_DELAY +1
        If WHICH_DELAY = MAX_COUNT_DELAY then
          WHICH_DELAY = 1
        EndIf 
        'assign new delay to current Y
        CURR_DELAY=TYP_DELAY[WHICH_DELAY]
        ONCE_MORE_DELAY:
        DELAY[Y]=Math.GetRandomNumber(Math.Round(CURR_DELAY))
        '----------random assigned delay  should not less than 80% of the reference TYP_DELAY
        If DELAY[Y] < (CURR_DELAY*0.8) then
          Goto ONCE_MORE_DELAY
        EndIf
 
 
        If New_Activation_Conflict_Control="TRUE" then
          'check whether self activation should be inhibited
          Inhibit = "FALSE"
          For Chk_Y = (Y-New_Px_Inhib_Radius) To (Y+New_Px_Inhib_Radius)
            For Chk_X = X To (X+New_Px_Inhib_Radius)
              If STATE[Chk_X][Chk_Y] <> "B" Then
                Inhibit = "TRUE"
              EndIf  
            EndFor
          EndFor
          ' activate unless inhibited
          If Inhibit = "FALSE" Then
            STATE[X][Y] = "E"
            '--------------------------------------------------------------------
            ' considering that the cell has just been activated, 
            ' we should reset its "time before next activation" count
            '--------------------------------------------------------------------
            TIME_TICK[Y] = 1
            'draw 2 (TWO) pixels      
            GraphicsWindow.SetPixel(X*2,Y,Edge_LINE_Color)
            GraphicsWindow.SetPixel((X*2)-1,Y,Edge_LINE_Color) 
            Goto SKIP_OTHER_TESTS 
          EndIf
        Else
          'ACTIVATE ANYWAY
          STATE[X][Y] = "E"
          '--------------------------------------------------------------------
          ' considering that the cell has just been activated, 
          ' we should reset its "time before next activation" count
          '--------------------------------------------------------------------
          TIME_TICK[Y] = 1          
          'draw 2 (TWO) pixels      
          GraphicsWindow.SetPixel(X*2,Y,Edge_LINE_Color)
          GraphicsWindow.SetPixel((X*2)-1,Y,Edge_LINE_Color)           
          Goto SKIP_OTHER_TESTS   
        EndIf
      EndIf 
 
      '==============================================
      ' CONVERGENCE + STOP - FIRST CASE
      '              X     X+1     X+2
      '  Y-2     -         -          * 
      '  Y-1     -         *          -
      '  Y        *         -          -
      '  Y+1   ?         *          -
      '  Y+2  ?          -         *
      '==============================================
      If STATE[X+1][Y-1] = "E" And STATE[X+1][Y+1] = "E" then
        'I must be sure that I am observing a convergence and not just
        'the first step of a divergence (in this latter case I find the 
        'originating point two steps right)
        If STATE[X+2][Y] = "B" Then
          'draw 2 (TWO) pixels      
          GraphicsWindow.SetPixel(X*2,Y,Edge_LINE_Color)
          GraphicsWindow.SetPixel((X*2)-1,Y,Edge_LINE_Color) 
          '===================================================
          ' WHICH LINE SURVIVES AFTER COLLISION???
          ' NONE, GOING UP, OR GOING DOWN???
          '===================================================
          If OLDER_SURVIVES = "FALSE" THEN
            '===========================================
            ' CYCLING ARRAY-BASED SURVIVAL STRATEGY
            '===========================================
            COUNT_SURVIVAL=COUNT_SURVIVAL+1
            If COUNT_SURVIVAL = 11 Then
              COUNT_SURVIVAL = 1 
            EndIf
            Survivor = WHO_SURVIVES[COUNT_SURVIVAL]
          else
            '===========================================
            ' THE OLDER SURVIVES
            '===========================================  
            '-----------------------------------------------------
            ' Line age control is in place! 
            ' the younger/shorter line should stop propagating
            '-----------------------------------------------------
            CURR_AGE = 0
            Check_X=X+1
            Check_Y=Y-1
            CHECK_AGE()
            AGE_Y_MINUS_ONE= CURR_AGE
            CURR_AGE = 0
            Check_X=X+1
            Check_Y=Y+1
            CHECK_AGE()
            AGE_Y_PLUS_ONE = CURR_AGE   
            If AGE_Y_MINUS_ONE > AGE_Y_PLUS_ONE then
              Survivor = "DOWN"
            elseif AGE_Y_PLUS_ONE > AGE_Y_MINUS_ONE Then
              Survivor = "UP"
            else
              Survivor = "NONE"
            EndIf          
 
          EndIf
 
 
          If Survivor = "NONE" Then
            '================
            ' SURVIVOR = NONE
            '================   
            'inhibit current state
            STATE[X][Y] = "B"    
            'inhibit ABOVE       'HERE
            STATE[X][Y-1] = "B" 'HERE
            'inhibit BELOW       'HERE
            STATE[X][Y+1] = "B" 'HERE            
 
          ElseIf Survivor = "UP" Then
            '================
            ' SURVIVOR = UP
            '================
            'draw 2 (TWO) pixels      HERE
            GraphicsWindow.SetPixel(X*2,Y,Edge_LINE_Color) 'HERE
            GraphicsWindow.SetPixel((X*2)-1,Y,Edge_LINE_Color) 'HERE
            'rise local state
            STATE[X][Y] = "E"
            '--------------------------------------------------------------------
            ' considering that the cell has just been activated, 
            ' we should reset its "time before next activation" count
            '--------------------------------------------------------------------
            TIME_TICK[Y] = 1   
            'inhibit position X+1, Y-1
            'the couple local state + state in [X+1][Y+1]
            'will allow continuation of upward line
            STATE[X+1][Y-1] = "B"
 
 
          Else
            '================
            ' SURVIVOR = DOWN
            '================
            'draw 2 (TWO) pixels      HERE
            GraphicsWindow.SetPixel(X*2,Y,Edge_LINE_Color) 'HERE
            GraphicsWindow.SetPixel((X*2)-1,Y,Edge_LINE_Color) 'HERE            
            'rise local state
            STATE[X][Y] = "E"
            '--------------------------------------------------------------------
            ' considering that the cell has just been activated, 
            ' we should reset its "time before next activation" count
            '--------------------------------------------------------------------
            TIME_TICK[Y] = 1   
            'inhibit position X+1, Y+1
            'the couple local state + state in [X+1][Y-1]
            'will allow continuation of downward line
            STATE[X+1][Y+1] = "B"            
          EndIf
 
        EndIf  
        ' convergence define borders. I should
        'fill the area
        X_SEED = ((X+1)*2)
        Y_SEED = Y
        'I add current X_Seed and Y_Seed to the list of areas that should be filled
        Add_fillRegion() 
        Goto SKIP_OTHER_TESTS
      EndIf 
 
 
      '==============================================
      ' CONVERGENCE + STOP - SECOND CASE
      '              X     X+1     X+2
      '  Y-2      -        -         *  
      '  Y-1     ?        *         -    
      '  Y        ?         *         -   
      '  Y+1   ?          -        *    
      '==============================================
      If STATE[X+1][Y-1] = "E" And STATE[X+1][Y] = "E" then
          '===================================================
          ' WHICH LINE SURVIVES AFTER COLLISION???
          ' NONE, GOING UP, OR GOING DOWN???
          '===================================================
 
          If OLDER_SURVIVES = "FALSE" THEN
            '===========================================
            ' CYCLING ARRAY-BASED SURVIVAL STRATEGY
            '===========================================
            COUNT_SURVIVAL=COUNT_SURVIVAL+1
            If COUNT_SURVIVAL = 11 Then
              COUNT_SURVIVAL = 1 
            EndIf
            Survivor = WHO_SURVIVES[COUNT_SURVIVAL]
          else
            '===========================================
            ' THE OLDER SURVIVES
            '===========================================  
            '-----------------------------------------------------
            ' Line age control is in place! 
            ' the younger/shorter line should stop propagating
            '-----------------------------------------------------
            CURR_AGE = 0
            Check_X=X+1
            Check_Y=Y-1
            CHECK_AGE()
            AGE_Y_MINUS_ONE= CURR_AGE
            CURR_AGE = 0
            Check_X=X+1
            Check_Y=Y
            CHECK_AGE()
            AGE_Y = CURR_AGE   
            If AGE_Y_MINUS_ONE > AGE_Y then
              Survivor = "DOWN"
            elseif AGE_Y > AGE_Y_MINUS_ONE Then
              Survivor = "UP"
            else
              Survivor = "NONE"
            EndIf          
 
          EndIf
 
 
          If Survivor = "NONE" Then
            '================
            ' SURVIVOR = NONE
            '================   
            'inhibit current state
            STATE[X][Y] ="B"
            STATE[X][Y-1] ="B"         
          ElseIf Survivor = "UP" Then
            '================
            ' SURVIVOR = UP
            '================
            'inhibit position X+1, Y-1
            'the couple [X][Y-1] +  [X+1][Y]
            'will allow continuation of upward line
            STATE[X+1][Y-1] = "B"
            STATE[X][Y-1] = "E"
            '--------------------------------------------------------------------
            ' considering that the cell has just been activated, 
            ' we should reset its "time before next activation" count
            '--------------------------------------------------------------------
            TIME_TICK[Y] = 1               
            'draw 2 (TWO) pixels      HERE
            GraphicsWindow.SetPixel(X*2,Y-1,Edge_LINE_Color) 'HERE
            GraphicsWindow.SetPixel((X*2)-1,Y-1,Edge_LINE_Color) 'HERE     
          Else
            '================
            ' SURVIVOR = DOWN
            '================
            'inhibit position X+1, Y
            'the couple [X][Y] +  [X+1][Y-1]
            'will allow continuation of upward line
            STATE[X+1][Y] = "B"
            STATE[X][Y] = "E"  
            '--------------------------------------------------------------------
            ' considering that the cell has just been activated, 
            ' we should reset its "time before next activation" count
            '--------------------------------------------------------------------
            TIME_TICK[Y] = 1               
            'draw 2 (TWO) pixels      HERE
            GraphicsWindow.SetPixel(X*2,Y,Edge_LINE_Color) 'HERE
            GraphicsWindow.SetPixel((X*2)-1,Y,Edge_LINE_Color) 'HERE                 
          EndIf
 
        'convergence defines borders. I should
        'fill the area
        X_SEED = ((X+1)*2)+1
        Y_SEED = Y
        'I add current X_Seed and Y_Seed to the list of areas that should be filled
        Add_fillRegion() 
        Goto SKIP_OTHER_TESTS
      EndIf      
 
 
      '==============================================
      ' DESCENDING
      ' at my right, in two consecutive steps UP the state is "E", 
      ' then current [X][Y] is the continuation of a DESCENDING line.
      ' I draw the dot and set [X][Y] to "E" (the line should continue)
      '              X     X+1   X+2
      '  Y-2      -        -        *   
      '  Y-1     -         *         -    
      '  Y        ?         -         -   
      '==============================================        
      If STATE[X+1][Y-1] = "E" And STATE[X+2][Y-2] = "E" then
        'If I found a descending line, I continue it only in case I don't 
        'observe a convergence
        If STATE[X+2][Y] ="B" And STATE[X+1][Y] ="B" Then
          If AGING = "FALSE" Then
            STATE[X][Y] ="E" 
            '--------------------------------------------------------------------
            ' considering that the cell has just been activated, 
            ' we should reset its "time before next activation" count
            '--------------------------------------------------------------------
            TIME_TICK[Y] = 1               
            'draw 2 (TWO) pixels      
            GraphicsWindow.SetPixel(X*2,Y,Edge_LINE_Color)
            GraphicsWindow.SetPixel((X*2)-1,Y,Edge_LINE_Color) 
            Goto SKIP_OTHER_TESTS             
          Else
            '-----------------------------------------------------
            ' Line age control is in place! Lines longer 
            ' than MAX_AGE should stop propagating
            '-----------------------------------------------------
            CURR_AGE = 0
            Check_X=X
            Check_Y=Y
            CHECK_AGE()
 
            'TextWindow.CursorLeft = 0
            'TextWindow.CursorTop = 0
            'TextWindow.WriteLine("CURR_AGE = "+CURR_AGE+"                                                         ") 
            'TextWindow.Read()
 
            If CURR_AGE >= MAX_AGE Then
              '------------------------------------
              ' INACTIVATE
              '------------------------------------
              STATE[X][Y]="B"
              Goto SKIP_OTHER_TESTS
            Else  
              STATE[X][Y] ="E" 
              '--------------------------------------------------------------------
              ' considering that the cell has just been activated, 
              ' we should reset its "time before next activation" count
              '--------------------------------------------------------------------
              TIME_TICK[Y] = 1                 
              'draw 2 (TWO) pixels      
              GraphicsWindow.SetPixel(X*2,Y,Edge_LINE_Color)
              GraphicsWindow.SetPixel((X*2)-1,Y,Edge_LINE_Color) 
              Goto SKIP_OTHER_TESTS   
            EndIf               
          EndIf  
        EndIf  
      EndIf  
 
 
      '==============================================
      ' ASCENDING
      ' at my right, in two consecutive steps DOWN the state is "E", 
      ' then current [X][Y] is the continuation of an ASCENDING line.
      ' I draw the dot and set [X][Y] to "E" (the line should continue)      
      '              X     X+1   X+2 
      '  Y        ?        -         -  
      '  Y+1   ?        *         -   
      '  Y+2  ?          -       *   
      '==============================================      
      If STATE[X+1][Y+1] = "E" And STATE[X+2][Y+2] = "E"  then
        'If I found an ascending line, I continue it only in case I don't 
        'observe a convergence
        If STATE[X+2][Y] = "B" And STATE[X+1][Y] ="B" Then
          If AGING = "FALSE" Then
            STATE[X][Y] ="E" 
            '--------------------------------------------------------------------
            ' considering that the cell has just been activated, 
            ' we should reset its "time before next activation" count
            '--------------------------------------------------------------------
            TIME_TICK[Y] = 1               
            'draw 2 (TWO) pixels      
            GraphicsWindow.SetPixel(X*2,Y,Edge_LINE_Color)
            GraphicsWindow.SetPixel((X*2)-1,Y,Edge_LINE_Color) 
            Goto SKIP_OTHER_TESTS          
          Else
            '-----------------------------------------------------
            ' Line age control is in place! Lines longer 
            ' than MAX_AGE should stop propagating
            '-----------------------------------------------------
            CURR_AGE = 0
            Check_X=X
            Check_Y=Y            
            CHECK_AGE()
 
            'TextWindow.CursorLeft = 0
            'TextWindow.CursorTop = 0
            'TextWindow.WriteLine("CURR_AGE = "+CURR_AGE+"                                                         ") 
            'TextWindow.Read()
 
            If CURR_AGE >= MAX_AGE Then
              '------------------------------------
              ' INACTIVATE
              '------------------------------------
              STATE[X][Y]="B"
              Goto SKIP_OTHER_TESTS
            Else  
              STATE[X][Y] ="E" 
              '--------------------------------------------------------------------
              ' considering that the cell has just been activated, 
              ' we should reset its "time before next activation" count
              '--------------------------------------------------------------------
              TIME_TICK[Y] = 1                 
              'draw 2 (TWO) pixels      
              GraphicsWindow.SetPixel(X*2,Y,Edge_LINE_Color)
              GraphicsWindow.SetPixel((X*2)-1,Y,Edge_LINE_Color) 
              Goto SKIP_OTHER_TESTS   
            EndIf  
          EndIf    
        EndIf
      EndIf    
 
 
      '==============================================
      ' NEW GENERATION POINT
      ' at my right the state is "E", but the point is not the continuation
      ' of any line: only explanation is that it was activated randomly
      ' and should originate two diverging lines
      '              X     X+1   X+2 
      '  Y-1     ?        -         -  
      '  Y        ?        *        -   
      '  Y+1   ?          -       -    
      '==============================================      
      If STATE[X+1][Y] = "E" And STATE[X+2][Y+1] = "B" And STATE[X+2][Y-1] = "B" then
        STATE[X][Y-1] ="E" 
        '--------------------------------------------------------------------
        ' considering that the cell has just been activated, 
        ' we should reset its "time before next activation" count
        '--------------------------------------------------------------------
        TIME_TICK[Y-1] = 1   
        'draw 2 (TWO) pixels      
        GraphicsWindow.SetPixel(X*2,Y-1,Edge_LINE_Color)
        GraphicsWindow.SetPixel((X*2)-1,Y-1,Edge_LINE_Color)        
        STATE[X][Y+1] ="E" 
        '--------------------------------------------------------------------
        ' considering that the cell has just been activated, 
        ' we should reset its "time before next activation" count
        '--------------------------------------------------------------------
        TIME_TICK[Y+1] = 1           
        'draw 2 (TWO) pixels      
        GraphicsWindow.SetPixel(X*2,Y+1,Edge_LINE_Color)
        GraphicsWindow.SetPixel((X*2)-1,Y+1,Edge_LINE_Color)      
 
        '----------------------------------------------------------------
        ' I just set the state of the element under the current Y
        ' I increase Y consequently to avoid reprocessing 
        ' that element
        '----------------------------------------------------------------
        Y = Y+1
      EndIf            
 
SKIP_OTHER_TESTS: 
    EndFor    
  EndFor   
 
fillRegions()  
 
 
Sub Add_fillRegion
  'I save the current X_SEED and Y_SEED in the X_TO_FILL and Y_TO_FILL arrays
  index_points_to_fill = index_points_to_fill + 1
  X_to_fill[index_points_to_fill]=X_SEED
  Y_to_fill[index_points_to_fill]=Y_SEED
EndSub
 
 
Sub fillRegions
 
For i = 1 To index_points_to_fill
 
  CURR_X_SEED = X_to_fill[i]
  CURR_Y_SEED = Y_to_fill[i]
 
  colOld = GraphicsWindow.GetPixel(CURR_X_SEED,CURR_Y_SEED)
 
  'only if the area wasn't filled before
  'in other words, only if currColor is not "Weath" = #F5DEB3)
  If colOld = "#F5DEB3" Then
 
    Stack.PushValue("X",CURR_X_SEED)
    Stack.PushValue("Y",CURR_Y_SEED)
 
    FillCol = FillCol+1
    If FillCol = 5 Then
        FillCol = 1 
    EndIf
    colFill = FillColor[FillCol]  
    GW_W = GraphicsWindow.Width-1
    GW_H = 699 ' Was: = GraphicsWindow.Height-1
    While (Stack.GetCount("X") > 0)
      My_x = Stack.PopValue("X")
      My_y = Stack.PopValue("Y")
 
      TextWindow.CursorLeft = 0
      TextWindow.CursorTop = 0
      TextWindow.WriteLine("fillregion My_X = "+My_X+ " My_Y = "+My_Y+"  colFill "+colFill+"                    ")   
      TextWindow.CursorLeft = 0
      TextWindow.CursorTop = 1
      TextWindow.WriteLine("colOld = "+ColOld+ " GraphicsWindow.GetPixel(My_x,My_y) = "+GraphicsWindow.GetPixel(My_x,My_y)+"                       ")   
      'TextWindow.Read()
 
      'We could have multiple entries in the stack at x,y so only process those we haven't dealt with
      If (GraphicsWindow.GetPixel(My_x,My_y) = colOld) Then 
        GraphicsWindow.SetPixel(My_x,My_y,colFill)
        'If (My_x > 1003) Then
        If (My_x > 3) Then
          If (GraphicsWindow.GetPixel(My_x-1,My_y) = colOld) Then
            Stack.PushValue("X",My_x-1)
            Stack.PushValue("Y",My_y)
          EndIf
        EndIf
        'X pixels go from 0 to GW_W
        If (My_x < GW_W) Then 
          If (GraphicsWindow.GetPixel(My_x+1,My_y) = colOld) Then
            Stack.PushValue("X",My_x+1)
            Stack.PushValue("Y",My_y)
          EndIf
        EndIf
        'If (My_y > 0) Then
        If (My_y > 2) Then          
          If (GraphicsWindow.GetPixel(My_x,My_y-1) = colOld) Then
            Stack.PushValue("X",My_x)
            Stack.PushValue("Y",My_y-1)
          EndIf
        EndIf
        'Y pixels go from 0 to GW_H
        If (My_y < GW_H) Then 
          If (GraphicsWindow.GetPixel(My_x,My_y+1) = colOld) Then
            Stack.PushValue("X",My_x)
            Stack.PushValue("Y",My_y+1)
          EndIf
        EndIf
      EndIf
    EndWhile 
  EndIf    
EndFor  
EndSub
 
Sub CHECK_AGE
  CURR_AGE=1
  GO_ON = "TRUE"
  ' Check adjacent E points and increase age accordingly until no
  ' E point is found
  While (GO_ON = "TRUE")
    If STATE[Check_X+1][Check_Y-1] = "E" Then
      CURR_AGE=CURR_AGE+1
      Check_X=Check_X+1
      Check_Y=Check_Y-1
      If Check_Y = 1 or Check_X = 1200 Then
        GO_ON = "FALSE"
      EndIf
    ElseIf STATE[Check_X+1][Check_Y+1] = "E" Then
      CURR_AGE=CURR_AGE+1
      Check_X=Check_X+1
      Check_Y=Check_Y+1
      If Check_Y = 700 or Check_X =1200 Then
        GO_ON = "FALSE"
      EndIf      
    Else
      GO_ON="FALSE"
    EndIf
  EndWhile   
EndSub