ikuro
ikuro

Reputation: 87

How to set that one variable is greater then the other in Python?

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

Answers (5)

ajrwhite
ajrwhite

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

BoarGules
BoarGules

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

Statistic Dean
Statistic Dean

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

sknat
sknat

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

Daniel Pryden
Daniel Pryden

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

Related Questions