diff --git a/ThinkPink/mainwindow.cpp b/ThinkPink/mainwindow.cpp index 82a9bc4..68b461b 100644 --- a/ThinkPink/mainwindow.cpp +++ b/ThinkPink/mainwindow.cpp @@ -94,12 +94,136 @@ void MainWindow::bubbleBoxes(std::set> *connected) { refreshButtonGrid(); } -void MainWindow::showHighscore() { +QMap, int> MainWindow::newEntry() { + QDialog entryDial; + QLabel *label1 = new QLabel("New highscore!"); + QLabel *label2 = new QLabel("Enter your name:"); + QLabel *label3 = new QLabel("Score:"); + QLineEdit *lineEdit = new QLineEdit; + QString name = qgetenv("USER"); + if (name.isEmpty()) + name = qgetenv("USERNAME"); + lineEdit->setText(name); + QString confirmed_name; + QPushButton *button = new QPushButton("Ok"); + QLCDNumber *lcdNumber = new QLCDNumber; + lcdNumber->display(ui->lcdScore->intValue()); + // Verbinden des Button-Klicks mit einem Slot + entryDial.connect(button, &QPushButton::clicked, &entryDial, [&]() { + confirmed_name = lineEdit->text(); + }); + + // Erstellen des Layouts + QVBoxLayout *layout = new QVBoxLayout; + QHBoxLayout *sub_layout1 = new QHBoxLayout; + QHBoxLayout *sub_layout2 = new QHBoxLayout; + layout->addWidget(label1); + layout->addLayout(sub_layout1); + sub_layout1->addWidget(label2); + sub_layout1->addWidget(lineEdit); + layout->addLayout(sub_layout2); + sub_layout2->addWidget(label3); + sub_layout2->addWidget(lcdNumber); + layout->addWidget(button, Qt::AlignRight); + entryDial.setLayout(layout); + entryDial.exec(); + + QMap, int> new_entry; + QPair new_key(confirmed_name, QDateTime::currentDateTime()); + new_entry.insert(new_key, ui->lcdScore->intValue()); + + entryDial.disconnect(); + return new_entry; +} + +void MainWindow::processHighscore() { + QList scores = highscore.values(); + std::sort(scores.begin(), scores.end()); + if (ui->lcdScore->intValue() <= *(scores.end())) + return; + + QMap, int> entry = newEntry(); + auto smallest = highscore.keyValueBegin(); + for (auto map_entry = highscore.keyValueBegin(); map_entry != highscore.keyValueEnd(); map_entry++) { + if (map_entry->second < smallest->second) + smallest = map_entry; + } + highscore.remove(smallest->first); + highscore.insert(entry); + + QDir appdata = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); + QFile highscoreCSV = QFile(appdata.filePath(csv_name)); + if (!appdata.exists()) { + appdata.mkpath(appdata.absolutePath()); + qDebug() << "Created data folder at " << appdata.absolutePath(); + } + + if (!highscoreCSV.open(QIODevice::WriteOnly)) { + qDebug() << "Error: Couldn't write new highscore."; + return; + } + + QTextStream hs(&highscoreCSV); + for (auto key = highscore.keyValueBegin(); key != highscore.keyValueEnd(); key++){ + hs << key->first.first << ";" << key->first.second.toString(Qt::DateFormat::ISODate) << ";" << key->second; + } + + highscoreCSV.close(); +} + +void MainWindow::readHighscore() { + QDir appdata = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); + QFile highscoreCSV = QFile(appdata.filePath(csv_name)); + if (!appdata.exists()) { + appdata.mkpath(appdata.absolutePath()); + qDebug() << "Created data folder at " << appdata.absolutePath(); + } + if (!highscoreCSV.exists()) + return; + if (!highscoreCSV.open(QIODevice::ReadOnly)) + return; + + QTextStream hs(&highscoreCSV); + QString line; + QStringList fields; + while (hs.readLineInto(&line)) { + fields = line.split(";"); + QPair entry; + entry.first = fields[0]; + entry.second = QDateTime::fromString(fields[1], Qt::ISODate); + highscore.insert(entry, fields[2].toInt()); + } + + highscoreCSV.close(); +} + +void MainWindow::showHighscore_triggered() { + readHighscore(); + if (highscore.size() == 0) { + ui->statusBar->showMessage("There are no highscores yet.", 3000); + return; + } + + QDialog highscoreDial; + + QVBoxLayout *layout = new QVBoxLayout; + for (auto entry = highscore.keyValueBegin(); entry != highscore.keyValueEnd(); entry++) { + QHBoxLayout *entry_layout = new QHBoxLayout; + QLabel *entry_name = new QLabel(entry->first.first); + QLCDNumber *entry_score = new QLCDNumber(entry->second); + QLabel *entry_datetime = new QLabel(entry->first.second.toString(Qt::DateFormat::TextDate)); + entry_layout->addWidget(entry_name); + entry_layout->addWidget(entry_score); + entry_layout->addWidget(entry_datetime); + layout->addLayout(entry_layout); + } + highscoreDial.setLayout(layout); + highscoreDial.show(); } // slots -void MainWindow::buttonPressed(int row, int column) { +void MainWindow::button_clicked(int row, int column) { MainWindow::setEnabled(false); if(game->getCell(row, column) != "none") { std::set> connected; @@ -108,15 +232,25 @@ void MainWindow::buttonPressed(int row, int column) { clearConnected(&connected); bubbleBoxes(&connected); } else - ui->statusBar->showMessage("Only friends get Stars!", 2000); + ui->statusBar->showMessage("Only friends get Stars!", 3000); } MainWindow::setEnabled(true); if (!checkLeftoverMoves()) { - ui->statusBar->showMessage("Game over."); + gameOver(); } } -void MainWindow::newGame() { +void MainWindow::gameOver() { + ui->statusBar->showMessage("Game over."); + usleep(400000); + readHighscore(); + if (rows == 9 && columns == 9 && game->getNumberOfColors() == 5 ) + processHighscore(); + showHighscore_triggered(); +} + +void MainWindow::newGame_triggered() { + gameOver(); // only for testing right now -- remove me! ui->statusBar->clearMessage(); MainWindow::setEnabled(false); QMessageBox newGameDialog; @@ -129,7 +263,7 @@ void MainWindow::newGame() { } MainWindow::setEnabled(true); if (!checkLeftoverMoves()) { - ui->statusBar->showMessage("Game over."); + gameOver(); } } @@ -156,7 +290,7 @@ void MainWindow::initialiseGameGrid() { button_row.push_back(button); connect(button, &QPushButton::clicked, button, [=, this](){ - buttonPressed(i, j); + button_clicked(i, j); }); } buttonGrid.push_back(std::move(button_row)); @@ -170,8 +304,10 @@ void MainWindow::initialiseWindow() { void MainWindow::initialiseMenuBar() { QAction *new_game_action = ui->menuPlay->addAction("New Game"); - connect(new_game_action, SIGNAL(triggered()), this, SLOT(newGame())); + connect(new_game_action, SIGNAL(triggered()), this, SLOT(newGame_triggered())); ui->menuPlay->addSeparator(); + QAction *show_highscore_action = ui->menuPlay->addAction("Highscores"); + connect(show_highscore_action, SIGNAL(triggered()), this, SLOT(showHighscore_triggered())); } void MainWindow::refreshSizes() { diff --git a/ThinkPink/mainwindow.h b/ThinkPink/mainwindow.h index 525f641..2d46b3f 100644 --- a/ThinkPink/mainwindow.h +++ b/ThinkPink/mainwindow.h @@ -6,11 +6,15 @@ #include #include +#include #include +#include #include #include #include #include +#include +#include #include "samegame.h" @@ -39,19 +43,27 @@ public: void bubbleUp(int row, int column); void bubbleBoxes(std::set> *connected); void setPalettes(); - void showHighscore(); + void gameOver(); + + // highscore functions + void processHighscore(); + void readHighscore(); + QMap, int> newEntry(); private slots: - void buttonPressed(int row, int column); - void newGame(); + void button_clicked(int row, int column); + void newGame_triggered(); + void showHighscore_triggered(); private: Ui::MainWindow *ui; const int rows; const int columns; + const QString csv_name = "highscore.csv"; double max_width; double max_height; SameGame *game; std::vector> buttonGrid; + QMap, int> highscore; }; #endif // MAINWINDOW_H diff --git a/ThinkPink/samegame.cpp b/ThinkPink/samegame.cpp index e9df90d..e3b2335 100644 --- a/ThinkPink/samegame.cpp +++ b/ThinkPink/samegame.cpp @@ -59,3 +59,7 @@ void SameGame::getConnected(std::set> *connectedSet, QString co checkNeighbour(connectedSet, color, row, column+1); checkNeighbour(connectedSet, color, row, column-1); } + +int SameGame::getNumberOfColors() { + return colors.size(); +} diff --git a/ThinkPink/samegame.h b/ThinkPink/samegame.h index 3b1af82..faec1ef 100644 --- a/ThinkPink/samegame.h +++ b/ThinkPink/samegame.h @@ -18,6 +18,7 @@ public: void setCell(int row, int column, QString color); void checkNeighbour(std::set> *connectedSet, QString color, int row, int column); void getConnected(std::set> *connectedSet, QString color, int row, int column); + int getNumberOfColors(); void deleteCell(int row, int column); };