Exemple #1
0
    /// <summary>
    /// Performs a hop within error recovery mode. It is checked whether this hop
    /// brings the player back to the last valid router. If the player returns to the
    /// last valid router, the error recovery mode will be disabled. Otherwise,
    /// the player remains in error recovery mode.
    /// </summary>
    /// <param name="path">The path along which the player performs the hop.</param>
    /// <returns>The current status of the error recovery.</returns>
    public ErrorRecoveryStatus PerformErrorRecoveryHop(PathScript path)
    {
        RouterScript from = path.from.GetComponent <RouterScript>();
        RouterScript to   = path.to.GetComponent <RouterScript>();

        // Check if player returns to the last valid hop.
        if (lastValidRouter == to || (bidirectional && lastValidRouter == from))
        {
            lastValidRouter = null;
            // Error recovery finished.
            errorRecovery = false;

            if (isLogEnabled)
            {
                Debug.Log("Left error recovery mode.");
            }
        }

        // Update the current player position according to the performed hop.
        UpdateCurrentPlayerPosition(path);

        // Check if still in error recovery mode.
        if (errorRecovery)
        {
            return(ErrorRecoveryStatus.ERROR_NOT_RECOVERED);
        }
        return(ErrorRecoveryStatus.ERROR_RECOVERED);
    }
Exemple #2
0
    void GameManagerInterface.Start(GameTuple startAndEndPoint)
    {
        recreateGraphRepresentation();

        base.InitializeRun(startAndEndPoint);

        RouterScript currentRouter = activeRouter.GetComponent <RouterScript>();

        currentRouter.SetPriority(0);

        neighboursOfActiveRouter = ExpandNode(currentRouter);
        prioQueue = new PriorityQueue <RouterScript>();

        for (int i = 0; i < neighboursOfActiveRouter.Count; i++)
        {
            PathScript pathToNeighbor = graphRepresentation2[currentRouter.GetRouterIndex(), neighboursOfActiveRouter[i].GetRouterIndex()];
            neighboursOfActiveRouter[i].SetPriority(pathToNeighbor.GetPathCosts());

            prioQueue.Enqueue(neighboursOfActiveRouter[i]);

            if (isLogEnabled)
            {
                Debug.Log(string.Format("Added router {0} to prio queue with path costs {1}.",
                                        neighboursOfActiveRouter[i],
                                        pathToNeighbor.GetPathCosts()));
            }
        }
    }
Exemple #3
0
    /// <summary>
    /// A helper method that sorts the entries of the array of RouterScript instances according
    /// to the current priority of their corresponding router. The entries are
    /// sorted ascendingly.
    /// </summary>
    /// <param name="routers">The array of RouterScript instances that should be sorted.</param>
    /// <returns>A sorted version of the array that was passed as a parameter.</returns>
    private RouterScript[] sortRouterArrayByPriority(RouterScript[] routers)
    {
        bool isSorted = false;

        while (!isSorted)
        {
            // Assume it is sorted.
            isSorted = true;

            // Check if all elements are sorted.
            for (int i = 0; i < routers.Length - 1; i++)
            {
                // Sort by priority ascendingly.
                if (routers[i].GetPriority() > routers[i + 1].GetPriority())
                {
                    // Not sorted yet.
                    isSorted = false;

                    // Swap elements.
                    RouterScript tmp = routers[i];
                    routers[i]     = routers[i + 1];
                    routers[i + 1] = tmp;
                }
            }
        }

        return(routers);
    }
Exemple #4
0
    /// <summary>
    /// Equivalent to neighborPaths in the GreedyManager, returns all children/neighbors of this router.
    /// </summary>
    /// <returns>The neighbors/children of the current working router</returns>
    /// <param name="current">Current Working router</param>
    public List <RouterScript> ExpandNode(RouterScript current)
    {
        List <RouterScript> neighbors     = new List <RouterScript>();
        List <PathScript>   neighborPaths = new List <PathScript>();

        int currentRouterIndex = current.GetRouterIndex();

        //Extract paths from graph representation.
        for (int i = 0; i < graphRepresentation2.GetLength(1); i++)
        {
            if (graphRepresentation2[currentRouterIndex, i] != null)
            {
                neighborPaths.Add(graphRepresentation2[currentRouterIndex, i]);
            }
        }

        foreach (PathScript p in neighborPaths)
        {
            RouterScript from = p.from.GetComponent <RouterScript>();
            RouterScript to   = p.to.GetComponent <RouterScript>();
            if (current == from)
            {
                neighbors.Add(to);
            }
        }

        return(neighbors);
    }
