'====================================== ' 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