Ejemplo n.º 1
0
        /// <summary>
        /// Strategy: weight cards by type.
        /// </summary>
        protected StrategyContinuation StrategyWeightByType(List <Card> possibleCards)
        {
            // matched only by value, times StandardValueMatchPriority
            var cardsByValue = CurrentHand.Where(hc => hc.Value == TopCard.Value && hc.Color != TopCard.Color).ToList();

            for (int i = 0; i < Config.StandardValueMatchPriority; ++i)
            {
                possibleCards.AddRange(cardsByValue);
            }

            // matched only by color, times StandardColorMatchPriority
            var cardsByColor = CurrentHand.Where(hc => hc.Color == TopCard.Color && hc.Value != TopCard.Value).ToList();

            for (int i = 0; i < Config.StandardColorMatchPriority; ++i)
            {
                possibleCards.AddRange(cardsByColor);
            }

            // matched by both color and value, times StandardColorAndValueMatchPriority
            var identicalCards = CurrentHand.Where(hc => hc.Color == TopCard.Color && hc.Value == TopCard.Value).ToList();

            for (int i = 0; i < Config.StandardColorAndValueMatchPriority; ++i)
            {
                possibleCards.AddRange(identicalCards);
            }

            // color changers (W, WD4), times StandardColorChangePriority
            var colorChangeCards = CurrentHand.Where(hc => hc.Color == CardColor.Wild).ToList();

            for (int i = 0; i < Config.StandardColorChangePriority; ++i)
            {
                possibleCards.AddRange(colorChangeCards);
            }

            // player sequence reordering cards (R, S, D2, WD4), times StandardReorderPriority
            var reorderCards = CurrentHand.Where(hc =>
                                                 hc.Value == CardValue.WildDrawFour ||
                                                 (
                                                     (
                                                         hc.Color == TopCard.Color ||
                                                         hc.Value == TopCard.Value
                                                     ) && (
                                                         hc.Value == CardValue.DrawTwo ||
                                                         hc.Value == CardValue.Reverse ||
                                                         hc.Value == CardValue.Skip
                                                         )
                                                 )
                                                 ).ToList();

            for (int i = 0; i < Config.StandardReorderPriority; ++i)
            {
                possibleCards.AddRange(reorderCards);
            }

            return(StrategyContinuation.ContinueToNextStrategy);
        }
Ejemplo n.º 2
0
        protected override void PlayACard()
        {
            // find a playable card with the lowest malus
            var cardToPlay = CurrentHand
                             .Where(IsCardPlayable)
                             .OrderBy(c => c.Malus)
                             .Select(c => (Card?)c)
                             .FirstOrDefault();

            if (cardToPlay.HasValue)
            {
                if (cardToPlay.Value.Color == CardColor.Wild)
                {
                    // choose the color of which we have the most cards, or red
                    var colorsByCount = CurrentHand
                                        .Where(c => c.Color != CardColor.Wild)
                                        .GroupBy(c => c.Color)
                                        .Select(grp => new { Color = grp.Key, Count = grp.Count() })
                                        .OrderByDescending(cc => cc.Count)
                                        .ToList();
                    var colorToPlay = (colorsByCount.Count > 0) ? colorsByCount[0].Color : CardColor.Red;

                    PlayWildCard(cardToPlay.Value.Value, colorToPlay);
                }
                else
                {
                    PlayColorCard(cardToPlay.Value);
                }
                DrewLast = false;
            }
            else
            {
                if (DrewLast)
                {
                    PassAfterDrawing();
                }
                else
                {
                    DrawACard();
                }
            }
        }
