-2

I'm trying to implement a function where I have 2 players and their payoffs depends on their actions.

def game(action1,action2):

  if action1 == "a" and action2 == "a":
     payoff1 = 1
     payoff2 = 1
  elif action1 == "a" and action2 == "b":
     payoff1 = -5
     payoff2 = 3
  elif action1 == "b" and action2 == "a":
     payoff1 = 3
     payoff2 = -5
  elif action1 == "b" and action2 == "b":
     payoff1 = 2
     payoff2 = 2
 return payoff1 , payoff2

Then I would have strategy for this game (example):

def TitForTat(round_num, previous_action):
    if round_num == 0:
       action = "a"
    else:
       action = previous_action
  return action

def AlwaysDefect():
  return "b"

action1 = TitForTat (0,'c')
action2 = AlwaysDefect()

game (action1,action2)

This returns an error:

local variable 'payoff1' referenced before assignment

I tried to initialize them to "0" , but the same. The exact functions works very well if I have all positive values.

EDIT:

So sorry for the typo error. And function AlwaysDefect() returns "b" and "d".

user3085433
  • 43
  • 2
  • 10
  • 1
    `payyoff2` --> `payoff2 `. – lurker Oct 30 '18 at 17:34
  • 2
    Are `action1` and `action2` limited to values of `"a"` or `"b"` going into your `game` function? The error implies that none of your `if` conditions triggered. If either `action1` or `action2` has a value other than `"a"` or `"b"` you're going to get that error. It looks like one of your actions might be `"c"` but you don't take care of that case in `game`. – lurker Oct 30 '18 at 17:34
  • Replace `payyoff2 = 2` by `payoff2 = 2` in the first step – Sheldore Oct 30 '18 at 17:35
  • You need to add an `else` clause in your game function to handle exceptional circumstances – kellymandem Oct 30 '18 at 17:36
  • 1
    You can make `game` much simpler. For instance, you can do `if (action1,action2)==('a',b'): return (1,1)`. You could also replace the entire function with one line: `{('a,'a'):(1,1),('a','b'):(-5,3),('b','a'):(3,-5),('b','b'):(2,2)}[(action1,action2)]` – Acccumulation Oct 30 '18 at 17:45
  • @Acccumulation Thank you very much for your suggestion, tried that and it worked! – user3085433 Oct 30 '18 at 18:00

5 Answers5

2

Your if statements arent catching if the action is c or d this leads to the payoff1 and payoff2 to not be initialized.

Neo
  • 79
  • 6
1

Too much chaff in your function call. Use a dictionary:

def game(action1, action2):
    payoffs = {
        ('a', 'a'): (1, 1),  ('a', 'b'): (-5, 3),
        ('b', 'a'): (3, -5), ('b', 'b'): (2, 2)
    }
    return payoffs.get((action1, action2), (0, 0))
PMende
  • 5,171
  • 2
  • 19
  • 26
0

Did you mean that AlwaysDefect function return 'd' or 'b'?

Now that it return 'd', you don't get into none of your if statements and you don't have a definition for either payoff1 or payoff2

Also a typo: payyoff2 -> payoff2

You can set a default statement in order to fix it (At the else section):

def game(action1,action2):

  if action1 == "a" and action2 == "a":
     payoff1 = 1
     payoff2 = 1
  elif action1 == "a" and action2 == "b":
     payoff1 = -5
     payoff2 = 3
  elif action1 == "b" and action2 == "a":
     payoff1 = 3
     payoff2 = -5
  elif action1 == "b" and action2 == "b":
     payoff1 = 2
     payoff2 = 2
  else:
     payoff1 = 0 # or any other value
     payoff2 = 0 # or any other value
  return payoff1, payoff2
omri_saadon
  • 10,193
  • 7
  • 33
  • 58
0

You should initialize both payoff to something because if your actions don't fall into a specific case, you endup returning nothing. So add in a default else so that your function return default payoffs the following code should help you solve your problem mate.

def game(action1,action2):


    if action1 == "a" and action2 == "a":
        payoff1 = 1
        payoff2 = 1
    elif action1 == "a" and action2 == "b":
        payoff1 = -5
        payoff2 = 3
    elif action1 == "b" and action2 == "a":
        payoff1 = 3
        payoff2 = -5
    elif action1 == "b" and action2 == "b":
        payoff1 = 2
        payoff2 = 2
    else:
        payoff1= 0
        payoff2=0


    return payoff1 , payoff2

This should technically prevent you from having that reference error.

0

You have a few problems in this code.

def game(action1,action2):
  # 1. this if/else chain only handles input values of "a" or "b"
  if action1 == "a" and action2 == "a":
     payoff1 = 1
     payoff2 = 1
  elif action1 == "a" and action2 == "b":
     payoff1 = -5
     payoff2 = 3
  elif action1 == "b" and action2 == "a":
     payoff1 = 3
     payoff2 = -5
  elif action1 == "b" and action2 == "b":
     payoff1 = 2
     # 2. this is misspelt, so payoff2 never gets declared for input "b","b"
     payyoff2 = 2

 return payoff1 , payoff2
  1. the code for game only works for inputs in ("a","b")x("a","b") but there is no error checking, and in fact the code you posted does provide inputs outside that range
  2. one of the valid inputs ("b","b") will still fail because you misspelt "payoff". Less verbose code has fewer opportunities for spelling mistakes, but really this is something you should find in testing.

    action1 = TitForTat (0,'c') action2 = AlwaysDefect()

Why not print your arguments before you pass them to your function? Or print the arguments inside the function? Or step into the function in pdb and look at them?

You've set them to "a", "d" here, and TitForTat could have produced "c". Neither "c" nor "d" are handled at all in your game function.

Useless
  • 64,155
  • 6
  • 88
  • 132