示例#1
0
        /// <summary>
        /// Locates the starting position for the walker.
        /// </summary>
        /// <param name="walker">The walker.</param>
        /// <returns>
        /// The walker with proper coordinates and direction.
        /// </returns>
        private MazeWalker findstart(MazeWalker walker)
        {
            int  s_y = 0;
            int  s_x = 0; //x and y coordinates of the start
            bool firstpixel_found = false;

            //first, find the location of the first red pixel (S)
            for (int y = 0; y < m_maze_to_solve.Count; y++)
            {
                List <string> pixel_row = m_maze_to_solve[y];
                for (int x = 0; x < pixel_row.Count; x++)
                {
                    if (pixel_row[x] == "S")
                    {
                        s_x = x;
                        s_y = y;
                        firstpixel_found = true;
                        break;
                    }
                }

                if (firstpixel_found)
                {
                    break;
                }
            }//end for

            walker.X = s_x;
            walker.Y = s_y;
            //at this point, we will have found the start's top left pixel
            //we now need to determine the best orientation that the walker should proceed
            return(setorientation(walker));
        }
示例#2
0
        /// <summary>
        /// Determines if the end is in the eastern vision of the walker and if so, sends the walker directly in that direction.
        /// </summary>
        /// <param name="walker">The walker.</param>
        /// <returns>
        /// A boolean value if the end is in the vicinity and also the walker with updated values.
        /// </returns>
        private bool is_eastfinish(MazeWalker walker)
        {
            bool is_finish = false;
            int  y         = walker.Y;
            int  x         = walker.X;

            if (y < 0 || x < 0 || y >= m_maze_to_solve.Count)
            {
                return(false);
            }

            List <string> pixel_row = m_maze_to_solve[y];

            if (x >= pixel_row.Count)
            {
                return(false);
            }

            while (pixel_row[x] != "1")
            {
                if (x >= pixel_row.Count)
                {
                    break;
                }
                if (pixel_row[x] == "E")
                {
                    is_finish = true;
                    break;
                }
                else
                {
                    x++;
                }
            }

            if (is_finish)
            {
                //finish the job
                x          = walker.X;
                walker.Dir = Direction.East;
                while (pixel_row[x] != "1" && pixel_row[x] != "E")
                {
                    if (x >= pixel_row.Count)
                    {
                        break;
                    }

                    pixel_row[x] = "G";
                    x++;
                    walker.X = walker.X + 1;
                    MazeParser.color(m_maze_to_solve, walker);
                }
            }

            return(is_finish);
        }
示例#3
0
        /// <summary>
        /// Determines if the end is in the southern vision of the walker and if so, sends the walker directly in that direction.
        /// </summary>
        /// <param name="walker">The walker.</param>
        /// <returns>
        /// A boolean value if the end is in the vicinity and also the walker with updated values.
        /// </returns>
        private bool is_southfinish(MazeWalker walker)
        {
            bool is_finish = false;
            int  y         = walker.Y;
            int  x         = walker.X;

            if (y < 0 || x < 0 || y >= m_maze_to_solve.Count)
            {
                return(false);
            }

            for (; y < m_maze_to_solve.Count; y++)
            {
                List <string> pixel_row = m_maze_to_solve[y];

                if (pixel_row[x] == "1")
                {
                    break;
                }

                if (pixel_row[x] == "E")
                {
                    is_finish = true;
                    break;
                }
            }

            if (is_finish)
            {
                //finish the job
                walker.Dir = Direction.South;
                for (y = walker.Y; y < m_maze_to_solve.Count; y++)
                {
                    List <string> pixel_row = m_maze_to_solve[y];

                    if (pixel_row[x] == "1")
                    {
                        break;
                    }

                    else if (pixel_row[x] == "E")
                    {
                        break;
                    }
                    else
                    {
                        pixel_row[x] = "X";
                    }
                    walker.Y = walker.Y + 1;
                    MazeParser.color(m_maze_to_solve, walker);
                }
            }

            return(is_finish);
        }
示例#4
0
 /// <summary>
 /// Moves the walker north. The orientation is adjusted.
 /// </summary>
 /// <param name="walker">The walker.</param>
 /// <returns>
 /// The walker with the coordinates and orientation adjusted.
 /// </returns>
 private MazeWalker movewalker_north(MazeWalker walker)
 {
     walker = movewalker(walker, walker.X, walker.Y - 1);
     if (walker == null)
     {
         return(null);
     }
     else
     {
         walker.Dir = Direction.North;
     }
     return(walker);
 }
示例#5
0
 private MazeWalker movewalker_east(MazeWalker walker)
 {
     walker = movewalker(walker, walker.X + 1, walker.Y);
     if (walker == null)
     {
         return(null);
     }
     else
     {
         walker.Dir = Direction.East;
     }
     return(walker);
 }
