Example #1
0
        public MazeState Pop()
        {
            MazeState result = _states[0];

            _states.RemoveAt(0);
            return(result);
        }
        // remove and return first element from frontier - in addition
        // it is added to the searched list
        public MazeState PopFrontier()
        {
            MazeState result = Frontier.Pop();

            Searched.Add(result);
            return(result);
        }
Example #3
0
        public MazeState Dequeue()
        {
            MazeState result = _states[_states.Count - 1];

            _states.RemoveAt(_states.Count - 1);
            return(result);
        }
 public MazeState(int[,] aState)
 {
     _state        = aState;
     _parent       = null;
     _children     = null;
     Cost          = 0;
     PathCost      = 0;
     HeuristicCost = 0;
     TotalCost     = Cost + HeuristicCost;
 }
        //function used to generate goal state when no already identfied in constructor
        //static function
        public static int[,] GenerateGoalState(MazeState aStartState)
        {
            //get current position so it can be changed back to traversable path
            int[] curPos = aStartState.FindPosition();
            int[,] result = MazeState.CloneState(aStartState.State);

            result[curPos[0], curPos[1]] = 1;                                                   //set curPos back to 1 (path)
            result[aStartState.State.GetLength(1) - 2, aStartState.State.GetLength(0) - 2] = 0; //set random position to goalstate

            return(result);
        }
 public MazeState(int[,] aState, MazeState aParent, Direction aDFP, int aPathCost = 1)
 {
     _state              = aState;
     _parent             = aParent;
     _children           = null;
     Cost                = aParent.Cost + aPathCost;
     PathCost            = aPathCost;
     HeuristicCost       = 0;
     TotalCost           = Cost + HeuristicCost;
     DirectionFromParent = aDFP;
 }
        // returns the manhattan distance between two nodes
        public int GetManhattanDistance(MazeState aState, MazeState aDest)
        {
            //Find possition of two states
            int[] aCords = aState.FindPosition();
            int[] bCords = aDest.FindPosition();

            //calculate distance - returning absolute value
            //eg aCord : (4,4)   bCord : (8, 8)
            //abs(4 - 8) + abs(4 - 8) = 8
            return(Math.Abs(aCords[0] - bCords[0]) + Math.Abs(aCords[1] - bCords[1]));
        }