Exemple #5
0
    /// <summary>
    /// Displays the destination router on top of the beer bottle.
    /// </summary>
    public void displayDestinationRouter()
    {
        SpriteRenderer spriteRenderer = transform.GetComponentInChildren <SpriteRenderer>();

        // Get the Text Mesh. The TextMesh is contained in the first child of the router game object.
        TextMesh textField = null;

        foreach (TextMesh m in GetComponentsInChildren <TextMesh>())
        {
            if (m.name == "PathDestinationText")
            {
                textField = m;
            }
        }

        if (textField != null)
        {
            textField.transform.localScale = new Vector3(0.1f, 0.1f, 1.0f);
            // Set the rendering order and the sorting order of the TextMesh.
            MeshRenderer textFieldRenderer = textField.transform.GetComponent <MeshRenderer>();
            textFieldRenderer.sortingLayerID = spriteRenderer.sortingLayerID;
            textFieldRenderer.sortingOrder   = spriteRenderer.sortingOrder + 2;   // Set sorting order +2 compared to the sprite renderer.

            // Set the position and text of the TextMesh.
            Vector3 routerPosition = transform.position;
            routerPosition.x             = routerPosition.x + offsetX;
            routerPosition.y             = routerPosition.y + offsetY;
            textField.transform.position = routerPosition;

            RouterScript toScript = to.GetComponent <RouterScript>();

            textField.text = toScript.routerName;
        }
    }
Exemple #6
0
 private void UpdateGreedyHeuristics(RouterScript source, RouterScript destination)
 {
     foreach (RouterScript tmp in listOfRouterScripts)
     {
         int heuristic = CalcStraightLineHeuristic(tmp, destination);
         tmp.SetGreedyHeuristicValue(heuristic);
     }
 }
Exemple #7
0
    /// <summary>
    /// Finds the greedy path between source and destination.
    /// </summary>
    /// <param name="source">Source.</param>
    /// <param name="destination">Destination.</param>
    private List <RouterScript> FindPath(RouterScript source, RouterScript destination)
    {
        if (isLogEnabled)
        {
            Debug.Log("Finding best greedy path!");
        }
        prioQueue = new PriorityQueue <RouterScript>();
        RouterScript        current  = source;
        List <RouterScript> closed   = new List <RouterScript>();
        List <RouterScript> children = new List <RouterScript>();

        if (isLogEnabled)
        {
            Debug.Log("Starting Greedy from " + current.name + " to " + destination.name);
        }
        UpdateGreedyHeuristics(source, destination);

        while (current != destination)
        {
            if (!closed.Contains(current))
            {
                children = ExpandNode(current);
                foreach (RouterScript tmp in children)
                {
                    if (isLogEnabled)
                    {
                        Debug.Log("Current Child: " + tmp.name + " | heuristic: " + tmp.GetGreedyHeuristicValue());
                    }
                    tmp.SetPriority(tmp.GetGreedyHeuristicValue());
                    prioQueue.Enqueue(tmp);
                }

                closed.Add(current);
            }
            if (isLogEnabled)
            {
                Debug.Log("Finished with: " + current.name);
            }
            //Check if more than one solution exists.
            current = prioQueue.PullHighest();
        }

        string path = "";

        foreach (RouterScript tmp in closed)
        {
            path += tmp.name + "|" + CalcStraightLineHeuristic(tmp, destination)
                    + " >> ";
        }
        path += current.name + "|0";
        if (isLogEnabled)
        {
            Debug.Log("Path=" + path);
        }

        closed.Add(destination);
        return(closed);
    }
Exemple #8
0
 /// <summary>
 /// Returns the predecessor router of the target router on the shortest path from the starting
 /// router to the target router.
 /// </summary>
 /// <param name="targetRouter">The router whose predecessor on the shortest path should be extracted.</param>
 /// <returns>The RouterScript instance from the predecessor router or null if there is no valid predecessor for the target router.</returns>
 public RouterScript GetPredecessorRouterOnShortestPath(RouterScript targetRouter)
 {
     // Check if router has a valid predecessor.
     if (predecessorRouter.ContainsKey(targetRouter))
     {
         return(predecessorRouter[targetRouter]);
     }
     return(null);
 }
Exemple #9
0
 /// <summary>
 /// Determines whether this router instance is already handled in the current run.
 /// </summary>
 /// <returns><c>true</c> if this router instance is already handled in the current run; otherwise, <c>false</c>.</returns>
 /// <param name="router">The router instance.</param>
 public bool IsRouterAlreadyHandled(RouterScript router)
 {
     // The routers in current path have already been visited and no shorter path
     // can be found for this routers.
     if (currentPath != null && !currentPath.Contains(router))
     {
         return(false);
     }
     return(true);
 }
