added racelistgenerator + changed title of windows with drivers and car statistics
This commit is contained in:
@@ -53,6 +53,7 @@ set(helloworld_SRCS
|
||||
resultmodel.cpp
|
||||
result.cpp
|
||||
evaluation.cpp
|
||||
racelistgenerator.cpp
|
||||
|
||||
mainwindow.ui
|
||||
windowrace.ui
|
||||
|
||||
96
racelistgenerator.cpp
Normal file
96
racelistgenerator.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
#include "racelistgenerator.h"
|
||||
|
||||
RaceListGenerator::RaceListGenerator(vector<int> driverIds,
|
||||
vector<int> 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<struct Combination> x1,
|
||||
vector<struct Combination> 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<vector<int>> RaceListGenerator::getList() {
|
||||
std::srand(unsigned(std::time(nullptr)));
|
||||
|
||||
vector<int> drivers = this->driverIds;
|
||||
|
||||
vector<int> cars = this->carIds;
|
||||
|
||||
vector<struct Combination> shellList;
|
||||
vector<struct Combination> 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<vector<int>> vecToReturn;
|
||||
vector<int> 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<int> drivers = {0, 1, 2};
|
||||
vector<int> cars = {0, 1, 2, 3, 4};
|
||||
vector<vector<int>> list = getList();
|
||||
|
||||
// std::for_each(list.begin(), list.end(), print);
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
void RaceListGenerator::print(vector<int> v) {
|
||||
std::for_each(v.begin(), v.end(), [](int vec) { cout << vec << " "; });
|
||||
cout << " " << endl;
|
||||
}
|
||||
|
||||
int RaceListGenerator::myrandom(int i) {
|
||||
return std::rand() % i;
|
||||
}
|
||||
35
racelistgenerator.h
Normal file
35
racelistgenerator.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef RACELISTGENERATOR_H
|
||||
#define RACELISTGENERATOR_H
|
||||
|
||||
#include <algorithm> // shuffle list
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::vector;
|
||||
|
||||
struct Combination {
|
||||
int driver;
|
||||
int car;
|
||||
};
|
||||
|
||||
|
||||
class RaceListGenerator
|
||||
{
|
||||
public:
|
||||
RaceListGenerator(vector<int> driverIds, vector<int> carIds);
|
||||
vector<vector<int>> getList() ;
|
||||
|
||||
private:
|
||||
void print(vector<int> v);
|
||||
static int myrandom(int i);
|
||||
bool matchList(vector<struct Combination> x1, vector<struct Combination> x2);
|
||||
bool matchCombination(struct Combination x1, struct Combination x2);
|
||||
|
||||
vector<int> driverIds;
|
||||
vector<int> carIds;
|
||||
};
|
||||
|
||||
#endif // RACELISTGENERATOR_H
|
||||
28
result.cpp
28
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<string>(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<string> carNames, vector<struct Times> 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<string> carNames, vector<struct Times> 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<string> 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<string> 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;
|
||||
}
|
||||
|
||||
1
result.h
1
result.h
@@ -50,6 +50,7 @@ class Result : public QWidget {
|
||||
DataBase * db;
|
||||
int rennid;
|
||||
int minimumTime;
|
||||
QString renndatum;
|
||||
};
|
||||
|
||||
#endif // RESULT_H
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "windowssettings.h"
|
||||
#include "racelistgenerator.h"
|
||||
#include "ui_windowssettings.h"
|
||||
#include <QStringListModel>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
@@ -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<QString> 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<QString> 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<int> selectedCarIds;
|
||||
foreach (const QModelIndex & index,
|
||||
this->ui->lVCars->selectionModel()->selectedIndexes()) {
|
||||
selectedCarIds.push_back(
|
||||
this->carIds.at(static_cast<unsigned long>(index.row()))
|
||||
.at(0)
|
||||
.toInt());
|
||||
}
|
||||
|
||||
vector<int> selectedDriverIds;
|
||||
foreach (const QModelIndex & index,
|
||||
this->ui->lVDrivers->selectionModel()->selectedIndexes()) {
|
||||
selectedDriverIds.push_back(
|
||||
this->driversList.at(static_cast<unsigned long>(index.row()))
|
||||
.at(1)
|
||||
.toInt());
|
||||
}
|
||||
|
||||
RaceListGenerator raceListGeneator(selectedDriverIds, selectedCarIds);
|
||||
vector<vector<int>> 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; });
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "database.h"
|
||||
#include <QMainWindow>
|
||||
#include <qstringlistmodel.h>
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
@@ -22,6 +23,10 @@ class WindowsSettings : public QMainWindow {
|
||||
string currentDateTime();
|
||||
DataBase * db;
|
||||
int rennId;
|
||||
vector<vector<QString>> carIds;
|
||||
vector<vector<QString>> 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
|
||||
|
||||
Reference in New Issue
Block a user