@@ -1305,3 +1305,114 @@ def strategy(self, opponent: Player) -> Action:
1305
1305
self .prob += 0.05
1306
1306
self .more_coop , self .last_generous_n_turns_ago = 2 , 1
1307
1307
return self .try_return (D , lower_flags = False )
1308
+
1309
+
1310
+ class MoreTidemanAndChieruzzi (Player ):
1311
+ """
1312
+ Strategy submitted to Axelrod's second tournament by T. Nicolaus Tideman
1313
+ and Paula Chieruzzi (K84R) and came in ninth in that tournament.
1314
+
1315
+ This strategy Cooperates if this player's score exceeds the opponent's
1316
+ score by at least `score_to_beat`. `score_to_beat` starts at zero and
1317
+ increases by `score_to_beat_inc` every time the opponent's last two moves
1318
+ are a Cooperation and Defection in that order. `score_to_beat_inc` itself
1319
+ increase by 5 every time the opponent's last two moves are a Cooperation
1320
+ and Defection in that order.
1321
+
1322
+ Additionally, the strategy executes a "fresh start" if the following hold:
1323
+
1324
+ - The strategy would Defect by score (difference less than `score_to_beat`)
1325
+ - The opponent did not Cooperate and Defect (in order) in the last two
1326
+ turns.
1327
+ - It's been at least 10 turns since the last fresh start. Or since the
1328
+ match started if there hasn't been a fresh start yet.
1329
+
1330
+ A "fresh start" entails two Cooperations and resetting scores,
1331
+ `scores_to_beat` and `scores_to_beat_inc`.
1332
+
1333
+ Names:
1334
+
1335
+ - MoreTidemanAndChieruzzi: [Axelrod1980b]_
1336
+ """
1337
+
1338
+ name = 'More Tideman and Chieruzzi'
1339
+ classifier = {
1340
+ 'memory_depth' : float ('inf' ),
1341
+ 'stochastic' : False ,
1342
+ 'makes_use_of' : {"game" },
1343
+ 'long_run_time' : False ,
1344
+ 'inspects_source' : False ,
1345
+ 'manipulates_source' : False ,
1346
+ 'manipulates_state' : False
1347
+ }
1348
+
1349
+ def __init__ (self ) -> None :
1350
+ super ().__init__ ()
1351
+ self .current_score = 0
1352
+ self .opponent_score = 0
1353
+ self .last_fresh_start = 0
1354
+ self .fresh_start = False
1355
+ self .score_to_beat = 0
1356
+ self .score_to_beat_inc = 0
1357
+
1358
+ def _fresh_start (self ):
1359
+ """Give the opponent a fresh start by forgetting the past"""
1360
+ self .current_score = 0
1361
+ self .opponent_score = 0
1362
+ self .score_to_beat = 0
1363
+ self .score_to_beat_inc = 0
1364
+
1365
+ def _score_last_round (self , opponent : Player ):
1366
+ """Updates the scores for each player."""
1367
+ # Load the default game if not supplied by a tournament.
1368
+ game = self .match_attributes ["game" ]
1369
+ last_round = (self .history [- 1 ], opponent .history [- 1 ])
1370
+ scores = game .score (last_round )
1371
+ self .current_score += scores [0 ]
1372
+ self .opponent_score += scores [1 ]
1373
+
1374
+ def strategy (self , opponent : Player ) -> Action :
1375
+ current_round = len (self .history ) + 1
1376
+
1377
+ if current_round == 1 :
1378
+ return C
1379
+
1380
+ # Calculate the scores.
1381
+ self ._score_last_round (opponent )
1382
+
1383
+ # Check if we have recently given the strategy a fresh start.
1384
+ if self .fresh_start :
1385
+ self ._fresh_start ()
1386
+ self .last_fresh_start = current_round
1387
+ self .fresh_start = False
1388
+ return C # Second cooperation
1389
+
1390
+ opponent_CDd = False
1391
+
1392
+ opponent_two_turns_ago = C # Default value for second turn.
1393
+ if len (opponent .history ) >= 2 :
1394
+ opponent_two_turns_ago = opponent .history [- 2 ]
1395
+ # If opponent's last two turns are C and D in that order.
1396
+ if opponent_two_turns_ago == C and opponent .history [- 1 ] == D :
1397
+ opponent_CDd = True
1398
+ self .score_to_beat += self .score_to_beat_inc
1399
+ self .score_to_beat_inc += 5
1400
+
1401
+ # Cooperate if we're beating opponent by at least `score_to_beat`
1402
+ if self .current_score - self .opponent_score >= self .score_to_beat :
1403
+ return C
1404
+
1405
+ # Wait at least ten turns for another fresh start.
1406
+ if (not opponent_CDd ) and current_round - self .last_fresh_start >= 10 :
1407
+ # 50-50 split is based off the binomial distribution.
1408
+ N = opponent .cooperations + opponent .defections
1409
+ # std_dev = sqrt(N*p*(1-p)) where p is 1 / 2.
1410
+ std_deviation = (N ** (1 / 2 )) / 2
1411
+ lower = N / 2 - 3 * std_deviation
1412
+ upper = N / 2 + 3 * std_deviation
1413
+ if opponent .defections <= lower or opponent .defections >= upper :
1414
+ # Opponent deserves a fresh start
1415
+ self .fresh_start = True
1416
+ return C # First cooperation
1417
+
1418
+ return D
0 commit comments