Author Topic: Steve's Magical Paint Fill  (Read 6981 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Steve's Magical Paint Fill
« Reply #15 on: November 23, 2019, 11:38:40 am »
Make sense?

A little, amazing trickery there Steve, tricks upon tricks, but doing things only once makes allot of sense like reading POINTs off screen and checking around for connecting neighbors. Another great reading job by bplus who totally missed the MEM part but glad you explained in English what I was supposed to be getting from code.

I'm afraid I don't understand it enough to make any prediction about what will happen when you try the skipping scheme.

I am eager to test this on a maze fill, a maze with 1 pixel passage ways? ;-)

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Steve's Magical Paint Fill
« Reply #16 on: November 23, 2019, 11:45:07 am »
Make sense?

A little, amazing trickery there Steve, tricks upon tricks, but doing things only once makes allot of sense like reading POINTs off screen and checking around for connecting neighbors. Another great reading job by bplus who totally missed the MEM part but glad you explained in English what I was supposed to be getting from code.

I'm afraid I don't understand it enough to make any prediction about what will happen when you try the skipping scheme.

I am eager to test this on a maze fill, a maze with 1 pixel passage ways? ;-)

Sounds fine.  I don't think it should have any trouble filling in the whole maze for you.  I just hope nobody fusses over the use of the dreaded GOTO in the code.  Everyone says that there's never any use for it in modern languages, but my brain just can't decipher a pretty way to sort out the logic which is any better than this:
Code: [Select]
               IF Array(x, y) = pass THEN
                    fill_left:
                    IF x > 0 THEN
                        IF Array(x - 1, y) = S(x - 1, y) THEN
                            Array(x - 1, y) = np
                            finished = 0
                            x = x - 1
                            IF x < MinX THEN MinX = x
                            GOTO fill_left
                        END IF
                    END IF
                END IF
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Steve's Magical Paint Fill
« Reply #17 on: November 23, 2019, 11:51:45 am »
I'm afraid I don't understand it enough to make any prediction about what will happen when you try the skipping scheme.

I imagine you're correct.  We can't really skip based on the simple idea I had before.  Even though a point is only a few pixels away from our starting position, it might be the very last point we color in, in a maze-like situation.  It's not going to be something as simple as "after X passes, we can rule it out"...  I think the way it is, is the way it's going to have to stay.  The only optimizing I can see that I could do to it now is to just convert the whole thing over to _MEM to speed it up, and I don't know if my brain is up to that math at the moment.  :P
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Steve's Magical Paint Fill
« Reply #18 on: November 23, 2019, 12:07:05 pm »
Here's a little test code, which should answer your question about, "Will it handle single pixel maze fills?"  I can't imagine something getting much more complicated for the routine than this for filling:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(800, 600, 32)
  2.  
  3. 'make a maze to fill
  4. FOR i = 1 TO 100
  5.     dir = INT(RND * 2) - 1 '0 or 1
  6.     IF dir THEN
  7.         LINE (RND * 800, RND * 600)-STEP(RND * 800, 0), &HFF0000FF
  8.     ELSE
  9.         LINE (RND * 800, RND * 600)-STEP(0, RND * 600), &HFF0000FF
  10.     END IF
  11.  
  12. FOR x = 0 TO _WIDTH - 1
  13.     FOR y = 0 TO _HEIGHT - 1
  14.         IF POINT(x, y) = &HFF0000FF~& GOTO done 'find a point which is on one of those lines
  15.     NEXT
  16.  
  17. done:
  18.  
  19. SLEEP 'pause for a keypress
  20.  
  21.  
  22. fill x, y, &HFFFF0000, 0 'then fill them in
  23.  
  24. SUB fill (tx AS INTEGER, ty AS INTEGER, kolor AS _UNSIGNED LONG, bordercolor AS _UNSIGNED LONG)
  25.     DIM x AS INTEGER, y AS INTEGER
  26.     DIM W AS INTEGER, H AS INTEGER
  27.     DIM pass AS INTEGER, finished AS INTEGER, np AS INTEGER
  28.     DIM TMX AS INTEGER, TMX2 AS INTEGER
  29.     DIM TMY AS INTEGER, TMY2 AS INTEGER
  30.     DIM left AS INTEGER, x1 AS INTEGER, y1 AS INTEGER
  31.     DIM MinX AS INTEGER, MinY AS INTEGER
  32.     DIM MaxX AS INTEGER, MaxY AS INTEGER
  33.  
  34.     x = tx: y = ty
  35.  
  36.     W = _WIDTH: H = _HEIGHT
  37.     DIM Array(W, H) 'AS INTEGER
  38.     DIM S(W, H) 'AS INTEGER
  39.     STATIC M AS _MEM: M = _MEMIMAGE(_DEST)
  40.     FOR x1 = 0 TO W - 1
  41.         FOR y1 = 0 TO H - 1
  42.             IF _MEMGET(M, M.OFFSET + (y1 * W + x1) * 4, _UNSIGNED LONG) = bordercolor THEN S(x1, y1) = -1 'MRM replacement for point below
  43.             'IF POINT(x1, y1) = bordercolor THEN S(x1, y1) = -1 'This is actually Sneaky Steve Logic at its best!
  44.             'Here we're checking to see if our array matches the proper border color or not.
  45.             'If it doesn't, then it might be a spot to fill (which is 0 -- the same as our inital Array()).
  46.         NEXT
  47.     NEXT
  48.     MinX = x: MinY = y
  49.     MaxX = x: MaxY = y
  50.     Array(x, y) = 1
  51.     pass = 1
  52.     DO
  53.         finished = -1
  54.         np = pass + 1 'next pass
  55.         TMX = MinX: TMX2 = MaxX
  56.         TMY = MinY: TMY2 = MaxY
  57.         FOR y = TMY TO TMY2
  58.             FOR x = TMX2 TO TMX STEP -1
  59.                 IF Array(x, y) = pass THEN
  60.                     fill_left:
  61.                     IF x > 0 THEN
  62.                         IF Array(x - 1, y) = S(x - 1, y) THEN
  63.                             Array(x - 1, y) = np
  64.                             finished = 0
  65.                             x = x - 1
  66.                             IF x < MinX THEN MinX = x
  67.                             GOTO fill_left
  68.                         END IF
  69.                     END IF
  70.                 END IF
  71.             NEXT
  72.             FOR x = TMX TO TMX2
  73.                 IF Array(x, y) = pass THEN
  74.                     fill_right:
  75.                     IF x < W - 2 THEN
  76.                         IF Array(x + 1, y) = S(x + 1, y) THEN
  77.                             Array(x + 1, y) = np
  78.                             finished = 0
  79.                             x = x + 1
  80.                             IF x > MaxX THEN MaxX = x
  81.                             GOTO fill_right
  82.                         END IF
  83.                     END IF
  84.                 END IF
  85.             NEXT
  86.         NEXT
  87.         FOR x = TMX TO TMX2
  88.             FOR y = TMY2 TO TMY STEP -1
  89.                 IF Array(x, y) = pass THEN
  90.                     fill_up:
  91.                     IF y > 0 THEN
  92.                         IF Array(x, y - 1) = S(x, y - 1) THEN
  93.                             Array(x, y - 1) = np
  94.                             finished = 0
  95.                             y = y - 1
  96.                             IF y < MinY THEN MinY = y
  97.                             GOTO fill_up
  98.                         END IF
  99.                     END IF
  100.                 END IF
  101.             NEXT
  102.             FOR y = TMY TO TMY2
  103.                 IF Array(x, y) = pass THEN
  104.                     fill_down:
  105.                     IF y < H - 2 THEN
  106.                         IF Array(x, y + 1) = S(x, y + 1) THEN
  107.                             Array(x, y + 1) = np
  108.                             finished = 0
  109.                             y = y + 1
  110.                             IF y > MaxY THEN MaxY = y
  111.                             GOTO fill_down
  112.                         END IF
  113.                     END IF
  114.                 END IF
  115.             NEXT
  116.         NEXT
  117.         pass = pass + 1
  118.     LOOP UNTIL finished
  119.  
  120.     FOR y = MinY TO MaxY
  121.         FOR x = MinX TO MaxX
  122.             IF Array(x, y) THEN 'PSET (x, y), kolor
  123.                 IF left = 0 THEN left = x
  124.             ELSE
  125.                 IF left THEN LINE (left, y)-(x - 1, y), kolor, BF: left = 0
  126.             END IF
  127.         NEXT
  128.         IF left THEN LINE (left, y)-(x - 1, y), kolor, BF: left = 0
  129.     NEXT
  130.  

