1 /*******************************************************************
2 Jan Cermak | johniez | aspt.johniez.com
3 Creative Commons 2.5 Attribution-NonCommercial-NoDerivs 2.5 license
4 http://creativecommons.org/licenses/by-nc-nd/2.5/legalcode
5 *******************************************************************/
7 #include "performance.h"
12 void PerformanceTab::init() {
13 QSettings settings("config/formation.ini", QSettings::IniFormat);
15 format = new QComboBox();
16 format->addItem("---", QVariant(0));
17 format->addItem("5-4-1", QVariant(1));
18 format->addItem("5-3-2", QVariant(2));
19 format->addItem("4-3-3", QVariant(3));
20 format->addItem("4-4-2", QVariant(4));
21 format->addItem("4-5-1", QVariant(5));
22 format->addItem("3-4-3", QVariant(6));
23 format->addItem("3-5-2", QVariant(7));
24 format->setToolTip(tr("Team formation."));
26 reorderPl = new QPushButton(tr("reorder players"));
27 reorderPl->setToolTip(tr("This button set on positions with wrong player type this player, who plays there (LM on LM post..)."));
29 aggression = new QComboBox();
30 for(int i=0; i<=100; i+=5) {
31 aggression->addItem(tr("aggression ") + QString().setNum(i) + "%", i);
33 aggression->setCurrentIndex(settings.value("aggr", 0).toInt()/5);
34 aggression->setToolTip(tr("Team aggression, same as you set in match."));
35 aggress = settings.value("aggr", 0).toInt();
37 home = new QComboBox();
38 home->addItem(tr("play home"), 0.0);
39 home->addItem(tr("play away"), 0.1);
40 home->setToolTip(tr("Where you will play the match."));
42 for(int j=0; j<11; ++j) {
43 plCont[j] = new QHBoxLayout();
44 player[j] = new QComboBox();
45 orders[j] = new QComboBox();
46 orders[j]->setToolTip(tr("'Ind. order' mean one of: Normal, Play along, Play along wing, Play it out, Passing, Own chance, Targetman and Free role."));
47 orders[j]->addItem(tr("ind. order"), 0);
48 for(int i=0; i<playerCnt; ++i) {
50 int age = pls[i].age.toInt();
51 double perf = ((pls[i].morale.toDouble()+pls[i].fitness.toDouble())/200)*pls[i].bestRate.toDouble();
53 oldPenale = (age-30)*3; // 3 points penale per each year over 30
56 player[j]->addItem("[" + pls[i].position + "] " + pls[i].fname + " " + pls[i].lname, QVariant(perf));
58 player[j]->setCurrentIndex(settings.value("Player/"+QString().setNum(j), 0).toInt());
59 postLabel[j] = new QLabel("pos");
60 plPerfLabel[j] = new QLabel(QString().setNum(player[j]->itemData(player[j]->currentIndex()).toDouble(), 'f', 2));
61 plCont[j]->addWidget(postLabel[j]);
62 plCont[j]->addWidget(player[j]);
63 plCont[j]->addWidget(orders[j]);
64 plCont[j]->addWidget(plPerfLabel[j]);
67 container = new QHBoxLayout();
69 container->addWidget(format);
70 container->addWidget(reorderPl);
71 container->addWidget(aggression);
72 container->addWidget(home);
73 mainLayout->addLayout(container);
74 for(int j=0; j<11; ++j) mainLayout->addLayout(plCont[j]);
76 cButt = new QPushButton(tr("count team performance"));
77 mainLayout->addWidget(cButt);
79 result = new QLabel(tr("Set formation, aggression and players.<br>") + "<span style=\"color:red\">" + tr("Results could be inaccurate!") + "</span><br>" + tr("This version do not penalize players at wrong position!<br>See http://flyspray.johniez.com/task/14"));
80 mainLayout->addWidget(result);
82 format->setCurrentIndex(settings.value("form", 0).toInt());
83 formatChange(settings.value("form", 0).toInt());
85 connect(format, SIGNAL(currentIndexChanged(int)), this, SLOT(formatChange(int)));
86 connect(aggression, SIGNAL(currentIndexChanged(int)), this, SLOT(aggressChange(int)));
87 connect(cButt, SIGNAL(clicked()), this, SLOT(recount()));
88 for(int i=0; i<11; i++) {
89 connect(player[i], SIGNAL(currentIndexChanged(int)), this, SLOT(playerChange(int)));
91 connect(reorderPl, SIGNAL(clicked()), this, SLOT(reorderPlayers()));
96 * \brief Performance Tab constructor.
98 PerformanceTab::PerformanceTab(QWidget *parent): QWidget(parent), defs(0), mids(0), fors(0) {
99 mainLayout = new QVBoxLayout;
100 setLayout(mainLayout);
105 * \brief Performance Tab destructor.
107 PerformanceTab::~PerformanceTab() {
108 for(int i=0; i<11; ++i) {
111 delete plPerfLabel[i];
126 * \brief Slot assigned to data change action.
128 void PerformanceTab::dataChanged() {
129 container->removeWidget(format);
131 container->removeWidget(aggression);
133 container->removeWidget(home);
135 container->removeWidget(reorderPl);
137 mainLayout->removeWidget(reinterpret_cast<QWidget*>(container));
140 for(int i=0; i<11; ++i) {
141 mainLayout->removeWidget(reinterpret_cast<QWidget*>(plCont[i]));
144 delete plPerfLabel[i];
148 mainLayout->removeWidget(cButt);
150 mainLayout->removeWidget(result);
152 mainLayout->update();
157 * \brief Set adequate player post by selected formation.
159 void PerformanceTab::postLabels() {
162 for(int i=0; i<11; ++i) {
163 postLabel[i]->setText("??");
166 postLabel[0]->setText("GK");
167 postLabel[1]->setText("LB");
169 orders[1]->addItem(tr("ind. order"), 0);
170 orders[1]->addItem(tr("offensive"), 2);
171 postLabel[2]->setText("CB");
174 postLabel[3]->setText("SW");
176 orders[3]->addItem(tr("ind. order"), 0);
177 postLabel[4]->setText("CB");
179 orders[4]->addItem(tr("ind. order"), 0);
180 postLabel[5]->setText("RB");
182 orders[5]->addItem(tr("ind. order"), 0);
183 orders[5]->addItem(tr("offensive"), 2);
187 postLabel[3]->setText("CB");
189 orders[3]->addItem(tr("ind. order"), 0);
190 postLabel[4]->setText("RB");
192 orders[4]->addItem(tr("ind. order"), 0);
193 orders[4]->addItem(tr("offensive"), 2);
197 postLabel[3]->setText("RB");
199 orders[3]->addItem(tr("ind. order"), 0);
200 orders[3]->addItem(tr("offensive"), 2);
206 postLabel[LMpos]->setText("LM");
207 postLabel[LMpos+1]->setText("CM");
208 postLabel[LMpos+2]->setText("CM");
209 postLabel[LMpos+3]->setText("CM");
210 postLabel[LMpos+4]->setText("RM");
213 postLabel[LMpos]->setText("LM");
214 postLabel[LMpos+1]->setText("CM");
215 postLabel[LMpos+2]->setText("CM");
216 postLabel[LMpos+3]->setText("RM");
219 postLabel[LMpos]->setText("LM");
220 postLabel[LMpos+1]->setText("CM");
221 postLabel[LMpos+2]->setText("RM");
223 for(int i=LMpos; i<LMpos+midsC; ++i) {
225 orders[i]->addItem(tr("ind. order"), 0);
226 orders[i]->addItem(tr("defensive"), 1);
227 orders[i]->addItem(tr("offensive"), 2);
231 postLabel[8]->setText("LF");
233 orders[8]->addItem(tr("ind. order"), 0);
234 orders[8]->addItem(tr("defensive"), 1);
235 postLabel[9]->setText("CF");
237 orders[9]->addItem(tr("ind. order"), 0);
238 postLabel[10]->setText("RF");
240 orders[10]->addItem(tr("ind. order"), 0);
241 orders[10]->addItem(tr("defensive"), 1);
244 postLabel[9]->setText("CF");
246 orders[9]->addItem(tr("ind. order"), 0);
247 postLabel[10]->setText("CF");
249 orders[10]->addItem(tr("ind. order"), 0);
252 postLabel[10]->setText("CF");
254 orders[10]->addItem(tr("ind. order"), 0);
260 * \brief Count performance of each line (def, mid, fwd).
262 * Count with offensive/defensive order of each player.
264 void PerformanceTab::countPerf() {
269 for(int i=0; i<=defsC; ++i) {
270 perf = player[i]->itemData(player[i]->currentIndex()).toDouble();
271 if(orders[i]->itemData(orders[i]->currentIndex()).toInt()==0) {
274 defs += (0.78 * perf);
275 mids += (0.22 * perf);
278 for(int i=defsC+1; i<=defsC+midsC; ++i) {
279 perf = player[i]->itemData(player[i]->currentIndex()).toDouble();
280 if(orders[i]->itemData(orders[i]->currentIndex()).toInt()==0) {
282 } else if(orders[i]->itemData(orders[i]->currentIndex()).toInt()==1) {
283 defs += (0.22 * perf);
284 mids += (0.78 * perf);
286 fors += (0.22 * perf);
287 mids += (0.78 * perf);
290 for(int i=defsC+midsC+1; i<11; ++i) {
291 perf = player[i]->itemData(player[i]->currentIndex()).toDouble();
292 if(orders[i]->itemData(orders[i]->currentIndex()).toInt()==0) {
295 fors += (0.78 * perf);
296 mids += (0.22 * perf);
302 * \brief Slot assigned to "count performance" button.
304 * Print all play-variants points..
306 void PerformanceTab::recount() {
307 double homeMod = home->itemData(home->currentIndex()).toDouble();
308 double pre = (1.0+((double)aggress/1000))/(7.0 - (club.spirit.toDouble()/1000) + homeMod);
312 if(!defsC) text = tr("Choose a formation");
317 text = "<table cellpadding=\"1\" width=\"100%\"><tr><td>----</td><td style=\"color:blue;\" align=\"right\">"+tr("Long Ball")+"</td><td align=\"right\">"+tr("Without tactics")+"</td><td style=\"color:blue;\" align=\"right\">"+tr("Kick and rush")+"</td><td align=\"right\">"+tr("Passing")+"</td><td style=\"color:blue;\" align=\"right\">"+tr("Defensive wall")+"</td></tr><tr><td>D</td><td style=\"color:blue;\" align=\"right\">"+QString().setNum(O*1.05,'f',2)+"</td><td align=\"right\">"+QString().setNum(O,'f',2)+"</td><td style=\"color:blue;\" align=\"right\">"+QString().setNum(O*0.9,'f',2)+"</td><td align=\"right\">"+QString().setNum(O*0.9,'f',2)+"</td><td style=\"color:blue;\" align=\"right\">"+QString().setNum(O*1.08,'f',2)+"</td></tr><tr><td>M</td><td style=\"color:blue;\" align=\"right\">"+QString().setNum(M*0.9,'f',2)+"</td><td align=\"right\">"+QString().setNum(M,'f',2)+"</td><td style=\"color:blue;\" align=\"right\">"+QString().setNum(M*0.9,'f',2)+"</td><td align=\"right\">"+QString().setNum(M*1.1,'f',2)+"</td><td style=\"color:blue;\" align=\"right\">"+QString().setNum(M*0.9,'f',2)+"</td></tr><tr><td>F</td><td style=\"color:blue;\" align=\"right\">"+QString().setNum(F*1.05,'f',2)+"</td><td align=\"right\">"+QString().setNum(F,'f',2)+"</td><td style=\"color:blue;\" align=\"right\">"+QString().setNum(F*1.27,'f',2)+"</td><td align=\"right\">"+QString().setNum(F*0.9,'f',2)+"</td><td style=\"color:blue;\" align=\"right\">"+QString().setNum(F*0.9,'f',2)+"</td></tr><tr><td>Sum</td><td style=\"color:blue;\" align=\"right\">"+QString().setNum((O*1.05+M*0.9+F*1.05),'f',2)+"</td><td align=\"right\">"+QString().setNum((O+M+F),'f',2)+"</td><td style=\"color:blue;\" align=\"right\">"+QString().setNum((O*0.9+M*0.9+F*1.27),'f',2)+"</td><td align=\"right\">"+QString().setNum((O*0.9+M*1.1+F*0.9),'f',2)+"</td><td style=\"color:blue;\" align=\"right\">"+QString().setNum((O*1.08+M*0.9+F*0.9),'f',2)+"</td></tr></table>";
319 result->setText(text);
323 * \brief Slot assigned to aggression change.
325 * \param[in] a Aggression ID.
326 * Save aggression to config file.
328 void PerformanceTab::aggressChange(int a) {
330 QSettings settings("config/formation.ini", QSettings::IniFormat);
331 settings.setValue("aggr", aggress);
336 * \brief Slot assigned to formation change.
337 * \param[in] t Formation ID.
339 void PerformanceTab::formatChange(int t) {
340 QSettings settings("config/formation.ini", QSettings::IniFormat);
341 if(t<8 && t>=0) { settings.setValue("form", t); settings.sync(); }
344 defsC = 0; midsC = 0; forsC = 0;
347 defsC = 5; midsC = 4; forsC = 1;
350 defsC = 5; midsC = 3; forsC = 2;
353 defsC = 4; midsC = 3; forsC = 3;
356 defsC = 4; midsC = 4; forsC = 2;
359 defsC = 4; midsC = 5; forsC = 1;
362 defsC = 3; midsC = 4; forsC = 3;
365 defsC = 3; midsC = 5; forsC = 2;
373 * \brief Slot assigned to player combobox changes.
374 * \param[in] id possition ID
376 void PerformanceTab::playerChange(int id) {
377 id = 1; //avoid warning :-D
378 QSettings settings("config/formation.ini", QSettings::IniFormat);
379 for(int i=0; i<11; ++i) {
380 settings.setValue("Player/"+QString().setNum(i), player[i]->currentIndex());
381 plPerfLabel[i]->setText(QString().setNum(player[i]->itemData(player[i]->currentIndex()).toDouble(), 'f', 2)); //player[i]->itemData(player[i]->currentIndex()).toInt()
387 * \brief Slot assigned to "re-order players" button.
389 * If there are players assigned to wrong possition (by selected formation),
390 * then this function give here players with correct post.
391 * This do not look at player performance, first is selected..
393 void PerformanceTab::reorderPlayers() {
396 for(i=1; i<=defsC; ++i) { // defenders
398 if(pls[player[i]->currentIndex()].position != "LB") {
399 player[i]->setCurrentIndex(findFirstOnPost("LB"));
401 } else if(i==defsC) { // RB
402 if(pls[player[i]->currentIndex()].position != "RB") {
403 player[i]->setCurrentIndex(findFirstOnPost("RB"));
405 // RB is last managed from defenders, should set finding from him
406 from = player[i]->currentIndex();
407 } else if(defsC == 5 && i==3) { // SW
408 if(pls[player[i]->currentIndex()].position != "SW") {
409 player[i]->setCurrentIndex(findFirstOnPost("SW"));
412 if(pls[player[i]->currentIndex()].position != "CB") {
413 player[i]->setCurrentIndex(findFirstOnPost("CB"));
417 for(i=defsC+1; i<=defsC+midsC; ++i) {
418 if(i==defsC+1) { // LM
419 if(pls[player[i]->currentIndex()].position != "LM") {
420 player[i]->setCurrentIndex(findFirstOnPost("LM"));
422 } else if(i==defsC+midsC) { // RM
423 if(pls[player[i]->currentIndex()].position != "RM") {
424 player[i]->setCurrentIndex(findFirstOnPost("RM"));
426 // RM is last managed from midfields, should set finding from him
427 from = player[i]->currentIndex();
429 if(pls[player[i]->currentIndex()].position != "CM") {
430 player[i]->setCurrentIndex(findFirstOnPost("CM"));
434 for(i=defsC+midsC+1; i<=defsC+midsC+forsC; ++i) {
436 if(i==defsC+midsC+1) { // LF
437 if(pls[player[i]->currentIndex()].position != "LF") {
438 player[i]->setCurrentIndex(findFirstOnPost("LF"));
440 } else if(i==10) { // RF
441 if(pls[player[i]->currentIndex()].position != "RF") {
442 player[i]->setCurrentIndex(findFirstOnPost("RF"));
445 } else { // always CF
446 if(pls[player[i]->currentIndex()].position != "CF") {
447 player[i]->setCurrentIndex(findFirstOnPost("CF"));
454 * \brief Searching for first player with this post.
455 * \param[in] post player possition.
457 int PerformanceTab::findFirstOnPost(const QString &post) {
458 for(int i=0; i<playerCnt; ++i) {
459 if(post == pls[i].position) return i;