예제 #1
0
    // Backtracks the path from input node
    public IEnumerator BacktrackShortestPath(Node node, WaitForSeconds demoStepDuration)
    {
        // Start backtracking from end node back to start node
        while (node != null)
        {
            // Node representation
            listVisual.RemoveCurrentNode();
            yield return(demoStepDuration);

            // Change color of node
            node.CurrentColor = UtilGraph.SHORTEST_PATH_COLOR;

            // Change color of edge leading to previous node
            Edge backtrackEdge = node.PrevEdge;

            if (backtrackEdge == null)
            {
                break;
            }

            backtrackEdge.CurrentColor = UtilGraph.SHORTEST_PATH_COLOR;

            // Set "next" node
            if (backtrackEdge is DirectedEdge)
            {
                ((DirectedEdge)backtrackEdge).PathBothWaysActive = true;
            }

            node = backtrackEdge.OtherNodeConnected(node);

            if (backtrackEdge is DirectedEdge)
            {
                ((DirectedEdge)backtrackEdge).PathBothWaysActive = false; // incase using same graph again at some point
            }
            yield return(demoStepDuration);

            listVisual.DestroyCurrentNode();

            yield return(demoStepDuration);
        }
    }
예제 #2
0
    // User test
    public int PrepareNextInstruction(InstructionBase instruction)
    {
        string inst = instruction.Instruction;

        Debug.Log(">>> " + instruction.DebugInfo());

        // First check whether the instruction contains a node and/or destination
        bool gotNode       = !graphAlgorithm.SkipDict[Util.SKIP_NO_ELEMENT].Contains(inst);
        bool noDestination = graphAlgorithm.SkipDict[Util.SKIP_NO_DESTINATION].Contains(inst);

        // List visual Update
        if (instruction is ListVisualInstruction)
        {
            // Only provide list visual support until <lvl>
            if (graphSettings.Difficulty > UtilGraph.LIST_VISUAL_MAX_DIFFICULTY)
            {
                return(1);
            }

            ListVisualInstruction listVisualInst = (ListVisualInstruction)instruction;
            listVisual.ExecuteInstruction(listVisualInst, true);

            //Debug.Log("List visual instruction: " + listVisualInst.DebugInfo());
        }
        else
        {
            Node node = null;

            if (gotNode)
            {
                if (instruction is TraverseInstruction)
                {
                    TraverseInstruction traverseInstruction = (TraverseInstruction)instruction;
                    //Debug.Log("Traverse instruction: " + traverseInstruction.DebugInfo());

                    // Get the Sorting element
                    node = traverseInstruction.Node;

                    // Hands out the next instruction
                    node.Instruction = traverseInstruction;

                    // Set goal
                    posManager.CurrentGoal = node;

                    // Reset if pointer must be used on the same node twice
                    if (traverseInstruction.VisitInst && pointer.prevNodeShot == node)
                    {
                        pointer.prevNodeShot = null;
                    }

                    // Reset position manager if the user already stands on top of the node
                    if (traverseInstruction.TraverseInst && posManager.ReportedNode == node)
                    {
                        posManager.ReportedNode = null;
                    }

                    // Give this sorting element permission to give feedback to progress to next intstruction
                    node.NextMove = NextIsUserMove(inst);

                    // Traverse instruction extra
                    switch (inst)
                    {
                    // Highlight the node we are currently going to work at
                    case UtilGraph.DEQUEUE_NODE_INST:
                    case UtilGraph.POP_INST:
                    case UtilGraph.PRIORITY_REMOVE_NODE:
                        // Hide all edge cost to make it easier to see node distances
                        if (graphSettings.GraphTask == UtilGraph.SHORTEST_PATH)
                        {
                            graphManager.MakeEdgeCostVisible(false);
                        }
                        break;

                    case UtilGraph.FOR_ALL_NEIGHBORS_INST:
                        // Make edge cost visible again
                        if (graphSettings.GraphTask == UtilGraph.SHORTEST_PATH)
                        {
                            graphManager.MakeEdgeCostVisible(true);
                        }
                        break;
                    }

                    // Perform list visual instruction in next step (when current instruction has been correctly performed)
                    if (traverseInstruction.ListVisualInstruction != null)
                    {
                        updateListVisualInstruction = traverseInstruction.ListVisualInstruction;
                    }
                }
                else if (instruction is ShortestPathInstruction)
                {
                    ShortestPathInstruction spInst = (ShortestPathInstruction)instruction;
                    //Debug.Log("Shortest path instruction: " + spInst.DebugInfo());

                    // Get the Sorting element
                    if (spInst.CurrentNode != null)
                    {
                        node = spInst.CurrentNode;
                    }
                    else
                    {
                        node = spInst.ConnectedNode;
                    }

                    // Hands out the next instruction
                    node.Instruction = spInst;

                    // Set goal
                    posManager.CurrentGoal = node;

                    // Give this sorting element permission to give feedback to progress to next intstruction
                    node.NextMove = NextIsUserMove(inst);

                    // Shortest path extra
                    switch (inst)
                    {
                    case UtilGraph.IF_DIST_PLUS_EDGE_COST_LESS_THAN:
                        // Turn off highlight effect of previous line
                        pseudoCodeViewer.ChangeColorOfText(8, Util.BLACKBOARD_TEXT_COLOR);

                        // Since we highlighted the color and/or text position of the node/edge we are working on (highlighting purpose) in the previous instruction, now we reset them
                        // Changed color of node
                        spInst.ConnectedNode.CurrentColor = UtilGraph.VISITED_COLOR;
                        // Reset text color/position of the edge cost
                        spInst.CurrentEdge.CurrentColor = UtilGraph.VISITED_COLOR;

                        // Perform sub task: calculate dist (current node) + edge cost to the connected node
                        if (!autoCalculation)
                        {
                            usingCalculator       = true;
                            pointer.AllowShooting = false;
                            calculator.InitCalculation(Calculator.GRAPH_TASK);
                            calculator.SpawnDeviceInfrontOfPlayer();
                        }
                        break;
                    }

                    // Perform list visual instruction in next step (when current instruction has been correctly performed)
                    if (spInst.ListVisualInstruction != null)
                    {
                        updateListVisualInstruction = spInst.ListVisualInstruction;
                    }
                }
            }
        }

        // Display help on blackboard
        if (graphSettings.Difficulty <= Util.PSEUDO_CODE_HIGHTLIGHT_MAX_DIFFICULTY)
        {
            WaitForSupportToComplete++;
            StartCoroutine(graphAlgorithm.UserTestHighlightPseudoCode(instruction, gotNode));// && !noDestination));
        }

        // InstructionBase extra
        switch (inst)
        {
        case UtilGraph.SET_ALL_NODES_TO_INFINITY:
            graphManager.SetAllNodesDist(UtilGraph.INF);
            break;

        case UtilGraph.SET_START_NODE_DIST_TO_ZERO:
            // Find start node and set distance to 0
            Node startNode = graphManager.StartNode;
            startNode.Dist = 0;

            // If list visual: update value
            if (Settings.Difficulty <= UtilGraph.LIST_VISUAL_MAX_DIFFICULTY)
            {
                listVisual.FindNodeRepresentation(startNode).UpdateSurfaceText(UtilGraph.DIST_UPDATE_COLOR);
            }
            break;

        case UtilGraph.MARK_END_NODE:
            Node endNode = graphManager.EndNode;
            endNode.CurrentColor          = UtilGraph.SHORTEST_PATH_COLOR;
            endNode.PrevEdge.CurrentColor = UtilGraph.SHORTEST_PATH_COLOR;
            break;

        case UtilGraph.END_FOR_LOOP_INST:
            if (graphSettings.Difficulty <= UtilGraph.LIST_VISUAL_MAX_DIFFICULTY)
            {
                listVisual.DestroyCurrentNode();
            }
            break;

        case UtilGraph.NO_PATH_FOUND:
        case Util.FINAL_INSTRUCTION:
            // No path found
            WaitForSupportToComplete++;
            StartCoroutine(FinishUserTest());
            break;
        }

        //Debug.Log("Got node: " + gotNode + ", no destination: " + noDestination);
        if (gotNode && !noDestination)
        {
            return(0);
        }
        //Debug.Log("Nothing to do for player, get another instruction");
        return(1);
    }