diff options
-rw-r--r-- | data/lexica/copyrights.txt | 1 | ||||
-rw-r--r-- | quacker/settings.cpp | 83 | ||||
-rw-r--r-- | quacker/settings.h | 8 | ||||
-rw-r--r-- | quackleio/gaddagfactory.h | 4 |
4 files changed, 77 insertions, 19 deletions
diff --git a/data/lexica/copyrights.txt b/data/lexica/copyrights.txt index 1e3e553..63edec3 100644 --- a/data/lexica/copyrights.txt +++ b/data/lexica/copyrights.txt @@ -1,2 +1,3 @@ eea8dfe5:Collins Scrabble™ Words 2012, ©HarperCollins Publishers Ltd 2015 48dea2c8:Collins Scrabble™ Words 2015, ©HarperCollins Publishers Ltd 2015 +0109ce12:Official Tournament and Club Word List 2014 Edition (OTCWL2014) Copyright © 2014 Hasbro, Inc. Published under license with Merriam-Webster, Incorporated. diff --git a/quacker/settings.cpp b/quacker/settings.cpp index e22a29e..89a19d8 100644 --- a/quacker/settings.cpp +++ b/quacker/settings.cpp @@ -148,7 +148,13 @@ void Settings::createGUI() m_editBoard->setMaximumWidth(60); connect(m_editBoard, SIGNAL(clicked()), this, SLOT(editBoard())); + m_buildGaddag = new QPushButton(tr("Build lexicon database...")); + connect(m_buildGaddag, SIGNAL(clicked()), this, SLOT(buildGaddag())); + + m_buildGaddagLabel = new QLabel(); + m_buildGaddagLabel->setWordWrap(true); m_copyrightLabel = new QLabel(); + m_copyrightLabel->setWordWrap(true); layout->addWidget(lexiconNameLabel, 0, 0, Qt::AlignRight); layout->addWidget(m_lexiconNameCombo, 0, 1); @@ -162,12 +168,14 @@ void Settings::createGUI() layout->addWidget(boardNameLabel, 3, 0, Qt::AlignRight); layout->addWidget(m_boardNameCombo, 3, 1); layout->addWidget(m_editBoard, 3, 2); - layout->addWidget(m_copyrightLabel, 4, 0, 1, -1, Qt::AlignTop); + layout->addWidget(m_buildGaddag, 4, 1); + layout->addWidget(m_buildGaddagLabel, 5, 1); + layout->addWidget(m_copyrightLabel, 6, 0, 1, -1, Qt::AlignTop); layout->setColumnMinimumWidth(3, 0); layout->setColumnStretch(3, 1); - layout->setRowMinimumHeight(4, 0); - layout->setRowStretch(4, 1); + layout->setRowMinimumHeight(6, 0); + layout->setRowStretch(6, 1); load(); @@ -184,6 +192,7 @@ void Settings::load() m_boardNameCombo->setCurrentIndex(m_boardNameCombo->findText(QuackleIO::Util::uvStringToQString(QUACKLE_BOARD_PARAMETERS->name()))); m_lastGoodBoardValue = m_boardNameCombo->currentIndex(); m_copyrightLabel->setText(QString::fromUtf8(QUACKLE_LEXICON_PARAMETERS->copyrightString().c_str())); + setGaddagLabel(); } void Settings::preInitialize() @@ -212,17 +221,52 @@ void Settings::initialize() setQuackleToUseBoardName(settings.value("quackle/settings/board-name", QString("")).toString()); } -void Settings::buildGaddag(const string &filename) +void Settings::setGaddagLabel() { + QString gaddagLabelString; + if (!QUACKLE_LEXICON_PARAMETERS->hasGaddag()) + { + gaddagLabelString = tr("Lexicon database is not up to date. Press the button to begin building the database. This may take several minutes to complete."); + m_buildGaddag->setEnabled(true); + } + else + { + gaddagLabelString = tr("Lexicon database is up to date."); + m_buildGaddag->setEnabled(false); + } + + m_buildGaddagLabel->setText(gaddagLabelString); +} + +void Settings::setGaddagLabel(const QString &label) +{ + m_buildGaddagLabel->setText(label); + qApp->processEvents(); +} + +void Settings::buildGaddag() +{ + const string gaddagFile(QUACKLE_DATAMANAGER->makeDataFilename("lexica", QUACKLE_LEXICON_PARAMETERS->lexiconName() + ".gaddag", true)); GaddagFactory factory((UVString())); Quackle::LetterString word; + int wordCount = 0; - pushIndex(factory, word, 1); - factory.generate(); - factory.writeIndex(filename); + setGaddagLabel(tr("Words processed: 0")); + pushIndex(factory, word, 1, wordCount); + if (wordCount < QUACKLE_MAX_GADDAG_WORDCOUNT) + { + setGaddagLabel(QString(tr("Lexicon total: %1 words. Compressing...")).arg(wordCount)); + factory.generate(); + setGaddagLabel(QString(tr("Lexicon total: %1 words. Writing to disk...")).arg(wordCount)); + factory.writeIndex(gaddagFile); + QUACKLE_LEXICON_PARAMETERS->loadGaddag(gaddagFile); + setGaddagLabel(); + } + else + setGaddagLabel(tr("Your lexicon is too large to be represented using the internal database format. Operation aborted.")); } -void Settings::pushIndex(GaddagFactory &factory, Quackle::LetterString &word, int index) +void Settings::pushIndex(GaddagFactory &factory, Quackle::LetterString &word, int index, int &wordCount) { unsigned int p; Quackle::Letter letter; @@ -236,9 +280,20 @@ void Settings::pushIndex(GaddagFactory &factory, Quackle::LetterString &word, in QUACKLE_LEXICON_PARAMETERS->dawgAt(index, p, letter, t, lastchild, british, playability); word.push_back(letter); if (t) + { factory.pushWord(word); + wordCount++; + if (wordCount % 1000 == 0) + setGaddagLabel(QString(tr("Words processed: %1")).arg(wordCount)); + if (wordCount > QUACKLE_MAX_GADDAG_WORDCOUNT) + return; + } if (p) - pushIndex(factory, word, p); + { + pushIndex(factory, word, p, wordCount); + if (wordCount > QUACKLE_MAX_GADDAG_WORDCOUNT) + return; + } index++; word.pop_back(); } while (!lastchild); @@ -276,15 +331,9 @@ void Settings::setQuackleToUseLexiconName(const QString &lexiconName) else QUACKLE_LEXICON_PARAMETERS->loadGaddag(gaddagFile); - // if (!QUACKLE_LEXICON_PARAMETERS->hasGaddag()) - // { - // gaddagFile = QUACKLE_DATAMANAGER->makeDataFilename("lexica", lexiconNameStr + ".gaddag", true); - // buildGaddag(gaddagFile); - // QUACKLE_LEXICON_PARAMETERS->loadGaddag(gaddagFile); - // } - QUACKLE_STRATEGY_PARAMETERS->initialize(lexiconNameStr); m_copyrightLabel->setText(QString::fromUtf8(QUACKLE_LEXICON_PARAMETERS->copyrightString().c_str())); + setGaddagLabel(); } } @@ -601,5 +650,5 @@ void Settings::populateComboFromFilenames(QComboBox* combo, const QString &path, combo->addItems(list); if (label.size() > 0) - combo->addItem(QString(tr("Add new ")).append(path).append("...")); + combo->addItem(QString(tr("Add new ")).append(label).append("...")); } diff --git a/quacker/settings.h b/quacker/settings.h index ef3449e..74c819a 100644 --- a/quacker/settings.h +++ b/quacker/settings.h @@ -74,6 +74,7 @@ protected slots: void editLexicon(); void editAlphabet(); void editTheme(); + void buildGaddag(); void setQuackleToUseLexiconName(const QString &lexiconName); void setQuackleToUseAlphabetName(const QString &alphabetName); @@ -89,7 +90,9 @@ protected: QPushButton *m_editAlphabet; QPushButton *m_editTheme; QPushButton *m_editBoard; + QPushButton *m_buildGaddag; QLabel *m_copyrightLabel; + QLabel *m_buildGaddagLabel; QString m_appDataDir; QString m_userDataDir; QString m_themeName; @@ -98,8 +101,9 @@ private: // populate the popup based on what's in QSettings void loadBoardNameCombo(); - void buildGaddag(const string &filename); - void pushIndex(GaddagFactory &factory, Quackle::LetterString &word, int index); + void setGaddagLabel(); + void setGaddagLabel(const QString &label); + void pushIndex(GaddagFactory &factory, Quackle::LetterString &word, int index, int &wordCount); static Settings *m_self; int m_lastGoodLexiconValue; diff --git a/quackleio/gaddagfactory.h b/quackleio/gaddagfactory.h index 3017085..a7289db 100644 --- a/quackleio/gaddagfactory.h +++ b/quackleio/gaddagfactory.h @@ -22,6 +22,10 @@ #include <cstdint> #include "flexiblealphabet.h" +// This isn't a strict maximum...you can go higher...but too much higher, and you risk overflowing +// node pointers, which will get you garbage words. The OSPS dictionary is known to trigger +// such overflows. +const int QUACKLE_MAX_GADDAG_WORDCOUNT = 500000; class GaddagFactory { public: |