Example #8
0
        //check whether a maze state is in a container
        //implemented this since we can not simply write e.g Search.Contains(aState) since
        //it could not determine if they were equal. This is way we want a function to
        //compare the state of a maze only, rather than a whole MazeState Object.
        public static bool Contains(MazeState aState, List <MazeState> aContainer)
        {
            foreach (MazeState s in aContainer)
            {
                if (AreEqual(aState.State, s.State))
                {
                    return(true);
                }
            }

            return(false);
        }
        //creates the child mazestates
        public List <MazeState> CreatePossibleMoves()
        {
            //get possble direction movements
            Direction[] possibleMovements = FindPossibleMovements();
            Children = new List <MazeState>();

            for (int i = 0; i < possibleMovements.Length; i++)
            {
                MazeState newState = Move(possibleMovements[i]);
                Children.Add(newState);
            }

            return(Children);
        }
        //returns the closest goal state from the current state
        // - this funciton allows flexibility for the program to determine the
        // best goal to traverse to out of a collection
        public MazeState PickDesiredGoalState(MazeState aState, MazeState[] aGoalStates)
        {
            MazeState result = aGoalStates[0];

            for (int i = 1; i < aGoalStates.Length; i++)
            {
                if (GetManhattanDistance(aState, result) > GetManhattanDistance(aState, aGoalStates[i]))
                {
                    result = aGoalStates[i];
                }
            }

            return(result);
        }
        public Maze GetMaze(StreamReader rdr)
        {
            //Size of Maze
            string[] mazeSizeString = Between(rdr.ReadLine(), "[", "]").Split(',');
            int[]    mazeSize       = new int[2] {
                Convert.ToInt32(mazeSizeString[0]), Convert.ToInt32(mazeSizeString[1])
            };

            //Init state
            string[] initStateString = Between(rdr.ReadLine(), "(", ")").Split(',');
            int[]    initState       = new int[] { Convert.ToInt32(initStateString[0]), Convert.ToInt32(initStateString[1]) };


            //Goal States
            string[] goalStatesString = rdr.ReadLine().Split('|');
            goalStatesString = new string[] { Between(goalStatesString[0], "(", ")"), Between(goalStatesString[1], "(", ")") };
            int[][] goalStates = new int[][] {
                new int[] { Convert.ToInt32(goalStatesString[0].Split(',')[0]), Convert.ToInt32(goalStatesString[0].Split(',')[1]) },
                new int[] { Convert.ToInt32(goalStatesString[1].Split(',')[0]), Convert.ToInt32(goalStatesString[1].Split(',')[1]) }
            };

            //Walls
            //Read out rest of mapconfig file
            List <int[]> wallsList = new List <int[]>();

            while (!rdr.EndOfStream)
            {
                string[] wallsString = Between(rdr.ReadLine(), "(", ")").Split(',');
                wallsList.Add(new int[] { Convert.ToInt32(wallsString[0]), Convert.ToInt32(wallsString[1]),
                                          Convert.ToInt32(wallsString[2]), Convert.ToInt32(wallsString[3]) });
            }
            int[][] walls = wallsList.ToArray();



            //parse data to int[,] state
            int[,] startState = GenerateMazeState(mazeSize, initState, walls);
            int[,] goalStateA = GenerateMazeState(mazeSize, goalStates[0], walls);
            int[,] goalStateB = GenerateMazeState(mazeSize, goalStates[1], walls);

            //initialize MazeStates
            MazeState StartState = new MazeState(startState);

            MazeState[] GoalStates = new MazeState[goalStates.Length];
            GoalStates[0] = new MazeState(goalStateA);
            GoalStates[1] = new MazeState(goalStateB);

            return(new Maze(StartState, GoalStates));
        }
        public override bool AddToFrontier(MazeState aState, Frontier aFrontier = null)
        {
            Frontier selectedFrontier = aFrontier == null ? Frontier : aFrontier;

            if (selectedFrontier.Contains(aState) || Maze.Contains(aState, Searched))
            {
                return(false);
            }
            else
            {
                selectedFrontier.Enqueue(aState);
            }

            return(true);
        }
Example #13
0
 public void SortByCost()
 {
     for (int i = 0; i < _states.Count - 1; i++)
     {
         for (int j = 0; j < _states.Count - i - 1; j++)
         {
             if (_states[j].PathCost > _states[j + 1].PathCost)
             {
                 MazeState temp = _states[j];
                 _states[j]     = _states[j + 1];
                 _states[j + 1] = temp;
             }
         }
     }
 }
Example #14
0
 public void SortByEvaluationCost()
 {
     for (int i = 0; i < _states.Count - 1; i++)
     {
         for (int j = 0; j < _states.Count - i - 1; j++)
         {
             if (_states[j].GetTotalCost > _states[j + 1].GetTotalCost)
             {
                 MazeState temp = _states[j];
                 _states[j]     = _states[j + 1];
                 _states[j + 1] = temp;
             }
         }
     }
 }
        //the variable cost bool is an option for different movement costs
        public MazeState Move(Direction aDirection)
        {
            //Get our current state position
            int[] position = FindPosition();

            //create copy of this.State to be manipulated for new state

            MazeState result = new MazeState(CloneState(this.State), this, aDirection);

            switch (aDirection)
            {
            case Direction.Up:
                result.State[position[0], position[1] - 1] = 0;     // set moved positioned to zero (new location1)
                if (SearchMethod.VariableCost)
                {
                    result.Cost    += 3;
                    result.PathCost = 4;
                }
                break;

            case Direction.Left:
                result.State[position[0] - 1, position[1]] = 0;     // set moved positioned to zero (new location1)
                if (SearchMethod.VariableCost)
                {
                    result.Cost    += 1;
                    result.PathCost = 2;
                }
                break;

            case Direction.Down:
                result.State[position[0], position[1] + 1] = 0;     // set moved positioned to zero (new location1)
                break;

            default:                                            //right direction
                result.State[position[0] + 1, position[1]] = 0; // set moved positioned to zero (new location1)
                if (SearchMethod.VariableCost)
                {
                    result.Cost    += 1;
                    result.PathCost = 2;
                }
                break;
            }

            //set previous position to traversable
            result.State[position[0], position[1]] = 1;

            return(result);
        }
