Beispiel #1
0
    // 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();
    }
Beispiel #2
0
 /// <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);
 }
Beispiel #3
0
    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());
                }
            }
        }
    }
Beispiel #4
0
    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);
        }
    }