carykh / PrisonersDilemmaTournament

Watch This Place's awesome video about iterated Prisoner's Dilemma for context! https://www.youtube.com/watch?v=BOvAbjfJ0x0
MIT License
205 stars 160 forks source link

[bugfix] Coerce all moves to be 0 or 1 #45

Closed l4vr0v closed 3 years ago

l4vr0v commented 3 years ago

Fixes #44

In strategyMove(), strings are parsed as 0 or 1 but non-string inputs that are not 0 or 1 are just parsed as themselves. This can mess with strategies (via silent defections) and/or create run-time errors. E.g., if a strategy looks like:

def strategy(history, memory):
    ...
    if history[1, -1] == 0:
        some_var = True
    if history[1, -1] == 1:
        some_var = False
    do_something(some_var)
    ...

and another strategy in the mix returns numeric results that aren't 1 or 0 (like in #44):

def strategy(history, memory): return -2, None

Running prisonersDilemma.py will throw a:

UnboundLocalError: local variable 'some_var' referenced before assignment

This single-commit one-liner PR fixes that by coercing all moves to be 0 or 1 by using Python's "truthy" and "falsy" values. All "falsy" values (other than string ones, which your code already handles) become 0, all "truthy" values become 1. You can no longer throw off opponents by returning 2, -2, 3.141592653589793238462643..., etc.

carykh commented 3 years ago

Oooh, thank you so much, @l4vr0v! This was definitely a mistake that needed to be fixed.

I guess one small question I had was, is there any way to quickly merge this fix with the three relevant branches? (main, gemstone, and policestation). I suppose I could do it manually for now, but I wonder if there's a more convenient way to do it for future use...

carykh commented 3 years ago

(P.S. It is fixed across all 3 branches now)

l4vr0v commented 3 years ago

re: merging with multiple branches - looks like neither git nor GitHub supports this directly and you're forced to do some manual work, like you did here.