Esempio n. 1
0
        public static ArchetypeResult Detect(Card[] mainboardCards, Card[] sideboardCards, ArchetypeFormat format, double minSimiliarity = 0.1)
        {
            Archetype[] archetypeData = format.Archetypes;
            Dictionary <string, ArchetypeColor> landColors = format.Lands;
            Dictionary <string, ArchetypeColor> cardColors = format.NonLands;

            ArchetypeSpecific[] specificArchetypes = archetypeData.Where(a => a is ArchetypeSpecific && !(a is ArchetypeVariant)).Select(a => a as ArchetypeSpecific).ToArray();
            ArchetypeGeneric[]  genericArchetypes  = archetypeData.Where(a => a is ArchetypeGeneric).Select(a => a as ArchetypeGeneric).ToArray();

            ArchetypeCompanion?companion = GetCompanion(mainboardCards, sideboardCards);
            ArchetypeColor     color     = GetColors(mainboardCards, sideboardCards, landColors, cardColors);

            List <ArchetypeMatch> results = new List <ArchetypeMatch>();

            foreach (ArchetypeSpecific archetype in specificArchetypes)
            {
                if (Test(mainboardCards, sideboardCards, color, archetype))
                {
                    bool isVariant = false;
                    if (archetype.Variants != null)
                    {
                        foreach (ArchetypeSpecific variant in archetype.Variants)
                        {
                            if (Test(mainboardCards, sideboardCards, color, variant))
                            {
                                isVariant = true;
                                results.Add(new ArchetypeMatch()
                                {
                                    Archetype = archetype, Variant = variant, Similarity = 1
                                });
                            }
                        }
                    }
                    if (!isVariant)
                    {
                        results.Add(new ArchetypeMatch()
                        {
                            Archetype = archetype, Variant = null, Similarity = 1
                        });
                    }
                }
            }

            if (results.Count == 0)
            {
                ArchetypeMatch genericArchetype = GetBestGenericArchetype(mainboardCards, sideboardCards, color, genericArchetypes);
                if (genericArchetype != null && genericArchetype.Similarity > minSimiliarity)
                {
                    results.Add(genericArchetype);
                }
            }

            return(new ArchetypeResult()
            {
                Matches = results.ToArray(), Color = color, Companion = companion
            });
        }
Esempio n. 2
0
        private static string GetArchetype(ArchetypeMatch match, ArchetypeColor color)
        {
            string result = match.Archetype.GetName(color);

            if (match.Variant != null)
            {
                result = match.Variant.GetName(color);
            }
            return(result);
        }
Esempio n. 3
0
        public string GetName(ArchetypeColor color)
        {
            string name = this.Name.Replace("Generic", "");

            if (IncludeColorInName)
            {
                string colorName = GetColorName(color);
                name = colorName + name;
            }

            // Source: https://stackoverflow.com/questions/3216085/split-a-pascalcase-string-into-separate-words
            name = new Regex(@"(?<=[A-Z])(?=[A-Z][a-z])|(?<=[^A-Z])(?=[A-Z])|(?<=[A-Za-z])(?=[^A-Za-z])").Replace(name, " ");

            return(name);
        }
Esempio n. 4
0
        private static ArchetypeMatch GetBestGenericArchetype(Card[] mainboardCards, Card[] sideboardCards, ArchetypeColor color, ArchetypeGeneric[] genericArchetypes)
        {
            Dictionary <ArchetypeGeneric, int> weights = new Dictionary <ArchetypeGeneric, int>();

            foreach (ArchetypeGeneric genericArchetype in genericArchetypes)
            {
                weights.Add(genericArchetype, 0);
                foreach (var card in mainboardCards.Concat(sideboardCards).Distinct())
                {
                    if (genericArchetype.CommonCards.Contains(card.Name))
                    {
                        weights[genericArchetype] += card.Count;
                    }
                }
            }

            if (weights.All(k => k.Value == 0))
            {
                return(null);
            }
            else
            {
                int max = weights.Max(k => k.Value);
                KeyValuePair <ArchetypeGeneric, int> bestMatch = weights.Where(k => k.Value == max).ToArray().OrderBy(k => k.Key.CommonCards.Length).First();
                return(new ArchetypeMatch()
                {
                    Archetype = bestMatch.Key, Variant = null, Similarity = ((double)max) / ((double)(mainboardCards.Length + sideboardCards.Length))
                });
            }
        }
