public float GetPriority(Node node)
 {
     for(int i = 0; i < values.Count; i++)
     {
         if (values[i] == node)
         {
             return priorities[i];
         }
     }
     return 0;
 }
 public Node GetNeighbor(Node node)
 {
     if (node == node1)
     {
         return node2;
     }
     else if (node == node2)
     {
         return node1;
     }
     else
     {
         return null;
     }
 }
        public void ReplacePriority(Node value, float priority)
        {
            int index = 0;
            for (int i = 0; i < values.Count; i++)
            {
                if (values[i] == value)
                {
                    index = i;
                }
            }

            values.RemoveAt(index);
            priorities.RemoveAt(index);

            values.Add(value);
            priorities.Add(priority);
        }
        public void Dequeue(out Node topValue, out float topPriority)
        {
            int bestIndex = 0;
            float bestPriority = priorities[0];
            for (int i = 1; i < priorities.Count; i++)
            {
                if (bestPriority > priorities[i])
                {
                    bestPriority = priorities[i];
                    bestIndex = i;
                }
            }


            topValue = values[bestIndex];
            topPriority = bestPriority;

            values.RemoveAt(bestIndex);
            priorities.RemoveAt(bestIndex);
        }
 public Edge(Node node1, Node node2, float length)
 {
     this.node1 = node1;
     this.node2 = node2;
     this.length = length;
 }
        public void BreadthFirstSearch()
        {
            //Set the distance to all nodes to infinity (i.e. Int32.MaxValue)
            if (nodeQueue.Count > 0)
            {
                curNode = nodeQueue.Dequeue();
                curNode.ChangeColor = Color.Yellow;

                //if we have found the target node
                if (curNode == nodeGrid[(int)end.X, (int)end.Y])
                {
                    hasResult = true;
                    targetPositions.Enqueue(curNode.Position);
                    //loop back through the backnodes to find the fastest path
                    while (curNode.BackNode != null)
                    {
                        curNode = curNode.BackNode.GetNeighbor(curNode);
                        curNode.ChangeColor = Color.Blue;
                        targetPositions.Enqueue(curNode.Position);
                    }
                    return;
                }

                //look through each neighbor to find who we have not checked yet.
                foreach (Edge edge in curNode.Neighbors)
                {
                    if (!edge.GetNeighbor(curNode).IsVisited && !edge.GetNeighbor(curNode).IsObstacle)
                    {
                        edge.GetNeighbor(curNode).IsVisited = true;
                        edge.GetNeighbor(curNode).BackNode = edge; //sets distance within this property: distance = curnode.GetDistance + 1;
                        nodeQueue.Enqueue(edge.GetNeighbor(curNode));
                    }
                }
            }
            else
            {
                //return error
            }
        }
        public Graph(GridCell[,] gridCell, int width, int height, HalfDeadCat cat)
        {
            myCat = cat;
            this.gridCell = gridCell;
            this.width = width;
            this.height = height;
            nodeGrid = new Node[width, height];
            searchType = SearchType.BREADTH;

            //Initializes all of the nodes
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    if (!gridCell[i, j].IsBlocked)
                        gridCell[i, j].ChangeColor = Color.CornflowerBlue;
                    nodeGrid[i, j] = new Node(gridCell[i, j], i, j);
                }
            }

            //Sets neighboring nodes for each node
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    //if node has four neighbors
                    if (i != 0 && i != width - 1 && j != 0 && j != height - 1)
                    {
                        nodeGrid[i, j].Neighbors = new List<Edge> {new Edge(nodeGrid[i, j], nodeGrid[i, j + 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i + 1, j], 1), new Edge(nodeGrid[i, j], nodeGrid[i, j - 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i - 1, j], 1) };
                    }
                    //if node has two neighbors
                    else if ((i == 0 || i == width - 1) && (j == 0 || j == height - 1))
                    {
                        if (i == 0 && j == 0)
                        {
                            nodeGrid[i, j].Neighbors = new List<Edge> { new Edge(nodeGrid[i, j], nodeGrid[i, j + 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i + 1, j], 1) };
                        }
                        else if (i == 0 && j == height - 1)
                        {
                            nodeGrid[i, j].Neighbors = new List<Edge> { new Edge(nodeGrid[i, j], nodeGrid[i + 1, j], 1), new Edge(nodeGrid[i, j], nodeGrid[i, j - 1], 1) };
                        }
                        else if (i == width - 1 && j == 0)
                        {
                            nodeGrid[i, j].Neighbors = new List<Edge> { new Edge(nodeGrid[i, j], nodeGrid[i, j + 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i - 1, j], 1) };
                        }
                        else if (i == width - 1 && j == height - 1)
                        {
                            nodeGrid[i, j].Neighbors = new List<Edge> { new Edge(nodeGrid[i, j], nodeGrid[i, j - 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i - 1, j], 1) };
                        }
                    }
                    //if node has three neighbors
                    else
                    {
                        if (i == 0)
                        {
                            nodeGrid[i, j].Neighbors = new List<Edge> { new Edge(nodeGrid[i, j], nodeGrid[i, j + 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i + 1, j], 1), new Edge(nodeGrid[i, j], nodeGrid[i, j - 1], 1) };
                            
                        }
                        else if (i == width - 1)
                        {
                            nodeGrid[i, j].Neighbors = new List<Edge> { new Edge(nodeGrid[i, j], nodeGrid[i, j + 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i, j - 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i - 1, j], 1) };
                        }
                        else if (j == 0)
                        {
                            nodeGrid[i, j].Neighbors = new List<Edge> { new Edge(nodeGrid[i, j], nodeGrid[i, j + 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i + 1, j], 1), new Edge(nodeGrid[i, j], nodeGrid[i - 1, j], 1) };
                        }
                        else if (j == height - 1)
                        {
                            nodeGrid[i, j].Neighbors = new List<Edge> { new Edge(nodeGrid[i, j], nodeGrid[i + 1, j], 1), new Edge(nodeGrid[i, j], nodeGrid[i, j - 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i - 1, j], 1) };
                        }
                    }
                }
            }
        }
        public void DijkstraSearch()
        {
            //Set the distance to all nodes to infinity (i.e. Int32.MaxValue)
            if (priorityQueue.Count > 0)
            {
                priorityQueue.Dequeue(out curNode, out topPriority);
                curNode.ChangeColor = Color.Yellow;



                //look through each neighbor to find who we have not checked yet.
                foreach (Edge edge in curNode.Neighbors)
                {
                    if (!edge.GetNeighbor(curNode).IsVisited && !edge.GetNeighbor(curNode).IsObstacle)
                    {
                        //if we have found the target node
                        if (edge.GetNeighbor(curNode) == nodeGrid[(int)end.X, (int)end.Y])
                        {
                            hasResult = true;
                            targetPositions.Enqueue(curNode.Position);
                            nodeGrid[(int)end.X, (int)end.Y].BackNode = edge;
                            curNode = nodeGrid[(int)end.X, (int)end.Y];

                            //loop back through the backnodes to find the fastest path
                            while (curNode.BackNode != null)
                            {
                                curNode = curNode.BackNode.GetNeighbor(curNode);
                                curNode.ChangeColor = Color.Blue;
                                targetPositions.Enqueue(curNode.Position);
                            }
                            return;
                        }

                        edge.GetNeighbor(curNode).IsVisited = true;
                        edge.GetNeighbor(curNode).BackNode = edge; //sets distance within this property: distance = curnode.GetDistance + 1;
                        priorityQueue.Enqueue(edge.GetNeighbor(curNode), curNode.Length + edge.Length);
                        edge.GetNeighbor(curNode).Length = curNode.Length + edge.Length;
                    }
                    else if (edge.GetNeighbor(curNode).IsVisited && !edge.GetNeighbor(curNode).IsObstacle)
                    {
                        if (edge.GetNeighbor(curNode).Length > curNode.Length + edge.Length)
                        {
                            priorityQueue.ReplacePriority(edge.GetNeighbor(curNode), curNode.Length + edge.Length);
                            edge.GetNeighbor(curNode).Length = curNode.Length + edge.Length;
                            edge.GetNeighbor(curNode).BackNode = edge;
                        }
                    }
                }
            }
            else
            {
                //return error
            }
        }
        public Graph(GridCell[,] gridCell, int width, int height, bool isDijkstra, HalfDeadCat cat)
        {
            myCat = cat;
            this.gridCell = gridCell;
            this.width = width;
            this.height = height;
            nodeGrid = new Node[width, height];
            if (isDijkstra)
            {
                searchType = SearchType.DIJKSTRA;
            }
            else
            {
                searchType = SearchType.ASTAR;
            }

            //Initializes all of the nodes
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    if (!gridCell[i, j].IsBlocked)
                        gridCell[i, j].ChangeColor = Color.CornflowerBlue;
                    nodeGrid[i, j] = new Node(gridCell[i, j], i, j);
                }
            }

            //Sets neighboring nodes for each node
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    //if node has 8 neighbors
                    if (i != 0 && i != width - 1 && j != 0 && j != height - 1)
                    {
                        nodeGrid[i, j].Neighbors = new List<Edge> { new Edge(nodeGrid[i, j], nodeGrid[i, j + 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i + 1, j], 1), new Edge(nodeGrid[i, j], nodeGrid[i, j - 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i - 1, j], 1),
                        new Edge(nodeGrid[i, j], nodeGrid[i - 1, j - 1], (float)Math.Sqrt(2)), new Edge(nodeGrid[i, j], nodeGrid[i + 1, j - 1], (float)Math.Sqrt(2)), new Edge(nodeGrid[i, j], nodeGrid[i - 1, j + 1], (float)Math.Sqrt(2)), new Edge(nodeGrid[i, j], nodeGrid[i + 1, j + 1], (float)Math.Sqrt(2)),};
                    }
                    //if node has 3 neighbors
                    else if ((i == 0 || i == width - 1) && (j == 0 || j == height - 1))
                    {
                        if (i == 0 && j == 0)
                        {
                            nodeGrid[i, j].Neighbors = new List<Edge> { new Edge(nodeGrid[i, j], nodeGrid[i, j + 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i + 1, j], 1), new Edge(nodeGrid[i, j], nodeGrid[i + 1, j + 1], (float)Math.Sqrt(2)) };
                        }
                        else if (i == 0 && j == height - 1)
                        {
                            nodeGrid[i, j].Neighbors = new List<Edge> { new Edge(nodeGrid[i, j], nodeGrid[i + 1, j], 1), new Edge(nodeGrid[i, j], nodeGrid[i, j - 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i + 1, j - 1], (float)Math.Sqrt(2)) };
                        }
                        else if (i == width - 1 && j == 0)
                        {
                            nodeGrid[i, j].Neighbors = new List<Edge> { new Edge(nodeGrid[i, j], nodeGrid[i, j + 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i - 1, j], 1), new Edge(nodeGrid[i, j], nodeGrid[i - 1, j + 1], (float)Math.Sqrt(2)) };
                        }
                        else if (i == width - 1 && j == height - 1)
                        {
                            nodeGrid[i, j].Neighbors = new List<Edge> { new Edge(nodeGrid[i, j], nodeGrid[i, j - 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i - 1, j], 1), new Edge(nodeGrid[i, j], nodeGrid[i - 1, j - 1], (float)Math.Sqrt(2)) };
                        }
                    }
                    //if node has 5 neighbors
                    else
                    {
                        if (i == 0)
                        {
                            nodeGrid[i, j].Neighbors = new List<Edge> { new Edge(nodeGrid[i, j], nodeGrid[i, j + 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i + 1, j], 1), new Edge(nodeGrid[i, j], nodeGrid[i, j - 1], 1),
                            new Edge(nodeGrid[i, j], nodeGrid[i + 1, j + 1], (float)Math.Sqrt(2)), new Edge(nodeGrid[i, j], nodeGrid[i + 1, j - 1], (float)Math.Sqrt(2))};

                        }
                        else if (i == width - 1)
                        {
                            nodeGrid[i, j].Neighbors = new List<Edge> { new Edge(nodeGrid[i, j], nodeGrid[i, j + 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i, j - 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i - 1, j], 1),
                            new Edge(nodeGrid[i, j], nodeGrid[i - 1, j - 1], (float)Math.Sqrt(2)), new Edge(nodeGrid[i, j], nodeGrid[i - 1, j + 1], (float)Math.Sqrt(2))};
                        }
                        else if (j == 0)
                        {
                            nodeGrid[i, j].Neighbors = new List<Edge> { new Edge(nodeGrid[i, j], nodeGrid[i, j + 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i + 1, j], 1), new Edge(nodeGrid[i, j], nodeGrid[i - 1, j], 1),
                            new Edge(nodeGrid[i, j], nodeGrid[i - 1, j + 1], (float)Math.Sqrt(2)), new Edge(nodeGrid[i, j], nodeGrid[i + 1, j + 1], (float)Math.Sqrt(2))};
                        }
                        else if (j == height - 1)
                        {
                            nodeGrid[i, j].Neighbors = new List<Edge> { new Edge(nodeGrid[i, j], nodeGrid[i + 1, j], 1), new Edge(nodeGrid[i, j], nodeGrid[i, j - 1], 1), new Edge(nodeGrid[i, j], nodeGrid[i - 1, j], 1),
                            new Edge(nodeGrid[i, j], nodeGrid[i - 1, j - 1], (float)Math.Sqrt(2)), new Edge(nodeGrid[i, j], nodeGrid[i + 1, j - 1], (float)Math.Sqrt(2))};
                        }
                    }
                }
            }
        }
 public void Enqueue(Node value, float priority)
 {
     values.Add(value);
     priorities.Add(priority);
 }