Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

RTTI and Multiple Dispatch

69 views
Skip to first unread message

Gareth Owen

unread,
Aug 2, 2012, 2:10:04 AM8/2/12
to
What would people consider the most idiomatic way to create an
Rock-Paper-Scissors style game in C++

class Choice;
class Rock : public Choice;
class Scissors : public Choice;
class Paper : public Choice;

// extensions : http://en.wikipedia.org/wiki/Rock-paper-scissors
class Lizard : public Choice;
class Spock : public Choice;

int main()
{
Choice * p1 = player_one_chooses();
Choice * p2 = player_two_chooses();

/// ????
// what goes here to decide whether a beats b

}

Christian Gollwitzer

unread,
Aug 2, 2012, 3:55:51 AM8/2/12
to
Am 02.08.12 08:10, schrieb Gareth Owen:
class Choice {
enum what {Empty, Rock, Scissors, Paper};
std::string additional_info;
// constructor etc.
};

Choice p = player_one_choose();

switch (p.what) {
// ...
}

Nick Keighley

unread,
Aug 2, 2012, 4:46:01 AM8/2/12
to
On Aug 2, 8:55 am, Christian Gollwitzer <aurio...@gmx.de> wrote:
> Am 02.08.12 08:10, schrieb Gareth Owen:


> > What would people consider the most idiomatic way to create an
> > Rock-Paper-Scissors style game in C++
>
> > class Choice;
> > class Rock : public Choice;
> > class Scissors : public Choice;
> > class Paper : public Choice;

seems over the top. What's the difference between these classes?

> > // extensions :http://en.wikipedia.org/wiki/Rock-paper-scissors
> > class Lizard : public Choice;
> > class Spock : public Choice;
>
> > int main()
> > {
> >    Choice * p1 = player_one_chooses();
> >    Choice * p2 = player_two_chooses();
>
> >    /// ????
> >    // what goes here to decide whether a beats b
>
> > }
>
> class Choice {
>         enum what {Empty, Rock, Scissors, Paper};
>         std::string additional_info;
> // constructor etc.
>
> };
>
> Choice p = player_one_choose();
>
> switch (p.what) {
> // ...
> }

maybe an abstract Chooser class so different strategies can be tried
out

enum Choice {rock, paper, scissors};

class Chooser
{
public:
Chooser();
virtual ~Chooser();

virtual Choice makeChoice() = 0;
virtual void result (Choice otherGuy, bool youWon) = 0;
};


gwowen

unread,
Aug 2, 2012, 6:36:18 AM8/2/12
to
On Aug 2, 9:46 am, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:
> On Aug 2, 8:55 am, Christian Gollwitzer <aurio...@gmx.de> wrote:
>
> > Am 02.08.12 08:10, schrieb Gareth Owen:
> > > What would people consider the most idiomatic way to create an
> > > Rock-Paper-Scissors style game in C++
>
> > > class Choice;
> > > class Rock : public Choice;
> > > class Scissors : public Choice;
> > > class Paper : public Choice;
>
> seems over the top. What's the difference between these classes?

I oversimplified. Suppose that these objects were more complicated
game pieces with their own movement characteristics

class Spaceship {
public:
virtual void move();
virtual void launch();
int loc_x,loc_y;
}

class Mine : public Spaceship;
class MineSweeper : public Spaceship;
class BattleShip : public Spaceship;

... with some fighting such that MineSweeper destroys Mine; Mine
destroys Battleship; Battleship destroys MineSweeper...

Jorgen Grahn

unread,
Aug 2, 2012, 7:29:42 AM8/2/12
to
On Thu, 2012-08-02, gwowen wrote:
> On Aug 2, 9:46�am, Nick Keighley <nick_keighley_nos...@hotmail.com>
> wrote:
>> On Aug 2, 8:55�am, Christian Gollwitzer <aurio...@gmx.de> wrote:
>>
>> > Am 02.08.12 08:10, schrieb Gareth Owen:
>> > > What would people consider the most idiomatic way to create an
>> > > Rock-Paper-Scissors style game in C++
>>
>> > > class Choice;
>> > > class Rock : public Choice;
>> > > class Scissors : public Choice;
>> > > class Paper : public Choice;
>>
>> seems over the top. What's the difference between these classes?
>
> I oversimplified.

I don't think so. Even with such a simple game, my first design would
have been something like that. It would not be a /good/ one, but that
was your point, as I understood it.

I think next step I'd go "ok the choices are just like any algebraic
group (or "ring" or whatever they call it) except '<' isn't commutative.

That would lead me to an enum, with a

bool beats(Choice a, Choice b);

attached to it. Then I'd do ugly things inside beats(), because I see
no obvious general way to encode such algebra as C++ (except a full
NxN matrix). And beats() will not be changed often anyways, because it
doesn't make the game any more fun.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Alain Ketterlin

unread,
Aug 2, 2012, 7:31:24 AM8/2/12
to
gwowen <gwo...@gmail.com> writes:

> On Aug 2, 9:46 am, Nick Keighley <nick_keighley_nos...@hotmail.com>
> wrote:
>> On Aug 2, 8:55 am, Christian Gollwitzer <aurio...@gmx.de> wrote:
>>
>> > Am 02.08.12 08:10, schrieb Gareth Owen:
>> > > What would people consider the most idiomatic way to create an
>> > > Rock-Paper-Scissors style game in C++
>>
>> > > class Choice;
>> > > class Rock : public Choice;
>> > > class Scissors : public Choice;
>> > > class Paper : public Choice;
>>
>> seems over the top. What's the difference between these classes?
>
> I oversimplified. Suppose that these objects were more complicated
> game pieces with their own movement characteristics

enum Type { MINE, ... };

> class Spaceship {
> public:
> virtual void move();
> virtual void launch();
> int loc_x,loc_y;

virtual Type type() const = 0;
> }
>
> class Mine : public Spaceship;

virtual Type type() const { return MINE; }

> class MineSweeper : public Spaceship;
> class BattleShip : public Spaceship;

(idem)

(or use an attribute in Spaceship to avoid virtual calls overhead).

> ... with some fighting such that MineSweeper destroys Mine; Mine
> destroys Battleship; Battleship destroys MineSweeper...

bool destroys(const Spaceship & s1, const Spaceship & s2)
{
const static bool d [][] =
{
{ true, false, ... }
...
};
return d[s1.type()][s2.type()]
}

or whatever implementation is suitable (You can put that in Spaceship.)

We're back to C here (treating enums as ints, but you can change this to
a switch). I know of no other good way to implement multiple dispatch in
C++. You could try:

class Mine : public Spaceship {

virtual bool destroys(const Spaceship & s) const
{
s.destroys_mine(s); // or ()
}
virtual bool destroys_mine(const Mine & m) const { ... }
virtual bool destroys_minesweeper(const MineSweeper & m) const { ... }
...
};

(with virtuals declared in Spaceship). You end up with N^2 + N methods
for N subclasses.

Common Lisp would have a great solution for this (defgeneric+defmethod).
Functional languages would use pattern-matching. But "classical" OO has
no good answer.

-- Alain.
0 new messages