/// <summary> /// This function get the graph and random value /// </summary> /// <param name="graph"></param> /// <returns></returns> public Dictionary <Tuple <int, int>, int> UpdateValues(ref IMazeable graph) { Dictionary <Tuple <int, int>, int> values = new Dictionary <Tuple <int, int>, int>(); List <ICell> allNodes = graph.GetAllNodes(); int firstDiemn = (int)graph.GetGraphDimension().Item1; int length = (int)(graph.GetGraphDimension().Item1 *graph.GetGraphDimension().Item2); Random rnd = new Random(); foreach (ICell item in allNodes) { //Rand value to each node. item.SetValue(rnd.Next(0, 100)); List <ICell> tempList = new List <ICell>(graph.GetNeighbors(item)); foreach (ICell tempCell in tempList) { //Rand values to the cell edges. Tuple <int, int> t = new Tuple <int, int>(item.GetPlace(), tempCell.GetPlace()); int rndValue = rnd.Next(0, 100); values.Add(t, rndValue); } } //make value of edge (u,v) = (v,u) foreach (ICell item in allNodes) { List <ICell> tempList = new List <ICell>(graph.GetNeighbors(item)); foreach (ICell tempCell in tempList) { Tuple <int, int> t = new Tuple <int, int>(item.GetPlace(), tempCell.GetPlace()); Tuple <int, int> tTemp = new Tuple <int, int>(tempCell.GetPlace(), item.GetPlace()); values[tTemp] = values[t]; } } return(values); }
/// <summary> /// Function Name: Create. /// This function is randing cell to be the beginning, and after the function goes /// over his neighbors and open one of them (by random), then the function keep going /// with the dfs logic till she opened all of the cells. /// </summary> /// <param name="graph"></param> The graph that we want to maze it. public void Create(ref IMazeable graph) { Stack <ICell> DFSStack = new Stack <ICell>(); Random rnd = new Random(); ICell beginning = graph.GetRandomCell(); //Get random beginning. graph.ChangeToBeginSituation(beginning); ICell current = beginning; //Calculate the min path length. int path = (int)(1.5 * graph.GetGraphDimension().Item1); bool flag = false; while (graph.GetUnvisitedNodes().Count > 0) { path--; if (path <= 0 && !flag) { //If we found cell that can be the end point of the maze. if (graph.IsBelongToBounds(current)) { graph.ChangeToEndSituation(current); flag = true; } } if (graph.GetReachableCells(current).Count > 0) { //Get random cell from the current cell neighbors. ICell temp = (graph.GetReachableCells(current))[rnd.Next(0, graph.GetReachableCells(current).Count)]; //Find only cells that we can not reach. while (temp.GetReached()) { temp = (graph.GetReachableCells(current))[rnd.Next(0, graph.GetReachableCells(current).Count)]; } DFSStack.Push(current); //Set current and temp an edge. graph.SetConnection(current, temp); current = temp; //Change the current cell state (Reached etc.) graph.ChangeCellState(current); } else { if (DFSStack.Count > 0) { current = DFSStack.Pop(); graph.ChangeCellState(current); } else { break; } } } }
/// <summary> /// take the match creator and create /// </summary> /// <param name="graph">the graph</param> /// <param name="type">the type</param> public void CreateTheMaze(IMazeable graph, int type) { ICreator create; if (this.fact.TryGetValue(type, out create)) { create.Create(ref graph); } }
/// <summary> /// take the match solver and solve /// </summary> /// <param name="graph">the graph</param> /// <param name="type">the type</param> /// <rereturns>list of the cell of the solve</rereturns> public List <ICell> SolveTheMaze(IMazeable graph, int type) { SolveMaze solve; if (this.fact.TryGetValue(type, out solve)) { return(solve.Solve(graph)); } return(null); }
/// <summary> /// This funtion is getting maze and with the method of bfs solve it. /// </summary> /// <param name="graph"></param> the maze that we want to solve. /// <returns></returns> public List <ICell> Solve(IMazeable graph) { //The edges values. Dictionary <Tuple <int, int>, int> values = UpdateValues(ref graph); Queue <ICell> BFSQueue = new Queue <ICell>(); List <ICell> pathToTheEnd = new List <ICell>(); List <ICell> realPath = new List <ICell>(); Random rnd = new Random(); //Get the beginning of the maze. ICell beginning = graph.GetBeginning(); beginning.SetValue(0); int length; BFSQueue.Enqueue(beginning); ICell temp = null; while (BFSQueue.Count > 0) { temp = BFSQueue.Dequeue(); pathToTheEnd.Add(temp); if (graph.IsTheEnd(temp)) { break; } //Call to the abstract method. InsertToQueue(ref BFSQueue, graph.GetNeighbors(temp), ref pathToTheEnd, ref temp, values); } length = pathToTheEnd.Count; if (!graph.IsTheEnd(temp)) { return(null); } realPath.Add(temp); //Recover the path to the end. for (int i = length - 2; i >= 0; i--) { if (graph.IsNeighbors(temp, pathToTheEnd[i])) { temp = pathToTheEnd[i]; realPath.Add(temp); } } return(realPath); }
/// <summary> /// Function name: BreakWalls. /// The function is completing the create of the matrix. /// </summary> /// <param name="graph"></param> the ref to the graph. /// <param name="path"></param> the path that we already did. public void BreakWalls(ref IMazeable graph, List <ICell> path) { Random rnd = new Random(); int count = 0; int trys = 0; while (count != 4 && trys <= 10) { trys++; ICell rand = path[rnd.Next(0, path.Count)]; List <ICell> l = graph.GetReachableCells(rand); if (l.Count == 0) { continue; } ICell tempCell = l[rnd.Next(0, l.Count)]; graph.ChangeCellState(tempCell); graph.SetConnection(rand, tempCell); count++; } }
/// <summary> /// Function Name: Create. /// This function is randing cell to be the beginning, and after the function goes /// through the neighbors list and get one random neighbors and set the connection, /// and keep going. /// </summary> /// <param name="graph"></param> The graph that we want to maze it. public void Create(ref IMazeable graph) { ICell beginning = graph.GetRandomCell(); //Get random cell. graph.ChangeToBeginSituation(beginning); Tuple <double, double> dim = graph.GetGraphDimension(); int pathLength = (int)(1.5 * dim.Item1), index; ICell current = beginning, tempCell; List <ICell> neigh = null, path = new List <ICell>(); path.Add(current); neigh = graph.GetReachableCells(current); graph.ChangeCellState(current); Random rnd = new Random(); //Goes over the path length that we evalueted, and create it. for (int i = 0; i < pathLength; i++) { if (neigh.Count == 0) { break; } index = rnd.Next(0, neigh.Count); tempCell = neigh[index]; graph.SetConnection(current, tempCell); current = tempCell; path.Add(current); neigh = graph.GetReachableCells(current); graph.ChangeCellState(current); } //Check if the current cell can be the end cell. if (neigh.Count == 0 || graph.IsBelongToBounds(current)) { graph.ChangeToEndSituation(current); } else { //Keep looking till we find a good cell that can be the end point. while (path.Count != graph.GetAllNodes().Count&& !graph.IsBelongToBounds(current)) { graph.ChangeCellState(current); neigh = graph.GetReachableCells(current); if (neigh.Count == 0) { break; } index = rnd.Next(0, neigh.Count); tempCell = neigh[index]; graph.SetConnection(current, tempCell); path.Add(current); current = tempCell; } if (neigh.Count == 0 || graph.IsBelongToBounds(current)) { graph.ChangeToEndSituation(current); } } int tempCount = 0; //Openning all of the rest cells. while (path.Count != graph.GetAllNodes().Count) { ICell tempBreakWallsCell = path[rnd.Next(0, path.Count)]; tempCount = graph.GetReachableCells(tempBreakWallsCell).Count; if (tempCount == 0) { continue; } ICell newCell = graph.GetReachableCells(tempBreakWallsCell)[rnd.Next(0, tempCount)]; if (newCell.GetReached()) { continue; } graph.SetConnection(tempBreakWallsCell, newCell); path.Add(newCell); graph.ChangeCellState(newCell); } }