//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();
        }
예제 #2
0
        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;
        }
예제 #3
0
        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);
                }
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
 public void AddInLaw(IFamilyMember inlaw)
 {
     inlaw.AddFact(FactType.InLaw, true);
     AddMember(inlaw);
 }