Ejemplo n.º 1
0
        /// <summary>
        /// Recursive backtracking maze generation algorithm.
        /// </summary>
        /// <param name="currentPos"></param>
        private void CarvePassage(Point currentPos)
        {
            this.Board[currentPos.Y, currentPos.X].Point   = new Point(currentPos.X, currentPos.Y);
            this.Board[currentPos.Y, currentPos.X].Visited = true;
            this.Board[currentPos.Y, currentPos.X].position_in_iteration = ++iterationcount;

            List <Direction> validDirections = GetAllDirections();

            ValidateDirections(currentPos, validDirections);

            //If there is no valid direction we have found a dead end.
            if (validDirections.Count == 0)
            {
                this.Board[currentPos.Y, currentPos.X].isdeadend = true;
                Points.Add(new Tuple <Cell, Direction>(this.Board[currentPos.Y, currentPos.X], Direction.Invalid));
            }

            while (validDirections.Count > 0)
            {
                Direction rndDirection = Direction.Invalid;

                if (validDirections.Count > 1)
                {
                    rndDirection = validDirections[rng.Next(validDirections.Count)];
                }
                else if (validDirections.Count == 1)
                {
                    rndDirection = validDirections[0];
                }

                this.Board[currentPos.Y, currentPos.X].visited_count = ++this.Board[currentPos.Y, currentPos.X].visited_count;

                RemoveWall(currentPos, rndDirection);
                validDirections.Remove(rndDirection);
                Point newPos = GetAdjPos(currentPos, rndDirection);
                Points.Add(new Tuple <Cell, Direction>(this.Board[currentPos.Y, currentPos.X], rndDirection));
                statesChangeRecall.OnStatusUpdated();
                Thread.Sleep(1);
                CarvePassage(newPos);

                ValidateDirections(currentPos, validDirections);
            }
        }
Ejemplo n.º 2
0
        public void Evolve()
        {
            statesChangeRecall.IsEngineRunning = true;

            // algorithm

            Location current    = null;
            Location start      = null;
            Location target     = null;
            Location error      = new Location();
            var      openList   = new List <Location>();
            var      closedList = new List <Location>();

            for (int x = 0; x < Map.GetLength(0); x++)
            {
                for (int y = 0; y < Map.GetLength(1); y++)
                {
                    switch (Map[x, y].Type)
                    {
                    case LocationType.START_POINT:
                        if (start == null)
                        {
                            start = new Location()
                            {
                                X = x,
                                Y = y,
                            };
                        }
                        else
                        {
                            start = error;
                        }
                        break;

                    case LocationType.END_POINT:
                        if (target == null)
                        {
                            target = new Location()
                            {
                                X = x,
                                Y = y,
                            };
                        }
                        else
                        {
                            target = error;
                        }
                        break;

                    case LocationType.WALL:
                        break;

                    default:
                        break;
                    }
                    Map[x, y].Status      = LocationStatus.NULL;
                    Map[x, y].IsSlopeMove = false;
                    Map[x, y].SlopePath   = new List <Location>();
                }
            }

            //  if multiple start/targer found, return
            if (start == error || target == error || start == null || target == null)
            {
                statesChangeRecall.IsEngineRunning = false;
                statesChangeRecall.OnStatusUpdated();
                return;
            }

            // start by adding the original position to the open list
            openList.Add(start);
            int g = 0;

            while (openList.Count > 0)
            {
                // get the square with the lowest F score
                var lowest = openList.Min(l => l.F);
                current = openList.First(l => l.F == lowest);

                // add the current square to the closed list
                closedList.Add(current);

                // show current square on the map
                current.Status = LocationStatus.SEARCHED;
                if (current.IsSlopeMove)
                {
                    var lowestSlopeSquare = current.SlopePath.Min(l => l.F);
                    var slopeSquare       = current.SlopePath.First(l => l.F == lowestSlopeSquare);
                    slopeSquare.Status = LocationStatus.SEARCHED;
                }
                statesChangeRecall.OnStatusUpdated();
                System.Threading.Thread.Sleep(5);

                // remove it from the open list
                openList.Remove(current);

                // if we added the destination to the closed list, we've found a path
                if (closedList.FirstOrDefault(l => l.X == target.X && l.Y == target.Y) != null)
                {
                    break;
                }

                var adjacentSquares = GetWalkableAdjacentSquares(current.X, current.Y, Map);

                //g++;
                foreach (var adjacentSquare in adjacentSquares)
                {
                    // if this adjacent square is already in the closed list, ignore it
                    if (closedList.FirstOrDefault(l => l.X == adjacentSquare.X &&
                                                  l.Y == adjacentSquare.Y) != null)
                    {
                        continue;
                    }

                    // if it's not in the open list...
                    if (openList.FirstOrDefault(l => l.X == adjacentSquare.X &&
                                                l.Y == adjacentSquare.Y) == null)
                    {
                        // compute its score, set the parent
                        adjacentSquare.G      = g + current.G + ComputeHScore(adjacentSquare.X, adjacentSquare.Y, current.X, current.Y);
                        adjacentSquare.H      = ComputeHScore(adjacentSquare.X, adjacentSquare.Y, target.X, target.Y);
                        adjacentSquare.F      = adjacentSquare.G + adjacentSquare.H;
                        adjacentSquare.Parent = current;

                        // and add it to the open list
                        openList.Insert(0, adjacentSquare);
                    }
                    else
                    {
                        // test if using the current G score makes the adjacent square's F score
                        // lower, if yes update the parent because it means it's a better path
                        if (g + current.G + ComputeHScore(adjacentSquare.X, adjacentSquare.Y, current.X, current.Y) + adjacentSquare.H < adjacentSquare.F)
                        {
                            adjacentSquare.G      = g + current.G + ComputeHScore(adjacentSquare.X, adjacentSquare.Y, current.X, current.Y);
                            adjacentSquare.F      = adjacentSquare.G + adjacentSquare.H;
                            adjacentSquare.Parent = current;
                        }
                    }
                }
            }

            // Show result
            if (closedList.FirstOrDefault(l => l.X == target.X && l.Y == target.Y) != null)
            {
                //  Path found
                while (current != null)
                {
                    if (Map[current.X, current.Y].Type == LocationType.SPACE)
                    {
                        Map[current.X, current.Y].Status = LocationStatus.PATH;
                        statesChangeRecall.OnStatusUpdated();
                    }
                    current = current.Parent;
                    System.Threading.Thread.Sleep(5);
                }
            }
            else
            {
                //  No path found
                while (closedList.Count != 0)
                {
                    Location l = closedList.First();
                    l.Status = LocationStatus.ERROR;
                    closedList.Remove(l);

                    statesChangeRecall.OnStatusUpdated();
                    System.Threading.Thread.Sleep(1);
                }
            }

            // end

            statesChangeRecall.IsEngineRunning = false;
            statesChangeRecall.OnStatusUpdated();
        }