Example #16
0
        public Maze(MazeState aStartState, MazeState[] aGoalStates)
        {
            //asign start and goal state(s)
            _startState    = aStartState;
            _goalStates    = aGoalStates;
            _iterations    = new List <MazeState>();
            _finalPathCost = 0;


            //initialize search alogorithms
            _bfs  = new BreadthFirstSearch();
            _dfs  = new DepthFirstSearch();
            _as   = new AStarSearch();
            _gbfs = new GreedyBestFirstSearch();
            _ucs  = new UniformCostSearch();
        }
        public override Direction[] Solve(Maze aMaze)
        {
            //push the StartState to the frontier
            AddToFrontier(aMaze.StartState);

            while (!Frontier.Empty())
            {
                //Pop frontier state into curState
                MazeState curState = PopFrontier();

                //check if curState is a goalState
                //using a loop for each of the varient goal states listed
                for (int i = 0; i < aMaze.GoalStates.Length; i++)
                {
                    if (Maze.AreEqual(curState.State, aMaze.GoalStates[i].State))
                    {
                        Maze.OutputState(curState.State);
                        aMaze.FinalPathCost = curState.Cost;
                        Console.WriteLine($"Path cost: {aMaze.FinalPathCost}");
                        iterationCount++;
                        return(curState.GetPathFromParent());
                    }
                }

                //Find most desirable goal state - i.e. which is closes to the current state
                MazeState ClosestGoal = PickDesiredGoalState(curState, aMaze.GoalStates);

                //get all possible new states from curState
                List <MazeState> newStates = curState.CreatePossibleMoves();

                //add all children frontier
                foreach (MazeState s in newStates)
                {
                    //Need to implement a way to have a heuristic cost for each of the goal states
                    s.HeuristicCost = GetManhattanDistance(s, ClosestGoal);
                    AddToFrontier(s);
                }

                //Sort the frontier by f(n) = g(n) + h(n)
                Frontier.SortByEvaluationCost();
                iterationCount++;
            }
            return(null);
        }
        public override Direction[] Solve(Maze aMaze)
        {
            //ensure variable cost mode is on
            SearchMethod.VariableCost = true;

            AddToFrontier(aMaze.StartState);

            while (!Frontier.Empty())
            {
                //Pop frontier state into curState
                MazeState curState = Frontier.Pop();
                Searched.Add(curState);

                //check if curState is a goalState
                //using a loop for each of the varient goal states listed
                for (int i = 0; i < aMaze.GoalStates.Length; i++)
                {
                    if (Maze.AreEqual(curState.State, aMaze.GoalStates[i].State))
                    {
                        Maze.OutputState(curState.State);
                        aMaze.FinalPathCost = curState.Cost;
                        Console.WriteLine($"Path cost: {aMaze.FinalPathCost}");
                        iterationCount++;
                        return(curState.GetPathFromParent());
                    }
                }

                //get all possible new states from curState
                List <MazeState> newStates = curState.CreatePossibleMoves();

                foreach (MazeState s in newStates)
                {
                    AddToFrontier(s);
                }
                iterationCount++;

                Frontier.SortByCost();
            }

            return(null);
        }
        public override Direction[] Solve(Maze aMaze)
        {
            //push the StartState to the frontier
            AddToFrontier(aMaze.StartState);

            while (!Frontier.Empty())
            {
                //Pop frontier state into curState
                MazeState curState = Frontier.Dequeue();
                Searched.Add(curState);

                //check if curState is a goalState
                //using a loop for each of the varient goal states listed
                for (int i = 0; i < aMaze.GoalStates.Length; i++)
                {
                    if (Maze.AreEqual(curState.State, aMaze.GoalStates[i].State))
                    {
                        Maze.OutputState(curState.State);
                        aMaze.FinalPathCost = curState.Cost;
                        Console.WriteLine($"Path cost: {aMaze.FinalPathCost}");
                        iterationCount++;
                        return(curState.GetPathFromParent());
                    }
                }

                //get all possible new states from curState
                List <MazeState> newStates = curState.CreatePossibleMoves();
                newStates.Reverse(); //Reverse elements to ensure priority is U > L > D > R

                foreach (MazeState s in newStates)
                {
                    AddToFrontier(s);
                }
                iterationCount++;
            }

            return(null);
        }
        //Returns a list of directions back from the starting node to the finishing node
        //ex. {Right, Right, Right, Down, Down, Down, Left....}
        public Direction[] GetPathFromParent()
        {
            Stack <Direction> result = new Stack <Direction>();
            MazeState         node   = this;

            while (node != null)
            {
                //if our node is StartNode (cost 0) ignore and break loop
                if (node.Cost == 0)
                {
                    break;
                }

                //push direction to result
                result.Push(node.DirectionFromParent);

                //set the parent variable to the parent of the last parent
                node = node.Parent;
            }

            //convert result Stack<Direction> into Array<Direction>
            return(result.ToArray());
        }
