7 changed files with 683 additions and 0 deletions
@ -0,0 +1,42 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
using System.Globalization; |
||||
|
using Newtonsoft.Json; |
||||
|
using Newtonsoft.Json.Converters; |
||||
|
|
||||
|
namespace FabStarterDeckGen |
||||
|
{ |
||||
|
public partial class DeckConfig |
||||
|
{ |
||||
|
[JsonProperty("Hero")] |
||||
|
public string Hero { get; set; } |
||||
|
|
||||
|
[JsonProperty("Core")] |
||||
|
public List<CardSpec> Core { get; set; } |
||||
|
|
||||
|
[JsonProperty("Variables")] |
||||
|
public List<CardSpec> Variables { get; set; } |
||||
|
} |
||||
|
|
||||
|
public partial class CardSpec |
||||
|
{ |
||||
|
[JsonProperty("Name")] |
||||
|
public string Name { get; set; } |
||||
|
|
||||
|
[JsonProperty("IsPitchless")] |
||||
|
public bool IsPitchless { get; set; } |
||||
|
|
||||
|
[JsonProperty("Count", NullValueHandling = NullValueHandling.Ignore)] |
||||
|
public string Count { get; set; } |
||||
|
|
||||
|
[JsonProperty("R", NullValueHandling = NullValueHandling.Ignore)] |
||||
|
public string R { get; set; } |
||||
|
|
||||
|
[JsonProperty("Y", NullValueHandling = NullValueHandling.Ignore)] |
||||
|
public string Y { get; set; } |
||||
|
|
||||
|
[JsonProperty("B", NullValueHandling = NullValueHandling.Ignore)] |
||||
|
public string B { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,325 @@ |
|||||
|
using System.Diagnostics; |
||||
|
using System.Diagnostics.CodeAnalysis; |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace FabStarterDeckGen |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
using System.Globalization; |
||||
|
using Newtonsoft.Json; |
||||
|
using Newtonsoft.Json.Converters; |
||||
|
|
||||
|
public partial class DeckConfig |
||||
|
{ |
||||
|
[JsonProperty("Name")] |
||||
|
public string Name { get; set; } |
||||
|
|
||||
|
[JsonProperty("Hero")] |
||||
|
public string Hero { get; set; } |
||||
|
|
||||
|
[JsonProperty("Core")] |
||||
|
public CardSpec[] Core { get; set; } |
||||
|
|
||||
|
[JsonProperty("Variables")] |
||||
|
public CardSpec[] Variables { get; set; } |
||||
|
} |
||||
|
|
||||
|
public partial class CardSpec |
||||
|
{ |
||||
|
[JsonProperty("Name")] |
||||
|
public string Name { get; set; } |
||||
|
|
||||
|
[JsonProperty("IsPitchless")] |
||||
|
public bool IsPitchless { get; set; } |
||||
|
|
||||
|
[JsonProperty("Count", NullValueHandling = NullValueHandling.Ignore)] |
||||
|
public string Count { get; set; } |
||||
|
|
||||
|
[JsonProperty("R", NullValueHandling = NullValueHandling.Ignore)] |
||||
|
public string R { get; set; } |
||||
|
|
||||
|
[JsonProperty("Y", NullValueHandling = NullValueHandling.Ignore)] |
||||
|
public string Y { get; set; } |
||||
|
|
||||
|
[JsonProperty("B", NullValueHandling = NullValueHandling.Ignore)] |
||||
|
public string B { get; set; } |
||||
|
} |
||||
|
|
||||
|
public class DeckGenerator |
||||
|
{ |
||||
|
static IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<T> list, int length) |
||||
|
{ |
||||
|
if (length == 1) |
||||
|
return list.Select(t => new T[] { t }); |
||||
|
return GetPermutations(list, length - 1).SelectMany(t => list.Where(o => !t.Contains(o)), (t1, t2) => t1.Concat(new T[] { t2 })); |
||||
|
} |
||||
|
|
||||
|
static IEnumerable<IEnumerable<T>> GetPermutationsWithRept<T>(IEnumerable<T> list, int length) |
||||
|
{ |
||||
|
if (length == 1) |
||||
|
return list.Select(t => new T[] { t }); |
||||
|
return GetPermutationsWithRept(list, length - 1).SelectMany(t => list, (t1, t2) => t1.Concat(new T[] { t2 })); |
||||
|
} |
||||
|
|
||||
|
static IEnumerable<IEnumerable<T>> GetKCombsWithRept<T>(IEnumerable<T> list, int length) where T : IComparable |
||||
|
{ |
||||
|
if (length == 1) return list.Select(t => new T[] { t }); |
||||
|
return GetKCombsWithRept(list, length - 1) |
||||
|
.SelectMany(t => list.Where(o => o.CompareTo(t.Last()) >= 0), |
||||
|
(t1, t2) => t1.Concat(new T[] { t2 })); |
||||
|
} |
||||
|
|
||||
|
static IEnumerable<IEnumerable<T>> CartesianProduct<T> (IEnumerable<IEnumerable<T>> sequences) |
||||
|
{ |
||||
|
IEnumerable<IEnumerable<T>> emptyProduct = |
||||
|
new[] { Enumerable.Empty<T>() }; |
||||
|
return sequences.Aggregate( |
||||
|
emptyProduct, |
||||
|
(accumulator, sequence) => |
||||
|
from accseq in accumulator |
||||
|
from item in sequence |
||||
|
select accseq.Concat(new[] {item})); |
||||
|
} |
||||
|
|
||||
|
private List<DeckConfig>? DeckConfigs = new List<DeckConfig>(); |
||||
|
public List<Dictionary<string, int>> DeckLists = new List<Dictionary<string, int>>(); |
||||
|
|
||||
|
private readonly int REASONABLE_MAX = 10; |
||||
|
|
||||
|
private bool IsAssortedThree(string pValue) { return pValue == "3*";} |
||||
|
private bool IsAssortedTwo(string pValue) { return pValue == "2*";} |
||||
|
private bool IsAssortedOne(string pValue) { return pValue == "1*";} |
||||
|
private bool ProcessCountString(string count, ref int rAssorted3Count, ref int rAssorted2Count, ref int rAssorted1Count) |
||||
|
{ |
||||
|
if ( count == "" ) |
||||
|
return false; |
||||
|
|
||||
|
if ( IsAssortedThree(count) ) |
||||
|
{ |
||||
|
rAssorted3Count++; |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
if ( IsAssortedTwo(count) ) |
||||
|
{ |
||||
|
rAssorted2Count++; |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
if ( IsAssortedOne(count) ) |
||||
|
{ |
||||
|
rAssorted1Count++; |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
public void LoadDeckConfigs(string pfilePath) |
||||
|
{ |
||||
|
using (StreamReader file = File.OpenText(pfilePath)) |
||||
|
{ |
||||
|
DeckConfigs = JsonConvert.DeserializeObject <List<DeckConfig>> (file.ReadToEnd()); |
||||
|
} |
||||
|
|
||||
|
var three_over_two = GetPermutationsWithRept<int>(new[] {1, 2}, 2).Select(c => c.ToList()).ToList(); |
||||
|
three_over_two.RemoveAll(i => i.Sum() != 3); |
||||
|
var three_over_three = GetPermutationsWithRept<int>(new[] {0, 1, 2}, 3).Select(c => c.ToList()).ToList(); |
||||
|
three_over_three.RemoveAll(i => i.Sum() != 3); |
||||
|
|
||||
|
var two_over_two = GetPermutationsWithRept<int>(new[] {0, 1, 2}, 2).Select(c => c.ToList()).ToList(); |
||||
|
two_over_two.RemoveAll(i => i.Sum() != 2); |
||||
|
var two_over_three = GetPermutationsWithRept<int>(new[] {0, 1, 2}, 3).Select(c => c.ToList()).ToList(); |
||||
|
two_over_three.RemoveAll(i => i.Sum() != 2); |
||||
|
|
||||
|
var one_over_two = GetPermutationsWithRept<int>(new[] {0, 1}, 2).Select(c => c.ToList()).ToList(); |
||||
|
one_over_two.RemoveAll(i => i.Sum() != 1); |
||||
|
var one_over_three = GetPermutationsWithRept<int>(new[] {0, 1}, 3).Select(c => c.ToList()).ToList(); |
||||
|
one_over_three.RemoveAll(i => i.Sum() != 1); |
||||
|
|
||||
|
Debug.Assert(DeckConfigs != null, nameof(DeckConfigs) + " != null"); |
||||
|
foreach ( var config in DeckConfigs ) |
||||
|
{ |
||||
|
List<List<List<int>>> variable_card_perm_lists = new List<List<List<int>>>(); |
||||
|
foreach ( var variable_card in config.Variables ) |
||||
|
{ |
||||
|
int assorted_3_count = 0; |
||||
|
int assorted_2_count = 0; |
||||
|
int assorted_1_count = 0; |
||||
|
|
||||
|
bool spans_red = ProcessCountString(variable_card.R, ref assorted_3_count, ref assorted_2_count, ref assorted_1_count); |
||||
|
bool spans_blue = ProcessCountString(variable_card.B, ref assorted_3_count, ref assorted_2_count, ref assorted_1_count); |
||||
|
|
||||
|
ProcessCountString(variable_card.Y, ref assorted_3_count, ref assorted_2_count, ref assorted_1_count); |
||||
|
|
||||
|
List<List<int>> counts = null; |
||||
|
if ( assorted_3_count == 2 ) |
||||
|
counts = three_over_two.Select(x => x.ToList()).ToList(); |
||||
|
else if (assorted_3_count == 3) |
||||
|
counts = three_over_three.Select(x => x.ToList()).ToList(); |
||||
|
else if (assorted_2_count == 2) |
||||
|
counts = two_over_two.Select(x => x.ToList()).ToList(); |
||||
|
else if (assorted_2_count == 3) |
||||
|
counts = two_over_three.Select(x => x.ToList()).ToList(); |
||||
|
else if (assorted_1_count == 2) |
||||
|
counts = one_over_two.Select(x => x.ToList()).ToList(); |
||||
|
else if (assorted_1_count == 3) |
||||
|
counts = one_over_three.Select(x => x.ToList()).ToList(); |
||||
|
|
||||
|
if ( (!spans_red || !spans_blue) && counts != null ) |
||||
|
{ |
||||
|
for ( int i = 0; i < counts.Count; i++ ) |
||||
|
{ |
||||
|
if ( spans_red ) |
||||
|
counts[i].Add(int.Parse(variable_card.B)); |
||||
|
if (spans_blue) |
||||
|
counts[i].Insert(0,int.Parse(variable_card.R)); |
||||
|
} |
||||
|
} |
||||
|
variable_card_perm_lists.Add(counts); |
||||
|
} |
||||
|
|
||||
|
var lists = CartesianProduct(variable_card_perm_lists).ToList(); |
||||
|
Console.WriteLine(lists.Count); |
||||
|
|
||||
|
foreach ( var variation in lists ) |
||||
|
{ |
||||
|
var card_list = new Dictionary<string, int>(); |
||||
|
|
||||
|
foreach ( var card in config.Core ) |
||||
|
{ |
||||
|
if ( card.IsPitchless ) |
||||
|
{ |
||||
|
card_list.Add(card.Name, int.Parse(card.Count)); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
card_list.Add(card.Name + " - R", int.Parse(card.R)); |
||||
|
card_list.Add(card.Name + " - Y", int.Parse(card.Y)); |
||||
|
card_list.Add(card.Name + " - B", int.Parse(card.B)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
var variation_counts = variation.ToList(); |
||||
|
for ( int i = 0; i < config.Variables.Length; i++ ) |
||||
|
{ |
||||
|
var card = config.Variables[i]; |
||||
|
var counts = variation_counts[i]; |
||||
|
if(counts[0] > 0) |
||||
|
card_list.Add(card.Name + " - R", counts[0]); |
||||
|
if(counts[1] > 0) |
||||
|
card_list.Add(card.Name + " - Y", counts[1]); |
||||
|
if(counts[2] > 0) |
||||
|
card_list.Add(card.Name + " - B", counts[2]); |
||||
|
} |
||||
|
|
||||
|
int card_count = card_list.Sum(i => i.Value); |
||||
|
if ( card_count != 45 ) |
||||
|
{ |
||||
|
Console.WriteLine(card_list.ToString()); |
||||
|
Debug.Assert(card_count == 45); |
||||
|
} |
||||
|
|
||||
|
DeckLists.Add(card_list); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void DetermineMaxBuilds(in Dictionary<string, int> pCollectionCounts) |
||||
|
{ |
||||
|
var timer = new Stopwatch(); |
||||
|
timer.Start(); |
||||
|
|
||||
|
// Limit this to per hero once i have more specs written
|
||||
|
var range = Enumerable.Range(0, DeckLists.Count); |
||||
|
List<int> largest_buildable_combo = new List<int>(); |
||||
|
for (int i = 1; i <= REASONABLE_MAX; i++) |
||||
|
{ |
||||
|
bool combo_was_built = false; |
||||
|
var combos = GetKCombsWithRept(range, i).Select(c => c.ToList()); |
||||
|
var ints = pCollectionCounts; |
||||
|
|
||||
|
Parallel.ForEach(combos, (combo, state) => |
||||
|
{ |
||||
|
var temp_card_counts = new Dictionary<string, int>(ints); |
||||
|
if (ComboIsBuildable(combo, temp_card_counts)) |
||||
|
{ |
||||
|
// Cache it off somehwere as the largest buildable combo
|
||||
|
largest_buildable_combo = new List<int>(combo); |
||||
|
// Move on and enlarge the number of decks we are trying to build
|
||||
|
combo_was_built = true; |
||||
|
state.Break(); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
/* |
||||
|
foreach (var combo in combos) |
||||
|
{ |
||||
|
// Multithread!
|
||||
|
var temp_card_counts = new Dictionary<string, int>(pCollectionCounts); |
||||
|
if (ComboIsBuildable(combo, temp_card_counts)) |
||||
|
{ |
||||
|
// Cache it off somehwere as the largest buildable combo
|
||||
|
largest_buildable_combo = new List<int>(combo); |
||||
|
// Move on and enlarge the number of decks we are trying to build
|
||||
|
combo_was_built = true; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
*/ |
||||
|
|
||||
|
if (!combo_was_built) |
||||
|
break; |
||||
|
} |
||||
|
Console.WriteLine(string.Join(",", largest_buildable_combo)); |
||||
|
Dictionary<string, int> totals_for_combo_build = new Dictionary<string, int>(); |
||||
|
foreach (var index in largest_buildable_combo) |
||||
|
{ |
||||
|
var deck = DeckLists[index]; |
||||
|
foreach (var entry in deck) |
||||
|
{ |
||||
|
if (!totals_for_combo_build.ContainsKey(entry.Key)) |
||||
|
totals_for_combo_build[entry.Key] = 0; |
||||
|
totals_for_combo_build[entry.Key] += entry.Value; |
||||
|
} |
||||
|
var f = Newtonsoft.Json.JsonConvert.SerializeObject(deck, Newtonsoft.Json.Formatting.Indented); |
||||
|
Console.WriteLine(f); |
||||
|
} |
||||
|
var total_counts = Newtonsoft.Json.JsonConvert.SerializeObject(totals_for_combo_build, Newtonsoft.Json.Formatting.Indented); |
||||
|
Console.WriteLine(total_counts); |
||||
|
timer.Stop(); |
||||
|
TimeSpan timeTaken = timer.Elapsed; |
||||
|
Console.WriteLine("Time taken: " + timeTaken.ToString(@"m\:ss\.fff")); |
||||
|
} |
||||
|
|
||||
|
private bool DeckIsBuildable(in Dictionary<string, int> pDeckCardCounts, in Dictionary<string, int> pCardCounts) |
||||
|
{ |
||||
|
foreach (var required_count in pDeckCardCounts) |
||||
|
{ |
||||
|
if (pCardCounts[required_count.Key] - required_count.Value < 0) |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
private bool ComboIsBuildable(in List<int> pCombination, Dictionary<string, int> pCardCounts) |
||||
|
{ |
||||
|
Console.WriteLine("({1})Testing combo: {0}", String.Join(",", pCombination), Thread.CurrentThread.ManagedThreadId); |
||||
|
foreach (var index in pCombination) |
||||
|
{ |
||||
|
var deck = DeckLists[index]; |
||||
|
if (!DeckIsBuildable(deck, pCardCounts)) |
||||
|
return false; |
||||
|
|
||||
|
foreach (var required_count in deck) |
||||
|
pCardCounts[required_count.Key] -= required_count.Value; |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,80 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text.RegularExpressions; |
||||
|
using IronXL; |
||||
|
using static System.Text.RegularExpressions.Regex; |
||||
|
|
||||
|
namespace FabStarterDeckGen |
||||
|
{ |
||||
|
public class FABCollectionReader |
||||
|
{ |
||||
|
public static readonly string COLUMN_NUMBER = "B"; |
||||
|
public static readonly string COLUMN_NAME = "C"; |
||||
|
public static readonly string COLUMN_RARITY = "D"; |
||||
|
public static readonly string COLUMN_RED = "E"; |
||||
|
public static readonly string COLUMN_YELLOW = "F"; |
||||
|
public static readonly string COLUMN_BLUE = "G"; |
||||
|
|
||||
|
public static readonly string[] COLUMNS_PITCHES = { COLUMN_RED, COLUMN_YELLOW, COLUMN_BLUE }; |
||||
|
public static readonly string[] COLUMNS_DETAILS = { COLUMN_NUMBER, COLUMN_NAME, COLUMN_RARITY }; |
||||
|
|
||||
|
public readonly int STARTING_ROW_INDEX = 3; |
||||
|
|
||||
|
public Dictionary<string, int> CollectionCounts = new Dictionary<string, int>(); |
||||
|
public void LoadCollection(string pFilePath, ReferenceCardLoader pReferenceCard) |
||||
|
{ |
||||
|
WorkBook workbook = WorkBook.Load(pFilePath); |
||||
|
|
||||
|
foreach (var sheet in workbook.WorkSheets) |
||||
|
{ |
||||
|
var current_row_index = STARTING_ROW_INDEX; |
||||
|
var current_card_name = sheet[COLUMN_NAME + current_row_index.ToString()].StringValue; |
||||
|
while (current_card_name != "") |
||||
|
{ |
||||
|
Console.WriteLine(current_card_name); |
||||
|
var reference_cards = pReferenceCard.GetCardsWithName(current_card_name); |
||||
|
|
||||
|
foreach (var card in reference_cards) |
||||
|
{ |
||||
|
if (card.IsPitchless) |
||||
|
{ |
||||
|
if( !CollectionCounts.ContainsKey(card.CleanName) ) |
||||
|
CollectionCounts.Add(card.CleanName, 0); |
||||
|
|
||||
|
CollectionCounts[card.CleanName] += sheet[COLUMN_RED + current_row_index.ToString()].IntValue; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (card.IsRed) |
||||
|
{ |
||||
|
if( !CollectionCounts.ContainsKey(card.CleanNameRed) ) |
||||
|
CollectionCounts.Add(card.CleanNameRed, 0); |
||||
|
|
||||
|
CollectionCounts[card.CleanNameRed] += sheet[COLUMN_RED + current_row_index.ToString()].IntValue; |
||||
|
} |
||||
|
|
||||
|
if (card.IsYellow) |
||||
|
{ |
||||
|
if( !CollectionCounts.ContainsKey(card.CleanNameYellow) ) |
||||
|
CollectionCounts.Add(card.CleanNameYellow, 0); |
||||
|
|
||||
|
CollectionCounts[card.CleanNameYellow] += sheet[COLUMN_YELLOW + current_row_index.ToString()].IntValue; |
||||
|
} |
||||
|
|
||||
|
if (card.IsBlue) |
||||
|
{ |
||||
|
if( !CollectionCounts.ContainsKey(card.CleanNameBlue) ) |
||||
|
CollectionCounts.Add(card.CleanNameBlue, 0); |
||||
|
|
||||
|
CollectionCounts[card.CleanNameBlue] += sheet[COLUMN_BLUE + current_row_index.ToString()].IntValue; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
current_row_index++; |
||||
|
current_card_name = sheet[COLUMN_NAME + current_row_index.ToString()].StringValue; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<OutputType>Exe</OutputType> |
||||
|
<TargetFramework>net5.0</TargetFramework> |
||||
|
<ImplicitUsings>enable</ImplicitUsings> |
||||
|
<Nullable>enable</Nullable> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> |
||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="CsvHelper" Version="27.2.1" /> |
||||
|
<PackageReference Include="IronXL.Excel" Version="2022.3.0" /> |
||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<Compile Remove="DeckConfig.cs" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,18 @@ |
|||||
|
// See https://aka.ms/new-console-template for more information
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using FabStarterDeckGen; |
||||
|
using Newtonsoft.Json; |
||||
|
|
||||
|
string DATA_DIR = @"D:\Dev_P\FabCollectionTracker"; |
||||
|
var ref_card_loader = new ReferenceCardLoader(); |
||||
|
ref_card_loader.LoadSetCSV(DATA_DIR + @"\csvs\set.csv"); |
||||
|
ref_card_loader.LoadCardCSV(DATA_DIR + @"\csvs\card.csv"); |
||||
|
|
||||
|
var collection_reader = new FABCollectionReader(); |
||||
|
collection_reader.LoadCollection(DATA_DIR + @"\FabCollection-Generated.xlsx", ref_card_loader); |
||||
|
|
||||
|
var deckGenerator = new DeckGenerator(); |
||||
|
deckGenerator.LoadDeckConfigs(DATA_DIR + @"\DeckLists.json"); |
||||
|
deckGenerator.DetermineMaxBuilds(collection_reader.CollectionCounts); |
||||
@ -0,0 +1,178 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Globalization; |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Text.RegularExpressions; |
||||
|
using CsvHelper; |
||||
|
using CsvHelper.Configuration; |
||||
|
|
||||
|
namespace FabStarterDeckGen |
||||
|
{ |
||||
|
public class ReferenceCardRow |
||||
|
{ |
||||
|
public string Identifiers; |
||||
|
public string Set_Identifiers; |
||||
|
public string Name; |
||||
|
public string Pitch; |
||||
|
public string Rarity; |
||||
|
} |
||||
|
|
||||
|
public class ReferenceCardRowMap : ClassMap<ReferenceCardRow> |
||||
|
{ |
||||
|
public ReferenceCardRowMap() |
||||
|
{ |
||||
|
Map(m => m.Identifiers).Name("Identifiers"); |
||||
|
Map(m => m.Set_Identifiers).Name("Set Identifiers"); |
||||
|
Map(m => m.Name).Name("Name"); |
||||
|
Map(m => m.Pitch).Name("Pitch"); |
||||
|
Map(m => m.Rarity).Name("Rarity"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class CardInstance |
||||
|
{ |
||||
|
private Regex clean_card_name_regex = new Regex(@"[^a-zA-Z0-9_ ]+"); |
||||
|
public CardInstance(ReferenceCardRow pBase) |
||||
|
{ |
||||
|
Name = pBase.Name; |
||||
|
Pitch = pBase.Pitch; |
||||
|
Rarity = pBase.Rarity; |
||||
|
foreach (var part in pBase.Identifiers.Split(',')) |
||||
|
{ |
||||
|
if (part == "null") |
||||
|
continue; |
||||
|
Identifiers.Add(part); |
||||
|
} |
||||
|
|
||||
|
foreach (var part in pBase.Set_Identifiers.Split(',')) |
||||
|
{ |
||||
|
if (part == "null") |
||||
|
continue; |
||||
|
Set_Identifiers.Add(part); |
||||
|
} |
||||
|
|
||||
|
CleanName = clean_card_name_regex.Replace(Name, ""); |
||||
|
|
||||
|
} |
||||
|
public List<String> Identifiers = new List<String>(); |
||||
|
public List<String> Set_Identifiers = new List<String>(); |
||||
|
public string Name; |
||||
|
public string CleanName; |
||||
|
public string Pitch; |
||||
|
public string Rarity; |
||||
|
|
||||
|
public bool IsPitchless => Pitch == ""; |
||||
|
public bool IsRed => Pitch == "1"; |
||||
|
public bool IsYellow => Pitch == "2"; |
||||
|
public bool IsBlue => Pitch == "3"; |
||||
|
|
||||
|
public string CleanNameRed => CleanName + " - R"; |
||||
|
public string CleanNameYellow => CleanName + " - Y"; |
||||
|
public string CleanNameBlue => CleanName + " - B"; |
||||
|
} |
||||
|
|
||||
|
public class ReferenceSetRow |
||||
|
{ |
||||
|
public string Identifier; |
||||
|
public string Name; |
||||
|
public string Initial_Release_Dates; |
||||
|
} |
||||
|
|
||||
|
public class ReferenceSetRowMap : ClassMap<ReferenceSetRow> |
||||
|
{ |
||||
|
public ReferenceSetRowMap() |
||||
|
{ |
||||
|
Map(m => m.Identifier).Name("Identifier"); |
||||
|
Map(m => m.Initial_Release_Dates).Name("Initial Release Dates"); |
||||
|
Map(m => m.Name).Name("Name"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class SetInstance |
||||
|
{ |
||||
|
public SetInstance(ReferenceSetRow pBase) |
||||
|
{ |
||||
|
Identifier = pBase.Identifier; |
||||
|
Name = pBase.Name; |
||||
|
var release_dates = new List<DateTime>(); |
||||
|
foreach (var part in pBase.Initial_Release_Dates.Split(',')) |
||||
|
{ |
||||
|
if (part == "null") |
||||
|
continue; |
||||
|
release_dates.Add(DateTime.Parse(part)); |
||||
|
} |
||||
|
|
||||
|
if (release_dates.Count > 0) |
||||
|
{ |
||||
|
release_dates.Sort(); |
||||
|
EarliestReleaseDate = release_dates[0]; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
EarliestReleaseDate = DateTime.UnixEpoch; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public string Identifier; |
||||
|
public string Name; |
||||
|
public DateTime EarliestReleaseDate; |
||||
|
public bool IsPromoSet; |
||||
|
public bool IsDeckSet; |
||||
|
public bool IsClassicBattleSet; |
||||
|
} |
||||
|
|
||||
|
public class ReferenceCardLoader |
||||
|
{ |
||||
|
private List<ReferenceSetRow> ReferenceSets; |
||||
|
private List<ReferenceCardRow> ReferenceCards; |
||||
|
|
||||
|
public List<SetInstance> Sets = new List<SetInstance>(); |
||||
|
public List<CardInstance> Cards = new List<CardInstance>(); |
||||
|
|
||||
|
public void LoadSetCSV(string pFilePath) |
||||
|
{ |
||||
|
var config = new CsvConfiguration(CultureInfo.CurrentCulture) { Delimiter = "\t", Encoding = Encoding.UTF8 }; |
||||
|
using (var reader = new StreamReader(pFilePath)) |
||||
|
using (var csv = new CsvReader(reader, config)) |
||||
|
{ |
||||
|
csv.Context.RegisterClassMap<ReferenceSetRowMap>(); |
||||
|
ReferenceSets = csv.GetRecords<ReferenceSetRow>().ToList(); |
||||
|
} |
||||
|
|
||||
|
foreach (var set in ReferenceSets) |
||||
|
{ |
||||
|
Sets.Add(new SetInstance(set)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void LoadCardCSV(string pFilePath) |
||||
|
{ |
||||
|
var config = new CsvConfiguration(CultureInfo.CurrentCulture) { Delimiter = "\t", Encoding = Encoding.UTF8 }; |
||||
|
using (var reader = new StreamReader(pFilePath)) |
||||
|
using (var csv = new CsvReader(reader, config)) |
||||
|
{ |
||||
|
csv.Context.RegisterClassMap<ReferenceCardRowMap>(); |
||||
|
ReferenceCards = csv.GetRecords<ReferenceCardRow>().ToList(); |
||||
|
} |
||||
|
|
||||
|
foreach (var card in ReferenceCards) |
||||
|
{ |
||||
|
Cards.Add(new CardInstance(card)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public List<CardInstance> GetCardsWithName(string pName) |
||||
|
{ |
||||
|
List<CardInstance> card_list = new List<CardInstance>(); |
||||
|
foreach (var card in Cards) |
||||
|
{ |
||||
|
if(card.Name != pName) |
||||
|
continue; |
||||
|
card_list.Add(card); |
||||
|
} |
||||
|
return card_list; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
|
||||
|
Microsoft Visual Studio Solution File, Format Version 12.00 |
||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FabStarterDeckGen", ".\FabStarterDeckGen\FabStarterDeckGen.csproj", "{FEDDE3A6-84BD-4782-971A-BFFDC6A75C1C}" |
||||
|
EndProject |
||||
|
Global |
||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
||||
|
Debug|Any CPU = Debug|Any CPU |
||||
|
Release|Any CPU = Release|Any CPU |
||||
|
EndGlobalSection |
||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
||||
|
{FEDDE3A6-84BD-4782-971A-BFFDC6A75C1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{FEDDE3A6-84BD-4782-971A-BFFDC6A75C1C}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{FEDDE3A6-84BD-4782-971A-BFFDC6A75C1C}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{FEDDE3A6-84BD-4782-971A-BFFDC6A75C1C}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
EndGlobalSection |
||||
|
EndGlobal |
||||
Loading…
Reference in new issue