#include <vector>
#include <memory>

/** reprezentuje stan w grze w warcaby (polozenie pionow i informacja o tym, kto sie rusza */
struct State {};
using States = std::vector<State>;

//Rozwiazanie: wzorzec mostu

//tutaj dla wygody używam sprytnych wskaźników (shared_ptr), ale nie jest to częścią zadania

class Checkers { //klasa bazowa implementacji - rozne rodzaje warcabow
public:
   virtual States correctMoves(State s) = 0;
};

using PCheckers = std::shared_ptr<Checkers>;

//zasady wloskie
class ItalianCheckers : public Checkers {
    //implementacja nie ma znaczenia w tym zadaniu
    States correctMoves(State s) override { return States(); }
};
//zasady niemieckie
class GermanCheckers : public Checkers {
    //implementacja nie ma znaczenia w tym zadaniu
    States correctMoves(State s) override { return States(); }
};

//zasady hiszpanskie
class SpanishCheckers : public Checkers {
    //implementacja nie ma znaczenia w tym zadaniu
    States correctMoves(State s) override { return States(); }
};

//klasa bazow abstrakcji - rozne algorytmy gracza
class Player {
public:
    Player(PCheckers ch) : checkers_(ch) {}

    virtual State nextMove(State s) = 0;
protected:
    States correctMoves(State s) {
        return checkers_->correctMoves(s);
    }
private:
    PCheckers checkers_;
};

using PPlayer = std::shared_ptr<Player>;

//gracz losowy
class RandomPlayer : public Player {
public:
    RandomPlayer(PCheckers ch) : Player(ch) {}
    //implementacja nie ma znaczenia w tym zadaniu
    State nextMove(State s) override { return State(); }
};

//gracz AI
class AIPlayer : public Player {
public:
    AIPlayer(PCheckers ch) : Player(ch) {}
    //implementacja nie ma znaczenia w tym zadaniu
    State nextMove(State s) override { return State(); }
};

//gracz czlowiek
class HumanPlayer : public Player {
public:
    HumanPlayer(PCheckers ch) : Player(ch) {}
    //implementacja nie ma znaczenia w tym zadaniu
    State nextMove(State s) override { return State(); }
};

int main() {
    //przyklad obiektu - gracz losowy, zasady wloskie
    PPlayer italian_random = std::make_shared<RandomPlayer>(std::make_shared<ItalianCheckers>() );
    return 0;
}

//STARY, NADMIAROWY KOD

// class Player {
//  virtual State nextMove(State s) = 0;
// };


// class ItalianAIPlayer : public Player {
// public:
//  ItalianAIPlayer();
//  State nextMove(State s);
// private:
//  States correctMoves(State s);
// };

// class GermanAIPlayer : public Player {
// public:
//  GermanAIPlayer();
//  State nextMove(State s);
// private:
//  States correctMoves(State s);
// };

// class SpanishAIPlayer : public Player {
// public:
//  SpanishAIPlayer();
//  State nextMove(State s);
// private:
//  States correctMoves(State s);
// };


// class ItalianRandomPlayer : public Player {
// public:
//  ItalianRandomPlayer();
//  State nextMove(State s);
// private:
//  States correctMoves(State s);
// };

// class GermanRandomPlayer : public Player {
// public:
//  GermanRandomPlayer();
//  State nextMove(State s);
// private:
//  States correctMoves(State s);
// };

// class SpanishRandomPlayer : public Player {
// public:
//  SpanishRandomPlayer();
//  State nextMove(State s);
// private:
//  States correctMoves(State s);
// };


// class ItalianHumanPlayer : public Player {
// public:
//  ItalianHumanPlayer();
//  State nextMove(State s);
// private:
//  States correctMoves(State s);
// };

// class GermanHumanPlayer : public Player {
// public:
//  GermanHumanPlayer();
//  State nextMove(State s);
// private:
//  States correctMoves(State s);
// };

// class SpanishHumanPlayer : public Player {
// public:
//  SpanishHumanPlayer();
//  State nextMove(State s);
// private:
//  States correctMoves(State s);
// };