EDIT:

Modified below to allow for multiple runs, in case your first try gives you a single line which isn't connected to the main grid -- it happens more often than I would've expected!

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(800, 600, 32)
  2.  
  3.     CLS , 0
  4.     'make a maze to fill
  5.     FOR i = 1 TO 200
  6.         dir = INT(RND * 2) - 1 '0 or 1
  7.         IF dir THEN
  8.             LINE (RND * 400, RND * 600)-STEP(RND * 800, 0), &HFF0000FF
  9.         ELSE
  10.             LINE (RND * 800, RND * 600)-STEP(0, RND * 600), &HFF0000FF
  11.         END IF
  12.     NEXT
  13.  
  14.     FOR x = 0 TO _WIDTH - 1
  15.         FOR y = 0 TO _HEIGHT - 1
  16.             IF POINT(x, y) = &HFF0000FF~& GOTO done 'find a point which is on one of those lines
  17.         NEXT
  18.     NEXT
  19.     done:
  20.  
  21.     SLEEP 'pause for a keypress
  22.  
  23.     fill x, y, &HFFFF0000, 0 'then fill them in
  24.     SLEEP
  25.  
  26. SUB fill (tx AS INTEGER, ty AS INTEGER, kolor AS _UNSIGNED LONG, bordercolor AS _UNSIGNED LONG)
  27.     DIM x AS INTEGER, y AS INTEGER
  28.     DIM W AS INTEGER, H AS INTEGER
  29.     DIM pass AS INTEGER, finished AS INTEGER, np AS INTEGER
  30.     DIM TMX AS INTEGER, TMX2 AS INTEGER
  31.     DIM TMY AS INTEGER, TMY2 AS INTEGER
  32.     DIM left AS INTEGER, x1 AS INTEGER, y1 AS INTEGER
  33.     DIM MinX AS INTEGER, MinY AS INTEGER
  34.     DIM MaxX AS INTEGER, MaxY AS INTEGER
  35.  
  36.     x = tx: y = ty
  37.  
  38.     W = _WIDTH: H = _HEIGHT
  39.     DIM Array(W, H) 'AS INTEGER
  40.     DIM S(W, H) 'AS INTEGER
  41.     STATIC M AS _MEM: M = _MEMIMAGE(_DEST)
  42.     FOR x1 = 0 TO W - 1
  43.         FOR y1 = 0 TO H - 1
  44.             IF _MEMGET(M, M.OFFSET + (y1 * W + x1) * 4, _UNSIGNED LONG) = bordercolor THEN S(x1, y1) = -1 'MRM replacement for point below
  45.             'IF POINT(x1, y1) = bordercolor THEN S(x1, y1) = -1 'This is actually Sneaky Steve Logic at its best!
  46.             'Here we're checking to see if our array matches the proper border color or not.
  47.             'If it doesn't, then it might be a spot to fill (which is 0 -- the same as our inital Array()).
  48.         NEXT
  49.     NEXT
  50.     MinX = x: MinY = y
  51.     MaxX = x: MaxY = y
  52.     Array(x, y) = 1
  53.     pass = 1
  54.     DO
  55.         finished = -1
  56.         np = pass + 1 'next pass
  57.         TMX = MinX: TMX2 = MaxX
  58.         TMY = MinY: TMY2 = MaxY
  59.         FOR y = TMY TO TMY2
  60.             FOR x = TMX2 TO TMX STEP -1
  61.                 IF Array(x, y) = pass THEN
  62.                     fill_left:
  63.                     IF x > 0 THEN
  64.                         IF Array(x - 1, y) = S(x - 1, y) THEN
  65.                             Array(x - 1, y) = np
  66.                             finished = 0
  67.                             x = x - 1
  68.                             IF x < MinX THEN MinX = x
  69.                             GOTO fill_left
  70.                         END IF
  71.                     END IF
  72.                 END IF
  73.             NEXT
  74.             FOR x = TMX TO TMX2
  75.                 IF Array(x, y) = pass THEN
  76.                     fill_right:
  77.                     IF x < W - 2 THEN
  78.                         IF Array(x + 1, y) = S(x + 1, y) THEN
  79.                             Array(x + 1, y) = np
  80.                             finished = 0
  81.                             x = x + 1
  82.                             IF x > MaxX THEN MaxX = x
  83.                             GOTO fill_right
  84.                         END IF
  85.                     END IF
  86.                 END IF
  87.             NEXT
  88.         NEXT
  89.         FOR x = TMX TO TMX2
  90.             FOR y = TMY2 TO TMY STEP -1
  91.                 IF Array(x, y) = pass THEN
  92.                     fill_up:
  93.                     IF y > 0 THEN
  94.                         IF Array(x, y - 1) = S(x, y - 1) THEN
  95.                             Array(x, y - 1) = np
  96.                             finished = 0
  97.                             y = y - 1
  98.                             IF y < MinY THEN MinY = y
  99.                             GOTO fill_up
  100.                         END IF
  101.                     END IF
  102.                 END IF
  103.             NEXT
  104.             FOR y = TMY TO TMY2
  105.                 IF Array(x, y) = pass THEN
  106.                     fill_down:
  107.                     IF y < H - 2 THEN
  108.                         IF Array(x, y + 1) = S(x, y + 1) THEN
  109.                             Array(x, y + 1) = np
  110.                             finished = 0
  111.                             y = y + 1
  112.                             IF y > MaxY THEN MaxY = y
  113.                             GOTO fill_down
  114.                         END IF
  115.                     END IF
  116.                 END IF
  117.             NEXT
  118.         NEXT
  119.         pass = pass + 1
  120.     LOOP UNTIL finished
  121.  
  122.     FOR y = MinY TO MaxY
  123.         FOR x = MinX TO MaxX
  124.             IF Array(x, y) THEN 'PSET (x, y), kolor
  125.                 IF left = 0 THEN left = x
  126.             ELSE
  127.                 IF left THEN LINE (left, y)-(x - 1, y), kolor, BF: left = 0
  128.             END IF
  129.         NEXT
  130.         IF left THEN LINE (left, y)-(x - 1, y), kolor, BF: left = 0
  131.     NEXT
  132.     PRINT pass; " passes to completion"
  133.  

