#include<iostream>
#include<string>
#define KST 20
using namespace std;
class WinStrategy;
class SmallerBetterStrategy;
class ChampionshipStrategy;
class University;
class SmallerBetter;
class Championship;
class University {
private:
string universiada;
string name;
int win;
public:
University(string name, string universiada) {
this->name = name;
this->universiada = universiada;
win = 0;
}
University(){}
int GetWin() {
return win;
}
string GetName() {
return name;
}
string GetUniversiada() {
return universiada;
}
void SetWin(int win) {
this->win = win;
}
};
class SportUniver {
private:
WinStrategy* winStrategy; // вказівник на об'єкт з методом Win
protected:
string NazvaUniver;
string data;
public:
static University universities[KST];
static int uniCount;
int CompetitionType;
virtual void Input() = 0;
SportUniver();
void setStrategy(WinStrategy* strategy) {
winStrategy = strategy;
}
void GoWin(SportUniver** obj, int kst)
{
winStrategy->Win(obj, kst);
}
//virtual void Win(SportUniver** obj, int kst) = 0;
string GetNazvaUniver() {
return NazvaUniver;
}
string GetData() {
return data;
}
void AddWins(string team, string universiada) {
int i = 0;
while (universiada.compare(universities[i].GetUniversiada()) != 0)// шукає по масиву університетів задану універсіаду
i++;
while (team.compare(universities[i].GetName()) != 0)// тута шукає команду
i++;
universities[i].SetWin(universities[i].GetWin() + 1);// дододає в ту команду перемогу
}
void AddTeam(string player, string universiada) {
for (int i = 0; i < uniCount; i++)// спочатку воно не заходить в фор, а одразу додає універ в масив, вже потім заходить в фор і там збільшується к-сть
if (player.compare(universities[i].GetName()) == 0 && universiada.compare(universities[i].GetUniversiada()) == 0)
return;//перевіряє чи в масиві університетів є цей універ. якщо є то виходимо з циклу, якщо нема-записуємо в масив
universities[uniCount++] = University(player, universiada);
}
void Sort() {
for (int i = 0; i < uniCount; i++) {
for (int k = 0; k < uniCount; k++) {
if ((universities[i].GetWin()) > (universities[k].GetWin())) {
University temp = universities[i];
universities[i] = universities[k];
universities[k] = temp;
}
}
}
}
void OutputRecords() {
for (int i = 0; i < uniCount; i++)
cout << universities[i].GetUniversiada() << " - " << universities[i].GetName() << " - " << universities[i].GetWin() << endl;
}
};
int SportUniver::uniCount;
University SportUniver::universities[KST];
class Championship : public SportUniver {
private:
string komanda1;
string komanda2;
int goals1, goals2;
public:
Championship(string NazvaUniver, string data, int CompetitionType) {
this->NazvaUniver = NazvaUniver;
this->data = data;
this->CompetitionType = CompetitionType;
}
Championship() {}
string GetKomanda1() {
return komanda1;
}
string GetKomanda2() {
return komanda2;
}
int GetGoals1() {
return goals1;
}
int GetGoals2() {
return goals2;
}
//void Win(SportUniver** obj1, int kst) override {
// Championship* obj = (Championship*)(*obj1);//привела до типу
// if (obj->goals1 > obj->goals2)
// AddWins(obj->komanda1, obj->NazvaUniver);
// else if (obj->goals1 < obj->goals2)
// AddWins(obj->komanda2, obj->NazvaUniver);
//}
void Input() override {
cout << "Введіть команду 1" << endl;
cin >> komanda1;
cout << "Введіть команду 2" << endl;
cin >> komanda2;
cout << "Введіть к-сть голів 1 команди" << endl;
cin >> goals1;
cout << "Введіть к-сть голів 2 команди" << endl;
cin >> goals2;
AddTeam(komanda1, NazvaUniver);
AddTeam(komanda2, NazvaUniver);
}
};
class SmallerBetter : public SportUniver {
private:
string player;
double runTime;
double jumpLength;
double swimmingTime;
bool checked = false;
public:
SmallerBetter(string NazvaUniver, string data, int CompetitionType) {
this->NazvaUniver = NazvaUniver;
this->data = data;
this->CompetitionType = CompetitionType;
}
SmallerBetter() {}
void Input()override {
cout << "Введіть учасник-університет" << endl;
cin >> player;
cout << "Введіть його результат з бігу" << endl;
cin >> runTime;
cout << "Введіть його результат з стрибків" << endl;
cin >> jumpLength;
cout << "Введіть його результат з плавання" << endl;
cin >> swimmingTime;
AddTeam(player, NazvaUniver);
}
string GetPlayer() {
return player;
}
double GetRunTime() {
return runTime;
}
double GetJumpLength() {
return jumpLength;
}
double GetSwimmingTime() {
return swimmingTime;
}
double GetChecked() {
return checked;
}
void SetChecked(bool checked) {
this->checked = checked;
}
//void Win(SportUniver** obj1, int kst) override {
// SmallerBetter** obj = (SmallerBetter**)obj1;
// if ((*obj)->checked == true)
// return;
// SmallerBetter** pend = obj + kst;
// SmallerBetter* leader = *obj;
// string univerToCheck = (*obj)->NazvaUniver; //ставимо назву універсіади першого об'єкту
// // Шукаємо найкращого бігуна певної універсіади
// for (SmallerBetter** p1 = obj; p1 < pend; p1++) {
// if ((*p1)->NazvaUniver.compare(univerToCheck) == 0 && (*p1)->CompetitionType == 2) {
// (*p1)->checked = true; // помічаємо гравця, щоб не розглядати його для іншої універсіади
// //спочатку порівнюємо всіх з 1 універсіади і пропускаємо 2, а потім навпаки пропускаємо 1 бо ми її вже перевірили коли брали 1 об*єкт
// if ((*p1)->runTime < leader->runTime)
// leader = *p1;
// }
// }
// AddWins(leader->player, leader->NazvaUniver);
// // Шукаємо найкращого стрибунця певної універсіади
// for (SmallerBetter** p1 = obj; p1 < pend; p1++) {
// if ((*p1)->CompetitionType == 2)
// if ((*p1)->NazvaUniver.compare(univerToCheck) == 0 && (*p1)->jumpLength > leader->jumpLength)
// leader = *p1;
// }
// AddWins(leader->player, leader->NazvaUniver);
// // Шукаємо найкращого плавця певної універсіади
// for (SmallerBetter** p1 = obj; p1 < pend; p1++) {
// if ((*p1)->CompetitionType == 2)
// if ((*p1)->NazvaUniver.compare(univerToCheck) == 0 && (*p1)->swimmingTime < leader->swimmingTime)
// leader = *p1;
// }
// AddWins(leader->player, leader->NazvaUniver);
//}
};
class WinStrategy {
public:
WinStrategy() {};
~WinStrategy() {};
virtual void Win(SportUniver** obj, int kst) = 0;
};
class ChampionshipStrategy : public WinStrategy {
public:
void Win(SportUniver** obj1, int kst) override {
Championship* obj = (Championship*)(*obj1);//привела до типу
if (obj->GetGoals1() > obj->GetGoals2())
obj->AddWins(obj->GetKomanda1(), obj->GetNazvaUniver());
else if (obj->GetGoals1() < obj->GetGoals2())
obj->AddWins(obj->GetKomanda2(), obj->GetNazvaUniver());
}
};
class SmallerBetterStrategy : public WinStrategy {
public:
void Win(SportUniver** obj1, int kst) override {
SmallerBetter** obj = (SmallerBetter**)obj1;
if ((*obj)->GetChecked() == true)
return;
SmallerBetter** pend = obj + kst;
SmallerBetter* leader = *obj;
string univerToCheck = (*obj)->GetNazvaUniver(); //ставимо назву універсіади першого об'єкту
// Шукаємо найкращого бігуна певної універсіади
for (SmallerBetter** p1 = obj; p1 < pend; p1++) {
if ((*p1)->GetNazvaUniver().compare(univerToCheck) == 0 && (*p1)->CompetitionType == 2) {
(*p1)->SetChecked(true); // помічаємо гравця, щоб не розглядати його для іншої універсіади
//спочатку порівнюємо всіх з 1 універсіади і пропускаємо 2, а потім навпаки пропускаємо 1 бо ми її вже перевірили коли брали 1 об*єкт
if ((*p1)->GetRunTime() < leader->GetRunTime())
leader = *p1;
}
}
(*obj)->AddWins(leader->GetPlayer(), leader->GetNazvaUniver());
// Шукаємо найкращого стрибунця певної універсіади
for (SmallerBetter** p1 = obj; p1 < pend; p1++) {
if ((*p1)->CompetitionType == 2)
if ((*p1)->GetNazvaUniver().compare(univerToCheck) == 0 && (*p1)->GetJumpLength() > leader->GetJumpLength())
leader = *p1;
}
(*obj)->AddWins(leader->GetPlayer(), leader->GetNazvaUniver());
// Шукаємо найкращого плавця певної універсіади
for (SmallerBetter** p1 = obj; p1 < pend; p1++) {
if ((*p1)->CompetitionType == 2)
if ((*p1)->GetNazvaUniver().compare(univerToCheck) == 0 && (*p1)->GetSwimmingTime() < leader->GetSwimmingTime())
leader = *p1;
}
(*obj)->AddWins(leader->GetPlayer(), leader->GetNazvaUniver());
}
};
int InputData(SportUniver* [], SportUniver* []);
void Input1(SportUniver** p1, string NazvaUniver, string data, int choice);
void Input2(SportUniver** p1, string NazvaUniver, string data, int choice);
void CountWin(SportUniver* [], int kst);
int main() {
system("chcp 1251 & cls & color 70");
SportUniver* game[20];
int k = InputData(game, game + 19);
CountWin(game, k);
game[0]->Sort();
game[0]->OutputRecords();
for (int i = 0; i < k; i++)
{
delete game[i];
}
system("pause");
return 0;
}
int InputData(SportUniver* p1[], SportUniver* pend[])
{
string NazvaUniver, data;
int k = 0;
int choice = 0;
while (p1 < pend)
{
rewind(stdin);
cout << "Введіть назву Універсіади (пустий рядок - кінець)" << endl;
getline(cin, NazvaUniver);
if (NazvaUniver[0] == '\0')
break;
cout << "Введіть дату" << endl;
cin >> data;
while (p1 < pend)
{
cout << endl << k + 1 << ". Виберіть тип змагань: по командах/між учасниками [1/2] (0 - кінець) -> ";
cin >> choice;
if (choice == 1)
Input1(p1, NazvaUniver, data, choice);
else if (choice == 2)
Input2(p1, NazvaUniver, data, choice);
else
break;
p1++;
k++;
}
}
return k;
}
void Input1(SportUniver** p1, string NazvaUniver, string data, int choice) {
*p1 = new Championship(NazvaUniver, data, choice); //заносимо в конструктор дані
(*p1)->Input();
}
void Input2(SportUniver** p1, string NazvaUniver, string data, int choice)
{
*p1 = new SmallerBetter(NazvaUniver, data, choice);
(*p1)->Input();
}
void CountWin(SportUniver* pstart[], int kst)
{
SportUniver** pend = pstart + kst;
for (SportUniver** p1 = pstart; p1 < pend; p1++) {
if (dynamic_cast<Championship*>(*p1) != nullptr) // якшо *p1 належить до класу Championship
(*p1)->setStrategy(new ChampionshipStrategy());
else
(*p1)->setStrategy(new SmallerBetterStrategy());
(*p1)->GoWin(p1, kst);
//(*p1)->Win(p1, kst);//передаємо всі об*єкти
}
}