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); ;
        }
 public bool isEqual(Node a)
 {
     return position.Equals(a.getPosition());
 }
        public double getDistance(Node a, Method method)
        {
            double dx = Math.Abs(a.getPosition().X - this.position.X);
            double dy = Math.Abs(a.getPosition().Y - this.position.Y);

            switch (method)
            {
                case Method.Manhattan:
                    return dx + dy;
                case Method.Euclidean:
                    return Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2));
                case Method.EuclideanSquared:
                    return Math.Pow(dx, 2) + Math.Pow(dy, 2);
                case Method.Chebyshev:
                    return Math.Max(dx, dy);
                default:
                    throw new Exception("method not defined");
            }
        }
 public bool isAdjacent(Node node, int max)
 {
     /*     0 1 2
      *     _ _ _
      * 0  |_|_|_|
      * 1  |_|_|_|
      * 2  |_|_|_|
      *
      *   */
     try
     {
         if (node.getPosition().X - 1 == this.position.X && node.getPosition().Y + 1 == this.position.Y)
             return true;
         if (node.getPosition().X - 0 == this.position.X && node.getPosition().Y + 1 == this.position.Y)
             return true;
         if (node.getPosition().X + 1 == this.position.X && node.getPosition().Y + 1 == this.position.Y)
             return true;
         if (node.getPosition().X - 1 == this.position.X && node.getPosition().Y + 0 == this.position.Y)
             return true;
         if (node.getPosition().X - 0 == this.position.X && node.getPosition().Y + 0 == this.position.Y)
             return true;
         if (node.getPosition().X + 1 == this.position.X && node.getPosition().Y + 0 == this.position.Y)
             return true;
         if (node.getPosition().X - 1 == this.position.X && node.getPosition().Y - 1 == this.position.Y)
             return true;
         if (node.getPosition().X - 0 == this.position.X && node.getPosition().Y - 1 == this.position.Y)
             return true;
         if (node.getPosition().X + 1 == this.position.X && node.getPosition().Y - 1 == this.position.Y)
             return true;
     }
     catch
     {
         return false;
     }
     return false;
 }