示例#1
0
    public override IEnumerator ExecuteDemoInstruction(InstructionBase instruction, bool increment)
    {
        Node currentNode = null, connectedNode = null;
        Edge currentEdge = null, prevEdge = null;

        // Gather information from instruction
        if (instruction is TraverseInstruction)
        {
            TraverseInstruction travInst = (TraverseInstruction)instruction;
            if (instruction.Instruction == UtilGraph.ADD_NODE || instruction.Instruction == UtilGraph.PRIORITY_REMOVE_NODE || instruction.Instruction == UtilGraph.FOR_ALL_NEIGHBORS_INST)
            {
                currentNode = travInst.Node;
            }
            else
            {
                connectedNode = travInst.Node;
            }

            currentEdge = travInst.PrevEdge;

            // Do list visual instruction if there is one
            if (travInst.ListVisualInstruction != null)
            {
                graphMain.ListVisual.ExecuteInstruction(travInst.ListVisualInstruction, increment);
            }
        }
        else if (instruction is ShortestPathInstruction)
        {
            ShortestPathInstruction spInst = (ShortestPathInstruction)instruction;
            currentNode   = spInst.CurrentNode;
            connectedNode = spInst.ConnectedNode;
            currentEdge   = spInst.CurrentEdge;
            prevEdge      = spInst.PrevEdge;


            // Do list visual instruction if there is one
            if (spInst.ListVisualInstruction != null)
            {
                graphMain.ListVisual.ExecuteInstruction(spInst.ListVisualInstruction, increment);
            }
        }
        else if (instruction is InstructionLoop)
        {
            i = ((InstructionLoop)instruction).I;
            //j = ((InstructionLoop)instruction).J;
            //k = ((InstructionLoop)instruction).K;
        }

        // Remove highlight from previous instruction
        pseudoCodeViewer.ChangeColorOfText(prevHighlightedLineOfCode, Util.BLACKBOARD_TEXT_COLOR);

        // Gather part of code to highlight
        int lineOfCode = Util.NO_VALUE;

        useHighlightColor = Util.HIGHLIGHT_STANDARD_COLOR;
        switch (instruction.Instruction)
        {
        case Util.FIRST_INSTRUCTION:
            lineOfCode = 0;
            if (increment)
            {
                SetNodePseudoCode(graphMain.GraphManager.StartNode, 0);
            }
            else
            {
                startNodeAlpha = 's';
            }
            break;

        case UtilGraph.SET_ALL_NODES_TO_INFINITY:
            lineOfCode = 1;
            if (increment)
            {
                graphMain.GraphManager.SetAllNodesDist(UtilGraph.INF);
            }
            else
            {
                graphMain.GraphManager.SetAllNodesDist(UtilGraph.INIT_NODE_DIST);
            }
            break;

        case UtilGraph.EMPTY_LIST_CONTAINER:
            lineOfCode = 2;
            break;

        case UtilGraph.ADD_NODE:
            SetNodePseudoCode(currentNode, 0);     // start node
            lineOfCode = 3;
            if (increment)
            {
                currentNode.Visited = ((TraverseInstruction)instruction).VisitInst;
            }
            else
            {
                currentNode.Visited = !((TraverseInstruction)instruction).VisitInst;
            }
            break;

        case UtilGraph.SET_START_NODE_DIST_TO_ZERO:
            lineOfCode = 4;
            if (increment)
            {
                startNode.Dist = 0;
            }
            else
            {
                startNode.Dist = UtilGraph.INF;
            }

            // Update list visual
            ListVisualInstruction setStartNodeToZero = new ListVisualInstruction(UtilGraph.SET_START_NODE_DIST_TO_ZERO, 0, startNode, 0);
            graphMain.ListVisual.ExecuteInstruction(setStartNodeToZero, increment);
            break;

        case UtilGraph.WHILE_LIST_NOT_EMPTY_INST:
            lineOfCode        = 5;
            lengthOfList      = i.ToString();
            useHighlightColor = UseConditionColor(i != 0);
            break;

        case UtilGraph.PRIORITY_REMOVE_NODE:
            lineOfCode = 6;

            if (increment)
            {
                // Hide all edge cost to make it easier to see node distances
                graphMain.GraphManager.MakeEdgeCostVisible(false);
                SetNodePseudoCode(currentNode, 1);

                yield return(demoStepDuration);

                // Show the next node we'll work from
                currentNode.CurrentColor = UtilGraph.TRAVERSE_COLOR;
                currentNode.DisplayEdgeCost(true);

                // Display edge costs again
                graphMain.GraphManager.MakeEdgeCostVisible(true);
            }
            else
            {
                currentNode.CurrentColor = UtilGraph.VISITED_COLOR;
                currentNode.DisplayEdgeCost(false);
            }

            break;

        case UtilGraph.FOR_ALL_NEIGHBORS_INST:
            lineOfCode = 7;

            if (increment)
            {
                if (i != UtilGraph.NEIGHBORS_VISITED)
                {
                    SetNodePseudoCode(currentNode, 1);
                }

                useHighlightColor = UseConditionColor(i != UtilGraph.NEIGHBORS_VISITED);
            }
            else
            {
                if (currentNode == startNode)
                {
                    node1Alpha = 'w';
                }
            }
            break;

        case UtilGraph.RELAX_NEIGHBOR_NODE:
            SetNodePseudoCode(connectedNode, 2);
            lineOfCode = 8;

            if (increment)
            {
                connectedNode.Visited = ((TraverseInstruction)instruction).VisitInst;
                if (currentEdge != null)
                {
                    currentEdge.CurrentColor = UtilGraph.VISITED_COLOR;
                }
            }
            else
            {
                connectedNode.Visited = !((TraverseInstruction)instruction).VisitInst;
                if (currentEdge != null)
                {
                    currentEdge.CurrentColor = Util.STANDARD_COLOR;
                }
            }

            break;

        case UtilGraph.IF_DIST_PLUS_EDGE_COST_LESS_THAN:
            lineOfCode = 9;

            if (increment)
            {
                SetNodePseudoCode(connectedNode, 2);
                edgeCost           = currentEdge.Cost;
                ifStatementContent = CreateIfStatementContent(currentNode.Dist, edgeCost, connectedNode.Dist);
            }
            else
            {
                // TODO
            }
            break;

        case UtilGraph.UPDATE_CONNECTED_NODE_DIST:
            lineOfCode = 10;
            if (increment)
            {
                connectedNode.Dist = ((ShortestPathInstruction)instruction).ConnectedNodeNewDist;
            }
            else
            {
                connectedNode.Dist = ((ShortestPathInstruction)instruction).ConnectedNodeOldDist;
            }
            break;

        case UtilGraph.UPDATE_CONNECTED_NODE_PREV_EDGE:
            lineOfCode = 11;
            if (increment)
            {
                connectedNode.PrevEdge = prevEdge;
            }
            else
            {
                connectedNode.PrevEdge = ((ShortestPathInstruction)instruction).OldPrevEdge;
            }
            break;

        case UtilGraph.HAS_NODE_REPRESENTATION:     // update/add
            lineOfCode = 12;
            ListVisualInstruction listVisualInst = (ListVisualInstruction)instruction;
            graphMain.ListVisual.ExecuteInstruction(listVisualInst, increment);
            break;

        case UtilGraph.END_IF_INST:
            lineOfCode = 13;
            break;

        case UtilGraph.END_FOR_LOOP_INST:
            lineOfCode = 14;
            if (this.currentNode != null)
            {
                this.currentNode.Traversed = increment;
            }

            // Destroy current node in list visual
            graphMain.ListVisual.ExecuteInstruction(new ListVisualInstruction(UtilGraph.DESTROY_CURRENT_NODE, Util.NO_INSTRUCTION_NR, this.currentNode), increment);
            break;

        case UtilGraph.END_WHILE_INST:
            lineOfCode      = 15;
            IsTaskCompleted = increment;
            break;
        }
        prevHighlightedLineOfCode = lineOfCode;

        // Highlight part of code in pseudocode
        yield return(HighlightPseudoCode(CollectLine(lineOfCode), useHighlightColor));

        graphMain.WaitForSupportToComplete--;
    }
