private static RecordArchetype GetArchetype(Deck deck, ArchetypeFormat format) { var detectionResult = ArchetypeAnalyzer.Detect(deck.Mainboard.Select(i => new Card() { Name = i.Card, Count = i.Count }).ToArray(), deck.Sideboard.Select(i => new Card() { Name = i.Card, Count = i.Count }).ToArray(), format); string colorID = detectionResult.Color.ToString(); string companionID = detectionResult.Companion == null ? "" : detectionResult.Companion.Value.ToString(); string archetypeID = "Unknown"; if (detectionResult.Matches.Length == 1) { archetypeID = GetArchetype(detectionResult.Matches.First(), detectionResult.Color); } if (detectionResult.Matches.Length > 1) { archetypeID = $"Conflict({String.Join(",", detectionResult.Matches.Select(m => GetArchetype(m, detectionResult.Color)))})"; } return(new RecordArchetype() { Archetype = archetypeID, Companion = companionID, Color = colorID, }); }
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 }); }
static void Main(string[] args) { try { var settings = ExecutionSettings.FromJsonFile(_settingsFile); settings.ApplyOverrides(args); settings.Validate(); settings.Print(); Console.WriteLine("Starting detection engine:"); Console.WriteLine("* Loading format data"); ArchetypeFormat format = Formats.FromJson.Loader.GetFormat(settings.FormatDataFolder, settings.Format); ArchetypeFormat referenceFormat = null; if (!String.IsNullOrEmpty(settings.ReferenceFormat)) { referenceFormat = Formats.FromJson.Loader.GetFormat(settings.FormatDataFolder, settings.ReferenceFormat); } Console.WriteLine("* Loading meta information"); DateTime startDate = format.Metas.First().StartDate.AddDays(1); string metaFilter = String.Empty; if (!String.IsNullOrEmpty(settings.Meta)) { if (settings.Meta.ToLowerInvariant() == "current") { metaFilter = format.Metas.Where(m => m.StartDate.AddDays(1) < DateTime.UtcNow).Last().Name; } else { metaFilter = settings.Meta; } var meta = format.Metas.FirstOrDefault(m => m.Name.Contains(metaFilter, StringComparison.InvariantCultureIgnoreCase)); if (meta != null) { startDate = meta.StartDate.AddDays(1); } } Console.WriteLine("* Loading tournaments"); Tournament[] tournaments = settings.TournamentFolder.SelectMany(c => TournamentLoader.GetTournamentsByDate(c, startDate, t => { foreach (string filter in settings.Filter) { if (!t.Contains(filter, StringComparison.InvariantCultureIgnoreCase)) { return(false); } } foreach (string exclude in settings.Exclude) { if (t.Contains(exclude, StringComparison.InvariantCultureIgnoreCase)) { return(false); } } return(true); })).ToArray(); Record[] records = RecordLoader.GetRecords(tournaments, format, referenceFormat, settings.IncludeDecklists, settings.MaxDecksPerEvent); if (!String.IsNullOrEmpty(metaFilter)) { records = records.Where(r => r.Meta.Contains(metaFilter, StringComparison.InvariantCultureIgnoreCase)).ToArray(); if (!String.IsNullOrEmpty(settings.MetaWeek)) { int metaWeekFilter; if (settings.MetaWeek.ToLowerInvariant() == "current") { metaWeekFilter = records.Max(r => r.Week); } else { metaWeekFilter = Int32.Parse(settings.MetaWeek); } records = records.Where(r => r.Week == metaWeekFilter).ToArray(); } } if (!String.IsNullOrEmpty(settings.Archetype)) { records = records.Where(r => r.Archetype.Archetype.Contains(settings.Archetype, StringComparison.InvariantCultureIgnoreCase)).ToArray(); } if (settings.Card != null && settings.IncludeDecklists) { foreach (string card in settings.Card) { records = records.Where(r => r.Mainboard.Any(c => c.Card.Equals(card, StringComparison.InvariantCultureIgnoreCase)) || r.Sideboard.Any(c => c.Card.Equals(card, StringComparison.InvariantCultureIgnoreCase)) ).ToArray(); } } if (settings.ExcludeCard != null && settings.IncludeDecklists) { foreach (string card in settings.ExcludeCard) { records = records.Where(r => !r.Mainboard.Any(c => c.Card.Equals(card, StringComparison.InvariantCultureIgnoreCase)) && !r.Sideboard.Any(c => c.Card.Equals(card, StringComparison.InvariantCultureIgnoreCase)) ).ToArray(); } } if (records.Length == 0) { Console.WriteLine("No records found with the current filters"); } else { if (settings.Action == ExecutionAction.Compare) { records = records.Where(r => !r.Archetype.Equals(r.ReferenceArchetype)).ToArray(); } IOutput output; switch (settings.Output) { case ExecutionOutput.Csv: Console.WriteLine("Saving data to CSV file"); output = new CsvOutput(); break; case ExecutionOutput.Json: Console.WriteLine("Saving data to JSON file"); output = new JsonOutput(); break; case ExecutionOutput.Console: default: output = new ConsoleOutput(); break; } output.Write(records, settings.Action, settings.OutputFile); } if (settings.MetaBreakdown) { PrintBreakdown(records, settings); } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); if (ex is ValidationException) { Console.WriteLine(_usage); } } }
public static Record[] GetRecords(Tournament[] tournaments, ArchetypeFormat format, ArchetypeFormat referenceFormat, bool includeDecklists, int maxDecksPerEvent) { List <Record> records = new List <Record>(); foreach (var tournament in tournaments) { ArchetypeMeta meta = format.Metas.Last(m => m.StartDate <= tournament.Decks.First().Date); DateTime metaWeekReferenceDate = GetMetaWeekReferenceDate(meta.StartDate); string metaID = meta.Name; int weekID = ((int)Math.Floor((tournament.Decks.First().Date.Value - metaWeekReferenceDate).Days / 7.0)) + 1; List <Record> tournamentRecords = new List <Record>(); for (int i = 0; i < tournament.Decks.Length; i++) { RecordArchetype archetype = GetArchetype(tournament.Decks[i], format); RecordArchetype referenceArchetype = null; if (referenceFormat != null) { referenceArchetype = GetArchetype(tournament.Decks[i], referenceFormat); } string points = "-"; if (tournament.Standings != null) { var standing = tournament.Standings.FirstOrDefault(s => s.Player == tournament.Decks[i].Player); if (standing != null) { points = standing.Points.ToString(); } } tournamentRecords.Add(new Record() { TournamentFile = Path.GetFileNameWithoutExtension(tournament.File), Tournament = tournament.Information.Name, Meta = metaID, Week = weekID, Date = tournament.Decks.First().Date.Value, Result = tournament.Decks[i].Result, Points = points, Player = tournament.Decks[i].Player, AnchorUri = tournament.Decks[i].AnchorUri, Archetype = archetype, ReferenceArchetype = referenceArchetype, Mainboard = includeDecklists ? tournament.Decks[i].Mainboard : null, Sideboard = includeDecklists ? tournament.Decks[i].Sideboard : null }); } if (maxDecksPerEvent > 0) { tournamentRecords = tournamentRecords.Take(maxDecksPerEvent).ToList(); } records.AddRange(tournamentRecords); } return(records.OrderBy(r => r.Date).ToArray()); }