Example #21
0
 public bool Contains(MazeState aState)
 {
     return(Maze.Contains(aState, _states));
 }
Example #22
0
 //adds MazeState to end of linkedList
 public void Enqueue(MazeState aState)
 {
     _states.Add(aState);
 }
 public abstract bool AddToFrontier(MazeState aState, Frontier aFrontier = null);
Example #24
0
 public void Push(MazeState aState)
 {
     _states.Insert(0, aState);
 }
Example #25
0
        static void Main(string[] args)
        {
            //Search Algorithm Information: https://www.geeksforgeeks.org/a-search-algorithm/ (Heuristic Calculations and more)

            //Check command-line args
            if (args.Length < 3)
            {
                Console.WriteLine("Required args: <mapconfig file> <search method> <variable move cost>");
                Console.WriteLine("Map Config File: Enter filename with configuration OR enter 0 for random mazes");
                Console.WriteLine("Search methods: DFS, BFS, AS, GBFS, CUS1");
                Console.WriteLine("Variable move cost: 0 = false, 1 = true;");
                System.Environment.Exit(0);
            }

            //assign args to variables
            string file   = args[0];
            string method = args[1];

            SearchMethod.VariableCost = args[2] == "1" ? true : false;
            bool runtest = file == "0" ? true : false; //runtest if file == 0

            //initalize Test Object
            MazeTest mazeTest = new MazeTest(400); //(50*50)/2

            //create maze object
            Maze maze = new Maze(null, null);

            if (File.Exists(file))
            {
                StreamReader  rdr           = new StreamReader(file);
                MazeGenerator mazeGenerator = new MazeGenerator();
                maze = mazeGenerator.GetMaze(rdr);

                Output(maze, method);
            }
            else if (runtest)
            {
                int sizeIncrement = 20;
                for (int i = 0; i < 45; i++)
                {
                    if (i > sizeIncrement)
                    {
                        sizeIncrement += 5;
                    }

                    Console.WriteLine($"Test iteration no: {i + 1}");
                    MazeState randomState = new MazeState(MazeGenerator.GenerateRandomMaze(sizeIncrement));
                    maze = new Maze(randomState);

                    Output(maze, method);

                    mazeTest.LogTest(maze.StartState.State.GetLength(0) * maze.StartState.State.GetLength(1), maze.FinalPathCost, maze.IterationCount);
                }

                mazeTest.OutputResults();
            }
            else
            {
                Console.WriteLine($"The file: {file} was not found. Please try again!");
                Environment.Exit(1);
            }
        }
Example #26
0
 public Maze(MazeState aStartState) : this(aStartState, null)
 {
     _goalStates = new MazeState[] { new MazeState(MazeGenerator.GenerateGoalState(aStartState)) };
 }