-
Notifications
You must be signed in to change notification settings - Fork 269
/
Copy pathapavlov.py
122 lines (105 loc) · 4 KB
/
apavlov.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
from typing import Optional
from axelrod.action import Action
from axelrod.player import Player
C, D = Action.C, Action.D
class APavlov2006(Player):
"""
APavlov attempts to classify its opponent as one of five strategies:
Cooperative, ALLD, STFT, PavlovD, or Random. APavlov then responds in a
manner intended to achieve mutual cooperation or to defect against
uncooperative opponents.
Names:
- Adaptive Pavlov 2006: [Li2007]_
"""
name = "Adaptive Pavlov 2006"
classifier = {
"memory_depth": float("inf"),
"stochastic": False,
"long_run_time": False,
"inspects_source": False,
"manipulates_source": False,
"manipulates_state": False,
}
def __init__(self) -> None:
super().__init__()
self.opponent_class = None # type: Optional[str]
def strategy(self, opponent: Player) -> Action:
"""Actual strategy definition that determines player's action."""
# TFT for six rounds
if len(self.history) < 6:
return D if opponent.history[-1:] == [D] else C
# Classify opponent
if len(self.history) % 6 == 0:
if opponent.history[-6:] == [C] * 6:
self.opponent_class = "Cooperative"
if opponent.history[-6:] == [D] * 6:
self.opponent_class = "ALLD"
if opponent.history[-6:] == [D, C, D, C, D, C]:
self.opponent_class = "STFT"
if opponent.history[-6:] == [D, D, C, D, D, C]:
self.opponent_class = "PavlovD"
if not self.opponent_class:
self.opponent_class = "Random"
# Play according to classification
if self.opponent_class in ["Random", "ALLD"]:
return D
if self.opponent_class == "STFT":
if len(self.history) % 6 in [0, 1]:
return C
# TFT
if opponent.history[-1:] == [D]:
return D
if self.opponent_class == "PavlovD":
# Return D then C for the period
if len(self.history) % 6 == 0:
return D
if self.opponent_class == "Cooperative":
# TFT
if opponent.history[-1:] == [D]:
return D
return C
class APavlov2011(Player):
"""
APavlov attempts to classify its opponent as one of four strategies:
Cooperative, ALLD, STFT, or Random. APavlov then responds in a manner
intended to achieve mutual cooperation or to defect against
uncooperative opponents.
Names:
- Adaptive Pavlov 2011: [Li2011]_
"""
name = "Adaptive Pavlov 2011"
classifier = {
"memory_depth": float("inf"),
"stochastic": False,
"long_run_time": False,
"inspects_source": False,
"manipulates_source": False,
"manipulates_state": False,
}
def __init__(self) -> None:
super().__init__()
self.opponent_class = None # type: Optional[str]
def strategy(self, opponent: Player) -> Action:
"""Actual strategy definition that determines player's action."""
# TFT for six rounds
if len(self.history) < 6:
return D if opponent.history[-1:] == [D] else C
if len(self.history) % 6 == 0:
# Classify opponent
if opponent.history[-6:] == [C] * 6:
self.opponent_class = "Cooperative"
if opponent.history[-6:].count(D) >= 4:
self.opponent_class = "ALLD"
if opponent.history[-6:].count(D) == 3:
self.opponent_class = "STFT"
if not self.opponent_class:
self.opponent_class = "Random"
# Play according to classification
if self.opponent_class in ["Random", "ALLD"]:
return D
if self.opponent_class == "STFT":
# TFTT
return D if opponent.history[-2:] == [D, D] else C
if self.opponent_class == "Cooperative":
# TFT
return D if opponent.history[-1:] == [D] else C