Professional Documents
Culture Documents
The Modified Flood Fill Simulator
The Modified Flood Fill Simulator
Prerequisites
This article requires the reader to have some basic knowledge and understanding about
the following topics
1. Basic logical constructs of C like if-then-else, while, for etc.
2. Understanding of bitwise operators in C.
3. Implementation of Stack using arrays.
4. Simple 1D array manipulations.
5. Writing subroutines in C and macros.
It is advised that before putting up any question on the forum regarding doubts about the
software implementation of the Modified Flood fill algorithm, the reader goes through
some C-language tutorial like the one given here,
http://www.lysator.liu.se/c/bwk-tutor.html
Abstract
This article will first discuss the Flood Fill algorithm, modified flood fill will be built on
that. After the boring theory session, the actual C implementation of the algorithm will be
discussed and a sample simulator program is provided in the end of this article.
It should be noted that the algorithm and some of the pictures used in this article have
been taken from ‘micromouseinfo’ website,
http://www.micromouseinfo.com/introduction/floodfill.html
http://www.micromouseinfo.com/introduction/mfloodfill.html
It should be noted here that this illustration has no connection with the ones shown
before. Here also, it is easy to see if squares are chosen in ascending order of their
potential from the starting square, the center can be reached by the shortest path.
This algorithm has a relatively simple implementation in the software. Two arrays should
be maintained in the memory, one for keeping the flood fill numbers and the other for
keeping the wall information of the maze. Every time the mouse enters a new square, it
stops and checks for the walls, runs the flood fill algorithm, decides where to go
depending upon the information given by the flood fill and moves on till it finds the
center. Needless to say, this is not a great approach, firstly because your mouse is
stopping at every square and secondly, you are flooding the maze from the center every
time. This is where the modified flood fill kicks in.
Whenever we enter a cell, we check for the walls and update the wall map accordingly.
Now we need to call the modified flood fill to flood only that part of the maze which is
required. The cell values are updated according to the following rule,
When the cell values violate the above rule, they need to be updated.
Push the current cell (the one the robot is standing on) onto the stack
{
Pull a cell from the stack
Is the distance value of this cell = 1 + the minimum value of its open neighbors?
No -> Change the cell to 1 + the minimum value of its open neighbors and
push all of the cell's open neighbors onto the stack to be checked
Yes -> Do nothing
}
The stack empty check is not required in the program presented in this article.
The wall map is updated, required part of the maze is also flooded now what? Guess we
need to make the right move.
Pull all of the cells from the stack (The stack is now empty)
Sort the cells to determine which has the lowest distance value
After making the move, the above process is repeated again and again till the mouse
reaches the center/runs out of gas/stops to say ‘Hi!’ to you/stops for a photograph/bangs
into the wall!
The simulator is divided into two parts, the ‘.cpp’ file which implements the algorithm
and the header ‘.h’ file which provides the graphics and basic front, left and right
movements. At this point you might think that the main program is the most important
thing, but you must understand that the header file is a general purpose file which can be
used to implement any higher level maze solving algorithms.
The ‘MAZE.h’ header file deals only with the graphics and I must clearly state here that it
has not been written by me. It has the following functions that you are supposed to know,
1. void movestraight(int)
This function makes the mouse on screen go straight the number of
squares mentioned in the argument when calling.
2. void turnleft()
This makes the mouse point to its left direction. If you call the
movestraight(1) function after calling turnleft(), the mouse will move into
the square in its left.
3. void turnright()
This makes the mouse point to its right direction. If you call the
movestraight(1) function after calling turnright(), the mouse will move
into the square in its right.
You should note that the left and right directions are relative to mouse and not yours’ left
and right, don’t get confused.
4. void show_maze()
Calling this function would display the maze on the screen. This should be
done in the start of the main().
5. int sense(int)
This function has three arguments, FRONT, LEFT and RIGHT. It returns a
high(i.e. ‘1’) if there is a wall in the given direction. Basically this is the
sensor of your virtual mouse on screen.
6. int hori_walls[sizemaze+1][sizemaze] and int vert_walls[sizemaze][sizemaze+1]
These two variables contain the maze’s wall information. Putting a ‘1’
builds a wall, ‘0’ removes it. I have provided two actual competition
mazes for you. One was used in a competition in the USA in 1982 and the
other was used in Japan in 1991 (yes, we are far behind them). The design
has been taken from Peter Harrison’s micromouse site,
http://micromouse.cannock.ac.uk/maze/samples.htm
Watch out for that Japanese maze, it is the best I have ever seen. Also, you
can build your own test maze.
Before going through the simulator program, you need to understand a few things about
this implementation,
1. I have tried to things as simple as possible(with few exceptions of course!),
thus the implementation is not very efficient in terms of memory consumption
and execution speed, mainly because of my 2.4Ghz machine with 1Gb RAM.
You are probably going to implement this on a 16MHz 2Kb thingy
(ATMega32), so take this program as a reference only.
2. The maze has been mapped as a 1-dimensional array to maintain simplicity
and has been visualized as shown below
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
(Start)
In the implementation, cell number 119 has been taken as the destination cell.
This happens to be the bottom left cell of the maze’s center.
NORTH
WEST EAST
SOUTH
It is pretty evident that if the mouse is facing north in the cell number ‘x’ and it moves
straight one cell, it will find itself in the cell number ‘x+16’.
If the mouse is facing west in the cell number ‘x’ and it moves one cell to its left, it will
find itself in the cell number ‘x-16’. You can work out for other directions and
movements in a similar way.
7. The unsigned char wallflood[256] variable holds the flood fill numbers (or the
potential values) of the squares. This variable is initialized with values assuming that
there are no walls in the maze.
8. There is a variable in the program called cell_count, this variable was declared
solely for debugging purposes and has no use in the current program. You can surely put
it to some good use.
9. Rest of the code is very heavily commented (that’s my habit, a good one) and is
pretty much self explanatory given you have gone through the theory part and you have a
good command in C.
10. Please go through ‘Read Me.txt’ before running the simulator on your PC.
Final Remarks
First things first, flood fill algorithm of any kind is pretty inefficient. Your mouse will
take a long time to reach the center and come back for a speed run. But yes, you will
reach the center and complete the problem statement which might be enough for you to
be the champion!
There is a reason why I like that Japan competition maze, the shortest path in it is not the
fastest one! Yup, this is possible! Here, you will see, flood fill’s performance is horrible.
Here, something you need to know about the pedigree of flood fill. Flood Fill Algorithm
has been derived from Kruskal’s Algorithm which happens to be a kind of greedy
algorithm. Kruskal’s Algorithm finds a minimum spanning tree (i.e. the shortest path in
the maze) for a connected weighted graph (which is The Maze). I know I am speaking too
much! It does not assigns costs to the paths, that is, a turn takes more time than a straight
and hence, ‘costs’ more. Kruskal’s Algorithm doesn’t cares about this.