示例#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);
    }
示例#3
0
    // Update the node status based on the instruction
    protected void UpdateNodeState()
    {
        if (nodeInstruction != null)
        {
            // Debugging
            instruction = nodeInstruction.Instruction;
            status      = nodeInstruction.Status;

            // This node is the next to be visited (shot at)
            if (nodeInstruction is TraverseInstruction)
            {
                TraverseInstruction travInst = (TraverseInstruction)nodeInstruction;

                // If visit (shoot at node)
                if (travInst.VisitInst)
                {
                    visitNextMove = true;

                    if (graphMain.Settings.Difficulty <= UtilGraph.ANIMATION_DIRECTION_MAX_DIFFICULTY)
                    {
                        animator.SetBool("NodeCheck", true);
                    }
                }

                // This node is the next to be traversed (player move to node)
                if (travInst.TraverseInst)
                {
                    traverseNextMove = true;

                    if (graphMain.Settings.Difficulty <= UtilGraph.ANIMATION_DIRECTION_MAX_DIFFICULTY)
                    {
                        animator.SetBool("NodeTraverse", true);
                    }
                }

                // Set the edge between the node we traversed from to reach this node
                if (travInst.PrevEdge != null)
                {
                    switch (algorithm)
                    {
                    case Util.BFS:
                    case Util.DFS:
                    case Util.DFS_RECURSIVE:
                        prevEdge = travInst.PrevEdge;
                        break;

                    case Util.DIJKSTRA:
                        currentEdge = travInst.PrevEdge; break;
                    }
                }
            }
            else if (nodeInstruction is ShortestPathInstruction)
            {
                ShortestPathInstruction spInst = (ShortestPathInstruction)nodeInstruction;

                switch (spInst.Instruction)
                {
                case UtilGraph.UPDATE_CONNECTED_NODE_DIST:
                    if (spInst.CurrentNode == this)
                    {
                        spInst.ConnectedNode.Dist = spInst.ConnectedNodeNewDist;
                    }
                    else if (spInst.ConnectedNode == this)
                    {
                        Dist = spInst.ConnectedNodeNewDist;
                    }
                    break;

                case UtilGraph.UPDATE_CONNECTED_NODE_PREV_EDGE:
                    if (spInst.CurrentNode == this)
                    {
                        spInst.ConnectedNode.PrevEdge = spInst.PrevEdge;
                    }
                    else if (spInst.ConnectedNode == this)
                    {
                        prevEdge = spInst.PrevEdge;
                    }

                    break;
                }
            }
        }
    }
