public IEnumerable <Tuple <LinkedNode, Requirement> > SuccessorsRequires(Capabilities capsForward, bool onlyInternal = false) { foreach (var iedge in this.Static.Edges) { if (iedge.NodeTarget == null) { continue; } var reqs = iedge.ReqOut.Conflicts(capsForward); if (reqs is Impossible) { continue; } yield return(Tuple.Create(this.Room.Nodes[iedge.NodeTarget.Name], reqs)); } if (!onlyInternal) { foreach (var edge in this.Edges) { var check1 = edge.CorrespondingEdge(this); var check2 = edge.OtherEdge(this); var reqs = Requirement.And(new List <Requirement> { check1.ReqOut.Conflicts(capsForward), check2.ReqIn.Conflicts(capsForward) }); if (reqs is Impossible) { continue; } yield return(Tuple.Create(edge.OtherNode(this), reqs)); } } }
public static Requirement TraversalRequires(LinkedNode start, Capabilities capsForward, bool internalOnly, UnlinkedEdge end) { return(Requirement.And(new List <Requirement> { TraversalRequires(start, capsForward, internalOnly, end.Node), end.Static.ReqOut.Conflicts(capsForward) })); }
public static Requirement TraversalRequires(LinkedNode start, Capabilities capsForward, bool internalOnly, LinkedNode end) { var queue = new PriorityQueue <Tuple <Requirement, LinkedNode> >(); var seen = new Dictionary <LinkedNode, List <Requirement> >(); Requirement p = new Possible(); queue.Enqueue(Tuple.Create(p, start)); seen[start] = new List <Requirement> { p }; // implementation question: should this loop break as soon as one path to end is found, or should it exhaust the queue? // for now, let's go with exhaust the queue so if there's a Possible we don't miss it while (queue.Count != 0) { var entry = queue.Dequeue(); var entryReq = entry.Item1; var entryNode = entry.Item2; foreach (var where in entryNode.SuccessorsRequires(capsForward)) { var realReq = Requirement.And(new List <Requirement> { entryReq, where.Item2 }); var nextNode = where.Item1; if (!seen.TryGetValue(nextNode, out var seenLst)) { seenLst = new List <Requirement>(); seen[nextNode] = seenLst; } // search for any requirement already seen which obsoletes this new requirement var found = false; foreach (var req in seenLst) { if (req.Equals(realReq) || req.StrictlyBetterThan(realReq)) { found = true; break; } } if (!found) { seenLst.Add(realReq); queue.Enqueue(Tuple.Create(realReq, nextNode)); } } } if (!seen.TryGetValue(end, out var disjunct)) { return(new Impossible()); } return(Requirement.Or(disjunct)); }
public Requirement ReqsTo(LinkedNode one) { var extra = this.ExtraReqsFrom(one); var total = new List <Requirement> { this.CorrespondingEdge(one).ReqIn, this.OtherEdge(one).ReqOut, }; if (extra != null) { total.Add(extra); } return(Requirement.And(total)); }