private void mouseClick(object sender, MouseButtonEventArgs e) { CheckPath(); // Pobiera miejsce ze współrzędnych kliknięcia, jeśli nie ma jest równy null Node location = currentMap.getNodeAtPoint((int)e.GetPosition(dataCanvas).X, (int)e.GetPosition(dataCanvas).Y); if ((bool)mode.IsChecked) // Jeśli tryb tworzenia jest włączony { if (location != null) // sprawdza czy kliknęliśmy miejsce czy puste pole { if (currentMap.selectedLocation != null) // Jeśli już raz zaznaczyliśmy jakąś lokację czyli nie jest ona równa null { if (!currentMap.selectedLocation.Equals(location)) // Oraz jeśli ta wcześniejsza lokacja nie jest tą samą którą zaznaczyliśmy teraz { foreach (Edge edge in currentMap.selectedLocation.Edges) { if (edge.LocB.Equals(location)) { return; } } // Tworzy połączenie pomiędzy wcześniej wybraną i teraz zaznaczoną lokacją DeselectNodes(location); if ((bool)scale.IsChecked) // Koszt połączenia to albo wartość od użytkownika albo wyznaczona na podstawie prawdziwych odległości { currentMap.CreateEdges(int.Parse(costLabel.Content.ToString()), location, dataCanvas, wayMode.IsChecked.Value); } else { currentMap.CreateEdges(Heuristic.HeuristicValue(currentMap.selectedLocation, location), location, dataCanvas, wayMode.IsChecked.Value); } } else // Jeśli lokację są takie same, odznacza je { DeselectNodes(); currentMap.selectedLocation = null; } } else // Jeśli wcześniej nie było wybranej lokacji to wybiera tą klikniętą { currentMap.SelectNode(location); } } } else { if (location != null) { if (currentMap.selectedLocation != null) // Jeśli tryb tw. jest wyłączony, kliknięcie nie jest równe null oraz już poprzednio zostało wybrane jedno miejsce uruchamiany jest algorytm { if (!location.Equals(currentMap.selectedLocation)) { if (ASTAR.IsChecked.Value) { path = aStar.CostSearch(currentMap.selectedLocation, location, true); } else { path = aStar.CostSearch(currentMap.selectedLocation, location, false); } CheckPath(); DeselectNodes(location); foreach (Node next in currentMap.places) // Po znalezieniu trasy resetuje wartości które były używane w algorytmie, umożliwiając ponowne jego uruchomienie { next.Ancestor = null; next.TotalCost = 0; } location = null; currentMap.selectedLocation = null; } else { DeselectNodes(); currentMap.selectedLocation = null; } } else { currentMap.SelectNode(location); } } } }
public List <Node> CostSearch(Node startPoint, Node goalPoint, bool useHeuristic) { if (startPoint.Successors.Count == 0) { return(null); } costQueue = new PriorityQueue(); closedList = new List <Node>(); costQueue.Enqueue(startPoint); costQueue[0].Ancestor = new Node("Beginner"); while (costQueue.Count != 0) { Node current = costQueue.Dequeue(); closedList.Add(current); if (current.Equals(goalPoint)) { Node beginning = new Node(" "); Queue <Node> myRoute = new Queue <Node>(); List <Node> route = new List <Node>(); myRoute.Enqueue(current); route.Add(current); while (!beginning.Equals(startPoint)) { beginning = myRoute.Dequeue().Ancestor; if (beginning == null) { break; } myRoute.Enqueue(beginning); route.Add(beginning); } costQueue = null; return(route); } // Algorytm uruchamiany jest synchronicznie gdyż udało mi się go na tyle zoptymalizować że nawet przy większych mapach // czas wyszukiwania jest praktycznie niezauważalny, zostawiłem jednak na przyszłość prostą możliwość uruchamiania go asynchronicznie, // w nnowym wątku z wykorzystaniem słów kluczowych async i await // await Task.Run(() => //{ for (int i = 0; i < current.Successors.Count; i++) { tempCost = 0; if (!closedList.Contains(current.Successors[i])) { if (!costQueue.Contains(current.Successors[i])) { costQueue.Enqueue(current.Successors[i]); current.Successors[i].Ancestor = current; foreach (Edge e in current.Successors[i].Ancestor.Edges) { if (e.LocB == current.Successors[i]) { tempCost = e.Cost; break; } } current.Successors[i].TotalCost = current.TotalCost + tempCost; current.Successors[i].FullValue = current.Successors[i].TotalCost + Heuristic.HeuristicValue(current.Successors[i], goalPoint); if (!useHeuristic) { current.Successors[i].FullValue = current.Successors[i].TotalCost; } } else { Node potentiallyBetterNeighbor = CloneNode(current.Successors[i]); potentiallyBetterNeighbor.Ancestor = current; foreach (Edge e in potentiallyBetterNeighbor.Ancestor.Edges) { if (e.LocB == current.Successors[i]) { tempCost = e.Cost; break; } } potentiallyBetterNeighbor.TotalCost = current.TotalCost + tempCost; if (potentiallyBetterNeighbor.TotalCost < current.Successors[i].TotalCost) { current.Successors[i].Ancestor = potentiallyBetterNeighbor.Ancestor; current.Successors[i].TotalCost = potentiallyBetterNeighbor.TotalCost; current.Successors[i].FullValue = current.Successors[i].TotalCost + Heuristic.HeuristicValue(current.Successors[i], goalPoint); if (!useHeuristic) { current.Successors[i].FullValue = current.Successors[i].TotalCost; } } } } costQueue.CheckPriority(); } //}); } return(null); }
public List <Node> CostSearch(Node startPoint, Node goalPoint, bool useHeuristic) { if (startPoint.Successors.Count == 0) { return(null); } costQueue = new PriorityQueue(); closedList = new List <Node>(); costQueue.Enqueue(startPoint); costQueue[0].Ancestor = new Node("Beginner"); while (costQueue.Count != 0) { Node current = costQueue.Dequeue(); closedList.Add(current); if (current.Equals(goalPoint)) { Node beginning = new Node(" "); Queue <Node> myRoute = new Queue <Node>(); List <Node> route = new List <Node>(); myRoute.Enqueue(current); route.Add(current); while (!beginning.Equals(startPoint)) { beginning = myRoute.Dequeue().Ancestor; if (beginning == null) { break; } myRoute.Enqueue(beginning); route.Add(beginning); } costQueue = null; return(route); } for (int i = 0; i < current.Successors.Count; i++) { tempCost = 0; if (!closedList.Contains(current.Successors[i])) { if (!costQueue.Contains(current.Successors[i])) { costQueue.Enqueue(current.Successors[i]); current.Successors[i].Ancestor = current; foreach (Edge e in current.Successors[i].Ancestor.Edges) { if (e.LocB == current.Successors[i]) { tempCost = e.Cost; break; } } current.Successors[i].TotalCost = current.TotalCost + tempCost; current.Successors[i].FullValue = current.Successors[i].TotalCost + Heuristic.HeuristicValue(current.Successors[i], goalPoint); if (!useHeuristic) { current.Successors[i].FullValue = current.Successors[i].TotalCost; } } else { Node potentiallyBetterNeighbor = CloneNode(current.Successors[i]); potentiallyBetterNeighbor.Ancestor = current; foreach (Edge e in potentiallyBetterNeighbor.Ancestor.Edges) { if (e.LocB == current.Successors[i]) { tempCost = e.Cost; break; } } potentiallyBetterNeighbor.TotalCost = current.TotalCost + tempCost; if (potentiallyBetterNeighbor.TotalCost < current.Successors[i].TotalCost) { current.Successors[i].Ancestor = potentiallyBetterNeighbor.Ancestor; current.Successors[i].TotalCost = potentiallyBetterNeighbor.TotalCost; current.Successors[i].FullValue = current.Successors[i].TotalCost + Heuristic.HeuristicValue(current.Successors[i], goalPoint); if (!useHeuristic) { current.Successors[i].FullValue = current.Successors[i].TotalCost; } } } } costQueue.CheckPriority(); } } return(null); }