Exemple #10
0
    /// <summary>
    /// Performs the path discovery on the specified path. The path costs of this path
    /// are determined and it is checked whether the target router can be reached with
    /// less path costs using this path. If the target router can be reached with less
    /// path costs via this path, the distance (priority) of the router is adjusted and
    /// the previous router on this path stored in the predecessorRouter data structure.
    /// Finally, the path is set to discovered.
    /// </summary>
    /// <param name="path">The path for which the path discovery is performed.</param>
    public void PerformPathDiscovery(PathScript path)
    {
        RouterScript from = path.from.GetComponent <RouterScript>();
        RouterScript to   = path.to.GetComponent <RouterScript>();

        RouterScript previousRouter   = null;
        RouterScript discoveredRouter = null;

        // Check which router will be discovered.
        if (from == routerScriptCurrentPlayerPosition)
        {
            // Player discovers 'to' router.
            discoveredRouter = to;
            previousRouter   = routerScriptCurrentPlayerPosition;
        }
        else if (bidirectional && to == routerScriptCurrentPlayerPosition)
        {
            // Player discovers 'from' router.
            discoveredRouter = from;
            previousRouter   = routerScriptCurrentPlayerPosition;
        }

        // Update the current distance if we have found a shorter path to the discovered router.
        // This only needs to be done when the discovered router has not already been handled by the dijkstra algorithm.
        if (priorityQueue.IsContained(discoveredRouter))
        {
            // Path costs to the discovered router are the path cost to the previous router + the path costs of this path.
            int pathCost = previousRouter.GetPriority() + graphRepresentation2[previousRouter.GetRouterIndex(), discoveredRouter.GetRouterIndex()].GetPathCosts();
            // Are the new path costs lower than the currently stored lowest path costs.
            if (pathCost < discoveredRouter.GetPriority())
            {
                // Update the path costs of the router.
                priorityQueue.DecreasePriority(discoveredRouter, pathCost);
                // Set the new predecessor for this router.
                predecessorRouter[discoveredRouter] = previousRouter;
            }
        }

        // Set path to discovered.
        graphRepresentation2[previousRouter.GetRouterIndex(), discoveredRouter.GetRouterIndex()].SetDiscovered(true);
        //graphRepresentation2[previousRouter.GetRouterIndex(), discoveredRouter.GetRouterIndex()].DisplayPathCosts();

        // If there is a path back with the same costs, discover this path as well.
        PathScript backPath = graphRepresentation2[discoveredRouter.GetRouterIndex(), previousRouter.GetRouterIndex()];

        if (backPath != null && backPath.GetPathCosts() == path.GetPathCosts())
        {
            backPath.SetDiscovered(true);
            //backPath.DisplayPathCosts();
        }

        // Test: Output the current priority queue.
        // Debug.Log(priorityQueue.ToString());
    }
Exemple #11
0
    /// <summary>
    /// Determines whether this hop is a valid uniform cost hop for the specified targetRouter.
    /// </summary>
    /// <returns><c>true</c> if this instance is a valid uniform cost hop for the specified targetRouter; otherwise, <c>false</c>.</returns>
    /// <param name="targetRouter">Target router.</param>
    private bool IsValidUniformCostHop(RouterScript targetRouter)
    {
        if (!prioQueue.IsContained(targetRouter))
        {
            // Valid hop.
            return(true);
        }

        // Is the target the first element in the priority queue?
        if (prioQueue.Peek() == targetRouter)
        {
            return(true);
        }
        else
        {
            // Target is not the first element in the priority Queue.
            // But it is still a valid hop if there are more elements with
            // the same costs.

            bool isValidHop = false;
            // To check this, we need to remove the elements before this router from the queue and later put them back in.
            RouterScript headOfQueue = prioQueue.PullHighest();
            // Check the following routers. Stop if they have a higher priority than the original head.
            List <RouterScript> nextRouterCandidates = new List <RouterScript>();
            while (prioQueue.Count() > 0 && prioQueue.Peek().GetPriority() == headOfQueue.GetPriority())
            {
                RouterScript candidateRouter = prioQueue.PullHighest();
                nextRouterCandidates.Add(candidateRouter);
                if (candidateRouter == targetRouter)
                {
                    isValidHop = true;
                    break;
                }
            }

            // Store the candidate routers and the original headOfQueue back into the priority queue.
            prioQueue.Enqueue(headOfQueue);
            for (int i = 0; i < nextRouterCandidates.Count; i++)
            {
                prioQueue.Enqueue(nextRouterCandidates[i]);
            }

            if (!isValidHop)
            {
                return(false);
            }
        }

        return(true);
    }
Exemple #12
0
    /// <summary>
    /// Performs a hop which is considered invalid due to the dijkstra algorithm.
    /// Starts the error recovery which lasts until the player returns to the last valid hop.
    /// </summary>
    /// <param name="path">The path along which the player performs the hop.</param>
    public void PerformWrongHop(PathScript path)
    {
        if (isLogEnabled)
        {
            Debug.Log("Started error recovery mode.");
        }

        // Start the error recovery.
        errorRecovery = true;
        // Store the last valid router to that the player needs to return.
        // Last valid position is the router on which the player is located before the wrong hop.
        lastValidRouter = routerScriptCurrentPlayerPosition;

        // Update the current player position.
        UpdateCurrentPlayerPosition(path);
    }
Exemple #13
0
 /// <summary>
 /// Indicates whether the specified router is already marked as handled in the current dijkstra run.
 /// </summary>
 /// <param name="router">The RouterScript instance of the router that should be checked.</param>
 /// <returns>Returns true, if the router is already handled, false otherwise.</returns>
 public bool IsRouterAlreadyHandled(RouterScript router)
 {
     if (router != null && priorityQueue != null)
     {
         if (priorityQueue.IsContained(router))
         {
             // Not yet handled as it is still in the priority queue.
             return(false);
         }
         else
         {
             return(true);
         }
     }
     return(false);
 }
    /// <summary>
    /// Gets the path between the provided nodes.
    /// </summary>
    /// <returns>The path between the nodes.</returns>
    /// <param name="from">From.</param>
    /// <param name="to">To.</param>
    public PathScript GetPathBetweenNodes(RouterScript from, RouterScript to)
    {
        PathScript path = graphRepresentation2[
            from.GetRouterIndex(),
            to.GetRouterIndex()
                          ];

        if (path == null)
        {
            path = graphRepresentation2[
                to.GetRouterIndex(),
                from.GetRouterIndex()
                   ];
        }

        return(path);
    }
