A bidirectional association connects agents to their PD strategies:
PD Strategies are dedicated. This means they aren't shared among agents. Each PD strategy is the strategy for exactly one agent. The PDStrategy base class manages the myAgent link that points to this agent.
This is needed because some strategies need to access their agent's memory about previous encounters with the current competitor:
The other strategies don't care about past encounters:
When agent A competes with agent B—A.compete(B)—A uses its strategy to decide if it will cooperate with B and B uses its strategy to decide if it will cooperate with A. Both agents update their fitness scores, number of games played, and memories. Pay attention to how memory (lastMoves and defectors) is declared and updated.
A tournament maintains a table of strategy names and a list of scores of all agents that employed that strategy:
Map<String, List<Double>> stats = new Hashtable<String, List<Double>>();
When displayed, the average of the list of scores is computed:
Here's a sample output:
selfish strategy: 49.65%
naive strategy: 34.35%
tit4tat strategy: 39.7%
unforgiving strategy: 39.4%
random strategy: 50.3%
As suspected, the crazy, selfish, and unforgiving dominate. Adding vindictiveness (punishment for defectors) tilts things back in favor of tit for tatters.