0

I'm trying to make a chopsticks game. Here's a wikipedia link to the game https://en.wikipedia.org/wiki/Chopsticks_(hand_game). So far I just added a couple methods so that one hand can attack another hand using the 'attack' method. I feel like the code I wrote is very verbose, ugly and maybe even wrong though. How can I write this more elegantly?

class game:
    def __init__(self):
        self.x_left = 1
        self.x_right = 1
        self.o_left = 1
        self.o_right = 1  

    def set_x_left(self, num):
        self.x_left = num

    def set_x_right(self, num):
        self.x_right = num

    def set_o_left(self, num):
        self.o_left = num

    def set_o_right(self, num):
        self.o_right = num    

    def dict_func(self, hand):        
        self.func= {'x_left': self.set_x_left, 'x_right': self.set_x_right,
             'o_left': self.set_o_left, 'o_right': self.set_o_right}

        return self.func[hand]

    def dict_hand(self, hand):
        self.hands = {'x_left': self.x_left, 'x_right': self.x_right,
             'o_left': self.o_left, 'o_right': self.o_right}     

        return self.hands[hand]

    def attack(self, from_hand, to_hand):
        self.dict_func(to_hand)(self.dict_hand(from_hand) + self.dict_hand(to_hand))

1 Answer 1

1

your code seems to have some unnecessary methods. You can get rid of the methods that set the variables with a number:

def set_x_left(self, num):
    self.x_left = num

When you create an instance of game you can use dot notation to set the values:

chopsticks = game()
#   ^^^ that's the instance

chopsticks.set_x_left(0)
# is the same as 
chopsticks.x_left = 0

As you can see it's quicker to type, doesn't require any methods. It's just attribute assignments. Doing this will affect you dict_func method, so you can create an anonymous function instead:

def dict_func(self, hand):        
    self.func = {'x_left': lambda self, x: self.x_left = x,
                 'x_right': lambda self, x: self.x_right = x,
                 'o_left': lambda self, x: self.o_left = x,
                 'o_right': lambda self, x: self.o_right = x}

    return self.func[hand]

In fact you can declare the self.func self.hands attributes in __init__ to make sure that they're only assigned to once. Then in the function you can just write return self.func[hand]

Your dict_hand method is also slightly over complicated. Your aim is to get the attribute from the instance dict, so you can do:

def dict_hand(self, hand):
    return getatttr(self, hand)

(You may want to rename this function :))

Sign up to request clarification or add additional context in comments.

4 Comments

I put those in for the purpose of my attack method.
I don't think this works actually. From what I've read and the errors I'm encountering, you can't make an assignment statement with lambda. Also, I think that syntax might be wrong.
Hmm I believe you're entirely correct. Didn't know about that. But I think your dict_hand method should work with getattr instead

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.