From ca5f1dd43426d1fb7f383914bdc0bc1f79bbe5c1 Mon Sep 17 00:00:00 2001 From: ebbit1q Date: Mon, 23 Nov 2020 01:57:51 +0100 Subject: [PATCH] do some guesswork if cards can't be found (#4131) modify up the simplifyCardName function to ignore right halves add guessCard function that prioritises full card names the simple ones fix imports for misformatted split cards or double faced cards introduces a small concession: not completely formatted names with a shared name on the left side will get mixed up, eg "bind" but not "Bind" this should be fine considering how this would fix a lot more cards --- cockatrice/src/carddatabase.cpp | 31 +++++++++++++++++++++++-------- cockatrice/src/carddatabase.h | 1 + cockatrice/src/cardframe.cpp | 2 +- cockatrice/src/cardinfowidget.cpp | 5 +++-- cockatrice/src/deck_loader.cpp | 2 +- cockatrice/src/player.cpp | 2 +- 6 files changed, 30 insertions(+), 13 deletions(-) diff --git a/cockatrice/src/carddatabase.cpp b/cockatrice/src/carddatabase.cpp index 3ae2b98a..48b72b31 100644 --- a/cockatrice/src/carddatabase.cpp +++ b/cockatrice/src/carddatabase.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -291,22 +292,23 @@ void CardInfo::refreshCachedSetNames() QString CardInfo::simplifyName(const QString &name) { - QString simpleName(name); + static const QRegularExpression spaceOrSplit("(\\s+|\\/\\/.*)"); + static const QRegularExpression nonAlnum("[^a-z0-9]"); + + QString simpleName = name.toLower(); + + // remove spaces and right halves of split cards + simpleName.remove(spaceOrSplit); // So Aetherling would work, but not Ætherling since 'Æ' would get replaced // with nothing. simpleName.replace("æ", "ae"); - simpleName.replace("Æ", "AE"); // Replace Jötun Grunt with Jotun Grunt. simpleName = simpleName.normalized(QString::NormalizationForm_KD); - // Replace dashes with spaces so that we can say "garruk the veil cursed" - // instead of the unintuitive "garruk the veilcursed". - simpleName = simpleName.replace("-", " "); - - simpleName.remove(QRegExp("[^a-zA-Z0-9 ]")); - simpleName = simpleName.toLower(); + // remove all non alphanumeric characters from the name + simpleName.remove(nonAlnum); return simpleName; } @@ -437,6 +439,19 @@ CardInfoPtr CardDatabase::getCardBySimpleName(const QString &cardName) const return getCardFromMap(simpleNameCards, CardInfo::simplifyName(cardName)); } +CardInfoPtr CardDatabase::guessCard(const QString &cardName) const +{ + CardInfoPtr temp = getCard(cardName); + if (temp == nullptr) { // get card by simple name instead + temp = getCardBySimpleName(cardName); + if (temp == nullptr) { // still could not find the card, so simplify the cardName too + QString simpleCardName = CardInfo::simplifyName(cardName); + temp = getCardBySimpleName(simpleCardName); + } + } + return temp; // returns nullptr if not found +} + CardSetPtr CardDatabase::getSet(const QString &setName) { if (sets.contains(setName)) { diff --git a/cockatrice/src/carddatabase.h b/cockatrice/src/carddatabase.h index b1890914..fe884c51 100644 --- a/cockatrice/src/carddatabase.h +++ b/cockatrice/src/carddatabase.h @@ -409,6 +409,7 @@ public: void removeCard(CardInfoPtr card); CardInfoPtr getCard(const QString &cardName) const; QList getCards(const QStringList &cardNames) const; + CardInfoPtr guessCard(const QString &cardName) const; /* * Get a card by its simple name. The name will be simplified in this diff --git a/cockatrice/src/cardframe.cpp b/cockatrice/src/cardframe.cpp index eeec5bc2..a9044652 100644 --- a/cockatrice/src/cardframe.cpp +++ b/cockatrice/src/cardframe.cpp @@ -107,7 +107,7 @@ void CardFrame::setCard(CardInfoPtr card) void CardFrame::setCard(const QString &cardName) { - setCard(db->getCardBySimpleName(cardName)); + setCard(db->guessCard(cardName)); } void CardFrame::setCard(AbstractCardItem *card) diff --git a/cockatrice/src/cardinfowidget.cpp b/cockatrice/src/cardinfowidget.cpp index cb864c4f..4c0d1671 100644 --- a/cockatrice/src/cardinfowidget.cpp +++ b/cockatrice/src/cardinfowidget.cpp @@ -65,9 +65,10 @@ void CardInfoWidget::setCard(CardInfoPtr card) void CardInfoWidget::setCard(const QString &cardName) { - setCard(db->getCardBySimpleName(cardName)); - if (!info) + setCard(db->guessCard(cardName)); + if (info == nullptr) { text->setInvalidCardName(cardName); + } } void CardInfoWidget::setCard(AbstractCardItem *card) diff --git a/cockatrice/src/deck_loader.cpp b/cockatrice/src/deck_loader.cpp index 8f8cd38c..2967e018 100644 --- a/cockatrice/src/deck_loader.cpp +++ b/cockatrice/src/deck_loader.cpp @@ -291,7 +291,7 @@ QString DeckLoader::getCardZoneFromName(QString cardName, QString currentZoneNam QString DeckLoader::getCompleteCardName(const QString cardName) const { if (db) { - CardInfoPtr temp = db->getCardBySimpleName(cardName); + CardInfoPtr temp = db->guessCard(cardName); if (temp) { return temp->getName(); } diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp index 740d069a..7b819584 100644 --- a/cockatrice/src/player.cpp +++ b/cockatrice/src/player.cpp @@ -1242,7 +1242,7 @@ void Player::actCreateToken() lastTokenName = dlg.getName(); lastTokenPT = dlg.getPT(); - CardInfoPtr correctedCard = db->getCardBySimpleName(lastTokenName); + CardInfoPtr correctedCard = db->guessCard(lastTokenName); if (correctedCard) { lastTokenName = correctedCard->getName(); lastTokenTableRow = TableZone::clampValidTableRow(2 - correctedCard->getTableRow());