示例#4
0
    protected override void UserTestUpdate()
    {
        // If a node is set to be visited or traversed, wait until it has been achieved
        if (userTestGoalActive && !posManager.PlayerWithinGoalPosition)
        {
            return;
        }
        else
        {
            userTestGoalActive = false;
        }

        // First check if user test setup is complete
        if (userTestManager.HasInstructions())
        {
            // If a calculation is required to progress in the algorithm
            if (algorithmName == Util.DIJKSTRA && usingCalculator)
            {
                // Check if it's in process and whether the equal button has been clicked
                if (calculator.CalculationInProcess && calculator.EqualButtonClicked)
                {
                    InstructionBase         inst   = userTestManager.GetInstruction();
                    ShortestPathInstruction spInst = null;
                    if (inst != null && inst.Instruction == UtilGraph.IF_DIST_PLUS_EDGE_COST_LESS_THAN)
                    {
                        spInst = ((ShortestPathInstruction)userTestManager.GetInstruction());
                    }
                    else
                    {
                        return;
                    }

                    // When equal buttons has been clicked, check  whether the input data is correct
                    int node1Dist = spInst.CurrentNode.Dist;
                    int edgeCost  = spInst.CurrentEdge.Cost;
                    int node2Dist = spInst.ConnectedNode.Dist;

                    bool correctUserInput = calculator.ControlUserInput(node1Dist, edgeCost, node2Dist);

                    // If input data was correct, then progress to next instruction (add only one)
                    if (correctUserInput && userTestManager.ReadyForNext != userTestManager.UserActionToProceed)
                    {
                        userTestManager.IncrementTotalCorrect();
                        userTestManager.ReadyForNext += 1;

                        ((Dijkstra)graphAlgorithm).IfStatementContent = calculator.IfStatementContent();
                        pseudoCodeViewer.SetCodeLine(((Dijkstra)graphAlgorithm).CollectLine(9), Util.BLACKBOARD_TEXT_COLOR);
                        calculator.FeedbackReceived = true;
                    }
                    else if (!calculator.FeedbackReceived)
                    {
                        userTestManager.Mistake();
                        calculator.FeedbackReceived = true;
                    }
                }
                else if (!calculator.CalculationInProcess)
                {
                    // Feedback is given on the calculator, so when calculationInProcess = false (calculation completed), we continue
                    usingCalculator       = false;
                    pointer.AllowShooting = true;
                }
            }

            // Continue when user has finished sub task, or else whenever ready
            if (userTestManager.ReadyForNext == userTestManager.UserActionToProceed)
            {
                if (graphSettings.Difficulty <= UtilGraph.LIST_VISUAL_MAX_DIFFICULTY && updateListVisualInstruction != null)
                {
                    listVisual.ExecuteInstruction(updateListVisualInstruction, true);
                    updateListVisualInstruction = null;
                }

                // Reset counter
                userTestManager.ReadyForNext = 0;

                // Check if we still have any instructions
                if (!userTestManager.HasInstructions()) // ???
                {
                    graphAlgorithm.IsTaskCompleted = true;
                }
                else
                {
                    // Still got instructions?
                    bool hasInstruction = userTestManager.IncrementToNextInstruction();

                    // Hot fix - solve in some other way?
                    if (hasInstruction)
                    {
                        userTestManager.ReadyForNext += PrepareNextInstruction(userTestManager.GetInstruction());
                    }
                }
            }

            if (Settings.UserTestScore)
            {
                blackboard.ChangeText(1, userTestManager.FillInBlackboard());
            }
        }
    }