What I find astonishing is that this never needs more than 8 or 9 passes to complete.  How the heck was we running out of stack space before, with the recursive calls to the paint fill routines??
« Last Edit: November 23, 2019, 12:14:18 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Steve's Magical Paint Fill
« Reply #19 on: November 23, 2019, 12:17:35 pm »
Quote
I just hope nobody fusses over the use of the dreaded GOTO in the code.

Oh my the GOTO thing, what a joke, underneath everything the machine code is using GOTO all the time.

Sure GOTO can be abused and make code very hard to read, doesn't mean it should be forbidden or even bad form all the time. BTW it beats the heck out of a FOR loop in my timed tests.

LET It += Be ;-))

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Steve's Magical Paint Fill
« Reply #20 on: November 23, 2019, 12:26:24 pm »
Quote
What I find astonishing is that this never needs more than 8 or 9 passes to complete.  How the heck was we running out of stack space before, with the recursive calls to the paint fill routines??

Because recursion has to work all the way to the end, pass #xxx, and then work it's way back to level #1 before going down another rabbit hole.

Your routine that cuts down the number of passes tremendously might make recursion possible?

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Steve's Magical Paint Fill
« Reply #21 on: November 23, 2019, 12:54:03 pm »
Ha, Steve that test might be handy for finding non connected lines!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Steve's Magical Paint Fill
« Reply #22 on: November 23, 2019, 04:33:26 pm »
Wow PAINT is fast through the maze! For Steve's fill routine I had to draw as I go because it sure beats staring at a blank screen for the time it takes to run out the maze (at first I thought it wasn't even working!):
Code: QB64: [Select]
  1. _TITLE "Maze Generator to test Paint or Fills, press any to awaken from SLEEP, esc to quit" 'B+
  2. '2019-11-23 using Maze Generator to test Steve's nice fill routine posted 2019-11-23
  3.  
  4. ' 2019-09-02 isolated and updated generator code for OPTION _EXPLICIT
  5. ' from trans 2018-06-15 for Amazing Rat.bas (QB64)
  6. ' From SmallBASIC code written by Chris WS developer
  7. ' Backtracking maze generator by chrisws 2016-06-30 now found at
  8. ' https://github.com/smallbasic/smallbasic.github.io/blob/5601c8bc1d794c5b143d863555bb7c15a5966a3c/samples/node/1623.bas
  9. '
  10. ' Chris notes:
  11. ' https://en.wikipedia.org/wiki/Maze_generation_algorithm
  12. ' - Starting from a random cell,
  13. ' - Selects a random neighbouring cell that has not been visited.
  14. ' - Remove the wall between the two cells and marks the new cell as visited,
  15. '   and adds it to the stack to facilitate backtracking.
  16. ' - Continues with a cell that has no unvisited neighbours being considered a dead-end.
  17. '   When at a dead-end it backtracks through the path until it reaches a cell with an
  18. '   unvisited neighbour, continuing the path generation by visiting this new,
  19. '   unvisited cell (creating a new junction).
  20. '   This process continues until every cell has been visited, backtracking all the
  21. '   way back to the beginning cell. We can be sure every cell is visited.
  22. '
  23.  
  24. 'B+ notes for using:
  25. ' The most important item is that the maze uses 2 arrays one for vertical walls the other for horizontal
  26. ' CONST xmax, ymax is pixel size used in maze coder, using SW, SH for screen dimensions
  27. ' Maze should mount in top left corner of screen with min border space around it at left and top at least.
  28. ' CONST W, H - number of cells Wide and High you can specify.
  29. ' CONST wallThk - adjusts thickness of walls
  30. ' CONST mazeClr - colors walls made with BF in LINE statement
  31. ' CONST border - will create a space around the maze
  32. ' SHARED cellW, cellH - are pixels sizes for cell, see calcs before SCREEN command
  33. ' SHARED  h_walls(W, H) AS INTEGER, v_walls(W, H) AS INTEGER - these are your Maze, 0 no wall, 1 = wall
  34. ' When player occupies cell x, y that cell may v_wall that blocks player going left;
  35. ' a cell v_wall(x+1, y) = 1 will block a player going right;
  36. ' cell (x, y) may have an h_wall that stops player from going up;
  37. ' cell (x, y+1) may have h_wall that stops player at x, y from going down.
  38. ' Cells at (W, y) should not be occupied with W cells wide and array base 0 only W-1 can be occupied
  39. ' unless game needs something special.
  40. ' Likewise cells at (x, H) should only provide wall to stop player from going out of box.
  41. DEFINT A-Z
  42. CONST xmax = 801, ymax = 601, SW = 801, SH = 601 'maze pixels from 0,0 and screen SH, SW
  43. CONST W = 200, H = 150, border = 0, wallThk = 1 'maze cells wide and high
  44. CONST mazeClr = &HFFFF8800
  45.  
  46. TYPE cell
  47.     x AS INTEGER
  48.     y AS INTEGER
  49.  
  50. DIM SHARED cellW AS SINGLE, cellH AS SINGLE, h_walls(W, H) AS INTEGER, v_walls(W, H) AS INTEGER
  51. cellW = (xmax - 2 * border - wallThk) / W
  52. cellH = (ymax - 2 * border - wallThk) / H
  53.  
  54. SCREEN _NEWIMAGE(SW, SH, 32)
  55. _SCREENMOVE 100, 20
  56. WHILE _KEYDOWN(27) = 0
  57.     LINE (0, 0)-(xmax, ymax), &HFF000000, BF
  58.     init_walls
  59.     generate_maze
  60.     show_maze
  61.     'PSET (border + 0 * cellW + wallThk + 1, border + 0 * cellH + wallThk + 1), &HFFFFFFFF 'ok looks right
  62.     SLEEP
  63.     _KEYCLEAR
  64.     'first test with normal PAINT
  65.     'PAINT (border + 0 * cellW + wallThk + 1, border + 0 * cellH + wallThk + 1), &HFFFFFFFF, mazeClr
  66.     fill border + 0 * cellW + wallThk + 1, border + 0 * cellH + wallThk + 1, &HFFFFFFFF, &HFFFF8800
  67.     SLEEP
  68.     _KEYCLEAR
  69.  
  70. SUB init_walls ()
  71.     DIM x AS INTEGER, y AS INTEGER
  72.     FOR x = 0 TO W
  73.         FOR y = 0 TO H
  74.             v_walls(x, y) = 1
  75.             h_walls(x, y) = 1
  76.         NEXT
  77.     NEXT
  78.  
  79. SUB show_maze ()
  80.     DIM py AS SINGLE, px AS SINGLE, y AS INTEGER, x AS INTEGER
  81.     py = border
  82.     FOR y = 0 TO H
  83.         px = border
  84.         FOR x = 0 TO W
  85.             IF x < W AND h_walls(x, y) = 1 THEN
  86.                 LINE (px, py)-STEP(cellW + wallThk, wallThk), mazeClr, BF
  87.             END IF
  88.             IF y < H AND v_walls(x, y) = 1 THEN
  89.                 LINE (px, py)-STEP(wallThk, cellH + wallThk), mazeClr, BF
  90.             END IF
  91.             px = px + cellW
  92.         NEXT
  93.         py = py + cellH
  94.     NEXT
  95.  
  96. SUB rand_cell (rWx, rHy)
  97.     rWx = INT(RND * 1000) MOD W
  98.     rHy = INT(RND * 1000) MOD H
  99.  
  100. SUB get_unvisited (visited() AS INTEGER, current AS cell, unvisited() AS cell, uvi AS INTEGER)
  101.     REDIM unvisited(0) AS cell
  102.     DIM x AS INTEGER, y AS INTEGER
  103.     x = current.x
  104.     y = current.y
  105.     uvi = 0
  106.     IF x > 0 THEN
  107.         IF visited(x - 1, y) = 0 THEN
  108.             uvi = uvi + 1
  109.             REDIM _PRESERVE unvisited(uvi) AS cell
  110.             unvisited(uvi).x = x - 1
  111.             unvisited(uvi).y = y
  112.         END IF
  113.     END IF
  114.     IF x < W - 1 THEN
  115.         IF visited(x + 1, y) = 0 THEN
  116.             uvi = uvi + 1
  117.             REDIM _PRESERVE unvisited(uvi) AS cell
  118.             unvisited(uvi).x = x + 1
  119.             unvisited(uvi).y = y
  120.         END IF
  121.     END IF
  122.     IF y > 0 THEN
  123.         IF visited(x, y - 1) = 0 THEN
  124.             uvi = uvi + 1
  125.             REDIM _PRESERVE unvisited(uvi) AS cell
  126.             unvisited(uvi).x = x
  127.             unvisited(uvi).y = y - 1
  128.         END IF
  129.     END IF
  130.     IF y < H - 1 THEN
  131.         IF visited(x, y + 1) = 0 THEN
  132.             uvi = uvi + 1
  133.             REDIM _PRESERVE unvisited(uvi) AS cell
  134.             unvisited(uvi).x = x
  135.             unvisited(uvi).y = y + 1
  136.         END IF
  137.     END IF
  138.  
  139. SUB generate_maze ()
  140.     DIM visited(W, H) AS INTEGER
  141.     DIM num_visited AS INTEGER, num_cells AS INTEGER, si AS INTEGER
  142.     DIM cnt AS INTEGER, rc AS INTEGER, x AS INTEGER, y AS INTEGER
  143.     REDIM stack(0) AS cell
  144.     DIM curr_cell AS cell, next_cell AS cell, cur_cell AS cell
  145.  
  146.     rand_cell cur_cell.x, cur_cell.y
  147.     visited(curr_cell.x, curr_cell.y) = 1
  148.     num_visited = 1
  149.     num_cells = W * H
  150.     si = 0
  151.     WHILE num_visited < num_cells
  152.         REDIM cells(0) AS cell
  153.         cnt = 0
  154.         get_unvisited visited(), curr_cell, cells(), cnt
  155.         IF cnt > 0 THEN
  156.  
  157.             ' choose randomly one of the current cell's unvisited neighbours
  158.             rc = INT(RND * 100) MOD cnt + 1
  159.             next_cell.x = cells(rc).x
  160.             next_cell.y = cells(rc).y
  161.  
  162.             ' push the current cell to the stack
  163.             si = si + 1
  164.             REDIM _PRESERVE stack(si) AS cell
  165.             stack(si).x = curr_cell.x
  166.             stack(si).y = curr_cell.y
  167.  
  168.             ' remove the wall between the current cell and the chosen cell
  169.             IF next_cell.x = curr_cell.x THEN
  170.                 x = next_cell.x
  171.                 y = max(next_cell.y, curr_cell.y)
  172.                 h_walls(x, y) = 0
  173.             ELSE
  174.                 x = max(next_cell.x, curr_cell.x)
  175.                 y = next_cell.y
  176.                 v_walls(x, y) = 0
  177.             END IF
  178.  
  179.             ' make the chosen cell the current cell and mark it as visited
  180.             curr_cell.x = next_cell.x
  181.             curr_cell.y = next_cell.y
  182.             visited(curr_cell.x, curr_cell.y) = 1
  183.             num_visited = num_visited + 1
  184.  
  185.         ELSEIF si > 0 THEN
  186.  
  187.             ' pop a cell from the stack and make it the current cell
  188.             curr_cell.x = stack(si).x
  189.             curr_cell.y = stack(si).y
  190.             si = si - 1
  191.             REDIM _PRESERVE stack(si) AS cell
  192.  
  193.         ELSE
  194.             EXIT WHILE
  195.         END IF
  196.     WEND
  197.  
  198. FUNCTION max (a, b)
  199.     IF a > b THEN max = a ELSE max = b
  200.  
  201. SUB fill (tx AS INTEGER, ty AS INTEGER, kolor AS _UNSIGNED LONG, bordercolor AS _UNSIGNED LONG)
  202.     '''$CHECKING:OFF  '                                                                 <<<<<<<<<<<<<<<<< B+ mod
  203.     DIM x AS INTEGER, y AS INTEGER
  204.     DIM fillW AS INTEGER, fillH AS INTEGER  ' <<<<<<<<<<<<<<<< B+ mod already using W and H
  205.     DIM pass AS INTEGER, finished AS INTEGER, np AS INTEGER
  206.     DIM TMX AS INTEGER, TMX2 AS INTEGER
  207.     DIM TMY AS INTEGER, TMY2 AS INTEGER
  208.     DIM left AS INTEGER, x1 AS INTEGER, y1 AS INTEGER
  209.     DIM MinX AS INTEGER, MinY AS INTEGER
  210.     DIM MaxX AS INTEGER, MaxY AS INTEGER
  211.  
  212.     x = tx: y = ty
  213.  
  214.     fillW = _WIDTH: fillH = _HEIGHT
  215.     DIM Array(fillW, fillH) 'AS INTEGER
  216.     DIM S(fillW, fillH) 'AS INTEGER
  217.     STATIC M AS _MEM: M = _MEMIMAGE(_DEST)
  218.     FOR x1 = 0 TO fillW - 1
  219.         FOR y1 = 0 TO fillH - 1
  220.             IF _MEMGET(M, M.OFFSET + (y1 * fillW + x1) * 4, _UNSIGNED LONG) = bordercolor THEN S(x1, y1) = -1 'MRM replacement for point below
  221.             'IF POINT(x1, y1) = bordercolor THEN S(x1, y1) = -1 'This is actually Sneaky Steve Logic at its best!
  222.             'Here we're checking to see if our array matches the proper border color or not.
  223.             'If it doesn't, then it might be a spot to fill (which is 0 -- the same as our inital Array()).
  224.         NEXT
  225.     NEXT
  226.     MinX = x: MinY = y
  227.     MaxX = x: MaxY = y
  228.     Array(x, y) = 1: LINE (x, y)-STEP(0, 0), kolor, BF '                                   <<<<<<<<<<<<<<<<< B+ mod
  229.     pass = 1
  230.     DO
  231.         finished = -1
  232.         np = pass + 1 'next pass
  233.         TMX = MinX: TMX2 = MaxX
  234.         TMY = MinY: TMY2 = MaxY
  235.         FOR y = TMY TO TMY2
  236.             FOR x = TMX2 TO TMX STEP -1
  237.                 IF Array(x, y) = pass THEN
  238.                     fill_left:
  239.                     IF x > 0 THEN
  240.                         IF Array(x - 1, y) = S(x - 1, y) THEN
  241.                             Array(x - 1, y) = np
  242.                             finished = 0: LINE (x, y)-STEP(0, 0), kolor, BF '                     <<<<<<<<<<<<<<<<< B+ mod
  243.                             x = x - 1
  244.                             IF x < MinX THEN MinX = x
  245.                             GOTO fill_left
  246.                         END IF
  247.                     END IF
  248.                 END IF
  249.             NEXT
  250.             FOR x = TMX TO TMX2
  251.                 IF Array(x, y) = pass THEN
  252.                     fill_right:
  253.                     IF x < fillW - 2 THEN
  254.                         IF Array(x + 1, y) = S(x + 1, y) THEN
  255.                             Array(x + 1, y) = np
  256.                             finished = 0:: LINE (x, y)-STEP(0, 0), kolor, BF '                     <<<<<<<<<<<<<<<<< B+ mod
  257.                             x = x + 1
  258.                             IF x > MaxX THEN MaxX = x
  259.                             GOTO fill_right
  260.                         END IF
  261.                     END IF
  262.                 END IF
  263.             NEXT
  264.         NEXT
  265.         FOR x = TMX TO TMX2
  266.             FOR y = TMY2 TO TMY STEP -1
  267.                 IF Array(x, y) = pass THEN
  268.                     fill_up:
  269.                     IF y > 0 THEN
  270.                         IF Array(x, y - 1) = S(x, y - 1) THEN
  271.                             Array(x, y - 1) = np
  272.                             finished = 0:: LINE (x, y)-STEP(0, 0), kolor, BF '                     <<<<<<<<<<<<<<<<< B+ mod
  273.                             y = y - 1
  274.                             IF y < MinY THEN MinY = y
  275.                             GOTO fill_up
  276.                         END IF
  277.                     END IF
  278.                 END IF
  279.             NEXT
  280.             FOR y = TMY TO TMY2
  281.                 IF Array(x, y) = pass THEN
  282.                     fill_down:
  283.                     IF y < fillH - 2 THEN
  284.                         IF Array(x, y + 1) = S(x, y + 1) THEN
  285.                             Array(x, y + 1) = np
  286.                             finished = 0:: LINE (x, y)-STEP(0, 0), kolor, BF '                     <<<<<<<<<<<<<<<<< B+ mod
  287.                             y = y + 1
  288.                             IF y > MaxY THEN MaxY = y
  289.                             GOTO fill_down
  290.                         END IF
  291.                     END IF
  292.                 END IF
  293.             NEXT
  294.         NEXT
  295.         pass = pass + 1
  296.     LOOP UNTIL finished
  297.  
  298.     FOR y = MinY TO MaxY
  299.         FOR x = MinX TO MaxX
  300.             IF Array(x, y) THEN 'PSET (x, y), kolor
  301.                 IF left = 0 THEN left = x
  302.             ELSE
  303.                 IF left THEN LINE (left, y)-(x - 1, y), kolor, BF: left = 0
  304.             END IF
  305.         NEXT
  306.         IF left THEN LINE (left, y)-(x - 1, y), kolor, BF: left = 0
  307.     NEXT
  308.     '''$CHECKING:ON   '<<<<<<<<<<<<<<<<< B+ mod
  309.  
  310.  
  311.  