Esempio n. 5
0
        private static bool Test(Card[] mainboardCards, Card[] sideboardCards, ArchetypeColor color, ArchetypeSpecific archetypeData)
        {
            foreach (var condition in archetypeData.Conditions)
            {
                switch (condition.Type)
                {
                case ArchetypeConditionType.InMainboard:
                    if (!mainboardCards.Any(c => c.Name == condition.Cards[0]))
                    {
                        return(false);
                    }
                    break;

                case ArchetypeConditionType.InSideboard:
                    if (!sideboardCards.Any(c => c.Name == condition.Cards[0]))
                    {
                        return(false);
                    }
                    break;

                case ArchetypeConditionType.InMainOrSideboard:
                    if (!mainboardCards.Any(c => c.Name == condition.Cards[0]) && !sideboardCards.Any(c => c.Name == condition.Cards[0]))
                    {
                        return(false);
                    }
                    break;

                case ArchetypeConditionType.OneOrMoreInMainboard:
                    if (!mainboardCards.Any(c => condition.Cards.Contains(c.Name)))
                    {
                        return(false);
                    }
                    break;

                case ArchetypeConditionType.OneOrMoreInSideboard:
                    if (!sideboardCards.Any(c => condition.Cards.Contains(c.Name)))
                    {
                        return(false);
                    }
                    break;

                case ArchetypeConditionType.OneOrMoreInMainOrSideboard:
                    if (!mainboardCards.Any(c => condition.Cards.Contains(c.Name)) && !sideboardCards.Any(c => condition.Cards.Contains(c.Name)))
                    {
                        return(false);
                    }
                    break;

                case ArchetypeConditionType.TwoOrMoreInMainboard:
                    if (mainboardCards.Where(c => condition.Cards.Contains(c.Name)).Count() < 2)
                    {
                        return(false);
                    }
                    break;

                case ArchetypeConditionType.TwoOrMoreInSideboard:
                    if (sideboardCards.Where(c => condition.Cards.Contains(c.Name)).Count() < 2)
                    {
                        return(false);
                    }
                    break;

                case ArchetypeConditionType.TwoOrMoreInMainOrSideboard:
                    if ((mainboardCards.Where(c => condition.Cards.Contains(c.Name)).Count() + sideboardCards.Where(c => condition.Cards.Contains(c.Name)).Count()) < 2)
                    {
                        return(false);
                    }
                    break;

                case ArchetypeConditionType.DoesNotContain:
                    if (mainboardCards.Any(c => c.Name == condition.Cards[0]) || sideboardCards.Any(c => c.Name == condition.Cards[0]))
                    {
                        return(false);
                    }
                    break;

                case ArchetypeConditionType.DoesNotContainMainboard:
                    if (mainboardCards.Any(c => c.Name == condition.Cards[0]))
                    {
                        return(false);
                    }
                    break;

                case ArchetypeConditionType.DoesNotContainSideboard:
                    if (sideboardCards.Any(c => c.Name == condition.Cards[0]))
                    {
                        return(false);
                    }
                    break;

                default:
                    throw new NotImplementedException();
                }
            }

            return(true);
        }
Esempio n. 6
0
        private void DetectionFailure(ArchetypeConditionType condition, string[] archetypeCards, ArchetypeColor archetypeColor, string[] testMainboard, string[] testSideboard)
        {
            var archetype = new ArchetypeSpecific()
            {
                Conditions = new ArchetypeCondition[]
                {
                    new ArchetypeCondition()
                    {
                        Type = condition, Cards = archetypeCards
                    }
                }
            };

            var result = ArchetypeAnalyzer.Detect(
                testMainboard.Select(c => new Card()
            {
                Count = 4, Name = c
            }).ToArray(),
                testSideboard.Select(c => new Card()
            {
                Count = 4, Name = c
            }).ToArray(),
                new ArchetypeFormat
            {
                Archetypes = new Archetype[]
                {
                    archetype
                },
                Lands    = _modern.Lands,
                NonLands = _modern.NonLands
            });

            result.Matches.Should().HaveCount(0);
        }
Esempio n. 7
0
 private void DetectionFailure(ArchetypeConditionType condition, ArchetypeColor archetypeColor, string[] testMainboard, string[] testSideboard)
 {
     DetectionFailure(condition, new string[0], archetypeColor, testMainboard, testSideboard);
 }
Esempio n. 8
0
        private string GetColorName(ArchetypeColor color)
        {
            switch (color)
            {
            case ArchetypeColor.W:
                return($"MonoWhite");

            case ArchetypeColor.U:
                return($"MonoBlue");

            case ArchetypeColor.B:
                return($"MonoBlack");

            case ArchetypeColor.R:
                return($"MonoRed");

            case ArchetypeColor.G:
                return($"MonoGreen");

            case ArchetypeColor.WU:       // Azorius
                return($"Azorius");

            case ArchetypeColor.WB:       // Orzhov
                return($"Orzhov");

            case ArchetypeColor.WR:       // Boros
                return($"Boros");

            case ArchetypeColor.WG:       // Selesnya
                return($"Selesnya");

            case ArchetypeColor.UB:       // Dimir
                return($"Dimir");

            case ArchetypeColor.UR:       // Izzet
                return($"Izzet");

            case ArchetypeColor.UG:       // Simic
                return($"Simic");

            case ArchetypeColor.BR:       // Rakdos
                return($"Rakdos");

            case ArchetypeColor.BG:       // Golgari
                return($"Golgari");

            case ArchetypeColor.RG:       // Gruul
                return($"Gruul");

            case ArchetypeColor.WUB:      // Esper
                return($"Esper");

            case ArchetypeColor.WUR:      // Jeskai
                return($"Jeskai");

            case ArchetypeColor.WUG:      // Bant
                return($"Bant");

            case ArchetypeColor.WBR:      // Mardu
                return($"Mardu");

            case ArchetypeColor.WBG:      // Abzan
                return($"Abzan");

            case ArchetypeColor.WRG:      // Naya
                return($"Naya");

            case ArchetypeColor.UBR:      // Grixis
                return($"Grixis");

            case ArchetypeColor.UBG:      // Sultai
                return($"Sultai");

            case ArchetypeColor.URG:      // Temur
                return($"Temur");

            case ArchetypeColor.BRG:      // Jund
                return($"Jund");

            case ArchetypeColor.WUBR:     // Not-G
                return($"WUBR");

            case ArchetypeColor.WBRG:     // Not-U
                return($"WBRG");

            case ArchetypeColor.WUBG:     // Not-R
                return($"WUBG");

            case ArchetypeColor.WURG:     // Not-B
                return($"WURG");

            case ArchetypeColor.UBRG:     // Not-W
                return($"UBRG");

            case ArchetypeColor.WUBRG:
                return($"5Color");

            default:
                return("");
            }
        }