help to understand maze solve algorithm with floodfill

Hello guys!
Before starting, i'm Brazilian and i don't speak inglish very well, so forgive me if i say something wrong!

well, i'm trying to create a micromouse robot to solve a maze, as college work. I will use the floodfill algortihm to do that, but i'm having much dificult to create this code.

i saw this code here in the forum and i using it like base:

const byte size=16;
const byte Empty=255;

int i = 0;

const byte North=1;
const byte South=2;
const byte East=4;
const byte West=8;

const byte Walls[size][size] PROGMEM=
{
  {West|North,North,North,North,North,North,North,North,North,North,North,North,North,North,North,North|East},
  {West,0,0,West,0,0,0,0,0,0,0,0,0,0,0,East},
  {West,0,0,West,0,0,0,0,0,0,0,0,0,0,0,East},
  {West,0,0,West,0,0,0,0,0,0,0,0,0,0,0,East},
  {West,0,0,West,0,0,0,0,0,0,0,0,0,0,0,East},
  {West,0,0,West|North,North,North,North,North,North,North,North,North,North,North,North,East|North},
  {West,0,0,West,0,0,0,0,0,0,0,0,0,0,0,East},
  {West,0,0,West,0,0,0,West|North,East,0,0,0,0,0,0,East},
  {West,0,0,West,0,0,0,West|South,South,0,0,0,0,0,0,East},
  {West,0,0,West,0,0,0,0,0,0,0,0,0,0,0,East},
  {West,0,0,West,0,0,0,0,0,0,0,0,0,0,0,East},
  {West,0,0,West,0,0,0,0,0,0,0,0,0,0,0,East},
  {West,0,0,West|South,South,South,South,South,South,South,South,South,South,South,South,East|South},
  {West,0,0,West,0,0,0,0,0,0,0,0,0,0,0,East},
  {West,0,0,0,West,0,0,0,0,0,0,0,0,0,0,East},
  {West|South,South,South,South,South,South,South,South,South,South,South,South,South,South,South,South|East}
};

typedef struct
{
//byte walls;
byte steps; 
}Cell;

Cell Maze[size][size];

void setup()
{
  Serial.begin(115200);
  ClearMaze();
  SetGoalCell(7,7);
  SetGoalCell(7,8);
  SetGoalCell(8,7);
  SetGoalCell(8,8);
  PrintWalls();
  Serial.println();
  PrintMaze();
  Serial.println();
  FloodFill(7,7);
  FloodFill(7,8);
  FloodFill(8,7);
  FloodFill(8,8);
  PrintMaze();
}

void ClearMaze()
{
for(byte row=0;row<size;row++)
  for(byte col=0;col<size;col++)
    Maze[row][col].steps=Empty;
}

void SetGoalCell(byte col,byte row)
{
Maze[row][col].steps=0; 
}

void FloodFill(byte row,byte col)
{
byte Next=Maze[row][col].steps+1;
byte wall = pgm_read_byte_near(&(Walls[row][col]));
if(row && (wall&North)==0)
  {
  if(Maze[row-1][col].steps>Next)
    {
    Maze[row-1][col].steps=Next;
    FloodFill(row-1,col);
    }
  }
if(col<size-1 && (wall&East)==0)
  {
  if(Maze[row][col+1].steps>Next)
    {
    Maze[row][col+1].steps=Next;
    FloodFill(row,col+1);
    }
  }
if(row<size-1 && (wall&South)==0)
  {
  if(Maze[row+1][col].steps>Next)
    {
    Maze[row+1][col].steps=Next;
    FloodFill(row+1,col);
    }
  }
  if(col && (wall&West)==0)
  {
  if(Maze[row][col-1].steps>Next)
    {
    Maze[row][col-1].steps=Next;
    FloodFill(row,col-1);
    }
  }
}

void PrintMaze()
{
for(byte row=0;row<size;row++)
  {
  for(byte col=0;col<size;col++)
    {
    Serial.print(Maze[row][col].steps);
    Serial.print("\t"); 
    }
  Serial.println();
  }
}

void PrintWalls()
{
for(byte row=0;row<size;row++)
  {
  for(byte col=0;col<size;col++)
    {
    Serial.print(pgm_read_byte_near(&(Walls[row][col])));
    Serial.print(","); 
    }
  Serial.println();
  }
}

void loop()
{
}

but, i didn't can understand how the all code works, someone can explain me some functions in the code?
for example, the function "const byte Walls PROGMEM", i know that is about a constant matriz 16x16 that represents the walls of the maze, but my doubt is, if this matriz represents the walls, why the values is seted this way?
I tried to draw the maze with base in this values, in the cell that is "west" i put a wall on west of that cell, and the same for the others cells, and the maze don't maked sense to me.
In the cells that the values is 0, means that there isn't a walls?
And if is this, means that there are more than 1 cells conected without wall, as in case the cells at (1,5),(1,6),(1,7),(2,5),(2,6),(2,7), being (row,col), and so on in the matriz of walls.

other doubt, the values of north, south, east, west, obligatorily should be this values (1,2,4,8) or can i put other values?
i think there is some rule to found this values, can someone explain me why these values are used?

The values 1 2 4 8 are each single bits and represent the four possible walls that may be in a cell.