BTW couldn't get 1 pixel passages, got tired of trying, 2 pixels bad enough.
« Last Edit: November 23, 2019, 04:34:42 pm by bplus »

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Steve's Magical Paint Fill
« Reply #23 on: November 23, 2019, 06:12:34 pm »
Hi
if you mind about GOTO here a version without GOTO:-)

Code: QB64: [Select]
  1. 'DIM c AS _UNSIGNED LONG
  2.  
  3. SCREEN _NEWIMAGE(640, 480, 32)
  4.  
  5. 'c = _RGBA32(127, 127, 127, 200)
  6. c = -1
  7. t# = TIMER(0.01)
  8. FOR i = 1 TO 10
  9.     CLS
  10.     CIRCLE (320, 240), 200, c
  11.     PAINT (320, 240), &HFFFF0000, c
  12. t2# = TIMER(0.01)
  13. FOR i = 1 TO 10
  14.     CLS
  15.     CIRCLE (320, 240), 200, c
  16.     fill 320, 240, &HFFFF0000, c
  17. t3# = TIMER(0.01)
  18.  
  19. PRINT USING "##.### seconds with PAINT"; t2# - t#
  20. PRINT USING "##.### seconds with FILL"; t3# - t2#
  21.  
  22.  
  23. SUB fill (tx AS INTEGER, ty AS INTEGER, kolor AS _UNSIGNED LONG, bordercolor AS _UNSIGNED LONG)
  24.     DIM x AS INTEGER, y AS INTEGER
  25.     DIM W AS INTEGER, H AS INTEGER
  26.     DIM pass AS INTEGER, finished AS INTEGER, np AS INTEGER
  27.     DIM TMX AS INTEGER, TMX2 AS INTEGER
  28.     DIM TMY AS INTEGER, TMY2 AS INTEGER
  29.     DIM left AS INTEGER, x1 AS INTEGER, y1 AS INTEGER
  30.     DIM MinX AS INTEGER, MinY AS INTEGER
  31.     DIM MaxX AS INTEGER, MaxY AS INTEGER
  32.  
  33.     x = tx: y = ty
  34.  
  35.     W = _WIDTH: H = _HEIGHT
  36.     DIM Array(W, H) 'AS INTEGER
  37.     DIM S(W, H) 'AS INTEGER
  38.     STATIC M AS _MEM: M = _MEMIMAGE(_DEST)
  39.     FOR x1 = 0 TO W - 1
  40.         FOR y1 = 0 TO H - 1
  41.             IF _MEMGET(M, M.OFFSET + (y1 * W + x1) * 4, _UNSIGNED LONG) = bordercolor THEN S(x1, y1) = -1 'MRM replacement for point below
  42.             'IF POINT(x1, y1) = bordercolor THEN S(x1, y1) = -1 'This is actually Sneaky Steve Logic at its best!
  43.             'Here we're checking to see if our array matches the proper border color or not.
  44.             'If it doesn't, then it might be a spot to fill (which is 0 -- the same as our inital Array()).
  45.         NEXT
  46.     NEXT
  47.     MinX = x: MinY = y
  48.     MaxX = x: MaxY = y
  49.     Array(x, y) = 1
  50.     pass = 1
  51.     DO
  52.         finished = -1
  53.         np = pass + 1 'next pass
  54.         TMX = MinX: TMX2 = MaxX
  55.         TMY = MinY: TMY2 = MaxY
  56.         FOR y = TMY TO TMY2
  57.             FOR x = TMX2 TO TMX STEP -1
  58.                 IF Array(x, y) = pass THEN
  59.                     '    fill_left:
  60.                     '    IF x > 0 THEN
  61.                     '        IF Array(x - 1, y) = S(x - 1, y) THEN
  62.                     '            Array(x - 1, y) = np
  63.                     '            finished = 0
  64.                     '            x = x - 1
  65.                     '            IF x < MinX THEN MinX = x
  66.                     '            GOTO fill_left
  67.                     '        END IF
  68.                     '    END IF
  69.                     DO WHILE x > 0
  70.                         IF Array(x - 1, y) = S(x - 1, y) THEN
  71.                             Array(x - 1, y) = np
  72.                             finished = 0
  73.                             x = x - 1
  74.                             IF x < MinX THEN MinX = x
  75.                         ELSE
  76.                             EXIT DO
  77.                         END IF
  78.                     LOOP
  79.                 END IF
  80.  
  81.             NEXT
  82.             FOR x = TMX TO TMX2
  83.                 IF Array(x, y) = pass THEN
  84.                     '    fill_right:
  85.                     '    IF x < W - 2 THEN
  86.                     '        IF Array(x + 1, y) = S(x + 1, y) THEN
  87.                     '            Array(x + 1, y) = np
  88.                     '            finished = 0
  89.                     '            x = x + 1
  90.                     '            IF x > MaxX THEN MaxX = x
  91.                     '            GOTO fill_right
  92.                     '        END IF
  93.                     '    END IF
  94.                     DO WHILE x < W - 2
  95.                         IF Array(x + 1, y) = S(x + 1, y) THEN
  96.                             Array(x + 1, y) = np
  97.                             finished = 0
  98.                             x = x + 1
  99.                             IF x > MaxX THEN MaxX = x
  100.                         ELSE
  101.                             EXIT DO
  102.                         END IF
  103.                     LOOP
  104.                 END IF
  105.             NEXT
  106.         NEXT
  107.         FOR x = TMX TO TMX2
  108.             FOR y = TMY2 TO TMY STEP -1
  109.                 IF Array(x, y) = pass THEN
  110.                     '    fill_up:
  111.                     '    IF y > 0 THEN
  112.                     '        IF Array(x, y - 1) = S(x, y - 1) THEN
  113.                     '            Array(x, y - 1) = np
  114.                     '            finished = 0
  115.                     '            y = y - 1
  116.                     '            IF y < MinY THEN MinY = y
  117.                     '            GOTO fill_up
  118.                     '        END IF
  119.                     DO WHILE y > 0
  120.                         IF Array(x, y - 1) = S(x, y - 1) THEN
  121.                             Array(x, y - 1) = np
  122.                             finished = 0
  123.                             y = y - 1
  124.                             IF y < MinY THEN MinY = y
  125.                         ELSE
  126.                             EXIT DO
  127.                         END IF
  128.                     LOOP
  129.                 END IF
  130.  
  131.  
  132.             NEXT
  133.             FOR y = TMY TO TMY2
  134.                 'IF Array(x, y) = pass THEN
  135.                 '    fill_down:
  136.                 '    IF y < H - 2 THEN
  137.                 '        IF Array(x, y + 1) = S(x, y + 1) THEN
  138.                 '            Array(x, y + 1) = np
  139.                 '            finished = 0
  140.                 '            y = y + 1
  141.                 '            IF y > MaxY THEN MaxY = y
  142.                 '            GOTO fill_down
  143.                 '        END IF
  144.                 '    END IF
  145.                 'END IF
  146.                 IF Array(x, y) = pass THEN
  147.                     DO WHILE y < H - 2
  148.                         IF Array(x, y + 1) = S(x, y + 1) THEN
  149.                             Array(x, y + 1) = np
  150.                             finished = 0
  151.                             y = y + 1
  152.                             IF y > MaxY THEN MaxY = y
  153.                         ELSE
  154.                             EXIT DO
  155.                         END IF
  156.                     LOOP
  157.                 END IF
  158.  
  159.             NEXT
  160.         NEXT
  161.         pass = pass + 1
  162.     LOOP UNTIL finished
  163.  
  164.     FOR y = MinY TO MaxY
  165.         FOR x = MinX TO MaxX
  166.             IF Array(x, y) THEN 'PSET (x, y), kolor
  167.                 IF left = 0 THEN left = x
  168.             ELSE
  169.                 IF left THEN LINE (left, y)-(x - 1, y), kolor, BF: left = 0
  170.             END IF
  171.         NEXT
  172.         IF left THEN LINE (left, y)-(x - 1, y), kolor, BF: left = 0
  173.     NEXT
  174.  
