Monday, July 20, 2009

Doors have been found!

Here is what I ended up using to find all doors in a tile. It could use a little refactoring, but it works!



        private List findDoors()
{
List foundDoors = new List();

for (int i = 0; i < blockGrid.GetLength(0); i++)
{
for (int j = 0; j < blockGrid.GetLength(1); j++)
{
if (blockGrid[i, j].type == "door" && !blockGrid[i, j].visited)
{
foundDoors.AddRange(figureWidth(i, j));
blockGrid[i, j].visited = true;
}
}
}

return foundDoors;
}

//Figures width of a door. Will check both horizontally and vertically.
private List figureWidth(int i, int j)
{
List doors = new List();
int width = 1;
Vector2 position = new Vector2(i, j);

width = PeekRight(i, j, width);

if (width > 1)
{
doors.Add(new Door(width, position, Orientation.Horizontal));
}

width = 1;
width = PeekDown(i, j, width);

if (width > 1)
{
doors.Add(new Door(width, position, Orientation.Vertical));
}

if (doors.Count == 0)
{
doors.Add(new Door(1, position, Orientation.None));
}

return doors;
}

private int PeekRight(int i, int j, int width)
{
if (DoorOnRight(i, j))
{
width = PeekRight(i, j + 1, width + 1);
blockGrid[i, j + 1].visited = true;
if (DoorBelow(i, j + 1))
{
blockGrid[i, j + 1].visited = false;
}
}
return width;
}

private int PeekDown(int i, int j, int width)
{
if (DoorBelow(i, j))
{
width = PeekDown(i + 1, j, width + 1);
blockGrid[i + 1, j].visited = true;
if (DoorOnRight(i + 1, j))
{
blockGrid[i + 1, j].visited = false;
}
}
return width;
}

private bool DoorOnRight(int i, int j)
{
bool doorOnRight = false;
if (j < blockGrid.GetLength(1) - 1 && blockGrid[i, j + 1].type == "door")
{
doorOnRight = true;
}
return doorOnRight;
}

private bool DoorBelow(int i, int j)
{
bool doorBelow = false;
if (i < blockGrid.GetLength(0) - 1 && blockGrid[i + 1, j].type == "door")
{
doorBelow = true;
}
return doorBelow;
}




The trick was the VISITED boolean. I wondered how I could make sure to evaluate doors that were on corners, but I didn't see how to do the evaluation without going through the tile twice -- once looking for vertical doors, and once looking for horizontal doors.

This way, each block is evaluated one-at-a-time. As the width of a door is found, it sets each block to 'visited' status, so it doesn't look for another door. Unless, that is, there is another door block to the right or below the current block. Then, the block is considered not visited, and will still be evaluated when the one-at-a-time evaluation hits.

Think of it as like a going through a maze. If you come to an intersection, you want to consider that intersection 'unexplored' until you have a chance to come back and explore the other paths.

Wednesday, July 8, 2009

2-D Arrays

I graduated my Computer Science focus, you would've thought that I would know how to reference a 2-D array. First number is the array number, and the second number is the number within that array. I thought It was like a grid, where a reference took x/y coordinates. Instead, it's y/x. Lesson learned!