//Algorithm to be implemented in derived classes public virtual void Execute(IFamilyTree tree, IFamilyMember source = null) { if (tree == null || tree.Root == null) { throw new ArgumentNullException("Tree cannot be null."); } this.tree = tree; if (source != null) { if (!tree.MemberExists(source)) { throw new NotInFamilyTreeException(source); } //prevent source from being inlaw. Inlaws do not have parents, which //breaks traversal. if (source.HasFact(FactType.InLaw)) { throw new InvalidSourceException(source); } source.AddFact(FactType.XPosition, 0); source.AddFact(FactType.XPosition, 0); this.source = source; } Execute(); }
public void AddNonPartnershipChild(IFamilyMember parent, IFamilyMember child) { if (!MemberExists(parent)) { throw new NotInFamilyTreeException(parent); } if (child.Parents != null) { throw new ExistingParentsReferenceException(child); } child.AddFact(FactType.HasSingleParent, true); child.AddFact(FactType.Depth, (int)parent.Facts[FactType.Depth].Value + 1); AddMember(child); parent.NonPartnership.Children.Add(child); child.Parents = parent.NonPartnership; }
private void Above(IChildBearingBase n, int x, int y) { // MarkedChildBearingBases.Add(n); if (n is IParentship) { IFamilyMember nextParent = ((IParentship)n).Partner1; //set relative position nextParent.AddFact(FactType.XPosition, x); nextParent.AddFact(FactType.YPosition, y); nextParent.AddFact(FactType.Ancestor, true); MarkedMembers.Add(nextParent); //ensure that we recurse over non-inlaw partner if (n is IPartnership) { var partnership = n as IPartnership; var otherPartner = partnership.OtherPartner(nextParent); //set relative position otherPartner.AddFact(FactType.XPosition, x); otherPartner.AddFact(FactType.YPosition, y); otherPartner.AddFact(FactType.Ancestor, true); MarkedMembers.Add(otherPartner); if (nextParent.HasFact(FactType.InLaw)) { nextParent = otherPartner; } } //recurse through nextParent parentships/partnerships foreach (IChildBearingBase p in nextParent) { if (!MarkedChildBearingBases.Contains(p)) { Below(p, x, y + 1, y); } } //move up if (!MarkedChildBearingBases.Contains(nextParent.Parents)) { Above(nextParent.Parents, x, y - 1); } } }
public void SetRoot(IPartnership root, IFamilyMember inlaw) { this.Root = root; if (root.Partner1 != null) { root.Partner1.AddFact(FactType.Depth, 0); AddMember(root.Partner1); } if (root.Partner2 != null) { root.Partner2.AddFact(FactType.Depth, 0); AddMember(root.Partner2); } inlaw.AddFact(FactType.InLaw, true); AddPartnership(root); }
public void AddChild(IPartnership partnership, IFamilyMember child) { if (partnership != null && !PartnershipExists(partnership)) { throw new InvalidPartnershipException("Cannot add children to a partnership that does not exist."); } if (child.Parents != null) { throw new ExistingParentsReferenceException(child); } AddMember(child); child.Parents = partnership; partnership.Children.Add(child); //Determine depth based on parents int depth = (int)(partnership.Partner1.Facts[FactType.Depth]?.Value ?? partnership.Partner2.Facts[FactType.Depth]?.Value) + 1; child.AddFact(FactType.Depth, depth); }
public IPartnership AddPartnership(IFamilyMember partner1, IFamilyMember partner2, bool isDivorced = false) { var p1Exists = MemberExists(partner1); var p2Exists = MemberExists(partner2); if (!p1Exists || !p2Exists) { throw new NotInFamilyTreeException(!p1Exists ? partner1 : partner2); } var partnership = FamilyTreeFactory.CreatePartnership(partner1, partner2, isDivorced); IFamilyMember blood = null, inlaw = null; inlaw = partner1.HasFact(FactType.InLaw) ? partner1 : partner2; blood = partnership.OtherPartner(inlaw); inlaw.AddFact(FactType.Depth, blood.Facts[FactType.Depth].Value); AddPartnership(partnership); return(partnership); }
public void AddInLaw(IFamilyMember inlaw) { inlaw.AddFact(FactType.InLaw, true); AddMember(inlaw); }