//
:?C10:PaperScissorsRock.cpp
//
?Demonstration?of?multiple?dispatching
#include?
<
algorithm
>
#include?
<
cstdlib
>
#include?
<
ctime
>
#include?
<
iostream
>
#include?
<
iterator
>
#include?
<
vector
>
#include?
"
../purge.h
"
using
?
namespace
?std;

class
?Paper;
class
?Scissors;
class
?Rock;


enum
?Outcome?
{?win,?lose,?draw?}
;

ostream
&
operator
<<
(ostream
&
?os,?
const
?Outcome?
out
)?

{

??
switch
(
out
)?
{
????
default
:
????
case
?win:?
return
?os?
<<
?
"
win
"
;
????
case
?lose:?
return
?os?
<<
?
"
lose
"
;
????
case
?draw:?
return
?os?
<<
?
"
draw
"
;
??}
}
class
?Item?

{
public
:
??
virtual
?Outcome?compete(
const
?Item
*
)?
=
?
0
;
??
virtual
?Outcome?eval(
const
?Paper
*
)?
const
?
=
?
0
;
??
virtual
?Outcome?eval(
const
?Scissors
*
)?
const
=
?
0
;
??
virtual
?Outcome?eval(
const
?Rock
*
)?
const
?
=
?
0
;
??
virtual
?ostream
&
?print(ostream
&
?os)?
const
?
=
?
0
;

??
virtual
?
~
Item()?
{}
??friend?ostream
&
??
operator
<<
(ostream
&
?os,?
const
?Item
*
?it)?
{
????
return
?it
->
print(os);
??}
}
;

class
?Paper?:?
public
?Item?

{
public
:

??Outcome?compete(
const
?Item
*
?it)?
{
????
return
?it
->
eval(
this
);
??}
??Outcome?eval(
const
?Paper
*
)?
const
?
{
????
return
?draw;
??}
??Outcome?eval(
const
?Scissors
*
)?
const
?
{
????
return
?win;
??}
??Outcome?eval(
const
?Rock
*
)?
const
?
{
????
return
?lose;
??}
??ostream
&
?print(ostream
&
?os)?
const
?
{
????
return
?os?
<<
?
"
Paper???
"
;
??}
}
;

class
?Scissors?:?
public
?Item?

{
public
:

??Outcome?compete(
const
?Item
*
?it)?
{
????
return
?it
->
eval(
this
);
??}
??Outcome?eval(
const
?Paper
*
)?
const
?
{
????
return
?lose;
??}
??Outcome?eval(
const
?Scissors
*
)?
const
?
{
????
return
?draw;
??}
??Outcome?eval(
const
?Rock
*
)?
const
?
{
????
return
?win;
??}
??ostream
&
?print(ostream
&
?os)?
const
?
{
????
return
?os?
<<
?
"
Scissors
"
;
??}
}
;

class
?Rock?:?
public
?Item?

{
public
:

??Outcome?compete(
const
?Item
*
?it)?
{
????
return
?it
->
eval(
this
);
??}
??Outcome?eval(
const
?Paper
*
)?
const
?
{
????
return
?win;
??}
??Outcome?eval(
const
?Scissors
*
)?
const
?
{
????
return
?lose;
??}
??Outcome?eval(
const
?Rock
*
)?
const
?
{
????
return
?draw;
??}
??ostream
&
?print(ostream
&
?os)?
const
?
{
????
return
?os?
<<
?
"
Rock????
"
;
??}
}
;

struct
?ItemGen?

{

??ItemGen()?
{?srand(time(
0
));?}
??Item
*
?
operator
()()?
{

????
switch
(rand()?
%
?
3
)?
{
??????
default
:
??????
case
?
0
:
????????
return
?
new
?Scissors;
??????
case
?
1
:
????????
return
?
new
?Paper;
??????
case
?
2
:
????????
return
?
new
?Rock;
????}
??}
}
;

struct
?Compete?

{

??Outcome?
operator
()(Item
*
?a,?Item
*
?b)?
{
????cout?
<<
?a?
<<
?
"
\t
"
?
<<
?b?
<<
?
"
\t
"
;
????
return
?a
->
compete(b);
??}
}
;

int
?main()?

{
??
const
?
int
?sz?
=
?
20
;
??vector
<
Item
*>
?v(sz
*
2
);
??generate(v.begin(),?v.end(),?ItemGen());
??transform(v.begin(),?v.begin()?
+
?sz,
????v.begin()?
+
?sz,
????ostream_iterator
<
Outcome
>
(cout,?
"
\n
"
),
????Compete());
??purge(v);

}
?
/**/
///
:~
說是用了雙分派,我對(duì)這個(gè)還不知道哦,希望高手指點(diǎn)哦!