private void AddPartnership(IPartnership partnership)
        {
            if (PartnershipExists(partnership) || SimilarPartnershipExists(partnership))
            {
                throw new DuplicateParntershipException(partnership);
            }

            partnerships.Add(partnership.Id, partnership);
        }
        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 DeliveryConstrainedInning(int duration, ITeam battingTeam, ITeam bowlingTeam)
        {
            if (duration == 0)
            {
                throw new ArgumentOutOfRangeException("Duration should be greater than zero");
            }

            if (battingTeam == null)
            {
                throw new ArgumentNullException("battingTeam");
            }

            if (bowlingTeam == null)
            {
                throw new ArgumentNullException("bowlingTeam");
            }

            _duration = duration;
            _battingTeam = battingTeam;
            _bowlingTeam = bowlingTeam;
            IList<IPlayer> partnership = _battingTeam.StartingXI.Take(2).ToList();
            _currentPartnership = new Partnership(partnership[0], partnership[1]);
        }
        public IDeliveryOutcome NewDelivery(IPartnership partnership, IPlayer bowler, ITeam bowlingTeam)
        {
            // default algorithm does basic weighted result with no intelligence
            int outcome = _random.Next(1001);
            Debug.WriteLine(outcome);

            if (outcome < 150)
            {
                return new DeliveryOutcome(partnership.Striker, bowler, 0);
            }
            else if (outcome < 450)
            {
                return new DeliveryOutcome(partnership.Striker, bowler, 1);
            }
            else if (outcome < 575)
            {
                return new DeliveryOutcome(partnership.Striker, bowler, 2);
            }
            else if (outcome < 650)
            {
                return new DeliveryOutcome(partnership.Striker, bowler, 3);
            }
            else if (outcome < 710)
            {
                return new DeliveryOutcome(partnership.Striker, bowler, 4);
            }
            else if (outcome < 860)
            {
                return new DeliveryOutcome(partnership.Striker, bowler, 6);
            }
            else if (outcome < 880)
            {
                Random fielderSelector = new Random();
                int fielderIndex = fielderSelector.Next(1, 12);
                int count = 1;
                IPlayer fielder = null;
                foreach (IPlayer player in bowlingTeam.StartingXI)
                {
                    if (count == fielderIndex)
                    {
                        fielder = player;
                        break;
                    }
                    count++;
                }
                return new CaughtDeliveryOutcome(partnership.Striker, bowler, fielder, 0);
            }
            else if (outcome < 930)
            {
                // bowled
                return new BowledDeliveryOutcome(partnership.Striker, bowler, 0);
            }
            else if (outcome < 960)
            {
                // run out
                 Random fielderSelector = new Random();
                int fielderIndex = fielderSelector.Next(1, 12);
                int count = 1;
                IPlayer fielder = null;
                foreach (IPlayer player in bowlingTeam.StartingXI)
                {
                    if (count == fielderIndex)
                    {
                        fielder = player;
                        break;
                    }
                    count++;
                }
                return new RunOutDeliveryOutcome(partnership.Striker, bowler, fielder, 0);
            }
            else if (outcome < 980)
            {
                // lbw
                return new LBWDeliveryOutcome(partnership.Striker, bowler, 0);
            }
            else if (outcome < 990)
            {
                // stumped
                Random fielderSelector = new Random();
                int fielderIndex = fielderSelector.Next(1, 12);
                int count = 1;
                IPlayer fielder = null;
                foreach (IPlayer player in bowlingTeam.StartingXI)
                {
                    if (count == fielderIndex)
                    {
                        fielder = player;
                        break;
                    }
                    count++;
                }
                return new StumpedDeliveryOutcome(partnership.Striker, bowler, fielder, 0);
            }
            else if (outcome < 995)
            {
                // hit wicket
                return new HitWicketDeliveryOutcome(partnership.Striker, bowler, 0);
            }
            else // outcome 990 - 1000
            {
                // retired hurt
                return new RetiredHurtDeliveryOutcome(partnership.Striker, bowler, 0);
            }
        }
 public DuplicateParntershipException(IPartnership partnership)
     : base(string.Format("Partnership Id:{0} already exists", partnership.Id))
 {
 }
 public bool SimilarPartnershipExists(IPartnership partnership)
 {
     return(partnerships.Values.Where(x => x.Partner1 == partnership.Partner1 && x.Partner2 == partnership.Partner2).SingleOrDefault() != null ||
            partnerships.Values.Where(x => x.Partner1 == partnership.Partner2 && x.Partner2 == partnership.Partner1).SingleOrDefault() != null);
 }
 public bool PartnershipExists(IPartnership partnership)
 {
     return(partnerships.ContainsValue(partnership));
 }