## Der Einsatz evolutionärer Computermodelle bei der Untersuchung historischer und politischer Fragestellungen |

Inhalt |

"""Classes for matches and tournaments. The the instances of the classes Match and Tournament can be connected to visualizing objects by appending a signal function to the signalXXXXXX lists of the class instance. Signal functions have the general form: function(originating_object, *argument_list) See the source code to find out which signals are defined and which arguments are passed to the signals. """ ########################################################### # # class Match # ########################################################### class Match: """Let two strategies play one series of iterated prisoners dilemmas and record the results. signals: signalROUND_FINISHED (match) - sent when one round of the match has been finished flags (read the "state" field, e.g. m = Match(p1, p2); flag=m.state): MATCH_READY - match has not yet started MATCH_RUNNING - match is currently running MATCH_FINISHED - match has been finished """ def __init__(self, player1, player2, T=5, R=3, P=1, S=0, w=200): """Initialize class with player strategies.""" self.signalROUND_FINISHED = [] # dummy function with # argument list self.player1 = player1 # strategy of player 1 self.player2 = player2 # strategy of player 2 self.moves1 = [] # sequence of moves from player 1 self.moves2 = [] # sequence of moves from player 2 self.score1 = 0 # absolute score of player 1 self.score2 = 0 # absolute score of player 2 self.round = 0 # number of round self.state = "MATCH_READY" self.T = T # reward for defecting if the other player cooperated self.R = R # reward for mutual cooperation self.P = P # "reward" for mutual defection self.S = S # "reward" for cooperation if the other player defected self.w = w # number of rounds def score(self, m1, m2): """Return the score of player one for the moves m1 and m2 of player one and player two respectively. In order to determine the score of player two just swap the parameters m1 and m2.""" if (m1, m2) == (0, 1): return self.T elif (m1, m2) == (1, 1): return self.R elif (m1, m2) == (0, 0): return self.P else: return self.S def nextRound(self): """Let the players meet and update the respective variables with the results. Then, determine if iteration stops after this round (random > w). Return 0 if it does, 1 otherwise.""" self.round += 1 m1 = self.player1.nextMove(self.round, self.moves1, self.moves2) m2 = self.player2.nextMove(self.round, self.moves2, self.moves1) self.moves1.append(m1) self.moves2.append(m2) self.score1 += self.score(m1, m2) self.score2 += self.score(m2, m1) if self.round >= self.w: return 0 else: return 1 def match(self): """Play one match. Call notifier function after each round.""" self.state = "MATCH_RUNNING" cont = 1 while cont: cont = self.nextRound() for s in self.signalROUND_FINISHED: s(self) # callback self.state = "MATCH_FINISHED" ########################################################### # # class Tournament # ########################################################### class Tournament: """Set up and play a tournament. signals: signalENLIST_PLAYER (tournament, player) a new player has been enlisted signalNEW_MATCH (tournament, match) a new match has just begun signalMATCH_COMPLETED (tournament, match) match "match" has been completed signalTOURNAMENT_FINISHED (tournament) the tournament has been finished flags (read the "state" field, e.g. t = Tournament(); flag=t.state): TOURNAMENT_READY - match has not yet started TOURNAMENT_RUNNING - match is currently running TOURNAMENT_FINISHED - match is finished """ def __init__(self, name = "Tournament", T=5, R=3, P=1, S=0, w=200): """Initialize class with match notifier and identification string.""" self.signalENLIST_PLAYER = [] self.signalNEW_MATCH = [] self.signalMATCH_COMPLETED = [] self.signalTOURNAMENT_FINISHED = [] self.name = name # identification string self.player = [] # list of players self.match = [] # list of matches self.score = {} # dictionary of player scores (indexed by players) self.state = "TOURNAMENT_READY" self.T = T # Parameters defining the reward (or punishment resp.) self.R = R # for cooperation or defection. self.P = P # These parameters are directly passed to Match.__init__() self.S = S self.w = w # number of rounds def __cmpfunc(self, p1, p2): if self.score[p1] > self.score[p2]: return -1 elif self.score[p1] == self.score[p2]: return 0 else: return 1 def enlistPlayer(self, newPlayer): """Adds a new Player to the tournament.""" self.player.append(newPlayer) for s in self.signalENLIST_PLAYER: s(self, newPlayer) def runTournament(self): """Run the tournament. Let each player play once against every other player. Invoke signalNEW_MATCH before a new new match is started and signalMATCH_COMPLETED after it is finished. When all matches are completed, calculate the scores of the players and sort self.player according to the players rank in the tournament.""" self.state = "TOURNAMENT_RUNNING" self.match = [] for p in self.player: self.score[p] = 0 for i in range(len(self.player)): for k in range(i+1, len(self.player)): p1 = self.player[i] p2 = self.player[k] m = Match(p1, p2, self.T, self.R, self.P, self.S, self.w) self.match.append(m) for s in self.signalNEW_MATCH: s(self, m) m.match() self.score[p1] += m.score1 self.score[p2] += m.score2 for s in self.signalMATCH_COMPLETED: s(self, m) self.player.sort(self.__cmpfunc) self.state = "TOURNAMENT_FINISHED" for s in self.signalTOURNAMENT_FINISHED: s(self)