示例#6
0
        /// <summary>
        /// Use function to set walker to the proper orientation and coordinates. The walker can be used to solve the maze.
        /// </summary>
        /// <param name="walker">The walker.</param>
        /// <returns>
        /// A walker where its direction and coordinates are properly set. The walker can be immediately used to solve the maze.
        /// </returns>
        private MazeWalker setorientation(MazeWalker walker)
        {
            //for now, don't do anything fancy. Just see if a direction is valid and arbitrarily choose one
            //for a direction to be valid, no walls should be in the vicinity of 10 pixels (10 is arbitrarily chosen)
            //and the direction with the most steps will be chosen

            int t_x = walker.X;
            int t_y = walker.Y;

            List <string> pixel_row_westeast = m_maze_to_solve[walker.Y];

            List <int> step_results = new List <int>();

            step_results.Add(find_weststeps(pixel_row_westeast, t_x, t_y));
            step_results.Add(find_eaststeps(pixel_row_westeast, t_x, t_y));
            step_results.Add(find_northsteps(m_maze_to_solve, t_x, t_y));
            step_results.Add(find_southsteps(m_maze_to_solve, t_x, t_y));

            int       maxsteps = 0;
            Direction dir      = Direction.North; //by default if there is no direction that provides the max steps

            for (int j = 0; j < step_results.Count; j++)
            {
                if (step_results[j] > maxsteps)
                {
                    maxsteps = step_results[j];
                    if (j == 0)
                    {
                        dir = Direction.West;
                    }
                    else if (j == 1)
                    {
                        dir = Direction.East;
                    }
                    else if (j == 2)
                    {
                        dir = Direction.North;
                    }
                    else
                    {
                        dir = Direction.South;
                    }
                }
            }//end for

            //at this point, we know the proper orientation of the walker


            return(adjustwalker_toorientation(walker, dir, m_maze_to_solve));
        }
示例#7
0
        /// <summary>
        /// Move the walker to the proposed x_loc and y_loc. The move will also be noted on the maze.
        /// NOTE: the orientation of the walker is not adjusted.
        /// </summary>
        /// <param name="walker">The walker.</param>
        /// <param name="x_loc">The proposed x coordinate location.</param>
        /// <param name="y_loc">The proposed y coordinate location.</param>
        /// <returns>
        /// The walker with coordinates moved to the x and y locations. NOTE: the orientation of the walker is not changed.
        /// Returns NULL if the walker cannot move to that location.
        /// </returns>
        private MazeWalker movewalker(MazeWalker walker, int x_loc, int y_loc)
        {
            if (!is_locationvalid(x_loc, y_loc))
            {
                return(null);
            }

            //adjust the value in the maze
            List <string> pixel_row = m_maze_to_solve[y_loc];

            pixel_row[x_loc] = "X";

            walker.X = x_loc;
            walker.Y = y_loc;
            return(walker);
        }
示例#8
0
        /// <summary>
        /// Moves the walker when it needs to turn a corner.
        /// Generally used to avoid the case when the walker needs to turn a corner but instead continues forward.
        /// </summary>
        /// <param name="walker">The walker.</param>
        /// <returns>
        /// The walker with proper orientation if it needs to turn a corner.
        /// </returns>
        private MazeWalker turncorner(MazeWalker walker, Direction curr_dir)
        {
            //since the walker is a little dumb, it needs to know if it should be turning a corner
            //the only corners will only be on the right-hand side of the direction the walker is facing towards (since we're applying right-hand follower)
            if (curr_dir == Direction.North)
            {
                //check if the east has an empty spot
                if (is_eastvalid(walker.X, walker.Y))
                {
                    walker.Dir = Direction.East;
                }
            }
            else if (curr_dir == Direction.South)
            {
                if (is_westvalid(walker.X, walker.Y))
                {
                    walker.Dir = Direction.West;
                }
            }
            else if (curr_dir == Direction.East)
            {
                if (is_southvalid(walker.X, walker.Y))
                {
                    walker.Dir = Direction.South;
                }
            }
            else if (curr_dir == Direction.West)
            {
                if (is_northvalid(walker.X, walker.Y))
                {
                    walker.Dir = Direction.North;
                }
            }

            return(walker);
        }
