понедельник, 27 июня 2011 г.

Модель "Камень, ножницы, бумага"

Написана с помощью метода двойной диспетчеризации.
#include <iostream>

class Rock;
class Paper;
class Scissors;
class Item;

enum Outcome {WIN, LOSE, DRAW};

class Item {
public:
  virtual Outcome hit(Rock&) = 0;
  virtual Outcome hit(Paper&) = 0;
  virtual Outcome hit(Scissors&) = 0;
  virtual Outcome hit(Item&) = 0;
};

class Rock: public Item {
  virtual Outcome hit(Rock& r) {
    return DRAW;
  }

  virtual Outcome hit(Paper& p) {
    return LOSE;
  }

  virtual Outcome hit(Scissors& p) {
    return WIN;
  }

  virtual Outcome hit(Item& i) {
    return i.hit(*this);
  }
};

class Paper: public Item {
  virtual Outcome hit(Rock& r) {
    return WIN;
  }

  virtual Outcome hit(Paper& p) {
    return DRAW;
  }

  virtual Outcome hit(Scissors& p) {
    return LOSE;
  }

  virtual Outcome hit(Item& i) {
    return i.hit(*this);
  }
};

class Scissors: public Item {
  virtual Outcome hit(Rock& r) {
    return LOSE;
  }

  virtual Outcome hit(Paper& p) {
    return WIN;
  }

  virtual Outcome hit(Scissors& p) {
    return DRAW;
  }

  virtual Outcome hit(Item& i) {
    return i.hit(*this);
  }
};

Outcome Compete(Item* a, Item* b) {
  return a->hit(*b);
}

// Quick test:
int main() {
  Rock r;
  Paper p;
  Scissors s;
  std::cout << "Rock vs Paper: " << Compete(&r, &p) << std::endl;
  std::cout << "Scissors vs Paper: " << Compete(&s, &p) << std::endl;
  std::cout << "Rock vs Rock: " << Compete(&r, &r) << std::endl;
  return 0;
}

Комментариев нет:

Отправить комментарий