Exemple #15
0
    /// <summary>
    /// A helper method that updates the current player position depending on the specified
    /// path. The method takes into account whether bidirectional movements are allowed.
    /// </summary>
    /// <param name="path">The path on which the player performs the hop.</param>
    private void UpdateCurrentPlayerPosition(PathScript path)
    {
        RouterScript from = path.from.GetComponent <RouterScript>();
        RouterScript to   = path.to.GetComponent <RouterScript>();

        // Check to which router the player moves.
        if (from == routerScriptCurrentPlayerPosition)
        {
            // Player performs hop to router "to".
            routerScriptCurrentPlayerPosition = to;
        }
        else if (bidirectional && to == routerScriptCurrentPlayerPosition)
        {
            // Player performs hop to router "from".
            routerScriptCurrentPlayerPosition = from;
        }
    }
Exemple #16
0
    /// <summary>
    /// Starts the Dijkstra algorithm. Performs the required initialization and fills the priority queue.
    /// Sets the player's position to the starting router.
    /// </summary>
    /// <param name="startingRouter">The starting router of the algorithm.</param>
    public void StartDijkstraAlgorithm(RouterScript startingRouter)
    {
        if (isLogEnabled)
        {
            Debug.Log("StartDijkstraAlgorithm() called.");
        }

        // Create the priority queue.
        priorityQueue = new PriorityQueue <RouterScript>();

        // Initialize Dijkstra algorithm by storing nodes in priority queue.
        for (int i = 0; i < listOfRouterScripts.Length; i++)
        {
            RouterScript router = listOfRouterScripts[i];
            if (router == startingRouter)
            {
                if (isLogEnabled)
                {
                    Debug.Log("router instance id: " + router.GetInstanceID() + " and starting router instance id " + startingRouter.GetInstanceID());
                }

                // Set the current shortest path of the starting router to 0.
                router.SetPriority(0);
                predecessorRouter[router] = router; // The predecessor of the starting router is the router itself.

                // Set this router as the current player position and as the current working router.
                routerScriptCurrentPlayerPosition = router;
                currentWorkingRouter = router;
            }
            else
            {
                // For all other routers, set the current distance to the max int value.
                Debug.Log("Router=" + router + " i=" + i + " list of routers size=" + listOfRouterScripts.Length);
                router.SetPriority(int.MaxValue);

                // Add the router to the priority queue.
                priorityQueue.Enqueue(router);
            }
        }

        if (isLogEnabled)
        {
            Debug.Log("Finished StartDijkstraAlgorithm().");
        }
    }
Exemple #17
0
    /// <summary>
    /// Performs a hop along the path to the target router. The target router will be the next
    /// router that is handled by the dijkstra algorithm. The target router is removed from the
    /// priority queue which marks it as processed. For this router no shorter path can be found.
    /// </summary>
    /// <param name="path"> The path on which the hop is performed. The path determines the previous router
    ///                     and the target router.</param>
    public void PerformHop(PathScript path)
    {
        // Update the current player position.
        UpdateCurrentPlayerPosition(path);

        // Update the current working router.
        currentWorkingRouter = routerScriptCurrentPlayerPosition;

        // The chosen router is now getting processed by the dijkstra algorithm and cannot get a shorter path afterwards.
        // Take it out of the priority queue.
        if (priorityQueue.IsContained(routerScriptCurrentPlayerPosition))
        {
            if (priorityQueue.Peek() == routerScriptCurrentPlayerPosition)
            {
                // It is the first element, so pull it from the queue.
                priorityQueue.PullHighest();
            }
            else
            {
                // Another router with the same distance is currently in front of the target router.
                // Remove those routers before the target router, but put them back into the queue afterwards.
                List <RouterScript> routerCache = new List <RouterScript>();
                while (priorityQueue.Count() > 0)
                {
                    if (priorityQueue.Peek() != routerScriptCurrentPlayerPosition)
                    {
                        routerCache.Add(priorityQueue.PullHighest());
                    }
                    else
                    {
                        // Found the target router. Remove it from the queue and abort the loop.
                        priorityQueue.PullHighest();
                        break;
                    }
                }

                // Put cached routers back into priority queue.
                for (int i = 0; i < routerCache.Count; i++)
                {
                    priorityQueue.Enqueue(routerCache[i]);
                }
            }
        }
    }