示例#9
0
        /// <summary>
        /// Determines if the walker has found the end of the maze.
        /// </summary>
        /// <param name="walker">The walker.</param>
        /// <returns>
        /// A boolean value indicating if the walker is at the end.
        /// </returns>
        private bool is_finish(MazeWalker walker)
        {
            //first, see if the walker is on a finish line
            List <string> pixel_row = m_maze_to_solve[walker.Y];

            if (pixel_row[walker.X] == "E")
            {
                return(true);
            }

            bool reached_end = false;

            //scan the region to see if the finish is in the walker's peripheral vision
            if (walker.Dir == Direction.North || walker.Dir == Direction.South)
            {
                //scan the west and east directions
                if (is_westfinish(walker) || is_eastfinish(walker))
                {
                    reached_end = true;
                }
            }
            else if (walker.Dir == Direction.East || walker.Dir == Direction.West)
            {
                //scan the north and south directions
                if (is_northfinish(walker) || is_southfinish(walker))
                {
                    reached_end = true;
                }
            }
            else
            {
                //should never get here but this is here just in case
                return(false);
            }
            return(reached_end);
        }
示例#10
0
        /// <summary>
        /// Adjusts the walker so that it will be right along the wall. This function should only be used for the Wall Follower method.
        /// </summary>
        /// <param name="walker">The walker.</param>
        /// <param name="dir">The direction the walker should be facing.</param>
        /// <param name="maze">The maze.</param>
        /// <returns>The walker with the proper coordinates and direction.</returns>
        private MazeWalker adjustwalker_toorientation(MazeWalker walker, Direction dir, List <List <string> > maze)
        {
            int x = walker.X;
            int y = walker.Y;

            //Because the starting point is not just one pixel, we need to locate the closest wall where the walker can place a right hand on.
            //For example, if the direction is east, then the walker would need to travel to the first wall on the bottom of the drawn block.
            if (dir == Direction.East)
            {
                while (true)
                {
                    if (y + 1 >= maze.Count)
                    {
                        break;
                    }
                    List <string> pixel_row = maze[y + 1];
                    if (pixel_row[x] == "1")
                    {
                        break;
                    }
                    else
                    {
                        y++;
                    }
                }
            }
            else if (dir == Direction.West)
            {
                while (true)
                {
                    if (y - 1 < 0)
                    {
                        break;
                    }
                    List <string> pixel_row = maze[y - 1];
                    if (pixel_row[x] == "1")
                    {
                        break;
                    }
                    else
                    {
                        y--;
                    }
                }
            }
            else if (dir == Direction.North)
            {
                List <string> pixel_row = maze[y];
                while (true)
                {
                    if (x >= pixel_row.Count)
                    {
                        break;
                    }

                    if (pixel_row[x + 1] == "1")
                    {
                        break;
                    }
                    else
                    {
                        x++;
                    }
                }
            }
            else if (dir == Direction.South)
            {
                List <string> pixel_row = maze[y];
                while (true)
                {
                    if (x - 1 < 0)
                    {
                        break;
                    }

                    if (pixel_row[x - 1] == "1")
                    {
                        break;
                    }
                    else
                    {
                        x--;
                    }
                }
            }

            walker.X   = x;
            walker.Y   = y;
            walker.Dir = dir;
            return(walker);
        }
