Exemplo n.º 1
0
        public List<Cell> Solve(Cell[,] maze, Cell startingCell, Cell endingCell)
        {
            var q = new Queue<Cell>();

            startingCell["parent"] = startingCell;
            q.Enqueue(startingCell);

            while (q.Peek() != endingCell)
            {
                Cell current = q.Dequeue();
                foreach (Cell cell in current.Neighbors)
                    if (cell["parent"] == null)
                    {
                        cell["parent"] = current;
                        q.Enqueue(cell);
                    }
            }

            var solution = RebuildPath(endingCell);

            foreach (var cell in maze)
                cell.ClearAdditionalValues();

            return solution;
        }
Exemplo n.º 2
0
        //Do not use this implementation... it's so slow!
        public List<Cell> Solve(Cell[,] maze, Cell startingCell, Cell endingCell)
        {
            var open = new List<Cell>();
            var closed = new List<Cell>();

            startingCell["g"] = 0;
            startingCell["h"] = EstimateDistance(startingCell, endingCell);
            startingCell["f"] = (int)startingCell["g"] + (int)startingCell["h"];
            open.Add(startingCell);

            while(true)
            {
                open.Sort((c1, c2) => (int)c1["f"] - (int)c2["f"]);

                var current = open[0];
                open.RemoveAt(0);
                closed.Add(current);

                if (current == endingCell) break;

                var neighbour = new [] {current.North, current.East, current.South, current.West};
                foreach (var cell in neighbour)
                {
                    if (cell == null || closed.Contains(cell))
                        continue;

                    if (open.Contains(cell))
                    {
                        if ((int)current["g"] + 1 < (int)cell["g"])
                        {
                            cell["g"] = (int) current["g"] + 1;
                            cell["f"] = (int) cell["g"] + (int)cell["h"];
                            cell["parent"] = current;
                        }
                    }
                    else
                    {
                        cell["g"] = (int)current["g"] + 1;
                        cell["h"] = EstimateDistance(cell, endingCell);
                        cell["f"] = (int)cell["g"] + (int)cell["h"];
                        cell["parent"] = current;

                        open.Add(cell);
                    }
                }
            }

            var solution = RebuildPath(endingCell);

            foreach (var cell in maze)
                cell.ClearAdditionalValues();

            return solution;
        }
Exemplo n.º 3
0
        private static List<Cell> RebuildPath(Cell endingCell)
        {
            List<Cell> ret = new List<Cell>();
            Cell current = endingCell;

            do
            {
                ret.Add(current);
                current = current["parent"] as Cell;
            } while (current != null);

            ret.Reverse();

            return ret;
        }
Exemplo n.º 4
0
 private static int EstimateDistance(Cell cell, Cell endingCell)
 {
     return Math.Abs(cell.X - endingCell.X) + Math.Abs(cell.Y - endingCell.Y);
 }
Exemplo n.º 5
0
        public Cell[,] Build(int width, int height)
        {
            var rnd = new Random();
            var maze = new Cell[width, height];
            int x, y;
            int startX = x = rnd.Next(width);
            int startY = y = rnd.Next(height);

            var directions = new List<int>();
            var history = new Stack<Cell>();

            for (int i = 0; i < width; i++)
                for (int j = 0; j < height; j++)
                {
                    maze[i, j] = new Cell(i, j);
                    maze[i, j]["processed"] = false;
                }

            history.Push(maze[x,y]);
            do
            {
                maze[x, y]["processed"] = true;
                directions.Clear();

                if (y - 1 >= 0 && !(bool)maze[x, y - 1]["processed"])
                    directions.Add(0);

                if (x + 1 < width && !(bool)maze[x + 1, y]["processed"])
                    directions.Add(1);

                if (y + 1 < height && !(bool)maze[x, y + 1]["processed"])
                    directions.Add(2);

                if (x - 1 >= 0 && !(bool)maze[x - 1, y]["processed"])
                    directions.Add(3);

                if (directions.Count == 0)
                {
                    var lastCell = history.Pop();
                    x = lastCell.X;
                    y = lastCell.Y;
                    continue;
                }

                switch (directions[rnd.Next(directions.Count)])
                {
                    case 0:
                        maze[x, y].North = maze[x, y - 1];
                        maze[x, y - 1].South = maze[x, y];
                        y -= 1;
                        break;

                    case 1:
                        maze[x, y].East = maze[x + 1, y];
                        maze[x + 1, y].West = maze[x, y];
                        x += 1;
                        break;

                    case 2:
                        maze[x, y].South = maze[x, y + 1];
                        maze[x, y + 1].North = maze[x, y];
                        y += 1;
                        break;

                    case 3:
                        maze[x, y].West = maze[x - 1, y];
                        maze[x - 1, y].East = maze[x, y];
                        x -= 1;
                        break;
                }
                history.Push(maze[x, y]);
            } while (x != startX || y != startY);

            foreach (var cell in maze)
                cell.ClearAdditionalValues();

            return maze;
        }