Here is a simpler version, but not terribly OO:
#include <iostream>
#include <map>
struct Contender{
enum class Thing {_, Rock, Scissors, Paper};
using StatusMap = std::map<Thing,bool>;
float _strength = 1.0;
Thing _thing;
StatusMap _map;
Contender(Thing t, StatusMap map): _thing(t), _map(map){}
void adjustStrength(bool won){
_strength *= (won)? 2.0 : .5;
}
void challenge(Contender& c) {
if (_thing != c._thing){
//Should be more defensive here.
bool win = c._map[_thing];
adjustStrength(win);
c.adjustStrength(!win);
}
}
virtual ~Contender(){}
};
struct Rock : Contender {
Rock() : Contender(Thing::Rock, StatusMap{
{Thing::Scissors, false},
{Thing::Paper, true}
}){}
~Rock() override {}
};
struct Scissors : Contender {
Scissors() : Contender(Thing::Scissors, StatusMap{
{Thing::Rock, true},
{Thing::Paper, false}
}){}
~Scissors() override {}
};
struct Paper : Contender {
Paper() : Contender(Thing::Paper, StatusMap{
{Thing::Rock, false},
{Thing::Scissors, true},
}){}
~Paper() override {}
};
int main(){
Rock r;
Scissors s;
Paper p;
r.challenge(s);
std::cout << r._strength << ":" << s._strength << "\n";
}