-
Notifications
You must be signed in to change notification settings - Fork 0
/
titForTatBot.py
131 lines (116 loc) · 4.76 KB
/
titForTatBot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# COMP-3710 Final project Prisoner Dilemma simulator
# it can start off as either cooperating and defecting depending on the arguments
# afterwards it will mirror the opponent
from botBase import baseBot
import random
class titForTatBot(baseBot):
def __init__(self, name, sM):
# bot inherits from base class and sets it's name
super().__init__(name)
self.startingMove = sM
def getMove(self,opponentMoves) -> bool:
if(len(opponentMoves)==0): #for first move return
return self.startingMove
# otherwise mirror
return opponentMoves[-1]
#bot that acts like tit-for -tat but gives an extra chance to forgive also called tit for 2 tats
class cooperativeTitForTatBot(baseBot):
def __init__(self):
# bot inherits from base class and sets it's name
super().__init__("cooperative tit-for-tat")
def getMove(self,opponentMoves) -> bool:
if(len(opponentMoves)<2): #for first move return
return baseBot.cooperate
if(opponentMoves[-1] == baseBot.defect and opponentMoves[-2] == baseBot.defect ):
return baseBot.defect
return baseBot.cooperate
#at starts gives two chances then it will punish if either of the last two move were defects
class hardTitForTatBot(baseBot):
def __init__(self):
# bot inherits from base class and sets it's name
super().__init__("hard tit-for-tat")
def getMove(self,opponentMoves) -> bool:
if(len(opponentMoves)<2): #for first move return
return baseBot.cooperate
if(opponentMoves[-1] == baseBot.defect or opponentMoves[-2] == baseBot.defect ):
return baseBot.defect
return baseBot.cooperate
#slow tit for tat starts of cooperating and defects if last two moves were defects then it needs two cooperates to make it calm down
class slowTitForTatBot(baseBot):
def __init__(self):
# bot inherits from base class and sets it's name
super().__init__("slow tit-for-tat")
self.niceMode = True
def getMove(self,opponentMoves) -> bool:
if(len(opponentMoves)>1): #for first move return
if(self.niceMode and opponentMoves[-1] == baseBot.defect
and opponentMoves[-2] == baseBot.defect):
self.niceMode =False
if (not self.niceMode and opponentMoves[-1] == baseBot.cooperate
and opponentMoves[-2] == baseBot.cooperate ):
self.niceMode=True
return self.niceMode
# make sure bot always starts off as nice
def newRound(self):
self.niceMode = True
# sneaky tit-for-tat acts like tit for tat but will try to get away with some cheating it it can
class sneakyTitForTatBot(baseBot):
def __init__(self):
# bot inherits from base class and sets it's name
super().__init__("sneaky tit-for-tat")
self.tricked = False
self.trickRound = random.randint(0,3)
def getMove(self,opponentMoves) -> bool:
# try trick
if(len(opponentMoves)==self.trickRound):
self.tricked = True
return baseBot.defect
if(self.tricked):
# if trick was retaliated then fall back and apologize
if(opponentMoves[-1] == baseBot.defect):
self.trick = False
return baseBot.cooperate
# otherwise exploit
return baseBot.defect
else: # if not tricking then play as tit for tat
# basic first round
if(len(opponentMoves)==0): #for first move return
return baseBot.cooperate
else:
return opponentMoves[-1]
# reset bot so it can try to trick again
def newRound(self):
self.tricked = False
self.trickRound = random.randint(0,5)
# forgiving tit for tat is a bot that will play tit-for-tat toward anyone who
# has defected more than set probability(10% by default) of the time otherwise it just cooperates
# can play with what percentage is best
class forgivingTitForTatBot(baseBot):
def __init__(self, p:float):
# bot inherits from base class and sets it's name
super().__init__("forgiving tit-for-tat")
self.opponentDefect = 0
self.probability =p
def getMove(self,opponentMoves) -> bool:
if(len(opponentMoves)==0): #for first move return
return baseBot.cooperate
if opponentMoves[-1] == baseBot.defect:
self.opponentDefect += 1
# more than set probability mirror
if self.opponentDefect/len(opponentMoves) >= self.probability:
return opponentMoves[-1]
return baseBot.cooperate
def newRound(self):
self.opponentDefect = 0
# generous plays tit-for tat except for a small probability that it randomly forgive by default a 5% chance
class generousTitForTatBot(baseBot):
def __init__(self, p:float):
# bot inherits from base class and sets it's name
super().__init__("generous tit-for-tat")
self.probability =p
def getMove(self,opponentMoves) -> bool:
if(len(opponentMoves)==0): #for first move return
return baseBot.cooperate
if opponentMoves[-1] == baseBot.defect and random.uniform(0,100)<self.probability:
return baseBot.cooperate
return opponentMoves[-1]