9da30aa0e80796d2e7b2917f36179bff1b2a199f
[aspt.git] / performance.cc
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 *******************************************************************/
6
7 #include "performance.h"
8
9 void PerformanceTab::init() {
10         QSettings settings("config/formation.ini", QSettings::IniFormat);
11         
12         format = new QComboBox();
13         format->addItem("---", QVariant(0));
14         format->addItem("5-4-1", QVariant(1));
15         format->addItem("5-3-2", QVariant(2));
16         format->addItem("4-3-3", QVariant(3));
17         format->addItem("4-4-2", QVariant(4));
18         format->addItem("4-5-1", QVariant(5));
19         format->addItem("3-4-3", QVariant(6));
20         format->addItem("3-5-2", QVariant(7));
21         format->setToolTip(tr("Team formation."));
22         
23         reorderPl = new QPushButton(tr("reorder players"));
24         reorderPl->setToolTip(tr("This button set on positions with wrong player type this player, who plays there (LM on LM post..)."));
25         
26         aggression = new QComboBox();
27         for(int i=0; i<=100; i+=5) {
28                 aggression->addItem(tr("aggression ") + QString().setNum(i) + "%", i);
29         }
30         aggression->setCurrentIndex(settings.value("aggr", 0).toInt()/5);
31         aggression->setToolTip(tr("Team aggression, same as you set in match."));
32         aggress = settings.value("aggr", 0).toInt();
33         
34         home = new QComboBox();
35         home->addItem(tr("play home"), 0.0);
36         home->addItem(tr("play away"), 0.1);
37         home->setToolTip(tr("Where you will play the match."));
38         
39         for(int j=0; j<11; ++j) {
40                 plCont[j] = new QHBoxLayout();
41                 player[j] = new QComboBox();
42                 orders[j] = new QComboBox();
43                 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."));
44                 orders[j]->addItem(tr("ind. order"), 0);
45                 for(int i=0; i<playerCnt; ++i) {
46                         int oldPenale = 0;
47                         int age = pls[i].age.toInt();
48                         double perf = ((pls[i].morale.toDouble()+pls[i].fitness.toDouble())/200)*pls[i].bestRate.toDouble();
49                         if(age > 30) {
50                                 oldPenale = (age-30)*3;         // 3 points penale per each year over 30
51                                 perf -= oldPenale;
52                         }
53                         player[j]->addItem("[" + pls[i].position + "] " + pls[i].fname + " " + pls[i].lname, QVariant(perf));
54                 }
55                 player[j]->setCurrentIndex(settings.value("Player/"+QString().setNum(j), 0).toInt());
56                 postLabel[j] = new QLabel("pos");
57                 plPerfLabel[j] = new QLabel(QString().setNum(player[j]->itemData(player[j]->currentIndex()).toDouble(), 'f', 2));
58                 plCont[j]->addWidget(postLabel[j]);
59                 plCont[j]->addWidget(player[j]);
60                 plCont[j]->addWidget(orders[j]);
61                 plCont[j]->addWidget(plPerfLabel[j]);
62         }
63         
64         container = new QHBoxLayout();
65         
66         container->addWidget(format);
67         container->addWidget(reorderPl);
68         container->addWidget(aggression);
69         container->addWidget(home);
70         mainLayout->addLayout(container);
71         for(int j=0; j<11; ++j) mainLayout->addLayout(plCont[j]);
72         
73         cButt = new QPushButton(tr("count team performance"));
74         mainLayout->addWidget(cButt);
75         
76         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"));
77         mainLayout->addWidget(result);
78         
79         format->setCurrentIndex(settings.value("form", 0).toInt());
80         formatChange(settings.value("form", 0).toInt());
81         
82         connect(format, SIGNAL(currentIndexChanged(int)), this, SLOT(formatChange(int)));
83         connect(aggression, SIGNAL(currentIndexChanged(int)), this, SLOT(aggressChange(int)));
84         connect(cButt, SIGNAL(clicked()), this, SLOT(recount()));
85         for(int i=0; i<11; i++) {
86                 connect(player[i], SIGNAL(currentIndexChanged(int)), this, SLOT(playerChange(int)));
87         }
88         connect(reorderPl, SIGNAL(clicked()), this, SLOT(reorderPlayers()));
89         mainLayout->update();
90 }
91
92 PerformanceTab::PerformanceTab(QWidget *parent): QWidget(parent), defs(0), mids(0), fors(0) {
93         mainLayout = new QVBoxLayout;
94         setLayout(mainLayout);
95         init();
96 }
97
98 PerformanceTab::~PerformanceTab() {
99         for(int i=0; i<11; ++i) {
100                 delete player[i];
101                 delete postLabel[i];
102                 delete plPerfLabel[i];
103                 delete orders[i];
104                 delete plCont[i];
105         }
106         delete format;
107         delete aggression;
108         delete home;
109         delete result;
110         delete cButt;
111         delete container;
112         delete reorderPl;
113         delete mainLayout;
114 }
115
116 void PerformanceTab::dataChanged() {
117         container->removeWidget(format);
118         delete format;
119         container->removeWidget(aggression);
120         delete aggression;
121         container->removeWidget(home);
122         delete home;
123         container->removeWidget(reorderPl);
124         delete reorderPl;
125         mainLayout->removeWidget(reinterpret_cast<QWidget*>(container));
126         delete container;
127         
128         for(int i=0; i<11; ++i) {
129                 mainLayout->removeWidget(reinterpret_cast<QWidget*>(plCont[i]));
130                 delete plCont[i];
131                 delete player[i];
132                 delete plPerfLabel[i];
133                 delete postLabel[i];
134                 delete orders[i];
135         }
136         mainLayout->removeWidget(cButt);
137         delete cButt;
138         mainLayout->removeWidget(result);
139         delete result;
140         mainLayout->update();
141         init();
142 }
143
144 void PerformanceTab::postLabels() {
145         int LMpos = 0;
146         if(!defsC) {
147                 for(int i=0; i<11; ++i) {
148                         postLabel[i]->setText("??");
149                 }
150         }
151         postLabel[0]->setText("GK");
152         postLabel[1]->setText("LB");
153         orders[1]->clear();
154         orders[1]->addItem(tr("ind. order"), 0);
155         orders[1]->addItem(tr("offensive"), 2);
156         postLabel[2]->setText("CB");
157         switch(defsC) {
158                 case 5:
159                         postLabel[3]->setText("SW");
160                         orders[3]->clear();
161                         orders[3]->addItem(tr("ind. order"), 0);
162                         postLabel[4]->setText("CB");
163                         orders[4]->clear();
164                         orders[4]->addItem(tr("ind. order"), 0);
165                         postLabel[5]->setText("RB");
166                         orders[5]->clear();
167                         orders[5]->addItem(tr("ind. order"), 0);
168                         orders[5]->addItem(tr("offensive"), 2);
169                         LMpos = 6;
170                         break;
171                 case 4:
172                         postLabel[3]->setText("CB");
173                         orders[3]->clear();
174                         orders[3]->addItem(tr("ind. order"), 0);
175                         postLabel[4]->setText("RB");
176                         orders[4]->clear();
177                         orders[4]->addItem(tr("ind. order"), 0);
178                         orders[4]->addItem(tr("offensive"), 2);
179                         LMpos = 5;
180                         break;
181                 case 3:
182                         postLabel[3]->setText("RB");
183                         orders[3]->clear();
184                         orders[3]->addItem(tr("ind. order"), 0);
185                         orders[3]->addItem(tr("offensive"), 2);
186                         LMpos = 4;
187                         break;
188         }
189         switch(midsC) {
190                 case 5:
191                         postLabel[LMpos]->setText("LM");
192                         postLabel[LMpos+1]->setText("CM");
193                         postLabel[LMpos+2]->setText("CM");
194                         postLabel[LMpos+3]->setText("CM");
195                         postLabel[LMpos+4]->setText("RM");
196                         break;
197                 case 4:
198                         postLabel[LMpos]->setText("LM");
199                         postLabel[LMpos+1]->setText("CM");
200                         postLabel[LMpos+2]->setText("CM");
201                         postLabel[LMpos+3]->setText("RM");
202                         break;
203                 case 3:
204                         postLabel[LMpos]->setText("LM");
205                         postLabel[LMpos+1]->setText("CM");
206                         postLabel[LMpos+2]->setText("RM");
207         }
208         for(int i=LMpos; i<LMpos+midsC; ++i) {
209                 orders[i]->clear();
210                 orders[i]->addItem(tr("ind. order"), 0);
211                 orders[i]->addItem(tr("defensive"), 1);
212                 orders[i]->addItem(tr("offensive"), 2);
213         }
214         switch(forsC) {
215                 case 3:
216                         postLabel[8]->setText("LF");
217                         orders[8]->clear();
218                         orders[8]->addItem(tr("ind. order"), 0);
219                         orders[8]->addItem(tr("defensive"), 1);
220                         postLabel[9]->setText("CF");
221                         orders[9]->clear();
222                         orders[9]->addItem(tr("ind. order"), 0);
223                         postLabel[10]->setText("RF");
224                         orders[10]->clear();
225                         orders[10]->addItem(tr("ind. order"), 0);
226                         orders[10]->addItem(tr("defensive"), 1);
227                         break;
228                 case 2:
229                         postLabel[9]->setText("CF");
230                         orders[9]->clear();
231                         orders[9]->addItem(tr("ind. order"), 0);
232                         postLabel[10]->setText("CF");
233                         orders[10]->clear();
234                         orders[10]->addItem(tr("ind. order"), 0);
235                         break;
236                 case 1:
237                         postLabel[10]->setText("CF");
238                         orders[10]->clear();
239                         orders[10]->addItem(tr("ind. order"), 0);
240                         break;
241         }
242 }
243
244 void PerformanceTab::countPerf() {
245         defs = 0;
246         mids = 0;
247         fors = 0;
248         double perf;
249         for(int i=0; i<=defsC; ++i) {
250                 perf = player[i]->itemData(player[i]->currentIndex()).toDouble();
251                 if(orders[i]->itemData(orders[i]->currentIndex()).toInt()==0) {
252                         defs += perf;
253                 } else {
254                         defs += (0.78 * perf);
255                         mids += (0.22 * perf);
256                 }
257         }
258         for(int i=defsC+1; i<=defsC+midsC; ++i) {
259                 perf = player[i]->itemData(player[i]->currentIndex()).toDouble();
260                 if(orders[i]->itemData(orders[i]->currentIndex()).toInt()==0) {
261                         mids += perf;
262                 } else if(orders[i]->itemData(orders[i]->currentIndex()).toInt()==1) {
263                         defs += (0.22 * perf);
264                         mids += (0.78 * perf);
265                 } else {
266                         fors += (0.22 * perf);
267                         mids += (0.78 * perf);
268                 }
269         }
270         for(int i=defsC+midsC+1; i<11; ++i) {
271                 perf = player[i]->itemData(player[i]->currentIndex()).toDouble();
272                 if(orders[i]->itemData(orders[i]->currentIndex()).toInt()==0) {
273                         fors += perf;
274                 } else {
275                         fors += (0.78 * perf);
276                         mids += (0.22 * perf);
277                 }
278         }
279 }
280
281 void PerformanceTab::recount() {
282         double homeMod = home->itemData(home->currentIndex()).toDouble();
283         double pre = (1.0+((double)aggress/1000))/(7.0 - (club.spirit.toDouble()/1000) + homeMod);
284
285         countPerf();
286         QString text;
287         if(!defsC) text = tr("Choose a formation");
288         else {
289                 double O = pre*defs;
290                 double M = pre*mids;
291                 double F = pre*fors;
292                 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>";
293         }
294         result->setText(text);
295 }
296
297 void PerformanceTab::aggressChange(int a) {
298         aggress = a*5;
299         QSettings settings("config/formation.ini", QSettings::IniFormat);
300         settings.setValue("aggr", aggress);
301         settings.sync();
302 }
303
304 void PerformanceTab::formatChange(int t) {
305         QSettings settings("config/formation.ini", QSettings::IniFormat);
306         if(t<8 && t>=0) { settings.setValue("form", t); settings.sync(); }
307         switch(t) {
308                 case 0: 
309                         defsC = 0; midsC = 0; forsC = 0;
310                         break;
311                 case 1:
312                         defsC = 5; midsC = 4; forsC = 1;
313                         break;
314                 case 2:
315                         defsC = 5; midsC = 3; forsC = 2;
316                         break;
317                 case 3:
318                         defsC = 4; midsC = 3; forsC = 3;
319                         break;
320                 case 4:
321                         defsC = 4; midsC = 4; forsC = 2;
322                         break;
323                 case 5:
324                         defsC = 4; midsC = 5; forsC = 1;
325                         break;
326                 case 6:
327                         defsC = 3; midsC = 4; forsC = 3;
328                         break;
329                 case 7:
330                         defsC = 3; midsC = 5; forsC = 2;
331                         break;
332         }
333         postLabels();
334         reorderPlayers();
335 }
336
337 void PerformanceTab::playerChange(int id) {
338         id = 1; //avoid warning :-D
339         QSettings settings("config/formation.ini", QSettings::IniFormat);
340         for(int i=0; i<11; ++i) {
341                 settings.setValue("Player/"+QString().setNum(i), player[i]->currentIndex());
342                 plPerfLabel[i]->setText(QString().setNum(player[i]->itemData(player[i]->currentIndex()).toDouble(), 'f', 2)); //player[i]->itemData(player[i]->currentIndex()).toInt()
343         }
344         settings.sync();
345 }
346
347 void PerformanceTab::reorderPlayers() {
348         int i;
349         int from = 0;
350         for(i=1; i<=defsC; ++i) {               // defenders
351                 if(i==1) {              // LB
352                         if(pls[player[i]->currentIndex()].position != "LB") {
353                                 player[i]->setCurrentIndex(findFirstOnPost("LB"));
354                         }
355                 } else if(i==defsC) {           // RB
356                         if(pls[player[i]->currentIndex()].position != "RB") {
357                                 player[i]->setCurrentIndex(findFirstOnPost("RB"));
358                         }
359                         // RB is last managed from defenders, should set finding from him
360                         from = player[i]->currentIndex();
361                 } else if(defsC == 5 && i==3) {         // SW
362                         if(pls[player[i]->currentIndex()].position != "SW") {
363                                 player[i]->setCurrentIndex(findFirstOnPost("SW"));
364                         }
365                 } else {                // CB
366                         if(pls[player[i]->currentIndex()].position != "CB") {
367                                 player[i]->setCurrentIndex(findFirstOnPost("CB"));
368                         }
369                 }
370         }
371         for(i=defsC+1; i<=defsC+midsC; ++i) {
372                 if(i==defsC+1) {                // LM
373                         if(pls[player[i]->currentIndex()].position != "LM") {
374                                 player[i]->setCurrentIndex(findFirstOnPost("LM"));
375                         }
376                 } else if(i==defsC+midsC) {             // RM
377                         if(pls[player[i]->currentIndex()].position != "RM") {
378                                 player[i]->setCurrentIndex(findFirstOnPost("RM"));
379                         }
380                         // RM is last managed from midfields, should set finding from him
381                         from = player[i]->currentIndex();
382                 } else {                // CM
383                         if(pls[player[i]->currentIndex()].position != "CM") {
384                                 player[i]->setCurrentIndex(findFirstOnPost("CM"));
385                         }
386                 }
387         }
388         for(i=defsC+midsC+1; i<=defsC+midsC+forsC; ++i) {
389                 if(forsC==3) {
390                         if(i==defsC+midsC+1) {          // LF
391                                 if(pls[player[i]->currentIndex()].position != "LF") {
392                                         player[i]->setCurrentIndex(findFirstOnPost("LF"));
393                                 }
394                         } else if(i==10) {              // RF
395                                 if(pls[player[i]->currentIndex()].position != "RF") {
396                                         player[i]->setCurrentIndex(findFirstOnPost("RF"));
397                                 }
398                         }
399                 } else {                // always CF
400                         if(pls[player[i]->currentIndex()].position != "CF") {
401                                 player[i]->setCurrentIndex(findFirstOnPost("CF"));
402                         }
403                 }
404         }
405 }
406
407 int PerformanceTab::findFirstOnPost(const QString &post) {
408         for(int i=0; i<playerCnt; ++i) {
409                 if(post == pls[i].position) return i;
410         }
411         return 0;
412 }