Floodfill sounds complicated, but it's actually fairly easy to implement as long as your search-space (the game grid) isn't too large, and performance isn't an issue (which for a small grid like this is not an issue)
Adding floodfill to z's code is actually fairly easy.
First though, there's a decision to be made on how to stop the floodfill going out of bounds, i.e. off any edge of the array. The choices are:
- put tests within the floodfill to stop x being less than 1 or greater than the grid width, with similar checks for y
- make the grid 1 size larger in each direction and filled with a value that can never be painted over.
With z's code already being 1 larger at the top and left (he's using the array as if it's 1-based), it's simpler to go with adding an extra row and column on the bottom and right - change the DIM to the following:
dim GameBoard(BoardSizeX + 1,BoardSizeY + 1)
As the board is being filled from 1 to BoardSizeX and 1 to BoardSizeY, this will leave the x & y at 0 as zero, and the x & y at BoardSizeX+1 and BoardSizeY+1 at zero. Seeing as we fill with numbers from 1 to 6 and never 0, this gives us our unpaintable border.
Next, the floodfill:
function FloodFill(x as integer, y as integer, OrigColour as integer, NewColour as integer)
if GameBoard(x,y) <> OrigColour then exitfunction
GameBoard(x,y) = NewColour
FloodFill(x-1, y, OrigColour, NewColour)
FloodFill(x+1, y, OrigColour, NewColour)
FloodFill(x, y-1, OrigColour, NewColour)
FloodFill(x, y+1, OrigColour, NewColour)
endfunction
As you can see, this is a direct implementation of the simplest algorithm on the wiki page - x and y together specify the node.
Next, we just want to fill with different colours, as selected by the player. I've gone with a simple key-based method that you'll need to replace with your preferred method. Put this code after the CLS command in your code:
Key$ = inkey$()
if Key$ >= "1" and Key$ <= "6"
if GameBoard(1, 1) <> val(Key$) then FloodFill(1, 1, GameBoard(1, 1), val(Key$))
endif
That's it. Run the code, hit the number keys and watch it just work.
Complete code:
Rem Project: Dark Basic Pro Project
Rem Created: Friday, September 02, 2011
Rem ***** Main Source File *****
`Set sync rate & display mode
sync on
sync rate 60
Set display mode 800,600,32
`setup some constants
#constant BlockSizeX 32
#constant BlockSizeY 32
#constant BoardSizeX 14
#constant BoardSizeY 14
#constant XOffset =128
#constant YOffset =32
`I like to initialize some variables I use
RandColor as integer
RandColor=0
ColorOfBlock as integer
ColorOfBlock=0
`Create a 2D array for now as the GameBoard
dim GameBoard(BoardSizeX + 1,BoardSizeY + 1)
`Seed our Random Generator
randomize timer()
`Lets put Random Values 1-6 in our 2D array
`These values represent 1 of 6 colored blocks
`The numbers correlate to the Image Numbers respectively
`1=BLUE : 2=RED : 3=GREEN : 4=PURPLE : 5=YELLOW : 6=PINK
for y=1 to BoardSizeY
for x=1 to BoardSizeX
RandColor=rnd(5)+1
GameBoard(x,y)=RandColor
next x
next Y
`Create 6 color blocks
`Blue
ink rgb(0,0,200)
box 1,1,BlockSizeX,BlockSizeY
get image 1,1,1,BlockSizeX,BlockSizeY
`Red
ink rgb(200,0,0)
box 1,1,BlockSizeX,BlockSizeY
get image 2,1,1,BlockSizeX,BlockSizeY
`Green
ink rgb(0,200,0)
box 1,1,BlockSizeX,BlockSizeY
get image 3,1,1,BlockSizeX,BlockSizeY
`Purple
ink rgb(100,0,120)
box 1,1,BlockSizeX,BlockSizeY
get image 4,1,1,BlockSizeX,BlockSizeY
`Yellow
ink rgb(200,200,0)
box 1,1,BlockSizeX,BlockSizeY
get image 5,1,1,BlockSizeX,BlockSizeY
`pink
ink rgb(200,0,100)
box 1,1,BlockSizeX,BlockSizeY
get image 6,1,1,BlockSizeX,BlockSizeY
`* * * * * * * * * * M A I N L O O P * * * * * * * * * *
DO
cls 0
Key$ = inkey$()
if Key$ >= "1" and Key$ <= "6"
if GameBoard(1, 1) <> val(Key$) then FloodFill(1, 1, GameBoard(1, 1), val(Key$))
endif
for y=1 to BoardSizeY
for x=1 to BoardSizeX
ColorOfBlock=GameBoard(x,y)
paste image ColorOfBlock,x*BlockSizeX+XOffset,y*BlockSizeY+YOffset
next x
next y
sync
LOOP
`* * * * * * * * E N D M A I N L O O P * * * * * * * *
function FloodFill(x as integer, y as integer, OrigColour as integer, NewColour as integer)
if GameBoard(x,y) <> OrigColour then exitfunction
GameBoard(x,y) = NewColour
FloodFill(x-1, y, OrigColour, NewColour)
FloodFill(x+1, y, OrigColour, NewColour)
FloodFill(x, y-1, OrigColour, NewColour)
FloodFill(x, y+1, OrigColour, NewColour)
endfunction