#include <iostream>
#include <vector>
#include <utility>
#include <functional>
#include <string>
#include <sstream>
#include <algorithm>
#include <set>
namespace sportstracker {
namespace algorithms {
#include <functional>
namespace detail {
template< typename T >
size_t divizer( std::vector< T >& array, size_t start, size_t end, std::function< bool( T, T )> comp )
{
auto marker = start;
for( auto i = start; i <= end; i++ ) {
if( comp( array[ i ], array[ end ] ) ) {
std::swap( array[ marker ] ,array[ i ] );
marker++;
}
}
return marker - 1;
}
template< typename T >
void quick_sort( std::vector< T >& array, size_t start, size_t end, std::function< bool( T, T )> comp )
{
if( start >= end )
return;
auto pivot = divizer< T >( array, start, end, comp );
quick_sort( array, start , pivot - 1, comp );
quick_sort( array, pivot + 1, end , comp );
}
}
/*
* Sorting vector in increasing order by default.
***/
template< typename T >
void quick_sort( std::vector< T >& array )
{
if( array.size() < 2 )
return;
detail::quick_sort( array, 0, array.size() - 1, []( T a, T b ) -> bool { return ( a <= b )? true : false; } );
}
/*
* Sorting vector using comparator
***/
template< typename T >
void quick_sort( std::vector< T >& array, std::function< bool( T, T )> comp )
{
if( array.size() < 2 )
return;
detail::quick_sort( array, 0, array.size() - 1, comp );
}
}
namespace utils {
struct Nocopy {
Nocopy() {}
Nocopy( const Nocopy& ) = delete;
Nocopy& operator=( const Nocopy& ) = delete;
};
std::string year_postfix( int yaer )
{
auto t1 = yaer % 10;
auto t2 = yaer % 100;
if( t1 == 1 && t2 != 11 ) {
return "год";
}
if( t1 >= 2 && t1 <= 4 && ( t2 < 10 || t2 >= 20 ) ) {
return "года";
}
else {
return "лет";
}
}
}
namespace football {
class IPosition {
public:
IPosition() {}
IPosition( const IPosition& ) {}
virtual ~IPosition() {}
virtual int id () { return 0; }
virtual std::string name() { return ""; }
};
class PosGoalkeeper : public IPosition {
public:
int id () override final { return 1; }
std::string name() override final { return "вратарь"; }
};
class PosDefender : public IPosition {
public:
int id () override final { return 2; }
std::string name() override final { return "защитник"; }
};
class PosMidfielder: public IPosition {
public:
int id () override final { return 3; }
std::string name() override final { return "полузащитник"; }
};
class PosDefensiveMidfielder : public IPosition {
public:
int id () override final { return 4; }
std::string name() override final { return "опорный полузащитник"; }
};
class PosAttackingMidfielder : public IPosition {
public:
int id () override final { return 5; }
std::string name() override final { return "атакующий полузащитник"; }
};
class PosForward : public IPosition {
public:
int id () override final { return 6; }
std::string name() override final { return "нападающий"; }
};
class IStatus {
public:
IStatus() {}
IStatus( const IStatus& ) {}
virtual ~IStatus() {}
virtual int id () { return 0; }
virtual std::string name() { return ""; }
};
class StatNewbie : public IStatus {
public:
int id () override final { return 1; }
std::string name() override final { return "новичок"; }
};
class StatMiddle : public IStatus {
public:
int id () override final { return 2; }
std::string name() override final { return "середняк"; }
};
class StatStar : public IStatus {
public:
int id () override final { return 3; }
std::string name() override final { return "звезда"; }
};
class StatSuperstar : public IStatus {
public:
int id () override final { return 4; }
std::string name() override final { return "суперзвезда"; }
};
class StatOldfag : public IStatus {
public:
int id () override final { return 5; }
std::string name() override final { return "старожил"; }
};
class Player {
public:
Player()
{
age_ = 0;
position_ = new PosGoalkeeper();
status_ = new StatNewbie();
}
Player( const Player& value )
{
firstName_ = value.firstName_;
secondName_ = value.secondName_;
age_ = value.age_;
status_ = value.status_;
position_ = value.position_;
}
Player(
const std::string& firstName,
const std::string& secondName,
int age,
IStatus* status,
IPosition* position )
: firstName_( firstName ),
secondName_( secondName ),
age_( age )
{
status_ = status;
position_ = position;
}
~Player()
{
}
std::string toString ()
{
return firstName_ + " " +
secondName_ + " " +
std::to_string( age_ ) + " " +
utils::year_postfix( age_ ) + " " +
position_->name() + " " +
status_->name();
}
std::string firstName ()
{
return firstName_;
}
std::string secondName()
{
return secondName_;
}
IPosition* position()
{
return position_;
}
unsigned int age()
{
return age_;
}
void setFirstName ( const std::string& value )
{
firstName_ = value;
}
void setSecondName( const std::string& value )
{
secondName_ = value;
}
void setAge ( unsigned int value )
{
age_ = value;
}
private:
std::string firstName_;
std::string secondName_;
unsigned int age_;
IPosition* position_;
IStatus* status_;
};
class SportsTeam {
public:
virtual void addPlayer ( const Player& player ) = 0;
virtual void removePlayerAt( size_t pos ) = 0;
virtual void output () = 0;
};
class FootballTeam : public SportsTeam, public utils::Nocopy {
public:
FootballTeam() {}
~FootballTeam() {}
virtual void addPlayer( const Player& player ) override
{
players_.push_back( player );
}
virtual void removePlayerAt( size_t pos ) override
{
// maybe it's worth to throw exception here?..
players_.erase( players_.begin() + pos );
}
virtual void output() override
{
for( auto& itr : players_ )
std::cout << itr.toString() << std::endl;
}
void sort()
{
auto comp = []( Player a, Player b ) -> bool {
bool result = true;
if( a.secondName().compare( b.secondName() ) == 0 ) {
result = ( a.secondName() > b.secondName() ) && ( a.firstName() > b.firstName() );
}
else {
result = ( a.secondName() > b.secondName() );
}
result &= ( a.age() > b.age() );
result &= ( a.position()->id() > b.position()->id() );
return result;
};
std::sort( players_.begin(), players_.end(), comp );
}
private:
std::vector< Player > players_;
};
class Game {
public:
static Game& getInstance()
{
std::cout << "I'm a singletone, lol!" << std::endl;
static Game instance;
return instance;
}
private:
FootballTeam firstTeam_;
FootballTeam secondTeam_;
Game() {}
Game( Game const& ) = delete;
void operator=( Game const& ) = delete;
};
}
}
using namespace sportstracker;
using namespace sportstracker::football;
using namespace std;
int main(int argc, char const *argv[])
{
// vector< int > array = { 1, 5, 3, 8 };
// algorithms::quick_sort< int >( array, []( int a, int b ) -> bool { return ( a <= b )? true : false; } );
// for( auto& itr : array )
// cout << itr << endl;
auto germany = new FootballTeam();
germany->addPlayer( Player( "Мануэль" , "Нойер" , 28, new StatStar() , new PosGoalkeeper() ) );
germany->addPlayer( Player( "Рон" , "Цилер" , 25, new StatNewbie() , new PosGoalkeeper() ) );
germany->addPlayer( Player( "Филипп" , "Лам" , 32, new StatStar() , new PosDefender() ) );
germany->addPlayer( Player( "Тонн" , "Кросс" , 23, new StatSuperstar(), new PosGoalkeeper() ) );
germany->addPlayer( Player( "Месут" , "Озил" , 26, new StatSuperstar(), new PosDefensiveMidfielder() ) );
germany->addPlayer( Player( "Бастиан" , "Швайнштайгер", 30, new StatSuperstar(), new PosDefensiveMidfielder() ) );
germany->addPlayer( Player( "Мирослав", "Клозе" , 36, new StatOldfag() , new PosAttackingMidfielder() ) );
germany->addPlayer( Player( "Марио" , "Гётце" , 22, new StatOldfag() , new PosGoalkeeper() ) );
germany->addPlayer( Player( "Лукаш" , "Подольски" , 29, new StatOldfag() , new PosDefensiveMidfielder() ) );
germany->sort();
germany->output();
set< IPosition* > positions;
positions.insert( new PosGoalkeeper() );
positions.insert( new PosDefender() );
positions.insert( new PosMidfielder() );
positions.insert( new PosDefensiveMidfielder() );
positions.insert( new PosAttackingMidfielder() );
positions.insert( new PosForward() );
cout << '\n';
for( auto& itr : positions )
cout << itr->name() << " " << itr->id() << endl;
set< IStatus* > statuses;
statuses.insert( new StatNewbie() );
statuses.insert( new StatMiddle() );
statuses.insert( new StatStar() );
statuses.insert( new StatSuperstar() );
statuses.insert( new StatOldfag() );
cout << '\n';
for( auto& itr : statuses )
cout << itr->name() << " " << itr->id() << endl;
vector< IPosition* > posVector( positions.begin(), positions.end() );
cout << '\n';
algorithms::quick_sort< IPosition* >( posVector, []( IPosition* a, IPosition* b ) -> bool { return ( a->id() > b->id() )? true : false; } );
for( auto& itr : posVector )
cout << itr->name() << " " << itr->id() << endl;
vector< IStatus* > statVector( statuses.begin(), statuses.end() );
cout << '\n';
// algorithms::quick_sort< IStatus* >( statVector, []( IStatus* a, IStatus* b ) -> bool { return ( a->id() > b->id() )? true : false; } );
for( auto& itr : statVector )
cout << itr->name() << " " << itr->id() << endl;
cout << '\n';
Game::getInstance();
return 0;
}