Exemple #18
0
    /// <summary>
    /// Create entries for the routers that have been handeld already by the dijkstra algorithm
    /// in the current run. The entries are concatenated to a string.
    /// </summary>
    /// <param name="routers">The list of all routers that are involved in the current dijkstra run.</param>
    /// <returns>A string containing the routing table entries of the already handled routers.</returns>
    private string createHandledRouterRoutingTableEntries(RouterScript[] routers)
    {
        System.Text.StringBuilder s = new System.Text.StringBuilder();

        for (int i = 0; i < routers.Length; i++)
        {
            // Check whether the router is already handled.
            if (dijkstraManager.IsRouterAlreadyHandled(routers[i]))
            {
                string currentRouter = string.Empty;

                // Request predecessor.
                RouterScript predecessorRouter = dijkstraManager.GetPredecessorRouterOnShortestPath(routers[i]);
                if (predecessorRouter != null)
                {
                    // Add entry to the routing table.
                    currentRouter = string.Format("Tisch {0}: ({1},{2})" + System.Environment.NewLine,
                                                  routers[i].GetRouterName(),
                                                  routers[i].GetPriority(),
                                                  predecessorRouter.GetRouterName());
                }

                // Is the router the current working router?
                if (routers[i] == dijkstraManager.GetCurrentWorkingRouter().GetComponent <RouterScript>())
                {
                    currentRouter = colorizeString(currentRouter, currentWorkingRouterColor);
                }

                s.Append(currentRouter);
            }
        }

        string output = s.ToString();

        output = colorizeString(output, handledRouterColor);

        if (isDebugging)
        {
            Debug.Log(" In handled routers: " + output);
        }

        return(output);
    }
Exemple #19
0
    /// <summary>
    /// Determines whether this instance is valid greedy hop for the specified hopTarget.
    /// </summary>
    /// <returns><c>true</c> if this instance is valid greedy hop for the specified hopTarget; otherwise, <c>false</c>.</returns>
    /// <param name="hopTarget">Hop target.</param>
    private bool IsValidGreedyHop(RouterScript hopTarget)
    {
        foreach (RouterScript router in neighboursOfActiveRouter)
        {
            if (hopTarget.gameObject == router.gameObject)
            {
                continue;
            }

            if (currentPath.Contains(router))
            {
                continue;
            }

            if (router.GetGreedyHeuristicValue() < hopTarget.GetGreedyHeuristicValue())
            {
                return(false);
            }
        }
        return(true);
    }
Exemple #20
0
    // Use this for initialization.
    void Start()
    {
        if (isLogEnabled)
        {
            Debug.Log("Start initializing graph datastructure.");
        }

        // Fill graph representation array with information taken from the nodes and edges
        for (int i = 0; i < listOfPathScripts.Length; i++)
        {
            RouterScript from = listOfPathScripts[i].from.GetComponent <RouterScript>();
            RouterScript to   = listOfPathScripts[i].to.GetComponent <RouterScript>();

            graphRepresentation2[from.GetRouterIndex(), to.GetRouterIndex()] = listOfPathScripts[i];
        }

        if (isLogEnabled)
        {
            Debug.Log("Finished initializing graph datastructure.");
        }
    }
Exemple #21
0
    /// <summary>
    /// Create entries for the routers that have not been handeld by the dijkstra algorithm so far
    /// in the current run. The entries are concatenated to a string.
    /// </summary>
    /// <param name="routers">The list of all routers that are involved in the current dijkstra run.</param>
    /// <returns>A string containing the routing table entries of the not yet handled routers.</returns>
    private string createUnhandledRouterRoutingTableEntries(RouterScript[] routers)
    {
        System.Text.StringBuilder s = new System.Text.StringBuilder();

        for (int i = 0; i < routers.Length; i++)
        {
            // Check whether the router is already handled.
            if (!dijkstraManager.IsRouterAlreadyHandled(routers[i]))
            {
                // Request predecessor.
                RouterScript predecessorRouter = dijkstraManager.GetPredecessorRouterOnShortestPath(routers[i]);
                if (predecessorRouter != null)
                {
                    // Add entry to the routing table.
                    s.Append(string.Format("Tisch {0}: ({1},{2})" + System.Environment.NewLine,
                                           routers[i].GetRouterName(),
                                           routers[i].GetPriority(),
                                           predecessorRouter.GetRouterName()));
                }
                else
                {
                    // Add entry to the routing table without predecessor.
                    s.Append(string.Format("Tisch {0}: (inf,-)" + System.Environment.NewLine,
                                           routers[i].GetRouterName()));
                }
            }
        }

        string output = s.ToString();

        output = colorizeString(output, unhandledRouterColor);

        if (isDebugging)
        {
            Debug.Log(" In unhandled routers: " + output.Substring(1, output.Length - 1));
        }

        return(output);
    }
Exemple #22
0
    /// <summary>
    /// Recreates the graph representation. Takes blocked routers into account.
    /// </summary>
    public void recreateGraphRepresentation()
    {
        graphRepresentation2 = new PathScript[listOfNodes.Length, listOfNodes.Length]; // Nodex x Nodes

        // Fill graph representation array with information taken from the nodes and edges.
        // Take blocked routers into the account.
        for (int i = 0; i < listOfPathScripts.Length; i++)
        {
            RouterScript from = listOfPathScripts[i].from.GetComponent <RouterScript>();
            RouterScript to   = listOfPathScripts[i].to.GetComponent <RouterScript>();

            if (!from.Disabled && !to.Disabled)
            {
                // Include only active paths.
                graphRepresentation2[from.GetRouterIndex(), to.GetRouterIndex()] = listOfPathScripts[i];
            }
            else
            {
                listOfPathScripts[i].Disabled = true;
            }
        }
    }
