Warning, file /games/katomic/src/levelset.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     This file is part of the KDE project "KAtomic"
0003 
0004     SPDX-FileCopyrightText: 2006-2009 Dmitry Suzdalev <dimsuz@gmail.com>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 #include "levelset.h"
0010 
0011 #include "katomic_debug.h"
0012 #include "atom.h"
0013 #include "molecule.h"
0014 
0015 #include <KConfigGroup>
0016 #include <KLocalizedString>
0017 
0018 #include <QFileInfo>
0019 #include <QStandardPaths>
0020 
0021 LevelData::LevelData(const QList<Element>& elements, const Molecule* mol)
0022     : m_molecule(mol)
0023 {
0024     memset(m_field, 0, sizeof(m_field));
0025     m_atoms.reserve(elements.size());
0026     for (const Element& el : elements)
0027     {
0028         if (el.atom == -1)
0029         {
0030             m_field[el.x][el.y] = true; // a wall
0031         }
0032         else
0033         {
0034             m_atoms.append(el);
0035         }
0036     }
0037     m_atoms.squeeze();
0038 }
0039 
0040 LevelData::~LevelData()
0041 {
0042     delete m_molecule;
0043 }
0044 
0045 QList<LevelData::Element> LevelData::atomElements() const
0046 {
0047     return m_atoms;
0048 }
0049 
0050 bool LevelData::containsWallAt(int x, int y) const
0051 {
0052     return m_field[x][y];
0053 }
0054 
0055 const Molecule* LevelData::molecule() const
0056 {
0057     return m_molecule;
0058 }
0059 
0060 // ==================================================
0061 
0062 LevelSet::LevelSet()
0063 {
0064     reset();
0065 }
0066 
0067 LevelSet::~LevelSet()
0068 {
0069     qDeleteAll(m_levelCache);
0070 }
0071 
0072 void LevelSet::reset()
0073 {
0074     m_name = QString();
0075     m_visibleName = QString();
0076     m_description = QString();
0077     m_author = QString();
0078     m_authorEmail = QString();
0079     m_levelCount = 0;
0080 
0081     qDeleteAll(m_levelCache);
0082     m_levelCache.clear();
0083 }
0084 
0085 bool LevelSet::load(const QString& levelSetName)
0086 {
0087     QString file = QStandardPaths::locate(QStandardPaths::AppDataLocation, QStringLiteral("levels/%1.dat").arg(levelSetName));
0088     if (file.isEmpty())
0089     {
0090         qCDebug(KATOMIC_LOG) << "level set \"" << levelSetName << "\" data file not found. Check your installation";
0091         return false;
0092     }
0093 
0094     bool res = loadFromFile(file);
0095     if (!res) {
0096         qCDebug(KATOMIC_LOG) << "warning: failed to load level set" << levelSetName;
0097     }
0098 
0099     return res;
0100 }
0101 
0102 bool LevelSet::loadFromFile(const QString& fileName)
0103 {
0104     reset();
0105 
0106     m_levelsFile = KSharedConfig::openConfig(fileName, KConfig::SimpleConfig);
0107     KConfigGroup gr = m_levelsFile->group(QStringLiteral("LevelSet"));
0108 
0109     m_visibleName = gr.readEntry("Name");
0110     m_description = gr.readEntry("Description");
0111     m_author = gr.readEntry("Author");
0112     m_authorEmail = gr.readEntry("AuthorEmail");
0113     m_levelCount = gr.readEntry("LevelCount", 0);
0114 
0115     m_name = QFileInfo(fileName).baseName();
0116 
0117     if (m_levelCount <= 0) {
0118         //qCDebug(KATOMIC_LOG) << "warning: in level set" << m_name << "level count not specified or invalid";
0119     }
0120 
0121     return true;
0122 }
0123 
0124 QString LevelSet::name() const
0125 {
0126     return m_name;
0127 }
0128 
0129 QString LevelSet::visibleName() const
0130 {
0131     return m_visibleName;
0132 }
0133 
0134 QString LevelSet::author() const
0135 {
0136     return m_author;
0137 }
0138 
0139 QString LevelSet::authorEmail() const
0140 {
0141     return m_authorEmail;
0142 }
0143 
0144 QString LevelSet::description() const
0145 {
0146     return m_description;
0147 }
0148 
0149 int LevelSet::levelCount() const
0150 {
0151     return m_levelCount;
0152 }
0153 
0154 const LevelData* LevelSet::levelData(int levelNum) const
0155 {
0156     LevelData* data = m_levelCache.value(levelNum, nullptr);
0157     return data ? data : readLevel(levelNum);
0158 }
0159 
0160 const LevelData* LevelSet::readLevel(int levelNum) const
0161 {
0162     KConfigGroup config = m_levelsFile->group(QStringLiteral("Level")+QString::number(levelNum));
0163 
0164     QList<LevelData::Element> elements;
0165 
0166     elements.reserve(FIELD_SIZE * FIELD_SIZE);
0167     for (int j = 0; j < FIELD_SIZE; j++)
0168     {
0169         const QString key = QString::asprintf("feld_%02d", j);
0170         QString line = config.readEntry(key,QString());
0171 
0172         for (int i = 0; i < FIELD_SIZE; i++)
0173         {
0174             if (line.isEmpty())
0175             {
0176                 //qCDebug(KATOMIC_LOG) << "error while reading level" << levelNum << "data from" << m_name;
0177                 return nullptr;
0178             }
0179 
0180             QChar c = line.at(i);
0181             if( c == QLatin1Char('#') )
0182             {
0183                 LevelData::Element el;
0184                 el.x = i;
0185                 el.y = j;
0186                 el.atom = -1; // indicates wall
0187 
0188                 elements.append(el);
0189             }
0190             else if (c != QLatin1Char('.'))//atom
0191             {
0192                 LevelData::Element el;
0193                 el.x = i;
0194                 el.y = j;
0195                 el.atom = atom2int(c.toLatin1());
0196 
0197                 elements.append(el);
0198             }
0199         }
0200     }
0201     elements.squeeze();
0202 
0203     // Molecule object will be deleted by LevelData, it takes ownership
0204     LevelData* level = new LevelData(elements, readLevelMolecule(levelNum));
0205     m_levelCache[levelNum] = level;
0206 
0207     return level;
0208 }
0209 
0210 const Molecule* LevelSet::readLevelMolecule(int levelNum) const
0211 {
0212     Molecule* mol = new Molecule();
0213     KConfigGroup config = m_levelsFile->group(QStringLiteral("Level")+QString::number(levelNum));
0214 
0215 
0216     atom current;
0217 
0218     int atom_index = 1;
0219     QString value;
0220     while (true) {
0221         const QString key = QString::asprintf("atom_%c", int2atom(atom_index));
0222         value = config.readEntry(key,QString());
0223         if (value.isEmpty())
0224             break;
0225 
0226         current.obj = value.at(0).toLatin1();
0227         value = value.mid(2);
0228 
0229         strncpy(current.conn, value.toLatin1().constData(), sizeof(current.conn));
0230         if (mol->m_atoms.indexOf(current) != -1)
0231             qCWarning(KATOMIC_LOG)
0232                 << "OOOPS, duplicate atom definition in" << key;
0233         mol->m_atoms.append(current);
0234         atom_index++;
0235     }
0236 
0237     QString line;
0238 
0239     mol->m_width = 0;
0240     mol->m_height = 0;
0241     mol->m_weight = 0.0;
0242 
0243     int max_i = -1;
0244     for (int j = 0; j < MOLECULE_SIZE; j++) {
0245 
0246         const QString key = QString::asprintf("mole_%d", j);
0247         line = config.readEntry(key,QString());
0248 
0249         int max_non_null_i = -1;
0250         for (int i = 0; i < MOLECULE_SIZE; i++)
0251         {
0252             if (i >= line.size())
0253                 mol->m_molek[i][j] = 0;
0254             else
0255             {
0256                 mol->m_molek[i][j] = atom2int(line.at(i).toLatin1());
0257                 mol->m_weight += mol->getAtom(mol->m_molek[i][j]).weight();
0258                 max_non_null_i = i;
0259             }
0260         }
0261         if( max_non_null_i != -1 )
0262             mol->m_height++;
0263         max_i = qMax( max_i, max_non_null_i );
0264     }
0265 
0266     mol->m_width = max_i+1;
0267 
0268     mol->m_name = i18n(config.readEntry("Name", i18n("Noname")).toUtf8().constData());
0269 
0270     return mol;
0271 }
0272 
0273 bool LevelSet::isDefaultLevelsAvailable()
0274 {
0275     QString file = QStandardPaths::locate(QStandardPaths::AppDataLocation, QStringLiteral("levels/%1.dat").arg(QLatin1String(DEFAULT_LEVELSET_NAME)));
0276     if (file.isEmpty())
0277     {
0278         //qCDebug(KATOMIC_LOG) << "default level set \"" << DEFAULT_LEVELSET_NAME << "\" data file not found. Check your installation";
0279         return false;
0280     }
0281 
0282     return true;
0283 }