Programming isn't difficult, only it's  consuming time and coffee

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Steve's Magical Paint Fill
« Reply #24 on: November 23, 2019, 06:32:21 pm »
Why EXIT DO there? 

                    DO
                        IF Array(x - 1, y) = S(x - 1, y) THEN
                            Array(x - 1, y) = np
                            finished = 0
                            x = x - 1
                            IF x < MinX THEN MinX = x
                        END IF
                    LOOP UNTIL X < = 0 OR Array(x - 1, y) <> S (x - 1, y)

Mind you, I don’t think it’s quite as easy to understand or follow (at least not for me, at least), but it does eliminate all evil GOTO and EXIT statements. 
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Steve's Magical Paint Fill
« Reply #25 on: November 23, 2019, 07:03:06 pm »
OK it is shorter
but you assume that x is >0 the first run of loop!
You can decide this, because your algorithm is your idea, I dunno! :-)
Programming isn't difficult, only it's  consuming time and coffee

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Steve's Magical Paint Fill
« Reply #26 on: November 23, 2019, 07:12:10 pm »
OK it is shorter
but you assume that x is >0 the first run of loop!
You can decide this, because your algorithm is your idea, I dunno! :-)

DO
  IF X > 0 THEN
      IF Array(x - 1, y) = S(x - 1, y) THEN
          Array(x - 1, y) = np
          finished = 0
          x = x - 1
          IF x < MinX THEN MinX = x
      END IF
  END IF