Exemple #23
0
    /// <summary>
    /// Searches all routers in the priority queue which currently have the shortest distance and
    /// are a suitable candidate for the next working router in the Dijkstra algorithm.
    /// </summary>
    /// <returns>A string which contains the names of the candidate routers.</returns>
    public string GetNextRouterSuggestionAsString()
    {
        if (priorityQueue.Count() == 0)
        {
            return(string.Empty);
        }

        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        RouterScript headOfQueue     = priorityQueue.PullHighest();

        sb.Append(headOfQueue.GetRouterName() + ", ");

        // Check if the next element in the priority queue also has the same distance.
        if (headOfQueue.GetCurrentDistance() == priorityQueue.Peek().GetCurrentDistance())
        {
            // Retrieve all routers that have the same current distance.
            List <RouterScript> routerCache = new List <RouterScript>();
            while (headOfQueue.GetCurrentDistance() == priorityQueue.Peek().GetCurrentDistance())
            {
                sb.Append(priorityQueue.Peek().GetRouterName() + ", ");
                routerCache.Add(priorityQueue.PullHighest());
            }

            // Put the routers back in.
            foreach (RouterScript router in routerCache)
            {
                priorityQueue.Enqueue(router);
            }
        }

        // Remove the last comma.
        sb.Remove(sb.Length - 2, 2);

        // Put head of priority queue back.
        priorityQueue.Enqueue(headOfQueue);

        return(sb.ToString());
    }
Exemple #24
0
    /// <summary>
    /// Removes the router from the priority queue.
    /// </summary>
    /// <param name="routerScript">Router script.</param>
    protected void RemoveRouterFromPrioQueue(RouterScript routerScript)
    {
        if (prioQueue.IsContained(routerScript))
        {
            if (prioQueue.Peek() == routerScript)
            {
                // It is the first element, so pull it from the queue.
                prioQueue.PullHighest();
            }
            else
            {
                // Another router with the same distance is currently in front of the target router.
                // Remove those routers before the target router, but put them back into the queue afterwards.
                List <RouterScript> routerCache = new List <RouterScript>();
                while (prioQueue.Count() > 0)
                {
                    if (prioQueue.Peek() != routerScript)
                    {
                        routerCache.Add(prioQueue.PullHighest());
                    }
                    else
                    {
                        // Found the target router. Remove it from the queue and abort the loop.
                        prioQueue.PullHighest();
                        break;
                    }
                }

                // Put cached routers back into priority queue.
                for (int i = 0; i < routerCache.Count; i++)
                {
                    prioQueue.Enqueue(routerCache[i]);
                }
            }
        }
    }
Exemple #25
0
 void GameManagerInterface.SetCurrentPlayerPosition(RouterScript playerPos)
 {
     activeRouter = playerPos.gameObject;
 }
Exemple #26
0
    protected void Initialize()
    {
        if (isLogEnabled)
        {
            Debug.Log("Awake the GameManager.");
        }

        // Extract scripts from nodes and edges
        listOfNodes = GameObject.FindGameObjectsWithTag("Node");
        listOfEdges = GameObject.FindGameObjectsWithTag("Path");

        // Initialize graph datastructure.
        //graphRepresentation = new int[listOfNodes.Length,listOfNodes.Length];  // Nodes x Nodes
        graphRepresentation2 = new PathScript[listOfNodes.Length, listOfNodes.Length]; // Nodex x Nodes

        // Keep track of the predecessor router for each router on the shortest path.
        //predecessorRouter = new Dictionary<RouterScript, RouterScript> ();

        if (isLogEnabled)
        {
            Debug.Log("Start extracting scripts in GameManager.");
        }

        // listOfRouterScripts = new RouterScript[listOfNodes.Length];
        // listOfPathScripts = new PathScript[listOfEdges.Length];

        // Extract scripts from nodes and edges
        listOfNodes = GameObject.FindGameObjectsWithTag("Node");
        listOfEdges = GameObject.FindGameObjectsWithTag("Path");

        // Initialize graph datastructure.
        //graphRepresentation = new int[listOfNodes.Length,listOfNodes.Length];  // Nodes x Nodes
        graphRepresentation2 = new PathScript[listOfNodes.Length, listOfNodes.Length]; // Nodex x Nodes


        listOfRouterScripts = new RouterScript[listOfNodes.Length];
        listOfPathScripts   = new PathScript[listOfEdges.Length];
        for (int i = 0; i < listOfNodes.Length; i++)
        {
            listOfRouterScripts[i] = listOfNodes[i].GetComponent <RouterScript>();
        }
        for (int i = 0; i < listOfEdges.Length; i++)
        {
            listOfPathScripts[i] = listOfEdges[i].GetComponent <PathScript>();
        }

        // Check router names.
        checkIntegrityOfRouterNames();

        if (isLogEnabled)
        {
            Debug.Log("Finished extracting scripts in GameManager.");
            Debug.Log("Finished Awake method of the GameManager.");
        }

        if (isLogEnabled)
        {
            Debug.Log("Start initializing graph datastructure.");
        }

        // Fill graph representation array with information taken from the nodes and edges
        for (int i = 0; i < listOfPathScripts.Length; i++)
        {
            RouterScript from = listOfPathScripts[i].from.GetComponent <RouterScript>();
            RouterScript to   = listOfPathScripts[i].to.GetComponent <RouterScript>();

            graphRepresentation2[from.GetRouterIndex(), to.GetRouterIndex()] = listOfPathScripts[i];
        }

        if (isLogEnabled)
        {
            Debug.Log("Finished initializing graph datastructure.");
        }
    }
