|
|
@ -94,12 +94,136 @@ void MainWindow::bubbleBoxes(std::set<std::vector<int>> *connected) {
|
|
|
|
refreshButtonGrid();
|
|
|
|
refreshButtonGrid();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MainWindow::showHighscore() {
|
|
|
|
QMap<QPair<QString, QDateTime>, 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<QPair<QString, QDateTime>, int> new_entry;
|
|
|
|
|
|
|
|
QPair<QString, QDateTime> new_key(confirmed_name, QDateTime::currentDateTime());
|
|
|
|
|
|
|
|
new_entry.insert(new_key, ui->lcdScore->intValue());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
entryDial.disconnect();
|
|
|
|
|
|
|
|
return new_entry;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void MainWindow::processHighscore() {
|
|
|
|
|
|
|
|
QList<int> scores = highscore.values();
|
|
|
|
|
|
|
|
std::sort(scores.begin(), scores.end());
|
|
|
|
|
|
|
|
if (ui->lcdScore->intValue() <= *(scores.end()))
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QMap<QPair<QString, QDateTime>, 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<QString, QDateTime> 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
|
|
|
|
// slots
|
|
|
|
void MainWindow::buttonPressed(int row, int column) {
|
|
|
|
void MainWindow::button_clicked(int row, int column) {
|
|
|
|
MainWindow::setEnabled(false);
|
|
|
|
MainWindow::setEnabled(false);
|
|
|
|
if(game->getCell(row, column) != "none") {
|
|
|
|
if(game->getCell(row, column) != "none") {
|
|
|
|
std::set<std::vector<int>> connected;
|
|
|
|
std::set<std::vector<int>> connected;
|
|
|
@ -108,15 +232,25 @@ void MainWindow::buttonPressed(int row, int column) {
|
|
|
|
clearConnected(&connected);
|
|
|
|
clearConnected(&connected);
|
|
|
|
bubbleBoxes(&connected);
|
|
|
|
bubbleBoxes(&connected);
|
|
|
|
} else
|
|
|
|
} else
|
|
|
|
ui->statusBar->showMessage("Only friends get Stars!", 2000);
|
|
|
|
ui->statusBar->showMessage("Only friends get Stars!", 3000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MainWindow::setEnabled(true);
|
|
|
|
MainWindow::setEnabled(true);
|
|
|
|
if (!checkLeftoverMoves()) {
|
|
|
|
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();
|
|
|
|
ui->statusBar->clearMessage();
|
|
|
|
MainWindow::setEnabled(false);
|
|
|
|
MainWindow::setEnabled(false);
|
|
|
|
QMessageBox newGameDialog;
|
|
|
|
QMessageBox newGameDialog;
|
|
|
@ -129,7 +263,7 @@ void MainWindow::newGame() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MainWindow::setEnabled(true);
|
|
|
|
MainWindow::setEnabled(true);
|
|
|
|
if (!checkLeftoverMoves()) {
|
|
|
|
if (!checkLeftoverMoves()) {
|
|
|
|
ui->statusBar->showMessage("Game over.");
|
|
|
|
gameOver();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -156,7 +290,7 @@ void MainWindow::initialiseGameGrid() {
|
|
|
|
button_row.push_back(button);
|
|
|
|
button_row.push_back(button);
|
|
|
|
|
|
|
|
|
|
|
|
connect(button, &QPushButton::clicked, button, [=, this](){
|
|
|
|
connect(button, &QPushButton::clicked, button, [=, this](){
|
|
|
|
buttonPressed(i, j);
|
|
|
|
button_clicked(i, j);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
buttonGrid.push_back(std::move(button_row));
|
|
|
|
buttonGrid.push_back(std::move(button_row));
|
|
|
@ -170,8 +304,10 @@ void MainWindow::initialiseWindow() {
|
|
|
|
|
|
|
|
|
|
|
|
void MainWindow::initialiseMenuBar() {
|
|
|
|
void MainWindow::initialiseMenuBar() {
|
|
|
|
QAction *new_game_action = ui->menuPlay->addAction("New Game");
|
|
|
|
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();
|
|
|
|
ui->menuPlay->addSeparator();
|
|
|
|
|
|
|
|
QAction *show_highscore_action = ui->menuPlay->addAction("Highscores");
|
|
|
|
|
|
|
|
connect(show_highscore_action, SIGNAL(triggered()), this, SLOT(showHighscore_triggered()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MainWindow::refreshSizes() {
|
|
|
|
void MainWindow::refreshSizes() {
|
|
|
|