diff --git a/CMakeLists.txt b/CMakeLists.txt index d9bf794..132c504 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,7 @@ set(helloworld_SRCS resultmodel.cpp result.cpp evaluation.cpp + racelistgenerator.cpp mainwindow.ui windowrace.ui diff --git a/racelistgenerator.cpp b/racelistgenerator.cpp new file mode 100644 index 0000000..3bb3be4 --- /dev/null +++ b/racelistgenerator.cpp @@ -0,0 +1,96 @@ +#include "racelistgenerator.h" + +RaceListGenerator::RaceListGenerator(vector driverIds, + vector carIds) { + this->driverIds = driverIds; + this->carIds = carIds; +} + +bool RaceListGenerator::matchCombination(struct Combination x1, + struct Combination x2) { + // returns true if combination is possible; means drivers as well as cars + // differs + if (x1.car != x2.car) { + if (x1.driver != x2.driver) { + return true; + } + return false; + } + return false; +} +bool RaceListGenerator::matchList(vector x1, + vector x2) { + if (x1.size() != x2.size()) { + return false; + } + + for (size_t i = 0; i < x1.size(); i++) { + if (!matchCombination(x1.at(i), x2.at(i))) { + // no match; driver or car used twice + return false; + } + } + return true; +} + +// returns a valid list for a race +// structur: shellcar, shelldriver, deacar, deadriver +vector> RaceListGenerator::getList() { + std::srand(unsigned(std::time(nullptr))); + + vector drivers = this->driverIds; + + vector cars = this->carIds; + + vector shellList; + vector deaList; + for (int driver : drivers) { + for (int car : cars) { + struct Combination x = {driver, car}; + shellList.push_back(x); + deaList.push_back(x); + } + } + + // shuffle shell list + std::random_shuffle(shellList.begin(), shellList.end(), myrandom); + + while (1) { + std::random_shuffle(deaList.begin(), deaList.end(), myrandom); + if (matchList(shellList, deaList) == true) { + break; + } + } + vector> vecToReturn; + vector subVec; + + for (unsigned long i = 0; i < shellList.size(); i++) { + subVec.push_back(shellList.at(i).car); + subVec.push_back(shellList.at(i).driver); + subVec.push_back(deaList.at(i).car); + subVec.push_back(deaList.at(i).driver); + vecToReturn.push_back(subVec); + // print(vecToReturn.back()); + subVec.clear(); + } + return vecToReturn; +} +/* +int main() { + vector drivers = {0, 1, 2}; + vector cars = {0, 1, 2, 3, 4}; + vector> list = getList(); + + // std::for_each(list.begin(), list.end(), print); + + return 0; +} +*/ +void RaceListGenerator::print(vector v) { + std::for_each(v.begin(), v.end(), [](int vec) { cout << vec << " "; }); + cout << " " << endl; +} + +int RaceListGenerator::myrandom(int i) { + return std::rand() % i; +} diff --git a/racelistgenerator.h b/racelistgenerator.h new file mode 100644 index 0000000..110f08f --- /dev/null +++ b/racelistgenerator.h @@ -0,0 +1,35 @@ +#ifndef RACELISTGENERATOR_H +#define RACELISTGENERATOR_H + +#include // shuffle list +#include +#include +#include + +using std::cout; +using std::endl; +using std::vector; + +struct Combination { + int driver; + int car; +}; + + +class RaceListGenerator +{ +public: + RaceListGenerator(vector driverIds, vector carIds); + vector> getList() ; + +private: + void print(vector v); + static int myrandom(int i); + bool matchList(vector x1, vector x2); + bool matchCombination(struct Combination x1, struct Combination x2); + + vector driverIds; + vector carIds; +}; + +#endif // RACELISTGENERATOR_H diff --git a/result.cpp b/result.cpp index b2a802e..2444d29 100644 --- a/result.cpp +++ b/result.cpp @@ -33,8 +33,6 @@ Result::Result(DataBase * db, int rennid, QWidget * parent) // this->rennid = 39; this->rennid = rennid; - this->drawPlots(rennid); - // test data header.push_back("Spalte 1"); header.push_back("Spalte 2"); @@ -58,7 +56,7 @@ Result::Result(DataBase * db, int rennid, QWidget * parent) << boost::lexical_cast(rennid); try { - QString renndatum = this->db->getData2(statement.str(), 1).at(0).at(0); + this->renndatum = this->db->getData2(statement.str(), 1).at(0).at(0); this->setWindowTitle(renndatum); } catch (std::exception & e) { Q_UNUSED(e); @@ -295,6 +293,8 @@ Result::Result(DataBase * db, int rennid, QWidget * parent) } this->ui->tWResult->resizeColumnsToContents(); this->ui->tWResult->horizontalHeader()->setStretchLastSection(true); + + this->drawPlots(rennid); } void Result::drawPlots(int rennid) { @@ -623,16 +623,18 @@ void Result::plotCars(vector carNames, vector times) { string strMinRange = boost::str(boost::format("%.2f") % minRange); string strMaxRange = boost::str(boost::format("%.2f") % maxRange); + double distance = (maxRange - minRange) / 35; + cout << "renndatum: " << this->renndatum.toStdString() << endl; gp << "set yrange [" << strMinRange << ":" << strMaxRange << "]\n"; + gp << "set term wxt title '" << this->renndatum.toStdString() << "'\n"; gp << "set boxwidth 0.3\nset style fill solid\n"; gp << "set title 'Vergleich der Autos'\n"; gp << "set ylabel 'Zeit in Sekunden'\n"; gp << "set xlabel 'Autos'\n"; gp << "show grid\nset grid ytics lc rgb '#bbbbbb' lw 1 lt 0\n"; gp << "plot" << gp.file1d(xy_pts) - << "with boxes title 'Shell' lt rgb '#FF0000', '' u 1:($2 + " - "0.05):($2) with labels notitle" - << std::endl; + << "with boxes title 'Shell' lt rgb '#FF0000', '' u 1:($2 + " << distance + << "):($2) with labels notitle" << std::endl; xy_pts.clear(); for (size_t i = 0; i < carNames.size(); i++) { @@ -641,7 +643,8 @@ void Result::plotCars(vector carNames, vector times) { } gp << "replot" << gp.file1d(xy_pts) - << "with boxes title 'Dea' lt rgb '#00FF00', ''u 1:($2 + 0.05):($2) " + << "with boxes title 'Dea' lt rgb '#00FF00', ''u 1:($2 + " << distance + << "):($2) " "with labels notitle" << std::endl; } @@ -676,16 +679,18 @@ void Result::plotDrivers(vector driverNames, string strMinRange = boost::str(boost::format("%.2f") % minRange); string strMaxRange = boost::str(boost::format("%.2f") % maxRange); + double distance = (maxRange - minRange) / 35; + gp << "set yrange [" << strMinRange << ":" << strMaxRange << "]\n"; + gp << "set term wxt title '" << this->renndatum.toStdString() << "'\n"; gp << "set boxwidth 0.3\nset style fill solid\n"; gp << "set title 'Vergleich der Fahrer'\n"; gp << "set ylabel 'Zeit in Sekunden'\n"; gp << "set xlabel 'Fahrer'\n"; gp << "show grid\nset grid ytics lc rgb '#bbbbbb' lw 1 lt 0\n"; gp << "plot" << gp.file1d(xy_pts) - << "with boxes title 'Shell' lt rgb '#FF0000', '' u 1:($2 + " - "0.05):($2) with labels notitle" - << std::endl; + << "with boxes title 'Shell' lt rgb '#FF0000', '' u 1:($2 + " << distance + << "):($2) with labels notitle" << std::endl; xy_pts.clear(); for (size_t i = 0; i < driverNames.size(); i++) { @@ -694,7 +699,8 @@ void Result::plotDrivers(vector driverNames, } gp << "replot" << gp.file1d(xy_pts) - << "with boxes title 'Dea' lt rgb '#00FF00', ''u 1:($2 + 0.05):($2) " + << "with boxes title 'Dea' lt rgb '#00FF00', ''u 1:($2 +" << distance + << "):($2) " "with labels notitle" << std::endl; } diff --git a/result.h b/result.h index 0bcd776..624a2d9 100644 --- a/result.h +++ b/result.h @@ -50,6 +50,7 @@ class Result : public QWidget { DataBase * db; int rennid; int minimumTime; + QString renndatum; }; #endif // RESULT_H diff --git a/windowssettings.cpp b/windowssettings.cpp index e879546..3fcf8be 100644 --- a/windowssettings.cpp +++ b/windowssettings.cpp @@ -1,5 +1,8 @@ #include "windowssettings.h" +#include "racelistgenerator.h" #include "ui_windowssettings.h" +#include +#include #include #include #include @@ -29,6 +32,11 @@ WindowsSettings::WindowsSettings(DataBase * db, QWidget * parent) QObject::connect(this->ui->lEMinRundenzeit, SIGNAL(textChanged(QString)), this, SLOT(repaintMinCurLapTime())); + QObject::connect(this->ui->pBcreateListClose, SIGNAL(clicked()), this, + SLOT(createRaceListAndClose())); + QObject::connect(this->ui->pBCancel, SIGNAL(clicked()), this, + SLOT(closeWindow())); + // update minimal lap time on changeing minimal sector time // QObject::connect(this->ui->lEMinTimeSec1, // SIGNAL(textChanged(QString)), @@ -88,13 +96,62 @@ WindowsSettings::WindowsSettings(DataBase * db, QWidget * parent) statement = "SELECT id, minimumroundtime FROM rennen order by id DESC limit 1"; res = this->db->getData(statement, 2); - this->rennId = res[0][0].toInt(); + this->rennId = res.at(0).at(0).toInt(); this->ui->lEMinRundenzeitAktRennen->setText(res.at(0).at(1)); + // setup Rennliste + // setup drivers + this->ui->lVDrivers->setSelectionMode( + QAbstractItemView::ExtendedSelection); + statement = "select name, id from fahrer"; + driversList = this->db->getData2(statement, 2); + driversModel = new QStringListModel(); + QStringList qDriversList; + std::for_each( + driversList.begin(), driversList.end(), + [&qDriversList](vector i) { qDriversList << i.at(0); }); + driversModel->setStringList(qDriversList); + this->ui->lVDrivers->setModel(driversModel); + + // setup cars + this->ui->lVCars->setSelectionMode( + QAbstractItemView::ExtendedSelection); + + QStringList carNames; + std::stringstream ss; + try { + statement = "select id from autos"; + this->carIds = this->db->getData2(statement, 1); + + for (vector carId : carIds) { + ss << "select AutoKonfiguration.name from AutoKonfiguration " + "where id_auto like " + << carId.at(0).toStdString() + << " order by seit DESC limit 1"; + carNames << this->db->getData2(ss.str(), 1).at(0).at(0); + ss.str(std::string()); + } + + } catch (std::exception & e) { + Q_UNUSED(e); + cout << "cars could not be read from database" << endl; + } + + carModel = new QStringListModel(); + + carModel->setStringList(carNames); + this->ui->lVCars->setModel(carModel); + } catch (std::exception & e) { + Q_UNUSED(e); cout << "missing database :(" << endl; } } + +void WindowsSettings::closeWindow() { + this->close(); +} + void WindowsSettings::repaintMinLapTime() { int minlapTime = 0; minlapTime += this->ui->lEMinTimeSec1->text().toInt(); @@ -179,7 +236,7 @@ WindowsSettings::~WindowsSettings() { // Get current date/time, format is YYYY-MM-DD.HH:mm:ss string WindowsSettings::currentDateTime() { - time_t now = time(0); + time_t now = time(nullptr); struct tm tstruct; char buf[80]; tstruct = *localtime(&now); @@ -189,3 +246,71 @@ string WindowsSettings::currentDateTime() { return buf; } + +void WindowsSettings::createRaceListAndClose() { + vector selectedCarIds; + foreach (const QModelIndex & index, + this->ui->lVCars->selectionModel()->selectedIndexes()) { + selectedCarIds.push_back( + this->carIds.at(static_cast(index.row())) + .at(0) + .toInt()); + } + + vector selectedDriverIds; + foreach (const QModelIndex & index, + this->ui->lVDrivers->selectionModel()->selectedIndexes()) { + selectedDriverIds.push_back( + this->driversList.at(static_cast(index.row())) + .at(1) + .toInt()); + } + + RaceListGenerator raceListGeneator(selectedDriverIds, selectedCarIds); + vector> generatedList; + try { + // structure: shellcar, shelldriver, deacar, deadriver + generatedList = raceListGeneator.getList(); + string statement = "select mindestrundendauer from renndauer"; + string minRoundTime = + this->db->getData2(statement, 1).at(0).at(0).toStdString(); + + // calc current time + time_t now = time(nullptr); + struct tm tstruct; + char buf[80]; + tstruct = *localtime(&now); + strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct); + // cout << buf << endl; + string curTime(buf); + + std::stringstream ss; + ss << "insert into Rennen (date, minimumRoundtime) values ('" << curTime + << "', " << minRoundTime << ")"; + this->db->setData(ss.str()); + + // get id of current race + statement = "select id from Rennen order by id DESC limit 1"; + string raceId = + this->db->getData2(statement, 1).at(0).at(0).toStdString(); + + for (auto zeile : generatedList) { + ss.str(std::string()); + ss << "insert into aktRennen (autoShellId, fahrerShellId, " + "autoDeaId, fahrerDeaId, id_rennen) values (" + << zeile.at(0) << ", " << zeile.at(1) << ", " << zeile.at(2) + << ", " << zeile.at(3) << ", " << raceId << ")"; + this->db->setData(ss.str()); + } + + } catch (std::exception & e) { + Q_UNUSED(e); + } + this->close(); + // test + // std::for_each(selectedCarIds.begin(), selectedCarIds.end(), + // [](int id) { cout << id << " " << endl; }); + // test + // std::for_each(selectedDriverIds.begin(), selectedDriverIds.end(), + // [](int id) { cout << id << " " << endl; }); +} diff --git a/windowssettings.h b/windowssettings.h index c4104b0..5fdd45f 100644 --- a/windowssettings.h +++ b/windowssettings.h @@ -3,6 +3,7 @@ #include "database.h" #include +#include #include using std::string; @@ -22,6 +23,10 @@ class WindowsSettings : public QMainWindow { string currentDateTime(); DataBase * db; int rennId; + vector> carIds; + vector> driversList; + QStringListModel * carModel; + QStringListModel * driversModel; public slots: void SaveDauerSlot(); void AbbrechenSlot(); @@ -29,6 +34,8 @@ class WindowsSettings : public QMainWindow { void SaveDauerAndExitSlot(); void repaintMinLapTime(); void repaintMinCurLapTime(); + void createRaceListAndClose(); + void closeWindow(); }; #endif // WINDOWSSETTINGS_H