Der Einsatz evolutionärer Computermodelle bei der Untersuchung historischer und politischer Fragestellungen
|
Eckhart Arnold
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
|
|
g+
f
@