Exemple #27
0
    void GameManagerInterface.PerformHop(PathScript path)
    {
        GameObject hopTarget = null;

        //to=active --> goto from
        if (path.to.gameObject == activeRouter.gameObject)
        {
            hopTarget = path.from.gameObject;
        }
        else           //from=active --> goto to
        if (path.from.gameObject == activeRouter.gameObject)
        {
            hopTarget = path.to.gameObject;
        }

        // Update the active router and the neighbours of the active router.
        activeRouter = hopTarget;
        currentPath.Add(hopTarget.GetComponent <RouterScript>());
        neighboursOfActiveRouter = ExpandNode(activeRouter.GetComponent <RouterScript>());


        // Remove the hop target from the priortiy queue.
        RemoveRouterFromPrioQueue(hopTarget.GetComponent <RouterScript>());

        for (int i = 0; i < neighboursOfActiveRouter.Count; i++)
        {
            RouterScript neighborRouter = neighboursOfActiveRouter[i].GetComponent <RouterScript>();

            // Path costs to the target router are the path cost to the currently active router + the path costs of this path.
            int pathCost = activeRouter.GetComponent <RouterScript>().GetPriority() +
                           graphRepresentation2[
                activeRouter.GetComponent <RouterScript>().GetRouterIndex(),
                neighborRouter.GetRouterIndex()
                           ].GetPathCosts();

            if (currentPath.Contains(neighborRouter))
            {
                continue;
            }

            if (prioQueue.IsContained(neighborRouter))
            {
                if (pathCost < neighborRouter.GetPriority())
                {
                    // Update the path costs of the router.
                    prioQueue.DecreasePriority(neighborRouter, pathCost);

                    if (isLogEnabled)
                    {
                        Debug.Log(string.Format("Updated path costs of router {0}, new path costs are {1}.",
                                                neighborRouter.GetRouterName(), neighborRouter.GetPriority()));
                    }
                }
            }
            else
            {
                neighborRouter.SetPriority(pathCost);

                if (isLogEnabled)
                {
                    Debug.Log(string.Format("Inserted neighbor into prio queue. Neighbor is {0}, path costs are {1}.",
                                            neighborRouter.GetRouterName(), pathCost));
                }

                // Insert neighbor into priority queue.
                prioQueue.Enqueue(neighborRouter);
            }
        }

        if (isLogEnabled)
        {
            Debug.Log("Prio Queue after hop: " + prioQueue.ToString());
        }
    }
Exemple #28
0
 /// <summary>
 /// Calculates the straight line heuristic.
 /// </summary>
 /// <returns>The straight line heuristic.</returns>
 /// <param name="source">Source.</param>
 /// <param name="destination">Destination.</param>
 private int CalcStraightLineHeuristic(RouterScript source, RouterScript destination)
 {
     return((int)Vector3.Distance(source.transform.position, destination.transform.position));
 }
Exemple #29
0
 public void SetCurrentPlayerPosition(RouterScript playerPos)
 {
     activeRouter = playerPos.gameObject;
 }
