Reputation: 87
I'm trying to make a "rock, paper, scissors" game in Python and i want to set one variable to be greater then the other one.
something like:
paper > rock
scissors > paper
rock > scissors
how could i do it..?
Upvotes: 2
Views: 860
Reputation: 8458
This is actually an interesting question, because it raises some useful ideas.
If, for example, paper-rock-scissors followed the laws of mathematical inequality it would be a trivial problem. Let's say paper > rock > scissors
is mathematically true (i.e. paper > scissors
, contrary to the rules of the game):
class fist(object):
def __init__(self, weapon):
WEAPON_VALUES = {'paper': 2, 'rock': 1, 'scissors': 0}
self.weapon_value = WEAPON_VALUES[weapon]
def __gt__(self, other):
return self.weapon_value > other.weapon_value
def __lt__(self, other):
return self.weapon_value < other.weapon_value
def __eq__(self, other):
return self.weapon_value == other.weapon_value
def __ne__(self, other):
return self.weapon_value != other.weapon_value
paper = fist('paper')
rock = fist('rock')
scissors = fist('scissors')
Now we can check:
In [7]: paper > rock
Out[7]: True
In [8]: rock == rock
Out[8]: True
In [9]: paper < scissors
Out[9]: False
In [10]: scissors < rock
Out[10]: True
Unfortunately, paper-rock-scissors has a circular logic, and so the usual concept of inequality doesn't work in this case (hence paper < scissors
evaluates to False
).
You could use custom comparables as explained in another answer, but bear in mind that this raises paradoxes like rock > scissors > paper == True
when of course rock < paper
.
Upvotes: 3
Reputation: 16942
For a simple solution that doesn't involve redefining operators:
First define the rules of the game:
rules = ['paper>rock', 'rock>scissors', 'scissors>paper']
and use a function like this to check the data against the rules:
def greater(opt1, opt2):
if opt1 == opt2:
return None # draw
return "{0}>{1}".format(opt1, opt2) in rules
>>> greater('paper','rock')
True
>>> greater('paper','scissors')
False
>>> greater('rock','paper')
False
Upvotes: 1
Reputation: 5280
What I would suggest in your case is to create a function that would return the winner. Something like
def winner(J1, J2):
if J1 == 'rock':
if J2 == 'paper':
return('J2')
if J2 == 'rock':
return('draw')
if J2 == 'paper':
return('J1')
...
That would allow you to see who wins.
Upvotes: 2
Reputation: 478
Yes as Daniel said, with the override of __cmp__
you can acheive this :
class Comparable(object):
def __init__(self, below_class, above_class):
self.above_class = above_class
self.below_class = below_class
def __cmp__(self, other):
if isinstance(other, self.below_class):
return 1
if isinstance(other, self.above_class):
return -1
return 0
class Paper(Comparable):
pass
class Rock(Comparable):
pass
class Scissors(Comparable):
pass
scissors = Scissors(Paper, Rock)
paper = Paper(Rock, Scissors)
rock = Rock(Scissors, Paper)
# True
print paper > rock
print scissors > paper
print rock > scissors
# False
print paper < rock
print scissors < paper
print rock < scissors
The documentation on the way this works is available here : https://docs.python.org/2.6/reference/datamodel.html#object.cmp
Upvotes: 5
Reputation: 60957
You can override the behavior of the >
operator by defining a __gt__
method on the object. See the documentation on the Python data model for more information.
Upvotes: 1