//If the player cannot draw destination cards or claim a route, they need to draw train cards.
        //Here's the logic for this:
        //First, the player looks at the available draw cards.
        //If two of them are their desired colors, they take them both.
        //If only one is a desired color, they will take that and one from the deck.
        //If there are no desired colors showing, but there is a locomotive, they will take that.
        //If no desired colors and no locomotives are showing, they will take two off the deck.
        public void DrawCards()
        {
            //If the player wants a grey route, they will also be able to take whatever they have the most of already
            if (DesiredColors.Contains(TrainColor.Grey))
            {
                var mostPopularColor = Hand.GetMostPopularColor(DesiredColors);
                DesiredColors.Add(mostPopularColor);
                DesiredColors.Remove(TrainColor.Grey);
            }

            //Check the desired colors against the shown cards
            var shownColors    = Board.ShownCards.Select(x => x.Color);
            var matchingColors = DesiredColors.Intersect(shownColors).ToList();

            var desiredCards = Board.ShownCards.Where(x => DesiredColors.Contains(x.Color));

            if (matchingColors.Count() >= 2)
            {
                //Take the cards and add them to the hand
                var cards = desiredCards.Take(2).ToList();
                foreach (var card in cards)
                {
                    Console.WriteLine(Name + " takes the shown " + card.Color + " card.");
                    Board.ShownCards.Remove(card);
                    Hand.Add(card);
                }
            }
            else if (matchingColors.Count() == 1)
            {
                //Take the shown color
                var card = desiredCards.First();
                Board.ShownCards.Remove(card);
                Hand.Add(card);

                Console.WriteLine(Name + " takes the shown " + card.Color + " card.");

                //Also take one from the deck
                var deckCard = Board.Deck.Pop(1).First();
                Hand.Add(deckCard);
                Console.WriteLine(Name + " also draws one card from the deck.");
            }
            else if (matchingColors.Count() == 0 && Board.ShownCards.Any(x => x.Color == TrainColor.Locomotive))
            {
                Console.WriteLine(Name + " takes the shown locomotive.");
                //Take the locomotive card
                var card = Board.ShownCards.First(x => x.Color == TrainColor.Locomotive);
                Board.ShownCards.Remove(card);
                Hand.Add(card);
            }
            else
            {
                Console.WriteLine(Name + " draws two cards from the deck.");
                //Take two cards from the deck
                var cards = Board.Deck.Pop(2);
                Hand.AddRange(cards);
            }

            Board.PopulateShownCards();
        }
        public void CalculateTargetedRoutes()
        {
            var allRoutes = new List <BoardRoute>();

            var highestCards = DestinationCards.OrderBy(x => x.PointValue).ToList();

            foreach (var destCard in highestCards)
            {
                var matchingRoutes = CalculateTargetedRoutes(destCard);
                if (matchingRoutes.Any())
                {
                    allRoutes.AddRange(matchingRoutes);
                    break;
                }
            }

            TargetedRoutes = allRoutes.GroupBy(x => new { x.Origin, x.Destination, x.Color, x.Length })
                             .Select(group => new
            {
                Metric = group.Key,
                Count  = group.Count()
            }).OrderByDescending(x => x.Count)
                             .ThenByDescending(x => x.Metric.Length)
                             .Take(5)
                             .Select(x => new BoardRoute(x.Metric.Origin, x.Metric.Destination, x.Metric.Color, x.Metric.Length))
                             .ToList();


            DesiredColors = TargetedRoutes.Select(x => x.Color)
                            .Distinct()
                            .ToList();

            if (!DesiredColors.Any() && Hand.Any())
            {
                //The player should target what they have the most of

                var color = Hand.GroupBy(x => x.Color)
                            .Select(group =>
                                    new
                {
                    Color = group.Key,
                    Count = group.Count()
                })
                            .OrderByDescending(x => x.Count)
                            .Select(x => x.Color)
                            .First();

                DesiredColors.Add(color);
            }
        }
        public bool TryClaimRoute()
        {
            //How do we know if the player can claim a route they desire?
            //For each of the desired routes, loop through and see if the player has sufficient cards to claim the route.
            foreach (var route in TargetedRoutes)
            {
                //How many cards do we need for this route?
                var cardCount = route.Length;

                var selectedColor = route.Color;

                //If the player is targeting a Grey route, they can use any color
                //as long as it's not their currently desired color.
                if (route.Color == TrainColor.Grey)
                {
                    //Select all cards in hand that are not in our desired color AND are not locomotives.
                    var matchingCard = Hand.Where(x => x.Color != TrainColor.Locomotive &&
                                                  !DesiredColors.Contains(x.Color))
                                       .GroupBy(x => x)
                                       .Select(group => new
                    {
                        Metric = group,
                        Count  = group.Count()
                    })
                                       .OrderByDescending(x => x.Count)
                                       .Select(x => x.Metric.Key)
                                       .FirstOrDefault();

                    if (matchingCard == null)
                    {
                        continue;
                    }

                    selectedColor = matchingCard.Color;
                }

                //Now attempt to claim the specified route with the selected color.
                return(ClaimRoute(route, selectedColor));
            }

            return(false);
        }