2

I am somewhat new to Python, and this is a homework question, so I would appreciate no answers, just advice to help me understand. I am writing a game program that plays two different strategies against each other - a greedy strategy and a zoom-in strategy, which I have written as function. I have a game function that needs to pass in my greedy and zoom-in functions, as well as a game board. I need to be able to have either strategy function go first. So far I can only get it to where my greedy strategy goes first.

def game(P1,P2,board):
    P1 = 0
    P2 = 0 
    for x in range(len(board)):
        if x%2 == 0:
           move = greedy(board)
           P1 += board[move]
           board.remove(board[move])
        else:
            move = zoomin(board)
            P2 += board[move]
            board.remove(board[move])
    if P1 > P2:
        return 1
    elif P1 == P2:
        return 0.5
    else:
        return 0

This strategy always assumes that P1 is the greedy function, but I need to be able to play either first. I thought I could pass in the functions, so my call would be

game(greedy,zoomin,board)

but I am not sure how to actually implement it so that it can recognize who is playing first.

Thank you in advance for your help!

EDIT:

Here are my greedy and zoomin functions:

def greedy(board):
    if board[0] > board[len(board)-1]:
        #returns position of first item
        return 0
    elif board[len(board)-1] > board[0]:
        #returns position of last item
        return len(board)-1
    else:
        #if board[-1] == board[0]
        return 0

def zoomin(board):
    if len(board)%2 == 0:
        evens = 0
        odds = 0
        for x in range(len(board)):
            if x%2 ==0:
                evens += board[x]
            else:
                odds += board[x]
        if evens > odds:
            return 0
        else:
            return len(board)-1
    else:
        #choose the larger value (greedy)
        if board[0] < board[len(board)-1]:
            return len(board)-1
        else:
            return 0
4
  • Please also post your greedy and zoomin functions. Commented Feb 12, 2014 at 22:36
  • "but I am not sure how to actually implement it so that it can recognize who is playing first." -- I don't understand why it is this that is a problem for you, since you already have a method for determining that in your current code (in that P1 plays first). Why do you feel this changes just because you pass in the functions as arguments? Commented Feb 12, 2014 at 22:50
  • 2
    Thank you for being up-front about posting homework, and for declining solutions. Commented Feb 12, 2014 at 22:52
  • In my game function, I have it hard-coded that greedy plays first, so I am not sure what you mean. The game begins with an even number of integers, so in my code greedy always has the first move. I guess I am unsure of how to use the functions I passed in as arguments.. Commented Feb 12, 2014 at 22:55

2 Answers 2

4

This is not a direct answer to your question (since senshin already answered it), but I wanted to point out that you can decrease your code duplication by using arrays instead. For instance, like this:

def game(players, board):
    scores = [0] * len(players)
    while i in range(len(board))
        p = i % len(players)
        move = players[p](board)
        scores[p] += board[move]
        del board[move]    # <-- This is also a faster and more fail-safe version of your "board.remove(board[move])"
    return scores

You can then call this function as game([greedy, zoomin], board). Also note how it extends to an arbitrary number of players, although that may not actually be useful for you. :)

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

1 Comment

@AbigailB: Mind you that, in this case, it's more about cognitive redundancy than performance optimization. Minimizing code duplication is primarily good for maintaining the code. For instance, if you want to change how the game plays out, or fix a bug, or something like that, you don't have to make the change in two or more places, but in one place only. While not a problem in your case, it's things like that which can make larger projects unmaintainable after a while.
2

You will want to rewrite your game function slightly. Notice that your game function accepts P1 and P2, but you don't do anything with them - you immediately assign 0 to both of them.

The correct way to approach this is to have your game function accept two strategies, which can be greedy or zoomin, or whatever else you might come up with later.

def game(strategy1, strategy2, board):

You will also need to replace the explicit calls to greedy and zoomin in the function body (e.g. move = greedy(board)) with calls to the strategies passed into your function instead - something like move = strategy1(board).

Then, in order to have greedy play first and zoomin play second, you could call:

game(greedy, zoomin, board)

Or if you wanted zoomin first and greedy second, you could call:

game(zoomin, greedy, board)

As you can see, the order of play is determined by the order in which you pass the two strategies into your function. Let me know if this needs clarification.

2 Comments

This makes perfect sense! I was thinking I actually had to code in the strategies instead of being able to pass them in in any order. THANK YOU! :)
Since you asked for general advice -- the answer from @Dolda2000 is a more general solution, and a better example for how to think in Python.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.