The bits can thus be ORed together if more than one wall is present, such as in the NW corner.

For flood fill you start from an empty cell and mark it visited first. Then check all neighbour cells, which are not hidden by a wall, and mark them visited next. Continue with all last recently visited cells, until you reach a goal cell or all reachable cells have been visited.

This simple algorithm can be implemented in various ways - find out how your current implementation works, or implement your own version.

Hello,
sorry for the time to answer,
Thanks jremington, i think i almost understood how to use this values with the matriz "const byte walls", that in the case of this code this matriz is constant, so i can't change this values in exploring step. For put the values of walls i need to create other matriz that don't be constant. In my case i did other matriz that is

byte paredes[size][size];

("paredes" means "walls" in portuguese.)

in the case of this code this matriz is constant

Yes, because it is put into Program Memory to save RAM memory.

It is fine for the array to be in RAM, in which case you can update it. For example, if the robot discovers an East wall in cell paredes[8][3], store that for future reference using a line of code like:

paredes[8][3] |= East; or equivalently,

paredes[8][3] = paredes[8][3] | East;

jremington, I'm doing the following, I created a function to read the infrared sensor of front, right and left, in this function, first i check the orientation, if is north, south, east or west, after if the orientation is north, i do a "if" to check each possibility of existing wall and if the variable "visited" is false, if is, then the array "paredes[currentCell.x][currentCell.y] = North" and the variable boolean visited receive "true". And so the same for the others possibilities and orientations.
i don't know if this method is the best, but is the way that i thought to do.

DrDiettrich, i'm implementing my own version, i created a variable boolean from a struct to thats store the value "true" if the cell was visited, starting with the start cell seted like "visited" = "true", and all the other seted "false", when the robot moves foward, according the orientation, the array which indicates the position moves to the new position and the variable "visited" = "true".

Now, other question, to robot move, i doing the robot check if the value of the accessible cells are differ, if is, he should take the way that has the lowest value; and if the value of cells is the same, he moves ever foward to gain time not doing turns.
But i'm not using the value "visited" of cells to compare. Is it correct for me to use this method to move the robot?

And Thanks for the help!

paredes[currentCell.x][currentCell.y] = North

This won't work if another wall is also in the cell. You MUST use bitwise OR to set the bits.

Make sure that all the cells without walls are initialized to zero at startup.

jremington, this will work right?

paredes[currentCell.x][currentCell.y] = South|West|North;

Yes, but that would be an extremely narrow maze, with the North and South boundary walls in the same cell.

To keep track of walls other than the outer boundaries, you can use the single bits corresponding to decimal 16, 32, 64 and 128, all in one unsigned char 8 bit variable.

To set a bit without disturbing previous settings, use the bitwise OR similar to the following:

paredes[currentCell.x][currentCell.y] |= North;

If walls are marked in cells, always 2 adjacent cells are affected by the same wall. Eventually a different grid for the walls is easier to handle, or a big grid with even indices for cells and odd for walls?

always 2 adjacent cells are affected by the same wall

I fail to see your point, and it does not seem to be true.

If a cell has a West wall, that simply means that the robot cannot move West from that cell. That is not the case for any adjacent, unmarked cell.

The cell in the West sees the same wall at East - unless we have semipermeable walls :wink:

Sorry, that makes no sense to me. We must be talking about different things.

It's the issue with how you represent the maze. The obvious first choice is a 2D array of cells. Then you specify for each cell, which of four possible walls are present. If the cell is not on the perimeter then every wall is also a wall in another cell. Using Cartesian coordinates, if cell 1,1 has a wall to the north then that wall is also a south wall for cell 1,2.

@wildbill: that is perfectly clear. The previous comment by DrDietrich is not.

I don't see the issue as a problem, either.

jremington:
I don't see the issue as a problem, either.

Agreed. It just bit me when I was tinkering with maze code long back for a Micromouse that was never completed.

One issue is to recognize that for interior walls, if for example an East wall is detected or specified in a cell, then a West bit needs to be in the appropriate adjacent cell. Or, equivalently, adjacent cells need to be checked for wall bits not set in the current cell.

Interesting that you mention Micromouse. Years ago, a friend and I were preparing entries that were also never finished. Since that time, young Japanese engineers have completely dominated the field. That friend is back, after a successful industry career, and is planning to mount a significant challenge. Given that the winning mice now use vacuum skirts to avoid slipping on the fast turns, best of luck to him.

DrDiettrich, i don't think i understood your point either, but what I did was.
I created an array that just will store the wall data in each cell

byte paredes[size][size];

//when I find a wall, i assign the wall data in array in the current location that my mouse is
paredes[currentCell.x][currentCell.y] |= North;

I agree with the point of willdbill and jremington because I see no problem with walls between adjacent cells.
And jremington, thanks i will use:

paredes[currentCell.x][currentCell.y] |= North;

my mouse is walking in the maze and reaching the goal, but as I always made him follow the shortest path, he doesn't quite explore the whole maze, any tips for implementing the whole maze exploration step?

You can mark a cell as "visited" using the same approach as setting a wall bit, then when almost done, look for cells that have not been visited. Available flag bits are valued 16, 32, 64 and 128.

If you want the entire maze explored, remove the goal and let the mouse stop only if all (reachable) cells have been visited.