public override bool Step(object sender)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            int visualizationDelay = model.getSimulation().get(View.ViewNumericUpDown.VisualizationDelay);

            while (open.Count > 0)
            {
                /* check if the run has been cancelled */
                if (worker.CancellationPending)
                    return false;

                /* pick the node in the open list with the shortest distance */
                current = getNext(open);

                if (current == null)
                    return false;

                if (current.isEqual(agent.getNode(Agent.NodeType.Target)) | (current.getCost(Node.Cost.Total) == double.MaxValue))
                    break;

                open.Remove(current);
                closed.Add(current);

                agent.getCounters().incNodesEvaluated();

                /* update current node visualizations when put on closed list */
                if (visualizationPaintOK(current, agent, model))
                {
                    Node sharedMapNode = model.getMap().getNodeAtLocation(current.getPosition());
                    int count = agent.getCounters().getNodesEvaluated();
                    sharedMapNode.repaintNode(Color.Pink, Color.Black, agent.getCounters().getNodesEvaluated().ToString());
                    Thread.Sleep(visualizationDelay);
                }

                /* get neighbors that are on the open list only */
                neighbors.Clear();
                neighbors = agent.getMap().getNeighbors(agent, current, open, fovMethod);

                foreach (Node node in neighbors)
                {
                    /* calculate the new distance */
                    double distance = current.getCost(Node.Cost.Total) + current.getDistance(node, fovMethod);

                    /* if distance is lower then replace */
                    if (distance < node.getCost(Node.Cost.Total))
                    {
                        node.setCost(Node.Cost.Total, distance);
                        node.setParent(current);

                        if (!closed.Contains(node))
                        {
                            if (visualizationPaintOK(node, agent, model))
                            {
                                Node sharedMapNode = model.getMap().getNodeAtLocation(node.getPosition());
                                int count = agent.getCounters().getNodesEvaluated();
                                sharedMapNode.repaintNode(Color.LightGreen, Color.Black, agent.getCounters().getNodesEvaluated().ToString());
                                Thread.Sleep(visualizationDelay);
                            }
                        }
                    }
                }
            }

            return checkTarget(model, agent, current);
        }
        public override bool Step(object sender)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            int visualizationDelay = model.getSimulation().get(View.ViewNumericUpDown.VisualizationDelay);

            /* run algorithm on agent's viewable map to determine the next step */
            while (open.Count > 0)
            {
                /* check if the run has been cancelled */
                if (worker.CancellationPending)
                    return false;

                /* get the next node */
                current = getNext(open);

                if (current == null)
                    return false;

                /* check if target node has been reached */
                Node target = agent.getNode(Agent.NodeType.Target);
                if (target != null && current.isEqual(target))
                    break;

                /* move node from open list to closed list */
                open.Remove(current);
                closed.Add(current);

                /* update current node visualizations when put on closed list */
                if (visualizationPaintOK(current, agent, model))
                {
                    Node sharedMapNode = model.getMap().getNodeAtLocation(current.getPosition());
                    int count = agent.getCounters().getNodesEvaluated();
                    sharedMapNode.repaintNode(Color.Pink, Color.Black, sharedMapNode.Text);
                    Thread.Sleep(visualizationDelay);
                }

                /* get the neighbors */
                neighbors.Clear();
                neighbors = agent.getMap().getNeighbors(agent, current, null, fovMethod);

                /* add neighbor's to open list if not already there */
                foreach (Node node in neighbors)
                {
                    /* skip nodes that are already on the closed list */
                    if (closed.Contains(node))
                        continue;

                    /* calculate the new movement cost */
                    double newMovementCost = current.getCost(Node.Cost.Movement) + current.getDistance(node, fovMethod);

                    if (!open.Contains(node) || newMovementCost < node.getCost(Node.Cost.Movement))
                    {
                        /* save the parent node */
                        node.setParent(current);

                        /* update the movement cost */
                        node.setCost(Node.Cost.Movement, newMovementCost);

                        /* calculate the heuristic cost */
                        node.setCost(Node.Cost.Heuristic, node.getDistance(agent.getNode(Agent.NodeType.Target), heuristicMethod));

                        /* update the f-score */
                        node.setCost(Node.Cost.Total, node.getCost(Node.Cost.Movement) + node.getCost(Node.Cost.Heuristic));

                        /* add to open list if not already there */
                        if (!open.Contains(node))
                        {
                            open.Add(node);

                            /* increment nodes evaluated only when nodes are added to open list */
                            agent.getCounters().incNodesEvaluated();

                            /* visualizations */
                            if (visualizationPaintOK(node, agent, model))
                            {
                                Node sharedMapNode = model.getMap().getNodeAtLocation(node.getPosition());
                                int count = agent.getCounters().getNodesEvaluated();
                                sharedMapNode.repaintNode(Color.LightGreen, Color.Black, count.ToString());
                                Thread.Sleep(visualizationDelay);
                            }
                        }
                    }
                }
            }

            return checkTarget(model, agent, current); ;
        }
        protected void takeStep(Agent agent, Node algorithmCurrent, Model model)
        {
            /* check to see if we didn't move at all */
            if (algorithmCurrent.isEqual(agent.getNode(Agent.NodeType.Current)))
                return;

            /* check to see if we need to backtrack */
            while (!algorithmCurrent.getParent().isEqual(agent.getNode(Agent.NodeType.Current)))
                algorithmCurrent = algorithmCurrent.getParent();

            /* take a step! */
            agent.setNode(Agent.NodeType.Current, algorithmCurrent);

            /* increment step counter */
            agent.getCounters().incSteps();
        }
        protected bool checkTarget(Model model, Agent agent, Node algorithmCurrent)
        {
            bool targetReached;

            /* target is target node if target is not null */
            targetReached = algorithmCurrent.isEqual(agent.getNode(Agent.NodeType.Target));

            /* take step if target is reached */
            if (targetReached)
                takeStep(agent, algorithmCurrent, model);

            return targetReached;
        }
 public bool isSpecialNode(Node node)
 {
     foreach (Agent a in agents)
     {
         if (node.isEqual(a.getNode(Agent.NodeType.Start)) | node.isEqual(a.getNode(Agent.NodeType.Finish)))
             return true;
     }
     return false;
 }
 public Agent getSpecialNodeAgent(Node node)
 {
     foreach (Agent a in agents)
     {
         if (node.isEqual(a.getNode(Agent.NodeType.Start)) | node.isEqual(a.getNode(Agent.NodeType.Finish)))
             return a;
     }
     return null;
 }