Compare commits

...

5 Commits

@ -10,6 +10,15 @@ SameGame in PINK by Isifluff
![Screenshot of ThinkPink](Screenshot.png "Screenshot of ThinkPink")
### Dependencies
## How to Build
### Required versions
* Qt6
* C++20
### Instructions
#### On Unix / Linux
```
git clone https://git.floating-in.space/isabell/ThinkPink.git && cd ThinkPink/ThinkPink
qmake
make -j
```

@ -94,12 +94,155 @@ void MainWindow::bubbleBoxes(std::set<std::vector<int>> *connected) {
refreshButtonGrid();
}
void MainWindow::showHighscore() {
QMap<QPair<QString, QDateTime>, int> MainWindow::newEntry() {
QDialog entryDial;
entryDial.setPalette(MainWindow::palette());
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();
entryDial.done(0);
});
// 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() {
QMap<QPair<QString, QDateTime>, int> entry = newEntry();
if(!highscore.empty() && highscore.size() == 10) {
QList<int> scores = highscore.values();
std::sort(scores.begin(), scores.end());
if (ui->lcdScore->intValue() <= *(scores.end()))
return;
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 << Qt::endl;
}
highscoreCSV.close();
usleep(500); // paranoia
}
void MainWindow::readHighscore() {
highscore.clear();
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;
highscoreDial.setPalette(MainWindow::palette());
QVBoxLayout *layout = new QVBoxLayout;
QLabel *title = new QLabel("<h1> Highscores </h1> <br>");
title->setAlignment(Qt::AlignCenter);
//title->set
layout->addWidget(title);
QList<QPair<QString, QDateTime>> sorted_keys = highscore.keys();
std::sort(sorted_keys.begin(), sorted_keys.end());
int i = 1;
for (auto key = sorted_keys.end()-1; key != sorted_keys.begin()-1; key--) {
auto entry = highscore.find(*key);
QHBoxLayout *entry_layout = new QHBoxLayout;
QLabel *entry_name = new QLabel(QString::fromStdString(std::to_string(i)) + ") <b>" + entry.key().first + "</b>");
QLCDNumber *entry_score = new QLCDNumber();
entry_score->display(entry.value());
QLabel *entry_datetime = new QLabel(entry.key().second.toString(Qt::DateFormat::TextDate));
entry_layout->addWidget(entry_name);
entry_layout->addWidget(entry_score);
entry_layout->addWidget(entry_datetime);
layout->addLayout(entry_layout);
i++;
}
highscoreDial.setLayout(layout);
highscoreDial.exec();
}
// 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<std::vector<int>> connected;
@ -108,15 +251,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 +282,7 @@ void MainWindow::newGame() {
}
MainWindow::setEnabled(true);
if (!checkLeftoverMoves()) {
ui->statusBar->showMessage("Game over.");
gameOver();
}
}
@ -156,7 +309,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 +323,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() {

@ -6,11 +6,15 @@
#include <vector>
#include <QDebug>
#include <QDir>
#include <QGenericMatrix>
#include <QLineEdit>
#include <QMainWindow>
#include <QMessageBox>
#include <QPushButton>
#include <QSettings>
#include <QStandardPaths>
#include <QTextStream>
#include "samegame.h"
@ -39,19 +43,27 @@ public:
void bubbleUp(int row, int column);
void bubbleBoxes(std::set<std::vector<int>> *connected);
void setPalettes();
void showHighscore();
void gameOver();
// highscore functions
void processHighscore();
void readHighscore();
QMap<QPair<QString, QDateTime>, 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<std::vector<QPushButton *>> buttonGrid;
QMap<QPair<QString, QDateTime>, int> highscore;
};
#endif // MAINWINDOW_H

@ -59,3 +59,7 @@ void SameGame::getConnected(std::set<std::vector<int>> *connectedSet, QString co
checkNeighbour(connectedSet, color, row, column+1);
checkNeighbour(connectedSet, color, row, column-1);
}
int SameGame::getNumberOfColors() {
return colors.size();
}

@ -18,6 +18,7 @@ public:
void setCell(int row, int column, QString color);
void checkNeighbour(std::set<std::vector<int>> *connectedSet, QString color, int row, int column);
void getConnected(std::set<std::vector<int>> *connectedSet, QString color, int row, int column);
int getNumberOfColors();
void deleteCell(int row, int column);
};

Loading…
Cancel
Save