Code
- Player.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace BFSMaze
{
class Pos
{
public Pos(int y, int x) { Y = y; X = x; }
public int Y;
public int X;
}
class Player
{
public int PosY { get; private set; }
public int PosX { get; private set; }
Random _random = new Random();
Board _board;
enum Dir
{
Up = 0,
Left = 1,
Down = 2,
Right = 3
}
int _dir = (int)Dir.Up;
List<Pos> _points = new List<Pos>();
public void Initialize(int posY, int posX, Board board)
{
PosY = posY;
PosX = posX;
_board = board;
BFS();
}
void BFS()
{
int[] deltaY = new int[] { -1, 0, 1, 0};
int[] deltaX = new int[] { 0, -1, 0, 1 };
bool[,] found = new bool[_board.Size, _board.Size];
Pos[,] parent = new Pos[_board.Size, _board.Size];
Queue<Pos> q = new Queue<Pos>();
q.Enqueue(new Pos(PosY, PosX));
found[PosY, PosX] = true;
parent[PosY, PosX] = new Pos(PosY, PosX);
while ( q.Count > 0)
{
Pos pos = q.Dequeue();
int nowY = pos.Y;
int nowX = pos.X;
for(int i=0; i<4; i++)
{
int nextY = nowY + deltaY[i];
int nextX = nowX + deltaX[i];
if (nextX < 0 || nextX >= _board.Size || nextY < 0 || nextY >= _board.Size)
continue;
if (_board.Tile[nextY, nextX] == Board.TileType.Wall)
continue;
if (found[nextY, nextX] == true)
continue;
q.Enqueue(new Pos(nextY, nextX));
found[nextY, nextX] = true;
parent[nextY, nextX] = new Pos(nowY, nowX);
}
}
int y = _board. DestY;
int x = _board.DestX;
while (parent[y,x].Y != y || parent[y, x].X != x)
{
_points.Add(new Pos(y, x));
Pos pos = parent[y, x];
y = pos.Y;
x = pos.X;
}
_points.Add(new Pos(y, x));
_points.Reverse();
}
const int MOVE_TICK = 10;
int _sumTick = 0;
int _lastIndex = 0;
public void Update(int deltaTick)
{
if (_lastIndex >= _points.Count)
return;
_sumTick += deltaTick;
if (_sumTick >= MOVE_TICK)
{
_sumTick = 0;
PosY = _points[_lastIndex].Y;
PosX = _points[_lastIndex].X;
_lastIndex++;
}
}
}
}
Algorithm
- Breadth First Search
- Start at the root node
- Navigate to adjacent nodes first
- BFS shortest Path Algorithm
- Use Queue
- Enqueue start root, looping while not empty
- Dequeue in loop
- If the node is not visited, change to be visited
- Save parent node, reverse
Queue
- Enqueue
- Insert new node to last
- Dequeue
- Pop first node
Queue<Pos> q = new Queue<Pos>();
q.Enqueue(new Pos(PosY, PosX));
...
while ( q.Count > 0)
{
Pos pos = q.Dequeue();
...
List
- Reverse
- Reverse order of list
_points.Reverse();
Search Path
- deltaY & deltaX
- Can go every direction
- If path faces wall, dequeue
- As a result, only shortest path remains
int[] deltaY = new int[] { -1, 0, 1, 0};
int[] deltaX = new int[] { 0, -1, 0, 1 };
for(int i=0; i<4; i++)
{
int nextY = nowY + deltaY[i];
int nextX = nowX + deltaX[i];
...