Ejemplo n.º 3
0
        protected override CardColor PickAColor()
        {
            if (ColorRequest.HasValue)
            {
                // we have a pending color request; honor it
                var color = ColorRequest.Value;
                StrategyLogger.LogDebug("honoring color request {Color}", color);
                ColorRequest = null;
                return(color);
            }

            // choose the color of which we have the most cards, or red
            var colorsByCount = CurrentHand
                                .Where(c => c.Color != CardColor.Wild)
                                .GroupBy(c => c.Color)
                                .Select(grp => new { Color = grp.Key, Count = grp.Count() })
                                .OrderByDescending(cc => cc.Count)
                                .ToList();

            return((colorsByCount.Count > 0) ? colorsByCount[0].Color : CardColor.Red);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Strategy: honor color requests.
        /// </summary>
        protected StrategyContinuation StrategyHonorColorRequests(List <Card> possibleCards)
        {
            if (!ColorRequest.HasValue)
            {
                // no color request to honor
                return(StrategyContinuation.ContinueToNextStrategy);
            }

            // do I have a usable card that matches the target color?
            possibleCards.AddRange(CurrentHand.Where(hc => hc.Color == ColorRequest.Value && hc.Value == TopCard.Value));
            if (possibleCards.Count == 0)
            {
                // nope; try changing with a wild card instead
                possibleCards.AddRange(CurrentHand.Where(hc => hc.Color == CardColor.Wild));
            }
            if (possibleCards.Count > 0)
            {
                // alright, no need for the standard pick
                return(StrategyContinuation.SkipAllOtherStrategiesUnlessFilteredEmpty);
            }

            return(StrategyContinuation.ContinueToNextStrategy);
        }
Ejemplo n.º 5
0
 protected StrategyContinuation StrategyAnyCard(List <Card> possibleCards)
 {
     // just anything
     possibleCards.AddRange(CurrentHand.Where(IsCardPlayable));
     return(StrategyContinuation.ContinueToNextStrategy);
 }
Ejemplo n.º 6
0
        public string GetChoice()
        {
            List <int> smallerChoice = CurrentHand.Where(x => x <= PlayerStatistics.ActualMana).ToList();

            if (smallerChoice.Count <= 0)
            {
                return(string.Empty);
            }
            if (smallerChoice.Contains(0))
            {
                return("0");
            }

            if (smallerChoice.Any(x => x == PlayerStatistics.ActualMana))
            {
                return(smallerChoice.First(x => x == PlayerStatistics.ActualMana).ToString());
            }

            int HigherToLower          = 0;
            int LowerToHigher          = 0;
            int MiddleChoice           = 0;
            int MiddleDefinitiveChoice = 0;


            int tempMana = PlayerStatistics.ActualMana;

            List <int> replica = new List <int>(smallerChoice);

            while (replica.Any() && tempMana >= 0)
            {
                if (replica.Max() <= tempMana)
                {
                    HigherToLower += replica.Max();
                    tempMana      -= replica.Max();
                }
                replica.Remove(replica.Max());
            }

            replica  = new List <int>(smallerChoice);
            tempMana = PlayerStatistics.ActualMana;

            while (replica.Any() && tempMana >= 0)
            {
                if (replica.Min() <= tempMana)
                {
                    LowerToHigher += replica.Min();
                    tempMana      -= replica.Min();
                }
                replica.Remove(replica.Min());
            }

            replica  = new List <int>(smallerChoice);
            tempMana = PlayerStatistics.ActualMana;

            while (replica.Any() && tempMana >= 0)
            {
                double avg = replica.Average();
                replica.Sort();
                var higher = replica.FirstOrDefault(x => x >= Math.Ceiling(avg));
                var lower  = replica.FirstOrDefault(x => x <= Math.Floor(avg));
                if (higher != 0 && tempMana >= higher && higher > lower)
                {
                    MiddleChoice += higher;
                    if (MiddleDefinitiveChoice == 0)
                    {
                        MiddleDefinitiveChoice = higher;
                    }
                    tempMana -= higher;

                    replica.Remove(higher);
                }
                else if (lower != 0 && tempMana >= lower && lower > higher)
                {
                    MiddleChoice += lower;
                    if (MiddleDefinitiveChoice == 0)
                    {
                        MiddleDefinitiveChoice = higher;
                    }
                    tempMana -= lower;

                    replica.Remove(lower);
                }
                else
                {
                    if (tempMana >= 0)
                    {
                        try
                        {
                            var temp = replica.Where(x => x <= tempMana).ToList().Max();
                            MiddleChoice += temp;
                            replica.Remove(temp);
                        }
                        catch
                        {
                            break;
                        }
                    }
                }
            }

            if (HigherToLower > LowerToHigher && HigherToLower > MiddleChoice)
            {
                return(smallerChoice.Max().ToString());
            }
            else if (LowerToHigher > HigherToLower && LowerToHigher > MiddleChoice)
            {
                return(smallerChoice.Min().ToString());
            }
            else if (MiddleChoice > HigherToLower && MiddleChoice > LowerToHigher)
            {
                return(MiddleDefinitiveChoice.ToString());
            }
            else
            {
                return(string.Empty);
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Strategy: try to destroy the next player if they are close to winning.
        /// </summary>
        protected StrategyContinuation StrategyDestroyNextPlayerIfDangerous(List <Card> possibleCards)
        {
            if (NextPlayer == null || !CurrentCardCounts.ContainsKey(NextPlayer))
            {
                // not sure who my next player is or how many cards they have
                return(StrategyContinuation.ContinueToNextStrategy);
            }

            StrategyLogger.LogDebug("next player {Nickname} has {CardCount} cards", NextPlayer, CurrentCardCounts[NextPlayer]);

            if (CurrentCardCounts[NextPlayer] > Config.PlayToWinThreshold)
            {
                // not dangerous
                return(StrategyContinuation.ContinueToNextStrategy);
            }

            // the player after me has too few cards; try finding an evil card first
            StrategyLogger.LogDebug("trying to find an evil card");

            // offensive cards first: D2, WD4
            possibleCards.AddRange(CurrentHand.Where(hc => hc.Color == TopCard.Color && hc.Value == CardValue.DrawTwo));
            possibleCards.AddRange(CurrentHand.Where(hc => hc.Value == CardValue.WildDrawFour));

            if (possibleCards.Count == 0)
            {
                // defensive cards next: S, R
                possibleCards.AddRange(CurrentHand.Where(hc =>
                                                         hc.Color == TopCard.Color && (
                                                             hc.Value == CardValue.Skip ||
                                                             hc.Value == CardValue.Reverse
                                                             )
                                                         ));
            }

            if (possibleCards.Count > 0)
            {
                StrategyLogger.LogDebug("we have at least one evil card for the next player ({Cards})", possibleCards.StringJoin(", "));

                // don't add the next pick
                return(StrategyContinuation.SkipAllOtherStrategiesUnlessFilteredEmpty);
            }
            else if (!DrewLast)
            {
                if (CurrentHand.Count <= Config.PlayToWinThreshold)
                {
                    StrategyLogger.LogDebug("not risking emergency strategic draw for evil card");
                }
                else if (Config.EmergencyStrategicDrawPercentage > 0)
                {
                    var emergencyStrategicDraw = (Randomizer.Next(100) < Config.EmergencyStrategicDrawPercentage);
                    if (emergencyStrategicDraw)
                    {
                        StrategyLogger.LogDebug("emergency strategic draw for evil card");
                        DrawACard();
                        return(StrategyContinuation.DontPlayCard);
                    }
                    else
                    {
                        StrategyLogger.LogDebug("skipping emergency strategic draw for evil card");
                    }
                }
            }

            return(StrategyContinuation.ContinueToNextStrategy);
        }