// Start is called before the first frame update void Start() { this.fileReader = new FileReader(); this.mazeParser = new DominoParser(fileReader.getFileLines()); this.maze = mazeParser.getDominoMaze(); shortestPathFromStart = new Dictionary <Vector2, Path>(); orderChecked = new List <Vector2>(); this.start = this.mazeParser.startNode; this.end = this.mazeParser.endNode; Visited = new HashSet <Vector2>(); toVisit = new SortedList <int, Queue <DominoNode> >(); this.start.costToGetToFromStart = 0; start.cost = 0; addToVisit(start); start.DominoPiece.GetComponent <Renderer>().material.SetColor("_BaseColor", Color.green); shortestPathFromStart.Add(start.getPlaceInMaze(), new Path() { cost = start.costToGetToFromStart, path = new List <DominoNode> { start } }); stopwatch = new Stopwatch(); stopwatch.Start(); }
/// <summary> /// Copy path to get to neighbor into newPath and append new end point /// </summary> /// <param name="currentDominoNode"></param> /// <param name="newPath"></param> /// <param name="end"></param> public void copyPath(DominoNode currentDominoNode, out List <DominoNode> newPath, DominoNode end) { newPath = new List <DominoNode>(); foreach (DominoNode dominoNode in shortestPathFromStart[currentDominoNode.getPlaceInMaze()].path) { newPath.Add(dominoNode); } newPath.Add(end); }
public DominoParser(List <string> dominoMazeFile) { if (dominoMazeFile.Count == 0 || dominoMazeFile == null) { throw new Exception("Bad Domino Maze parse call!!! Need to pass a valid DominoMazeFile In the format of List<string>!!! Got empty List!!!"); } this.dominoMaze = new List <List <DominoNode> >(); for (int r = 0; r < dominoMazeFile.Count; r++) { if (dominoMazeFile[r].Length > 0) { if (dominoMazeFile[r].StartsWith("#") || dominoMazeFile[r].StartsWith("//")) { continue; // Ignore comment lines } if (dominoMazeFile[r].StartsWith("start") || dominoMazeFile[r].StartsWith("end")) { string[] tmp = dominoMazeFile[r].Trim().Split('='); tmp = tmp[1].Trim().Split(':'); Tuple <int, int> location = new Tuple <int, int>(Int32.Parse(tmp[0]), Int32.Parse(tmp[1])); if (dominoMazeFile[r].StartsWith("end")) { this.end = new Vector2(location.Item1, location.Item2); } else { this.start = new Vector2(location.Item1, location.Item2); } } if (dominoMazeFile[r].StartsWith("maze")) { r++; int startOfMaze = r; while (!dominoMazeFile[r].StartsWith("}")) { string[] dominoNodes = dominoMazeFile[r].Trim().Split(','); // Split nodes that are in format "pip:Orientation pip:Orientation..." List <DominoNode> row = new List <DominoNode>(); for (int c = 0; c < dominoNodes.Length; c++) { string[] dominoPack = dominoNodes[c].Trim().Split(':'); if (dominoPack.Length < 2) { throw new Exception("Bad DominoNode!! need to be in format of 'pip:orientation,'\n\tError at line " + r.ToString() + " Column " + c.ToString()); } int pip = Int32.Parse(dominoPack[0]); row.Add(new DominoNode(pip, dominoPack[1], new Vector2(c, r - startOfMaze), ((end.x + c) + (end.y - (r - startOfMaze))))); } this.dominoMaze.Add(row); r++; } } } } startNode = this.dominoMaze[(int)start.y][(int)start.x]; endNode = this.dominoMaze[(int)end.y][(int)end.x]; int width = this.dominoMaze[0].Count; int height = dominoMaze.Count; // Set DominoNode Connections for (int r = 0; r < dominoMaze.Count; r++) { for (int c = 0; c < dominoMaze[r].Count; c++) { DominoNode curNode = dominoMaze[r][c]; if (r > 0 && curNode.isPipEqual(dominoMaze[r - 1][c].getPip())) //check domino node above { curNode.setConnection(dominoMaze[r - 1][c]); } if (r < height - 1 && curNode.isPipEqual(dominoMaze[r + 1][c].getPip())) //check domino node bellow { curNode.setConnection(dominoMaze[r + 1][c]); } if (c < width - 1 && curNode.isPipEqual(dominoMaze[r][c + 1].getPip())) //check domino node to the right { curNode.setConnection(dominoMaze[r][c + 1]); } if (c > 0 && curNode.isPipEqual(dominoMaze[r][c - 1].getPip())) //check domino node to the left { curNode.setConnection(dominoMaze[r][c - 1]); } //Handle Orientation switch (curNode.getOrientation()) { case "u": curNode.setConnection(dominoMaze[r - 1][c]); break; case "d": curNode.setConnection(dominoMaze[r + 1][c]); break; case "r": curNode.setConnection(dominoMaze[r][c + 1]); break; case "l": curNode.setConnection(dominoMaze[r][c - 1]); break; default: throw new Exception("Bad orientation Exception!!!! Domino node needs to be either l,r,u,d instead got: " + curNode.getOrientation() + "\n\tError at Node: " + curNode.getPlaceInMaze().ToString()); } } } }
public void traverse(List <List <DominoNode> > maze) { HashSet <DominoNode> Visited = new HashSet <DominoNode>(); List <DominoNode> toVisit = new List <DominoNode>(); this.start.costToGetToFromStart = 0; start.cost = 0; toVisit.Add(start); shortestPathFromStart.Add(start.getPlaceInMaze(), new Path() { cost = start.costToGetToFromStart, path = new List <DominoNode> { start } }); while (toVisit.Count > 0) { toVisit.Sort(); DominoNode currentDominoNode = toVisit[0]; orderChecked.Add(currentDominoNode.getPlaceInMaze()); Visited.Add(currentDominoNode); if (currentDominoNode == end) { break; } foreach (DominoNode neighboringDomino in currentDominoNode.connections) { int costToGetTo = shortestPathFromStart[currentDominoNode.getPlaceInMaze()].cost + 1; // Neightbor already visited before, // check if path to it from this city is cheaper then current path if (Visited.Contains(neighboringDomino) || shortestPathFromStart.ContainsKey(neighboringDomino.getPlaceInMaze())) { // New Path is cheaper to this city if (shortestPathFromStart[neighboringDomino.getPlaceInMaze()].cost > costToGetTo) { neighboringDomino.cost = costToGetTo; List <DominoNode> pathToCity; copyPath(currentDominoNode, out pathToCity, neighboringDomino); shortestPathFromStart[neighboringDomino.getPlaceInMaze()] = new Path() { cost = costToGetTo, path = pathToCity }; } } // Otherwise add city to toVisit to have its neighbors checked else { neighboringDomino.cost = costToGetTo + (usingAStar ? (int)neighboringDomino.getHeuristic() : 0); toVisit.Add(neighboringDomino); List <DominoNode> pathToCity; copyPath(currentDominoNode, out pathToCity, neighboringDomino); if (shortestPathFromStart.ContainsKey(neighboringDomino.getPlaceInMaze())) { printOutPaths(); throw new Exception("Trying to add CityPath that is already added!!"); } else { shortestPathFromStart.Add(neighboringDomino.getPlaceInMaze(), new Path() { cost = costToGetTo, path = pathToCity }); } } } toVisit.RemoveAt(0); } }