При разработке данной игровой программы были применены виртуальные функции и абстрактные классы.

#include <stdlib.h>
#include <iostream.h>

class Heap {
  private:
    int size;
  public:
    Heap(int s) : size(s) {};
    int get(int n = 0) { size -= n; return(size); };
};

class Gambler {
  protected:
    Heap* heap;
    const int limit;
    const char* name;
  public:
    Gambler(Heap& h, int l) : limit(l) { heap = &h; };
    virtual int move() = 0;
    int query();
};

class Man : public Gambler {
  public:
    Man(Heap& h, int l, char* n) : Gambler(h, l) { name = n; };
    virtual int move();
};

class Pen : public Gambler {
  public:
    Pen(Heap& h, int l, char* n) : Gambler(h, l) { name = n; };
    virtual int move();
};

int Gambler::query() {
cout << "Heap = " << heap->get() << " " << name << " > ";
return(heap->get());
}

int Man::move() {
int g;
cin >> g;
if((g < 1) || (g > (heap->get())) || (g > limit))
  g = 1;
return(heap->get(g));
}

int Pen::move() {
int rest = 0;
int n = 0;
int h;
if((h = heap->get()) == 1)
  h = heap->get(1);
while((rest = (n*limit + n + 1)) < h)
  n++;
if((rest > h) || (rest == h))
  rest = (n - 1)*limit + n;
heap->get(h - rest);
cout << h - rest << "\n";
return(heap->get());
}

int main(int argc, char* argv[]) {
int i = 0;
Heap h(atoi(argv[1]));
Gambler* g[] = { new Pen(h, atoi(argv[2]), "Pen"),
                 new Man(h, atoi(argv[2]), "Man")
               };
while(g[i]->query() != 0) {
  g[i]->move();
  if(++i > 1)
    i = 0;
}
cout << "Winner\n";
delete g[0];
delete g[1];
return(0);
}