示例#11
0
        /// <summary>
        /// Solves the given maze using the right-hand wall following method.
        /// NOTE: this algorithm will not work for mazes that are not simply connected.
        /// </summary>
        /// <returns>
        /// The parsed solution to the maze.
        /// </returns>
        private List <List <string> > solve_maze_RH()
        {
            bool       pathFound = false;
            MazeWalker walker    = new MazeWalker();

            walker = findstart(walker);
            while (!pathFound)
            {
                //for each direction, test to see which directions are valid
                //we always prioritize the current direction
                //then the directions are prioritized according to the right-hand following method
                if (walker.Dir == Direction.North)
                {
                    bool move_success = false;
                    if (is_northvalid(walker.X, walker.Y))
                    {
                        move_success = walker.move_north(m_maze_to_solve);
                    }
                    else if (is_eastvalid(walker.X, walker.Y))
                    {
                        move_success = walker.move_east(m_maze_to_solve);
                    }
                    else if (is_westvalid(walker.X, walker.Y))
                    {
                        move_success = walker.move_west(m_maze_to_solve);
                    }
                    else
                    {
                        //turning back
                        move_success = walker.move_south(m_maze_to_solve);
                    }

                    if (!move_success)
                    {
                        return(null); //something went wrong somewhere
                    }
                    else
                    {
                        walker = turncorner(walker, walker.Dir);
                    }
                }
                else if (walker.Dir == Direction.South)
                {
                    bool move_success = false;
                    if (is_southvalid(walker.X, walker.Y))
                    {
                        move_success = walker.move_south(m_maze_to_solve);
                    }
                    else if (is_westvalid(walker.X, walker.Y))
                    {
                        move_success = walker.move_west(m_maze_to_solve);
                    }
                    else if (is_eastvalid(walker.X, walker.Y))
                    {
                        move_success = walker.move_east(m_maze_to_solve);
                    }
                    else
                    {
                        //turn around
                        move_success = walker.move_north(m_maze_to_solve);
                    }

                    if (!move_success)
                    {
                        return(null);
                    }
                    else
                    {
                        walker = turncorner(walker, walker.Dir);
                    }
                }
                else if (walker.Dir == Direction.East)
                {
                    bool move_success = false;
                    if (is_eastvalid(walker.X, walker.Y))
                    {
                        move_success = walker.move_east(m_maze_to_solve);
                    }
                    else if (is_southvalid(walker.X, walker.Y))
                    {
                        move_success = walker.move_south(m_maze_to_solve);
                    }
                    else if (is_northvalid(walker.X, walker.Y))
                    {
                        move_success = walker.move_north(m_maze_to_solve);
                    }
                    else
                    {
                        //turn around
                        move_success = walker.move_west(m_maze_to_solve);
                    }

                    if (!move_success)
                    {
                        return(null);
                    }
                    else
                    {
                        walker = turncorner(walker, walker.Dir);
                    }
                }
                else if (walker.Dir == Direction.West)
                {
                    bool move_success = false;
                    if (is_westvalid(walker.X, walker.Y))
                    {
                        move_success = walker.move_west(m_maze_to_solve);
                    }
                    else if (is_northvalid(walker.X, walker.Y))
                    {
                        move_success = walker.move_north(m_maze_to_solve);
                    }
                    else if (is_southvalid(walker.X, walker.Y))
                    {
                        move_success = walker.move_south(m_maze_to_solve);
                    }
                    else
                    {
                        //turn around
                        move_success = walker.move_east(m_maze_to_solve);
                    }

                    if (!move_success)
                    {
                        return(null);
                    }
                    else
                    {
                        walker = turncorner(walker, walker.Dir);
                    }
                }
                else
                {
                    //this should never be executed, but in case something goes wrong here, we will arbitrarily place the walker into a direction
                    walker.Dir = Direction.North;
                }

                MazeParser.color(m_maze_to_solve, walker);

                pathFound = is_finish(walker);

                MazeParser.color(m_maze_to_solve, walker);
            }//end while

            //MazeParser.output_parse(m_maze_to_solve); //for debugging

            return(m_maze_to_solve);
        }
示例#12
0
        /// <summary>
        /// Colors the walker's surrounding with green.
        /// </summary>
        /// <param name="maze">The maze.</param>
        /// <param name="walker">The walker.</param>
        public static void color(List <List <string> > maze, MazeWalker walker)
        {
            int y = walker.Y;
            int x = walker.X;

            if (y < 0 || y >= maze.Count || x < 0)
            {
                return;
            }

            if (walker.Dir == Direction.North || walker.Dir == Direction.South)
            {
                //color west direction

                List <string> pixel_row = maze[y];
                for (int i = 0; i < Constants.COLOR_WIDTH; i++)
                {
                    if (x < 0 || x >= pixel_row.Count)
                    {
                        break;
                    }
                    if (pixel_row[x] == "1")
                    {
                        break;
                    }
                    else
                    {
                        pixel_row[x] = "X";
                        x--;
                    }
                }

                //color in east direction
                x = walker.X;
                for (int i = 0; i < Constants.COLOR_WIDTH; i++)
                {
                    if (x < 0 || x >= pixel_row.Count)
                    {
                        break;
                    }
                    if (pixel_row[x] == "1")
                    {
                        break;
                    }
                    else
                    {
                        pixel_row[x] = "X";
                        x++;
                    }
                }
            }

            else if (walker.Dir == Direction.East || walker.Dir == Direction.West)
            {
                //color south direction
                for (int i = 0; i < Constants.COLOR_WIDTH; i++)
                {
                    if (y < 0 || y >= maze.Count)
                    {
                        break;
                    }
                    List <string> pixel_row = maze[y];
                    if (pixel_row[x] == "1")
                    {
                        break;
                    }
                    else
                    {
                        pixel_row[x] = "X";
                        y++;
                    }
                }

                //color in north direction
                y = walker.Y;
                for (int i = 0; i < Constants.COLOR_WIDTH; i++)
                {
                    if (y < 0 || y >= maze.Count)
                    {
                        break;
                    }
                    List <string> pixel_row = maze[y];
                    if (pixel_row[x] == "1")
                    {
                        break;
                    }
                    else
                    {
                        pixel_row[x] = "X";
                        y--;
                    }
                }
            }
            else
            {
                //should never get here
                return;
            }
        }