-
Notifications
You must be signed in to change notification settings - Fork 282
Description
@drvinceknight suggested I open an issue sharing some code for asymmetric games (see asymmetric_game.py and trade_tournament.py here) which I have been using to run asymmetric tournaments in Axelrod. In particular, it generalises the Game object to take two matrices, rather than just one.
This could be more fully implemented into Axelrod (and I'm happy to do so after discussing it here) in one of two ways:
- Create the AsymmetricGame as a separate object, with AsymmetricTournament class etc. Via duck typing it would still be able to be put into Match objects and so on.
- Implement the AsymmetricGame as the 'base' game class, and then refactor the symmetric game code to inherit from there: e.g. in (truncated) code form:
class AsymmetricGame():
def __init__(self, A, B): # where A and B are the game matrices
# ... so on...
class Game(AsymmetricGame):
def __init__(self, A): # where A is the shared game matrix
super().__init__(A, A)
# ... the regular Game we all know and love...
Similarly, an asymmetric tournament takes two groups (one of row players, one of column players), and then a regular Tournament would become one where the same list of players is passed to both groups. This would build asymmetric Axelrod 'on top' of the existing code with minimal damage to the existing code.
One potential issue I've identified is with the RPST method, which doesn't make sense for asymmetric games; if any important code requires RPST this would need some deeper refactoring (to a 'self' and 'opponent' RPST), but otherwise this could just throw an error if used on an asymmetric game.
Finally, I had written a Paired Moran algorithm which generalises the Moran process to asymmetric games (which takes two populations, and uses fitness functions based on each players' performance against the other population), but this would be a separate PR. @marcharper Vince said your thoughts on this would be valuable.
I would angle towards implementation 2 if given full choice as it reduces code complexity and builds asymmetric games directly into Axelrod. However, it would be a deeper refactoring of the library, so I understand if that is undesirable :-)