Exemple #30
0
    /// <summary>
    /// Checks whether the attempted hop by the player is a valid hop which fulfills the conditions of the dijkstra algorithm.
    /// First, it is checked whether the path is connecting the router on which the player is currently located and an adjacent router.
    /// If not, it is an invalid hop. Second, it is checked whether the path is already discovered. If not, it is a valid hop, but a
    /// hop in discovery mode. If the path it is not discovered and there are still undiscovered paths connected to the router on which the player is
    /// located, it is an invalid hop due to undiscovered neighbors.  Third, if the target router of this path has already been handled, the user
    /// can move back to this router, so its a valid hop. Finally, if non of the cases mentioned before has applied, the player wants to perform an
    /// actual movement towards an router which should be handled by the dijkstra algorithm next. It is checked whether the target router determined by
    /// the path is actually a router that the dijkstra algorithm would handle next. If it is, it is a valid hop, otherwise it is an invalid hop concerning
    /// the dijkstra algorithm.
    /// </summary>
    /// <param name="path">The path between the two routers which should be passed in this hop.</param>
    /// <returns>The result of the dijkstra path check.</returns>
    public DijkstraStatus IsValidHop(PathScript path)
    {
        RouterScript from;
        RouterScript to;

        DijkstraMove dijkstraMove = new DijkstraMove();

        // Get path script.
        //PathScript currentPath = graphRepresentation2[from.GetRouterIndex(), to.GetRouterIndex()];
        PathScript currentPath = path;

        if (currentPath == null)
        {
            // Invalid hop, no path found between these routers.
            return(DijkstraStatus.HOP_UNREACHABLE);
        }

        // Check on which of the routers the player is located.
        if (path.from.GetComponent <RouterScript>() == routerScriptCurrentPlayerPosition)
        {
            to   = path.to.GetComponent <RouterScript>();
            from = path.from.GetComponent <RouterScript>();
        }
        else if (bidirectional && path.to.GetComponent <RouterScript>() == routerScriptCurrentPlayerPosition)
        {
            to   = path.from.GetComponent <RouterScript>();
            from = path.to.GetComponent <RouterScript>();
        }
        else
        {
            dijkstraMove.Source      = routerScriptCurrentPlayerPosition;
            dijkstraMove.Destination = currentPath.from.GetComponent <RouterScript>();
            dijkstraMove.Status      = DijkstraStatus.HOP_UNREACHABLE;
            listOfMoves.Add(dijkstraMove);

            // Invalid hop if player is not located on one of these routers.
            return(DijkstraStatus.HOP_UNREACHABLE);
        }

        // Store the routers in the DijkstraMove object.
        dijkstraMove.Source      = from;
        dijkstraMove.Destination = to;


        // Check if player is in error recovery mode.
        if (errorRecovery)
        {
            dijkstraMove.Status = DijkstraStatus.ERROR_RECOVERY;
            listOfMoves.Add(dijkstraMove);

            return(DijkstraStatus.ERROR_RECOVERY);
        }

        // Check whether the path is already discovered.
        if (!currentPath.IsDiscovered())
        {
            dijkstraMove.Status = DijkstraStatus.VALID_HOP_DISCOVERY;
            listOfMoves.Add(dijkstraMove);

            // It is a valid hop. It is a path discovery move.
            return(DijkstraStatus.VALID_HOP_DISCOVERY);
        }

        // Check if all paths to the adjacent routers have already been discovered.
        for (int i = 0; i < graphRepresentation2.GetLength(1); i++)
        {
            PathScript pathToNeighbor = graphRepresentation2[from.GetRouterIndex(), i];
            if (pathToNeighbor != null && !pathToNeighbor.IsDiscovered())
            {
                dijkstraMove.Status = DijkstraStatus.UNDISCOVERED_PATHS;
                listOfMoves.Add(dijkstraMove);

                // Not a valid move. The player needs to perform path discovery on all paths of this router first.
                return(DijkstraStatus.UNDISCOVERED_PATHS);
            }
        }

        // Check if the router has already been handled by the dijkstra algorithm.
        // If the router has already been handled, the player can perform a hop to this router.
        // Perform this check after the 'all paths discovered' check to make sure the player has handled the current working router completely before moving back to a already handled router.
        if (!priorityQueue.IsContained(to))
        {
            dijkstraMove.Status = DijkstraStatus.NOP;
            listOfMoves.Add(dijkstraMove);

            // Valid hop.
            return(DijkstraStatus.NOP);
        }

        // Check if the hop conforms to the hop which will be performed by the Dijkstra algorithm.
        // To do this, get the next hop from the priority queue, i.e. the router with the currently shortest distance.
        if (priorityQueue.Peek() == to)
        {
            dijkstraMove.Status = DijkstraStatus.VALID_HOP;
            listOfMoves.Add(dijkstraMove);

            // All conditions are met. It is a valid move.
            return(DijkstraStatus.VALID_HOP);
        }
        else
        {
            // It is still possible that there is another router which has the same distance and is thus a valid next hop.
            bool isValidHop = false;
            // To check this, we need to remove the elements before this router from the queue and later put them back in.
            RouterScript headOfQueue = priorityQueue.PullHighest();
            // Check the following routers. Stop if they have a higher priority than the original head.
            List <RouterScript> nextRouterCandidates = new List <RouterScript>();
            while (priorityQueue.Count() > 0 && priorityQueue.Peek().GetPriority() == headOfQueue.GetPriority())
            {
                RouterScript candidateRouter = priorityQueue.PullHighest();
                nextRouterCandidates.Add(candidateRouter);
                if (candidateRouter == to)
                {
                    isValidHop = true;
                    break;
                }
            }

            // Store the candidate routers and the original headOfQueue back into the priority queue.
            priorityQueue.Enqueue(headOfQueue);
            for (int i = 0; i < nextRouterCandidates.Count; i++)
            {
                priorityQueue.Enqueue(nextRouterCandidates[i]);
            }

            // Break if it isn't a valid hop.
            if (!isValidHop)
            {
                dijkstraMove.Status = DijkstraStatus.WRONG_HOP;
                listOfMoves.Add(dijkstraMove);

                return(DijkstraStatus.WRONG_HOP);
            }
        }

        dijkstraMove.Status = DijkstraStatus.VALID_HOP;
        listOfMoves.Add(dijkstraMove);

        // All conditions are met. It is a valid move.
        return(DijkstraStatus.VALID_HOP);
    }