From 5156495b47f1081a986b19b72085383457496e14 Mon Sep 17 00:00:00 2001 From: RickyRister <42636155+RickyRister@users.noreply.github.com> Date: Sat, 30 Nov 2024 19:32:39 -0800 Subject: [PATCH] add more sort options (#5214) * distinguish between groupBy and sortBy options * add more sort options --- cockatrice/src/game/cards/card_list.cpp | 76 ++++++++++++++++++- cockatrice/src/game/cards/card_list.h | 14 +++- .../src/game/zones/view_zone_widget.cpp | 8 +- 3 files changed, 92 insertions(+), 6 deletions(-) diff --git a/cockatrice/src/game/cards/card_list.cpp b/cockatrice/src/game/cards/card_list.cpp index 5d5e5dbef..a4499a98c 100644 --- a/cockatrice/src/game/cards/card_list.cpp +++ b/cockatrice/src/game/cards/card_list.cpp @@ -61,6 +61,55 @@ void CardList::sortBy(const QList &option) std::sort(begin(), end(), comparator); } +/** + * Creates a String for the card such that when sorting cards using that string, it will result in the + * following sort order: + * - Unrecognized colors + * - Land cards + * - Colorless cards + * - Monocolor cards, in wubrg order + * - Monocolor cards of any custom colors + * - 2C cards (no internal order) + * - 3C cards (no internal order) + * - 4C cards (no internal order) + * - 5C cards (no internal order) + * + * @param c The card info + * @param appendAtEnd For multicolor cards, whether to also append the entire color string at the end. + */ +static QString getColorSortString(CardInfoPtr c, bool appendAtEnd) +{ + QString colors = c->getColors(); + switch (colors.size()) { + case 0: { + if (c->getCardType().contains("Land")) { + return "a_land"; + } else { + return "b_colorless"; + } + } + case 1: + // force wubrg order + switch (colors.at(0).toLatin1()) { + case 'W': + return "c_W"; + case 'U': + return "d_U"; + case 'B': + return "e_B"; + case 'R': + return "f_R"; + case 'G': + return "g_G"; + default: + // handle any custom colors + return QString("h_%1").arg(colors.at(0)); + } + default: + return QString("i%1_%2").arg(colors.size()).arg(appendAtEnd ? colors : ""); + } +} + /** * @brief returns the function that extracts the given property from the CardItem. */ @@ -69,13 +118,34 @@ std::function CardList::getExtractorFor(SortOption option) switch (option) { case NoSort: return [](CardItem *) { return ""; }; - case SortByName: - return [](CardItem *c) { return c->getName(); }; - case SortByType: + case SortByMainType: return [](CardItem *c) { return c->getInfo() ? c->getInfo()->getMainCardType() : ""; }; case SortByManaValue: // getCmc returns the int as a string. We pad with 0's so that string comp also works on it return [](CardItem *c) { return c->getInfo() ? c->getInfo()->getCmc().rightJustified(4, '0') : ""; }; + case SortByColorGrouping: + return [](CardItem *c) { return c->getInfo() ? getColorSortString(c->getInfo(), false) : ""; }; + case SortByName: + return [](CardItem *c) { return c->getName(); }; + case SortByType: + return [](CardItem *c) { return c->getInfo() ? c->getInfo()->getCardType() : ""; }; + case SortByManaCost: + return [](CardItem *c) { + auto info = c->getInfo(); + if (!info) + return QString(""); + + // calculation copied from CardDatabaseModel. + // we pad the cmc and also append the mana cost to the end so same cmc cards still have a sort order + return QString("%1%2").arg(info->getCmc(), 4, QChar('0')).arg(info->getManaCost()); + }; + case SortByColors: + return [](CardItem *c) { return c->getInfo() ? getColorSortString(c->getInfo(), true) : ""; }; + case SortByPt: + // do the same padding trick as above + return [](CardItem *c) { return c->getInfo() ? c->getInfo()->getPowTough().rightJustified(10, '0') : ""; }; + case SortBySet: + return [](CardItem *c) { return c->getInfo() ? c->getInfo()->getSetsNames() : ""; }; } // this line should never be reached diff --git a/cockatrice/src/game/cards/card_list.h b/cockatrice/src/game/cards/card_list.h index cbfb3ecff..5b44764d5 100644 --- a/cockatrice/src/game/cards/card_list.h +++ b/cockatrice/src/game/cards/card_list.h @@ -14,9 +14,21 @@ public: enum SortOption { NoSort, + + // Options that are used by groupBy + // Should partition all cards into a reasonable number of buckets + SortByMainType, + SortByManaValue, + SortByColorGrouping, + + // Options that are used by sortBy + // We don't care about buckets; we want as many distinct values as possible. SortByName, SortByType, - SortByManaValue + SortByManaCost, + SortByColors, + SortByPt, + SortBySet }; CardList(bool _contentsKnown); CardItem *findCard(const int cardId) const; diff --git a/cockatrice/src/game/zones/view_zone_widget.cpp b/cockatrice/src/game/zones/view_zone_widget.cpp index e23a714b8..e8276898b 100644 --- a/cockatrice/src/game/zones/view_zone_widget.cpp +++ b/cockatrice/src/game/zones/view_zone_widget.cpp @@ -193,8 +193,9 @@ void ZoneViewWidget::retranslateUi() int oldIndex = groupBySelector.currentIndex(); groupBySelector.clear(); groupBySelector.addItem(tr("Group by ---"), CardList::NoSort); - groupBySelector.addItem(tr("Group by Type"), CardList::SortByType); + groupBySelector.addItem(tr("Group by Type"), CardList::SortByMainType); groupBySelector.addItem(tr("Group by Mana Value"), CardList::SortByManaValue); + groupBySelector.addItem(tr("Group by Color"), CardList::SortByColorGrouping); groupBySelector.setCurrentIndex(oldIndex); } @@ -204,7 +205,10 @@ void ZoneViewWidget::retranslateUi() sortBySelector.addItem(tr("Sort by ---"), CardList::NoSort); sortBySelector.addItem(tr("Sort by Name"), CardList::SortByName); sortBySelector.addItem(tr("Sort by Type"), CardList::SortByType); - sortBySelector.addItem(tr("Sort by Mana Value"), CardList::SortByManaValue); + sortBySelector.addItem(tr("Sort by Mana Cost"), CardList::SortByManaCost); + sortBySelector.addItem(tr("Sort by Colors"), CardList::SortByColors); + sortBySelector.addItem(tr("Sort by P/T"), CardList::SortByPt); + sortBySelector.addItem(tr("Sort by Set"), CardList::SortBySet); sortBySelector.setCurrentIndex(oldIndex); }