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

Eckhart Arnold

1 Einleitung
2 Evolutionäre Erklärungen
3 Computermodelle zur Simulation evolutionärer Vorgänge
4 Beispiele für evolutionäre Erklärungsansätze im Bereich der Kulturwissenschaften
5 Zitierte Literatur
6 Anhang: Programmcode des Computerturniers
    6.1 Tournament.py
    6.2 Strategy.py

6.2 Strategy.py


"""Some basic strategies."""


import whrandom


class Strategy:
    """An abstract class for a player strategy.

    Any concrete player strategy in the tournament is a child
    class of this one."""

    name = "no strategy"


    def nextMove(self, round, myMoves, opMoves):
        """Determine the next move (either 1 to coperate or 0 to defect)
        based on the sequences of all previous moves.

        Parameters:
        round     - Number of the current round starting with 1
        myMoves   - List of all previous moves of this strategy in this match
        opMoves   - List of all previous moves of the opponent strategy
        """
        pass



###########################################################
#
#   Trivial strategies
#
###########################################################


class AlwaysFriendly(Strategy):
    """This strategy never defects."""

    name = "Always friendly"

    def nextMove(self, round, myMoves, opMoves):
        return 1                                        # never defect



class UtterlyDestructive(Strategy):
    """This strategy always defects."""

    name = "Utterly destructive"

    def nextMove(self, round, myMoves, opMoves):
        return 0                                        # always defect



class Random(Strategy):
    """This strategy chooses its moves at random."""

    name = "Random"

    def nextMove(self, round, myMoves, opMoves):
        return whrandom.randint(0, 1)                   # play randomly




############################################################
#
#   simple strategies
#
############################################################


class TitForTat(Strategy):
    """Play cooperatively only if the other player did 
    so in the previous round. Start friendly."""

    name = "Tit for tat"

    def nextMove(self, round, myMoves, opMoves):
        if round == 1:
            return 1                                    # start friendly
        else:
            if opMoves[-1] == 1: return 1
            else:                return 0



class TitForTwoTats(Strategy):
    """Play friendly if the oponent did not defect in the
    two previous rounds. Start friendly."""

    name = "Tit for two tats"

    def nextMove(self, round, myMoves, opMoves):
        if round <=  2:
            return 1                                    # start friendly
        else:
            if (opMoves[-2:] == [0,0]): return 0
            else:                       return 1



class MassiveResponse(Strategy):
    """Play 'Tit for Tat' but punish twice for every single defection of
    the opponent. Start friendly though."""

    name = "MassiveResponse"

    def nextMove(self, round, myMoves, opMoves):
        if round == 1:
            return 1                                    # start friendly
        elif round == 2:
            if opMoves[-1] == 0:      return 0          # Tit for Tat
            else:                     return 1
        else:
            if opMoves[-2:] != [1,1]: return 0          # Massive response
            else:                     return 1



class Cheater(Strategy):
    """Play friendly if the oponent did not defect in the two
    previous rounds (like 'Tit for two Tats'). But try to cheat
    (play destrcutive) every 7th round."""

    name = "Cheater"

    def nextMove(self, round, myMoves, opMoves):
        if round <= 2:
            return 1                                    # start friendly
        else:
            if (round % 7) != 0:                        # play Tf2T usually
                if (opMoves[-2:] == [0,0]): return 0
                else:                       return 1
            else:                                       # but cheat sometimes
                return 0



class GraciousTfT(Strategy):
    """Play 'Tit for Tat', but play cooperatively (as an offer of peace),
    if there have already been five rounds of mutual defection (or
    alternating defection and cooperation) in sequence."""

    name = "GraciousTfT"

    def nextMove(self, round, myMoves, opMoves):
        if round == 1:
            return 1                                      # start friendly
        elif round > 6 and ((opMoves[-5:] == [0,0,0,0,0] and \
                             myMoves[-5:] == [0,0,0,0,0]) or \
                            (opMoves[-5:] == [0,1,0,1,0] and \
                             myMoves[-5:] == [1,0,1,0,1])):
            return 1                                      # peace offer
        else:
            if opMoves[-1] == 1: return 1                 # play tit for tat
            else:                return 0





class MaliciousTfT(Strategy):
    """Play 'Tit for Tat' but start unfriendly."""

    name = "MaliciousTfT"

    def nextMove(self, round, myMoves, opMoves):
        if round == 1:
            return 0                                    # start unfriendly
        else:
            if opMoves[-1] == 1: return 1
            else:                return 0



class DelayedTfT(Strategy):
    """Play friendly if the opponent did so three moves before, otherwise
    do not cooperate. Play friendly at the beginning."""

    name = "DelayedTfT"

    def nextMove(self, round, myMoves, opMoves):
        if round <= 3:
            return 1
        else:
            if opMoves[-3] == 1: return 1
            else:                return 0




############################################################
#
#   slightly more comples strategies
#
############################################################


class Tester(Strategy):
    """Defect in the first round in order to test
    the opponents reaction.  Based on the opponents reaction, play either
    Tit for Tat (starting friendly) or try to deceive opponent by playing
    cooperatively in the second and third round and then defecting every
    second round. (See Axelrod, ch. 2, p.40)"""

    name = "Tester"

    def nextMove(self, round, myMoves, opMoves):
        if round <= 2:
            return 0
        elif round == 3:
            if opMoves[-1] == 0:  self.state = "TFT"
            else:                 self.state = "Deceiver"
            return 1
        elif round == 4:
            return 1
        else:
            if self.state == "TFT":
                if opMoves[-1] == 1:  return 1
                else:                 return 0
            else:
                if round % 2 == 1:    return 0
                else:                 return 1


        
class Analyst(Strategy):
    """Play random for the first ten rounds. Then try to analyse 
    the opponents strategy based on the opponents reactions. If either
    the opponent could be exploited very  well or if the opponent 
    did attempt to exploit this strategy to often, play non-cooperatively.
    Play cooperativly, if it wasn't possible to exploit the opponent
    and if the opponent played fair as well."""

    name = "Analyst"

    def nextMove(self, round, myMoves, opMoves):
        if round <= 10:
            return whrandom.randint(0, 1)   # play random at the beginning
        else:

            # analyse

            ex_attempt, ex_success = 0,0
            opex_opportunity, opex_attempt = 0, 0

            i = -9
            while i <= -1:
                if myMoves[i-1] == 0:
                    ex_attempt += 1
                    if opMoves[i] != 0: ex_success += 1 # opponent did
                                                        # not punish exploit!
                else:
                    opex_opportunity += 1
                    if opMoves[i] == 0: opex_attempt += 1  # opponnent played
                                                           # defective without
                                                           # reason
                i += 1

            # and react accordingly

            ret = -1
            if (ex_attempt > 0):
                if (float(ex_success) / float(ex_attempt)) >= 0.6:
                    return 0                    # keep exploiting
                else: ret = 1                   # try to be friendly again

            if opex_opportunity > 0:
                if (float(opex_attempt) / float(opex_opportunity)) <= 0.4:
                    return 1            # opponent isn't really bad
                else:
                    return 0            # opponent tried to deceive to often
            else:
                if ret != -1: return ret      # fallback
                else:
                    if opMoves[-1] == 1: return 1   # play TfT if clueless
                    else:                return 0


t g+ f @