LOOP UNTIL X < = 0 OR Array(x - 1, y) <> S (x - 1, y)

There; corrected.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Steve's Magical Paint Fill
« Reply #27 on: November 24, 2019, 10:01:19 am »
Also this works using again WHILE instead of UNTIL and AND instead of OR

Code: QB64: [Select]
  1. 'DIM c AS _UNSIGNED LONG
  2.  
  3. SCREEN _NEWIMAGE(640, 480, 32)
  4.  
  5. 'c = _RGBA32(127, 127, 127, 200)
  6. c = -1
  7. t# = TIMER(0.01)
  8. FOR i = 1 TO 10
  9.     CLS
  10.     CIRCLE (320, 240), 200, c
  11.     PAINT (320, 240), &HFFFF0000, c
  12. t2# = TIMER(0.01)
  13. FOR i = 1 TO 10
  14.     CLS
  15.     CIRCLE (320, 240), 200, c
  16.     fill 320, 240, &HFFFF0000, c
  17. t3# = TIMER(0.01)
  18.  
  19. PRINT USING "##.### seconds with PAINT"; t2# - t#
  20. PRINT USING "##.### seconds with FILL"; t3# - t2#
  21.  
  22.  
  23. SUB fill (tx AS INTEGER, ty AS INTEGER, kolor AS _UNSIGNED LONG, bordercolor AS _UNSIGNED LONG)
  24.     DIM x AS INTEGER, y AS INTEGER
  25.     DIM W AS INTEGER, H AS INTEGER
  26.     DIM pass AS INTEGER, finished AS INTEGER, np AS INTEGER
  27.     DIM TMX AS INTEGER, TMX2 AS INTEGER
  28.     DIM TMY AS INTEGER, TMY2 AS INTEGER
  29.     DIM left AS INTEGER, x1 AS INTEGER, y1 AS INTEGER
  30.     DIM MinX AS INTEGER, MinY AS INTEGER
  31.     DIM MaxX AS INTEGER, MaxY AS INTEGER
  32.  
  33.     x = tx: y = ty
  34.  
  35.     W = _WIDTH: H = _HEIGHT
  36.     DIM Array(W, H) 'AS INTEGER
  37.     DIM S(W, H) 'AS INTEGER
  38.     STATIC M AS _MEM: M = _MEMIMAGE(_DEST)
  39.     FOR x1 = 0 TO W - 1
  40.         FOR y1 = 0 TO H - 1
  41.             IF _MEMGET(M, M.OFFSET + (y1 * W + x1) * 4, _UNSIGNED LONG) = bordercolor THEN S(x1, y1) = -1 'MRM replacement for point below
  42.             'IF POINT(x1, y1) = bordercolor THEN S(x1, y1) = -1 'This is actually Sneaky Steve Logic at its best!
  43.             'Here we're checking to see if our array matches the proper border color or not.
  44.             'If it doesn't, then it might be a spot to fill (which is 0 -- the same as our inital Array()).
  45.         NEXT
  46.     NEXT
  47.     MinX = x: MinY = y
  48.     MaxX = x: MaxY = y
  49.     Array(x, y) = 1
  50.     pass = 1
  51.     DO
  52.         finished = -1
  53.         np = pass + 1 'next pass
  54.         TMX = MinX: TMX2 = MaxX
  55.         TMY = MinY: TMY2 = MaxY
  56.         FOR y = TMY TO TMY2
  57.             FOR x = TMX2 TO TMX STEP -1
  58.                 IF Array(x, y) = pass THEN
  59.                     '    fill_left:
  60.                     '    IF x > 0 THEN
  61.                     '        IF Array(x - 1, y) = S(x - 1, y) THEN
  62.                     '            Array(x - 1, y) = np
  63.                     '            finished = 0
  64.                     '            x = x - 1
  65.                     '            IF x < MinX THEN MinX = x
  66.                     '            GOTO fill_left
  67.                     '        END IF
  68.                     '    END IF
  69.                     DO WHILE x > 0 AND Array(x - 1, y) = S(x - 1, y)
  70.                         '                        IF Array(x - 1, y) = S(x - 1, y) THEN
  71.                         Array(x - 1, y) = np
  72.                         finished = 0
  73.                         x = x - 1
  74.                         IF x < MinX THEN MinX = x
  75.                         '                    ELSE
  76.                         '                        EXIT DO
  77.                         '                        END IF
  78.                     LOOP
  79.                 END IF
  80.  
  81.             NEXT
  82.             FOR x = TMX TO TMX2
  83.                 IF Array(x, y) = pass THEN
  84.                     '    fill_right:
  85.                     '    IF x < W - 2 THEN
  86.                     '        IF Array(x + 1, y) = S(x + 1, y) THEN
  87.                     '            Array(x + 1, y) = np
  88.                     '            finished = 0
  89.                     '            x = x + 1
  90.                     '            IF x > MaxX THEN MaxX = x
  91.                     '            GOTO fill_right
  92.                     '        END IF
  93.                     '    END IF
  94.                     DO WHILE x < W - 2 AND Array(x + 1, y) = S(x + 1, y)
  95.                         '                        IF Array(x + 1, y) = S(x + 1, y) THEN
  96.                         Array(x + 1, y) = np
  97.                         finished = 0
  98.                         x = x + 1
  99.                         IF x > MaxX THEN MaxX = x
  100.                         '                       ELSE
  101.                         '                          EXIT DO
  102.                         '                     END IF
  103.                     LOOP
  104.                 END IF
  105.             NEXT
  106.         NEXT
  107.         FOR x = TMX TO TMX2
  108.             FOR y = TMY2 TO TMY STEP -1
  109.                 IF Array(x, y) = pass THEN
  110.                     '    fill_up:
  111.                     '    IF y > 0 THEN
  112.                     '        IF Array(x, y - 1) = S(x, y - 1) THEN
  113.                     '            Array(x, y - 1) = np
  114.                     '            finished = 0
  115.                     '            y = y - 1
  116.                     '            IF y < MinY THEN MinY = y
  117.                     '            GOTO fill_up
  118.                     '        END IF
  119.                     DO WHILE y > 0 AND Array(x, y - 1) = S(x, y - 1)
  120.                         '                        IF Array(x, y - 1) = S(x, y - 1) THEN
  121.                         Array(x, y - 1) = np
  122.                         finished = 0
  123.                         y = y - 1
  124.                         IF y < MinY THEN MinY = y
  125.                         '                       ELSE
  126.                         '                          EXIT DO
  127.                         '                     END IF
  128.                     LOOP
  129.                 END IF
  130.  
  131.  
  132.             NEXT
  133.             FOR y = TMY TO TMY2
  134.                 'IF Array(x, y) = pass THEN
  135.                 '    fill_down:
  136.                 '    IF y < H - 2 THEN
  137.                 '        IF Array(x, y + 1) = S(x, y + 1) THEN
  138.                 '            Array(x, y + 1) = np
  139.                 '            finished = 0
  140.                 '            y = y + 1
  141.                 '            IF y > MaxY THEN MaxY = y
  142.                 '            GOTO fill_down
  143.                 '        END IF
  144.                 '    END IF
  145.                 'END IF
  146.                 IF Array(x, y) = pass THEN
  147.                     DO WHILE y < H - 2 AND Array(x, y + 1) = S(x, y + 1)
  148.                         '                        IF Array(x, y + 1) = S(x, y + 1) THEN
  149.                         Array(x, y + 1) = np
  150.                         finished = 0
  151.                         y = y + 1
  152.                         IF y > MaxY THEN MaxY = y
  153.                         '                       ELSE
  154.                         '                      EXIT DO
  155.                         '                     END IF
  156.                     LOOP
  157.                 END IF
  158.  
  159.             NEXT
  160.         NEXT
  161.         pass = pass + 1
  162.     LOOP UNTIL finished
  163.  
  164.     FOR y = MinY TO MaxY
  165.         FOR x = MinX TO MaxX
  166.             IF Array(x, y) THEN 'PSET (x, y), kolor
  167.                 IF left = 0 THEN left = x
  168.             ELSE
  169.                 IF left THEN LINE (left, y)-(x - 1, y), kolor, BF: left = 0
  170.             END IF
  171.         NEXT
  172.         IF left THEN LINE (left, y)-(x - 1, y), kolor, BF: left = 0
  173.     NEXT
  174.  

