6
6
Based on Martin Jones @mojones original LookerUp code
7
7
"""
8
8
9
- import axelrod
9
+ from itertools import product
10
10
11
11
from pyswarm import pso
12
12
13
-
14
- class Gambler (Player ):
15
-
16
- name = 'Gambler'
17
- classifier = {
18
- 'memory_depth' : float ('inf' ),
19
- 'stochastic' : True ,
20
- 'makes_use_of' : set (),
21
- 'inspects_source' : False ,
22
- 'manipulates_source' : False ,
23
- 'manipulates_state' : False
24
- }
25
-
26
- @init_args
27
- def __init__ (self , lookup_table = None ):
28
- """
29
- If no lookup table is provided to the constructor, then use the TFT one.
30
- """
31
- Player .__init__ (self )
32
-
33
- if not lookup_table :
34
- lookup_table = {
35
- ('' , 'C' , 'D' ) : 0 ,
36
- ('' , 'D' , 'D' ) : 0 ,
37
- ('' , 'C' , 'C' ) : 1 ,
38
- ('' , 'D' , 'C' ) : 1 ,
39
- }
40
-
41
- self .lookup_table = lookup_table
42
- # Rather than pass the number of previous turns (m) to consider in as a
43
- # separate variable, figure it out. The number of turns is the length
44
- # of the second element of any given key in the dict.
45
- self .plays = len (list (self .lookup_table .keys ())[0 ][1 ])
46
- # The number of opponent starting actions is the length of the first
47
- # element of any given key in the dict.
48
- self .opponent_start_plays = len (list (self .lookup_table .keys ())[0 ][0 ])
49
- # If the table dictates to ignore the opening actions of the opponent
50
- # then the memory classification is adjusted
51
- if self .opponent_start_plays == 0 :
52
- self .classifier ['memory_depth' ] = self .plays
53
-
54
- # Ensure that table is well-formed
55
- for k , v in lookup_table .items ():
56
- if (len (k [1 ]) != self .plays ) or (len (k [0 ]) != self .opponent_start_plays ):
57
- raise ValueError ("All table elements must have the same size" )
58
-
59
-
60
- def strategy (self , opponent ):
61
- # If there isn't enough history to lookup an action, cooperate.
62
- if len (self .history ) < max (self .plays , self .opponent_start_plays ):
63
- return C
64
- # Count backward m turns to get my own recent history.
65
- history_start = - 1 * self .plays
66
- my_history = '' .join (self .history [history_start :])
67
- # Do the same for the opponent.
68
- opponent_history = '' .join (opponent .history [history_start :])
69
- # Get the opponents first n actions.
70
- opponent_start = '' .join (opponent .history [:self .opponent_start_plays ])
71
- # Put these three strings together in a tuple.
72
- key = (opponent_start , my_history , opponent_history )
73
- # Look up the action associated with that tuple in the lookup table.
74
- action = float (self .lookup_table [key ])
75
- return random_choice (action )
76
-
13
+ import axelrod as axl
14
+ from axelrod import Gambler , init_args
15
+ from axelrod_utils import score_single
77
16
78
17
79
18
class TestGambler (Gambler ):
@@ -83,7 +22,8 @@ class TestGambler(Gambler):
83
22
84
23
name = "TestGambler"
85
24
86
- def __init__ (self ,pattern ):
25
+ @init_args
26
+ def __init__ (self , pattern ):
87
27
plays = 2
88
28
opponent_start_plays = 2
89
29
@@ -102,7 +42,7 @@ def __init__(self,pattern):
102
42
Gambler .__init__ (self , lookup_table = lookup_table )
103
43
104
44
105
- def score_for_pattern (my_strategy_factory ,pattern , iterations = 200 ):
45
+ def score_for_pattern (my_strategy_factory , pattern , iterations = 200 ):
106
46
"""
107
47
Given a function that will return a strategy,
108
48
calculate the average score per turn
@@ -112,29 +52,31 @@ def score_for_pattern(my_strategy_factory,pattern, iterations=200):
112
52
a good estimate.
113
53
"""
114
54
scores_for_all_opponents = []
115
- for opponent in axelrod .ordinary_strategies :
55
+ strategies = [s for s in axl .strategies
56
+ if not s ().classifier ['long_run_time' ]]
57
+ for opponent in strategies :
116
58
117
- # decide whether we need to sample or not
118
- if opponent .classifier ['stochastic' ]:
59
+ # Decide whether we need to sample or not
60
+ if opponent () .classifier ['stochastic' ]:
119
61
repetitions = 100
120
62
else :
121
63
repetitions = 1
122
64
scores_for_this_opponent = []
123
65
124
- # calculate an average for this opponent
66
+ # Calculate an average for this opponent
125
67
for _ in range (repetitions ):
126
68
me = my_strategy_factory (pattern )
127
69
other = opponent ()
128
- # make sure that both players know what length the match will be
129
- me .set_tournament_attributes (length = iterations )
130
- other .set_tournament_attributes (length = iterations )
70
+ # Make sure that both players know what length the match will be
71
+ me .set_match_attributes (length = iterations )
72
+ other .set_match_attributes (length = iterations )
131
73
132
74
scores_for_this_opponent .append (score_single (me , other , iterations ))
133
75
134
76
mean_vs_opponent = sum (scores_for_this_opponent ) / len (scores_for_this_opponent )
135
77
scores_for_all_opponents .append (mean_vs_opponent )
136
78
137
- # calculate the average for all opponents
79
+ # Calculate the average for all opponents
138
80
overall_average_score = sum (scores_for_all_opponents ) / len (scores_for_all_opponents )
139
81
return overall_average_score
140
82
@@ -152,7 +94,10 @@ def optimizepso(x):
152
94
1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,
153
95
1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ]
154
96
155
- # The parameters of phip, phig and omega will lead to slower conversion
156
- xopt , fopt = pso (optimizepso , lb , ub , swarmsize = 100 , maxiter = 20 , processes = 60 ,
157
- debug = True ,
158
- phip = 0.8 , phig = 0.8 , omega = 0.8 )
97
+ # There is a multiprocessing version (0.7) of pyswarm available at
98
+ # https://github.com/tisimst/pyswarm
99
+ # Pip installs version 0.6
100
+ xopt , fopt = pso (optimizepso , lb , ub , swarmsize = 100 , maxiter = 20 ,
101
+ debug = True , phip = 0.8 , phig = 0.8 , omega = 0.8 )
102
+ print (xopt )
103
+ print (fopt )
0 commit comments