File indexing completed on 2024-05-12 05:40:40
0001 /*************************************************************************** 0002 * Copyright (C) 2015 by Renaud Guezennec * 0003 * https://rolisteam.org/contact * 0004 * * 0005 * rolisteam is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 0021 #include "namegeneratorwidget.h" 0022 #include "ui_namegeneratorwidget.h" 0023 #include <QDateTime> 0024 #include <QDebug> 0025 #include <QFile> 0026 #include <QJsonDocument> 0027 #include <QJsonObject> 0028 #include <stdlib.h> 0029 0030 #define FName "FemaleName" 0031 #define MName "MaleName" 0032 #define LName "LastName" 0033 #define BothName "BothName" 0034 0035 NameGeneratorWidget::NameGeneratorWidget(QWidget* parent) 0036 : QWidget(parent) 0037 , ui(new Ui::NameGeneratorWidget) 0038 , m_generator(quintptr(this) + QDateTime::currentDateTime().toMSecsSinceEpoch()) 0039 { 0040 setWindowTitle(QStringLiteral("Name Generator")); 0041 setObjectName(QStringLiteral("NameGenerator")); 0042 ui->setupUi(this); 0043 0044 m_model << tr("Chinese Name") << tr("Elve Name") << tr("English Name") << tr("French Name") << tr("Japanese Name") 0045 << tr("Star Wars Name") << tr("Russian Name"); 0046 ui->m_database->addItems(m_model); 0047 connect(ui->m_database, SIGNAL(currentIndexChanged(int)), this, SLOT(checkFeatureAvailability())); 0048 0049 connect(ui->m_gen, SIGNAL(clicked()), this, SLOT(generateName())); 0050 0051 // Japanese 0052 DataBase jpMale; 0053 jpMale.filepath= ":/data/result_Name_Japanese_Male.txt"; 0054 jpMale.gender= Male; 0055 jpMale.generate= true; 0056 jpMale.id= 0; 0057 0058 DataBase jpFemale; 0059 jpFemale.filepath= ":/data/result_Name_Japanese_Female.txt"; 0060 jpFemale.gender= Female; 0061 jpFemale.generate= true; 0062 jpFemale.id= 1; 0063 0064 // Elves 0065 DataBase elveMale; 0066 elveMale.filepath= ":/data/result_Name_Elve_Male.txt"; 0067 elveMale.gender= Male; 0068 elveMale.generate= true; 0069 elveMale.id= 2; 0070 0071 DataBase elveFemale; 0072 elveFemale.filepath= ":/data/result_Name_Elve_Female.txt"; 0073 elveFemale.gender= Female; 0074 elveFemale.generate= true; 0075 elveFemale.id= 3; 0076 0077 // Chinese 0078 DataBase chineseMale; 0079 chineseMale.filepath= ":/data/result_Name_Chinese_Male.txt"; 0080 chineseMale.gender= Male; 0081 chineseMale.generate= true; 0082 chineseMale.id= 4; 0083 0084 DataBase chineseFemale; 0085 chineseFemale.filepath= ":/data/result_Name_Chinese_Female.txt"; 0086 chineseFemale.gender= Female; 0087 chineseFemale.generate= true; 0088 chineseFemale.id= 5; 0089 0090 // French 0091 DataBase frenchMale; 0092 frenchMale.filepath= ":/data/data_Name_French_Male.txt"; 0093 frenchMale.gender= Male; 0094 frenchMale.generate= false; 0095 frenchMale.id= 6; 0096 0097 DataBase frenchFemale; 0098 frenchFemale.filepath= ":/data/data_Name_French_Female.txt"; 0099 frenchFemale.gender= Female; 0100 frenchFemale.generate= false; 0101 frenchFemale.id= 7; 0102 0103 DataBase frenchName; 0104 frenchName.filepath= ":/data/data_Last_Name_French.txt"; 0105 frenchName.gender= NONE; 0106 frenchName.generate= false; 0107 frenchName.id= 8; 0108 0109 // star wars 0110 DataBase swBoth; 0111 swBoth.filepath= ":/data/result_Name_human_star_wars_Male.txt"; 0112 swBoth.gender= BOTH; 0113 swBoth.generate= true; 0114 swBoth.id= 9; 0115 0116 DataBase swName; 0117 swName.filepath= ":/data/result_Last_Name_human_star_wars_Male.txt"; 0118 swName.gender= NONE; 0119 swName.generate= true; 0120 swName.id= 10; 0121 0122 // Russian 0123 DataBase russianMale; 0124 russianMale.filepath= ":/data/datarussian_firstname_h.txt"; 0125 russianMale.gender= Male; 0126 russianMale.generate= false; 0127 russianMale.id= 11; 0128 0129 DataBase russianFemale; 0130 russianFemale.filepath= ":/data/datarussian_firstname_w.txt"; 0131 russianFemale.gender= Female; 0132 russianFemale.generate= false; 0133 russianFemale.id= 12; 0134 0135 DataBase russianName; 0136 russianName.filepath= ":/data/result_last_name_russian.txt"; 0137 russianName.gender= NONE; 0138 russianName.generate= true; 0139 russianName.id= 13; 0140 0141 // English 0142 DataBase englishMale; 0143 englishMale.filepath= ":/data/data_Name_English_Male.txt"; 0144 englishMale.gender= Male; 0145 englishMale.generate= false; 0146 englishMale.id= 14; 0147 0148 DataBase englishFemale; 0149 englishFemale.filepath= ":/data/data_Name_English_Female.txt"; 0150 englishFemale.gender= Female; 0151 englishFemale.generate= false; 0152 englishFemale.id= 15; 0153 0154 DataBase englishName; 0155 englishName.filepath= ":/data/lastName_english.txt"; 0156 englishName.gender= NONE; 0157 englishName.generate= false; 0158 englishName.id= 16; 0159 0160 // database 0161 QHash<QString, DataBase> chineseDataBase; 0162 chineseDataBase.insert(MName, chineseMale); 0163 chineseDataBase.insert(FName, chineseFemale); 0164 0165 QHash<QString, DataBase> swDataBase; 0166 swDataBase.insert(BothName, swBoth); 0167 swDataBase.insert(LName, swName); 0168 0169 QHash<QString, DataBase> elveDataBase; 0170 elveDataBase.insert(MName, elveMale); 0171 elveDataBase.insert(FName, elveFemale); 0172 0173 QHash<QString, DataBase> jpnDataBase; 0174 jpnDataBase.insert(MName, jpMale); 0175 jpnDataBase.insert(FName, jpFemale); 0176 0177 // create french database 0178 QHash<QString, DataBase> FrenchDataBase; 0179 FrenchDataBase.insert(MName, frenchMale); 0180 FrenchDataBase.insert(FName, frenchFemale); 0181 FrenchDataBase.insert(LName, frenchName); 0182 0183 // russian 0184 QHash<QString, DataBase> russianDataBase; 0185 russianDataBase.insert(MName, russianMale); 0186 russianDataBase.insert(FName, russianFemale); 0187 russianDataBase.insert(LName, russianName); 0188 0189 QHash<QString, DataBase> englishDataBase; 0190 englishDataBase.insert(MName, englishMale); 0191 englishDataBase.insert(FName, englishFemale); 0192 englishDataBase.insert(LName, englishName); 0193 0194 // inserting databases 0195 m_complexName.insert(Japanese, jpnDataBase); 0196 m_complexName.insert(Chinese, chineseDataBase); 0197 m_complexName.insert(Elves, elveDataBase); 0198 m_complexName.insert(French, FrenchDataBase); 0199 m_complexName.insert(StarWars, swDataBase); 0200 m_complexName.insert(Russian, russianDataBase); 0201 m_complexName.insert(English, englishDataBase); 0202 0203 checkFeatureAvailability(); 0204 } 0205 0206 NameGeneratorWidget::~NameGeneratorWidget() 0207 { 0208 delete ui; 0209 } 0210 0211 void NameGeneratorWidget::buildAllNames(int count, QHash<QString, DataBase> data) 0212 { 0213 QList<DataBase> list; 0214 if((ui->m_femaleBtn->isChecked()) && (ui->m_femaleBtn->isEnabled())) 0215 { 0216 list << data.value(FName); 0217 } 0218 else if((ui->m_maleBtn->isChecked()) && (ui->m_maleBtn->isEnabled())) 0219 { 0220 list << data.value(MName); 0221 } 0222 else 0223 { 0224 list << data.value(BothName); 0225 } 0226 if(ui->m_complexName->isChecked()) 0227 { 0228 list << data.value(LName); 0229 } 0230 QList<QJsonDocument> generationData; 0231 QList<QStringList> pickUpData; 0232 0233 for(auto& database : list) 0234 { 0235 QFile loadFile(database.filepath); 0236 0237 if(!loadFile.open(QIODevice::ReadOnly)) 0238 { 0239 qWarning("Couldn't open save file."); 0240 return; 0241 } 0242 if(database.generate) 0243 { 0244 QByteArray saveData= loadFile.readAll(); 0245 0246 QJsonDocument loadDoc(QJsonDocument::fromJson(saveData)); 0247 generationData.append(loadDoc); 0248 } 0249 else 0250 { 0251 QTextStream in(&loadFile); 0252 0253 QStringList strData; 0254 while(!in.atEnd()) 0255 { 0256 strData << in.readLine(); 0257 } 0258 0259 pickUpData.append(strData); 0260 } 0261 } 0262 int maxTry= 30; 0263 for(int i= 0; i < count; ++i) 0264 { 0265 int indexGenerated= 0; 0266 int indexPickUp= 0; 0267 QString result(""); 0268 for(auto& database : list) 0269 { 0270 QString tmpresult; 0271 0272 if(database.generate) 0273 { 0274 QJsonObject json= generationData.at(indexGenerated).object(); 0275 do 0276 { 0277 --maxTry; 0278 tmpresult= buildName(json); 0279 } while(tmpresult.size() < 2 && maxTry > 0); 0280 ++indexGenerated; 0281 } 0282 else 0283 { 0284 do 0285 { 0286 --maxTry; 0287 tmpresult= pickUpName(pickUpData.at(indexPickUp)); 0288 } while(tmpresult.size() < 2 && maxTry > 0); 0289 ++indexPickUp; 0290 } 0291 0292 result+= QString("%1 ").arg(tmpresult); 0293 } 0294 ui->m_result->append(result); 0295 } 0296 } 0297 0298 void NameGeneratorWidget::generateName() 0299 { 0300 ui->m_result->clear(); 0301 int i= ui->m_database->currentIndex() * 2; 0302 if(ui->m_femaleBtn->isChecked()) 0303 { 0304 ++i; 0305 } 0306 TypeOfGeneration index= (TypeOfGeneration)ui->m_database->currentIndex(); 0307 0308 QHash<QString, DataBase> data= m_complexName.value(index); 0309 0310 buildAllNames(ui->m_nameCount->value(), data); 0311 } 0312 QString NameGeneratorWidget::pickUpName(QStringList data) 0313 { 0314 if(data.isEmpty()) 0315 return QString(); 0316 int len= m_generator.bounded(data.size()); 0317 0318 if(data.size() > len) 0319 return data.at(len); 0320 else 0321 return QString(); 0322 } 0323 0324 QString NameGeneratorWidget::buildName(const QJsonObject& json) 0325 { 0326 int len= m_generator.bounded(10) + 2; 0327 QString result; 0328 QJsonObject firstLetter= json["firstLetter"].toObject(); 0329 qreal first= m_generator.generateDouble(); // / std::numeric_limits<qreal>::digits; 0330 qreal sum= 0; 0331 0332 auto keys= firstLetter.keys(); 0333 for(auto& key : keys) 0334 { 0335 sum+= firstLetter[key].toDouble(); 0336 if((sum > first) && (result.isEmpty())) 0337 { 0338 result= key; 0339 } 0340 } 0341 int rLen= len - 1; // already find the first character. 0342 0343 for(int index= 0; index < rLen; ++index) 0344 { 0345 bool lastIndex= result.size() + 1 == len ? true : false; 0346 bool beforeLast= ((result.size() + 2) == len) ? true : false; 0347 QString duo; 0348 if(result.count() == 1) 0349 { 0350 duo= "0" + result; 0351 } 0352 else 0353 { 0354 duo= result.right(2); 0355 } 0356 0357 QJsonObject dataJson= json["data"].toObject(); 0358 QJsonObject duoJson= dataJson[duo.toLower()].toObject(); 0359 QString lastestChar= result.right(1); 0360 0361 if(lastIndex) 0362 { 0363 dataJson= json["lastLetter"].toObject(); 0364 duoJson= dataJson[duo.toLower()].toObject(); 0365 } 0366 0367 QJsonObject::iterator i; 0368 int sumDict= 0; 0369 for(i= duoJson.begin(); i != duoJson.end(); ++i) 0370 { 0371 if(i.key() != "0") 0372 { 0373 if(nextIsPossible(json, QStringLiteral("%1%2").arg(lastestChar, i.key()), beforeLast)) 0374 { 0375 sumDict+= i.value().toInt(); 0376 } 0377 } 0378 } 0379 if(sumDict > 0) 0380 { 0381 int value= m_generator.bounded(sumDict); 0382 sumDict= 0; 0383 bool unfound= true; 0384 for(i= duoJson.begin(); i != duoJson.end() && unfound; ++i) 0385 { 0386 if(i.key() != "0") 0387 { 0388 if(nextIsPossible(json, QStringLiteral("%1%2").arg(lastestChar, i.key()), beforeLast)) 0389 { 0390 sumDict+= i.value().toInt(); 0391 if(sumDict > value) 0392 { 0393 result.append(i.key()); 0394 unfound= false; 0395 } 0396 } 0397 } 0398 } 0399 } 0400 } 0401 return result; 0402 } 0403 bool NameGeneratorWidget::nextCharacterCanEnd(const QJsonObject& json, QString key) 0404 { 0405 QJsonObject dataJson= json["lastLetter"].toObject(); 0406 if(dataJson[key.toLower()].isUndefined()) 0407 { 0408 return false; 0409 } 0410 else 0411 { 0412 return true; 0413 } 0414 } 0415 void NameGeneratorWidget::checkFeatureAvailability() 0416 { 0417 TypeOfGeneration index= (TypeOfGeneration)ui->m_database->currentIndex(); 0418 0419 QHash<QString, DataBase> data= m_complexName.value(index); 0420 if(!data.contains(LName)) 0421 { 0422 ui->m_complexName->setChecked(false); 0423 ui->m_complexName->setEnabled(false); 0424 } 0425 else 0426 { 0427 ui->m_complexName->setEnabled(true); 0428 } 0429 0430 if(data.contains(FName)) 0431 { 0432 ui->m_femaleBtn->setEnabled(true); 0433 } 0434 else 0435 { 0436 ui->m_femaleBtn->setEnabled(false); 0437 ui->m_femaleBtn->setChecked(false); 0438 } 0439 if(data.contains(MName)) 0440 { 0441 ui->m_maleBtn->setEnabled(true); 0442 } 0443 else 0444 { 0445 ui->m_maleBtn->setEnabled(false); 0446 ui->m_maleBtn->setChecked(false); 0447 } 0448 } 0449 0450 bool NameGeneratorWidget::nextIsPossible(const QJsonObject& json, QString key, bool last) 0451 { 0452 if(last) 0453 { 0454 return nextCharacterCanEnd(json, key); 0455 } 0456 QJsonObject dataJson= json["data"].toObject(); 0457 if(dataJson[key.toLower()].isUndefined()) 0458 { 0459 return false; 0460 } 0461 else 0462 { 0463 return true; 0464 } 0465 }