focusing
at place of GOTO label loop
Code: QB64: [Select]
  1.                 IF Array(x, y) = pass THEN
  2.                     fill_down:
  3.                     IF y < H - 2 THEN
  4.                         IF Array(x, y + 1) = S(x, y + 1) THEN
  5.                             Array(x, y + 1) = np
  6.                             finished = 0
  7.                             y = y + 1
  8.                             IF y > MaxY THEN MaxY = y
  9.                             GOTO fill_down
  10.                         END IF
  11.                     END IF
  12.                 END IF
we put this
Code: QB64: [Select]
  1.                 IF Array(x, y) = pass THEN
  2.                     DO WHILE y < H - 2 AND Array(x, y + 1) = S(x, y + 1)
  3.                         Array(x, y + 1) = np
  4.                         finished = 0
  5.                         y = y + 1
  6.                         IF y > MaxY THEN MaxY = y
  7.                     LOOP
  8.                 END IF

thanks to read and to play with code together!
Programming isn't difficult, only it's  consuming time and coffee

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Steve's Magical Paint Fill
« Reply #28 on: November 24, 2019, 10:22:05 am »
                    DO WHILE y < H - 2 AND Array(x, y + 1) = S(x, y + 1)
                        Array(x, y + 1) = np
                        finished = 0
                        y = y + 1
                        IF y > MaxY THEN MaxY = y
                    LOOP
           

You have to separate these conditions, or face runtime errors.

Say y = H -2...   It passes the loop, gets incremented to H -1.

That compound IF statements wants to check “ Array(x, y + 1) = ...”, which makes it checking Array(x, H)...   This is an Out Of Bounds array error, as our array is only dimmed to H-1.

It’s why the original code separates the conditions for us.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Steve's Magical Paint Fill
« Reply #29 on: November 24, 2019, 02:24:00 pm »
Right Steve!
if y increases to be = H-2 and the second dimension of Array or S is lower than H-2 we get an out of bounds error!
So it is safe to put evaluation of arrays  Array and S after the evaluation of y<H-2!

Or you must rule the incrementation with a control like
 IF  y < Ubound(Array,2) then y = y+1
Or
 IF  y < Ubound(S,2) then y = y+1
Or
IF  y +1< H-2 then y = y+1

Or you must project a statement where two or more conditions are not in conflict.
In the specific case if y can reach the value of H-2 the associated conditions must permit that value for y

What I find beautyful of programming is the possibility to use our  mind in creative mode.

Thanks

Programming isn't difficult, only it's  consuming time and coffee