private CollectionSnapshot convertV2Collection(CollectionSnapshot collection) { var deck = Deck.Create(collection.CountById, collection.CountById.Keys.ToList(), null, null, null, null); var converted = _deckMigrator.ConvertV2Deck(deck); return(new CollectionSnapshot { CountById = converted.MainDeck.Count }); }
public DeckModel(Deck originalDeck, CardRepository repo, CollectionSnapshot collection, CollectedCardsDeckTransformation transformation) { int countInMain(Card c) => Deck.MainDeck.Count.TryGet(c.Id); int countTotal(Card c, int countInDeck) => countInDeck; int countCollected(Card c, int countInDeck) => Math.Min(countInDeck, Collection.GetCount(c)); int countCollectedSide(Card c, int countInDeck) => (Collection.GetCount(c) - countInMain(c)).WithinRange(0, countInDeck); float priceTotal(Card c, int countInDeck) => countInDeck * (c.PriceMid ?? 0f); float priceCollected(Card c, int countInDeck) => countCollected(c, countInDeck) * (c.PriceMid ?? 0f); float priceCollectedSide(Card c, int countInDeck) => countCollectedSide(c, countInDeck) * (c.PriceMid ?? 0f); IList <string> generatedMana(Card c, int countInDeck) => c.GeneratedManaArr; float f0() => 0f; int i0() => 0; float fSum(float a, float b) => a + b; int iSum(int a, int b) => a + b; float fE(float a) => a; int iE(int a) => a; Deck deck() => Deck; _priceTotalCache = new DeckAggregateCache <float, float, float>(repo, deck, f0, fSum, priceTotal, fE); _countTotalCache = new DeckAggregateCache <int, int, int>(repo, deck, i0, iSum, countTotal, iE); _priceCollectedCache = new DeckAggregateCache <float, float, float>(repo, deck, f0, fSum, priceCollected, fE); _countCollectedCache = new DeckAggregateCache <int, int, int>(repo, deck, i0, iSum, countCollected, iE); _priceCollectedSideCache = new DeckAggregateCache <float, float, float>(repo, deck, f0, fSum, priceCollectedSide, fE); _countCollectedSideCache = new DeckAggregateCache <int, int, int>(repo, deck, i0, iSum, countCollectedSide, iE); _generatedManaCache = new DeckAggregateCache <IList <string>, Dictionary <string, int>, string>( repo, () => OriginalDeck, () => new Dictionary <string, int>(Str.Comparer), (a, b) => { foreach (string s in b) { a.TryGetValue(s, out int count); count++; a[s] = count; } return(a); }, generatedMana, a => string.Concat(a.Keys.OrderBy(s => KeywordDefinitions.GeneratedMana.IndexOf(s, Str.Comparer)))); _filterNone = c => true; _filterPriceIsUnknown = c => !c.PriceMid.HasValue; _filterIsCreature = c => c.TypesArr.IndexOf("creature", Str.Comparer) >= 0; _filterIsLand = c => c.TypesArr.IndexOf("land", Str.Comparer) >= 0; _filterIsOtherSpell = c => !_filterIsCreature(c) && !_filterIsLand(c); _filterIsLandAndPriceIsUnknown = c => _filterIsLand(c) && _filterPriceIsUnknown(c); _filterIsCreatureAndPriceIsUnknown = c => _filterIsCreature(c) && _filterPriceIsUnknown(c); _filterIsOtherSpellAndPriceIsUnknown = c => _filterIsOtherSpell(c) && _filterPriceIsUnknown(c); Collection = collection; _repo = repo; _transformation = transformation; OriginalDeck = originalDeck; }
public Deck Transform( Deck original, CollectionSnapshot collection, Deck previousTransformed = null, HashSet <string> affectedNames = null) { if (!_priceRepo.IsLoadingPriceComplete.Signaled) { return(original); } var target = Deck.Create(); target.Name = original.Name + " transformed"; var usedCountById = new Dictionary <string, int>(); void use(Card card, int count, DeckZone targetZone) { var id = card.Id; usedCountById.TryGetValue(id, out int currentTotalCount); usedCountById[id] = currentTotalCount + count; if (!targetZone.Count.TryGetValue(id, out var currentZoneCount)) { targetZone.Order.Add(id); } targetZone.Count[id] = currentZoneCount + count; } int getUsedCount(Card c) { usedCountById.TryGetValue(c.Id, out int count); return(count); } void transform(Card card, int count, DeckZone targetZone) { var candidates = card.Namesakes .Select(c => (Card: c, AvailableCount: collection.GetCount(c) - getUsedCount(c))) .OrderBy(_ => _.AvailableCount <= 0) .ThenBy(_ => _.Card.Price == null) .ThenBy(_ => _.Card.Price) .ToList(); for (int i = 0; i < candidates.Count; i++) { var candidate = candidates[i]; if (candidate.AvailableCount <= 0) { var bestNotCollectedCandidate = candidates .AtMin(_ => _.Card.Price == null) .ThenAtMin(_ => _.Card.Price ?? 0) .Find(); use(bestNotCollectedCandidate.Card, count, targetZone); return; } int takeCount = i < candidates.Count - 1 ? Math.Min(count, candidate.AvailableCount) : count; count -= takeCount; use(candidate.Card, takeCount, targetZone); if (count == 0) { return; } } } var zones = new[] { original.MainDeck, original.Sideboard, original.Maybeboard }; var previousZones = new[] { previousTransformed?.MainDeck, previousTransformed?.Sideboard, previousTransformed?.Maybeboard }; var resultZones = new[] { target.MainDeck, target.Sideboard, target.Maybeboard }; for (int i = 0; i < zones.Length; i++) { bool transformPrevious = previousTransformed != null && affectedNames != null; var zone = transformPrevious ? previousZones[i] : zones[i]; var targetZone = resultZones[i]; foreach (string id in zone.Order) { var card = _repo.CardsById.TryGet(id); if (card == null) { continue; } int count = zone.Count[id]; if (transformPrevious && !affectedNames.Contains(card.NameEn)) { use(card, count, targetZone); } else { transform(card, count, targetZone); } } } return(target); }