public static bool Build(List <CycleElement> cycle, List <EngagedElement> plan) { _plan = plan; _cycle = cycle.First(); while (true) { // using try, catch to leave recursion try { cycle.Clear(); cycle.Add(_cycle); if (CycleBuilder.BuildCycle(cycle)) { return(true); } } catch (Exception) { } } }
public static bool BuildCycle(List <CycleElement> cycle) { CycleElement head = cycle.First();//destination CycleElement currentElement = cycle.Last(); // якщо є початок і цикл вміщує більше ніж 2 елемента, то повертаємося var engaged = _plan.FindAll(element => element.Position.X <currentElement.Position.X && element.Position.Y == currentElement.Position.Y || element.Position.X == currentElement.Position.X && element.Position.Y> currentElement.Position.Y || element.Position.X > currentElement.Position.X && element.Position.Y == currentElement.Position.Y || element.Position.X == currentElement.Position.X && element.Position.Y < currentElement.Position.Y).ToList(); if (engaged.Any(element => element.Position.X == cycle.First().Position.X&& element.Position.Y == cycle.First().Position.Y) && cycle.Count > 2) { return(true); } // шукаємо елементи зверху engaged = _plan.FindAll(element => element.Position.X < currentElement.Position.X && element.Position.Y == currentElement.Position.Y).ToList(); if (engaged.Count > 0) { if (!CheckForInterference(cycle, engaged)) { var elem = engaged.Find(e => e.Position.X == engaged.Min(k => k.Position.X)); engaged.Clear(); engaged.Add(elem); if (CheckCycleElement(engaged.ElementAt(0), head) && !cycle.ElementAt(cycle.Count() - 2).Equals(head)) { return(true); //якщо я знайшов початок і він не передує мені } if (!IsEqual(engaged.ElementAt(0), (head))) //на голову рекурсії не запускаєм { cycle.Add(new CycleElement(engaged.ElementAt(0).Position.X, engaged.ElementAt(0).Position.Y, cycle.Last().GetSign() * (-1))); // рекурсивно до цього елементу if (BuildCycle(cycle)) { return(true); } } } } // шукаємо елементи з правого боку engaged = _plan.FindAll(element => element.Position.X == currentElement.Position.X && element.Position.Y > currentElement.Position.Y).ToList(); if (engaged.Count > 0) { if (!CheckForInterference(cycle, engaged)) { var elem = engaged.Find(e => e.Position.Y == engaged.Max(k => k.Position.Y)); engaged.Clear(); engaged.Add(elem); if (CheckCycleElement(engaged.ElementAt(0), head) && !cycle.ElementAt(cycle.Count() - 2).Equals(head)) { return(true); //якщо я знайшов початок і він не передує мені } if (!IsEqual(engaged.ElementAt(0), (head))) { cycle.Add(new CycleElement(engaged.ElementAt(0).Position.X, engaged.ElementAt(0).Position.Y, cycle.Last().GetSign() * (-1))); // рекурсивно до цього елементу if (BuildCycle(cycle)) { return(true); } } } } // шукаємо елементи знизу engaged = _plan.FindAll(element => element.Position.X > currentElement.Position.X && element.Position.Y == currentElement.Position.Y).ToList(); if (engaged.Count > 0) { if (!CheckForInterference(cycle, engaged)) { var elem = engaged.Find(e => e.Position.X == engaged.Max(k => k.Position.X)); engaged.Clear(); engaged.Add(elem); if (CheckCycleElement(engaged.ElementAt(0), head) && !cycle.ElementAt(cycle.Count() - 2).Equals(head)) { return(true); //якщо я знайшов початок і він не передує мені } if (!IsEqual(engaged.ElementAt(0), (head))) { cycle.Add(new CycleElement(engaged.ElementAt(0).Position.X, engaged.ElementAt(0).Position.Y, cycle.Last().GetSign() * (-1))); // рекурсивно до цього елементу if (BuildCycle(cycle)) { return(true); } } } } // шукаємо елементи з лівого боку engaged = _plan.FindAll(element => element.Position.X == currentElement.Position.X && element.Position.Y < currentElement.Position.Y).ToList(); if (engaged.Count > 0) { if (!CheckForInterference(cycle, engaged)) { var elem = engaged.Find(e => e.Position.Y == engaged.Min(k => k.Position.Y)); engaged.Clear(); engaged.Add(elem); if (CheckCycleElement(engaged.ElementAt(0), head) && !cycle.ElementAt(cycle.Count() - 2).Equals(head)) { return(true); //якщо я знайшов початок і він не передує мені } if (!IsEqual(engaged.ElementAt(0), (head))) { cycle.Add(new CycleElement(engaged.ElementAt(0).Position.X, engaged.ElementAt(0).Position.Y, cycle.Last().GetSign() * (-1))); // рекурсивно до цього елементу if (BuildCycle(cycle)) { return(true); } } } } // видаляємо елемент і повертаємося _plan.Remove(_plan.Find(element => element.Position.X == currentElement.Position.X && element.Position.Y == currentElement.Position.Y)); throw new Exception(); }
private static bool IsEqual(EngagedElement prediction, CycleElement head) { return(prediction.Position.X == head.Position.X && prediction.Position.Y == head.Position.Y); }