package ie.errity.pd;
import java.util.BitSet;
import java.util.Random;
import java.awt.Color;
/**
*This class represents a Prisoner with a strategy to play the
*Prisoner's Dilemma {@link ie.errity.pd.Game Game}.
*@author Andrew Errity
*/
public class Prisoner implements Cloneable
{
private String name;
final private BitSet Strategy;
private int Score; //total payoffs recieved
private Moves m; //table used to decode strategy
/**
*Create a new Prisoner to play the prisoners dilemma
*@param na the Prisoner's name
*@param strat a BitSet representing the player's strategy
*/
public Prisoner(String na, BitSet strat)
{
name = na;
Strategy = strat;
Score= 0;
m = new Moves();
}
/**
*Create a new Prisoner to play the prisoners dilemma (nameless)
*@param strat a BitSet representing the player's strategy
*/
public Prisoner(BitSet strat)
{
name = null;
Strategy = strat;
Score = 0;
m = new Moves();
}
/**
*Create a Predefined Prisoner
*@param s the name of a predefined prisoner
Valid values include:
*
TFT - Tit for TatTFTT - Tit for Two TatsALLC - Always cooperateALLD - Always defectBitSet representing the strategy
*/
public BitSet getStrat(){return Strategy;}
/**
*Gets the Prisoner's next game move
*@param iteration current iteration number
*@param History game history represented as a BitSet
*true or false {C or D}
*/
public boolean play(int iteration, BitSet History)
{
// if first move return start move
if(iteration == 0)
return Strategy.get(0);
// if second move
else if(iteration == 1)
{
if(History.get(1)) //opponent Cooperated
return Strategy.get(1);
else //opponent Defected
return Strategy.get(2);
}
// if third move
else if(iteration == 2)
{
if(History.get(1) && History.get(3)) //opponent CC
return Strategy.get(3);
else if(History.get(1) && !History.get(3)) //opponent CD
return Strategy.get(4);
else if(!History.get(1) && History.get(3)) //opponent DC
return Strategy.get(5);
else if(!History.get(1) && !History.get(3)) ////opponent DD
return Strategy.get(6);
}
// if normal move use normal strategy
else
{
//Get last 3 sets of moves
BitSet hist = History.get( (iteration*2) - 6, (iteration*2));
int x = m.get(hist);
return Strategy.get(x+7); //adjust index to skip setup info
}
return false;
}
/**
*Copy the current Prisoner
*@return a copy of the current Prisoner
*/
public Object clone ()
{
Object self = null;
try
{
self = super.clone();
}
catch(CloneNotSupportedException e)
{
throw new RuntimeException("CloneNotSupportedException");
}
return self;
}
/**
*Convert the Prisoner's strategy to a string of C's and D's
*@return a string representation of the Prisoner's strategy
*/
public String toString()
{
String p = new String();
for(int i = 0; i < 71; i++)
{
if(Strategy.get(i))
p = p + 'C';
else
p = p + 'D';
}
return p;
}
/**
*Returns a Prisoner with a random strategy
*@return a Prisoner with a random strategy
*/
public static Prisoner getRand()
{
BitSet ra;
Random rand = new Random();
//build random player
ra = new BitSet(71);
for(int i = 0; i < 71;i++) //set strategy
{
if(rand.nextBoolean())
ra.set(i);
else
ra.clear(i);
}
return new Prisoner(ra);
}
/**
*Returns an array of Prisoners with random strategies
*@param num_players the number of Prisoners to create
*@return an array of Prisoners with random strategies
*/
public static Prisoner[] getRand(int num_players)
{
BitSet ra;
Random rand = new Random();
Prisoner Players [] = new Prisoner[num_players];
//build random players
for(int j = 0; j < num_players; j++)
{
ra = new BitSet(71);
for(int i = 0; i < 71;i++) //set strategy
{
if(rand.nextBoolean())
ra.set(i);
else
ra.clear(i);
}
Players[j] = new Prisoner(ra);
}
return Players;
}
/**
*Returns a 2D array of Prisoners with random strategies
*@param num_players the length of array to return
*@param num_players2 the depth of array to return
*@return a 2D array of Prisoners with random strategies
*/
public static Prisoner[][] getRand(int num_players,int num_players2)
{
BitSet ra;
Random rand = new Random();
Prisoner Players [][] = new Prisoner[num_players][num_players2];
for(int f = 0; f < num_players; f++)
{
for(int j = 0; j < num_players2; j++)
{
ra = new BitSet(71);
for(int i = 0; i < 71;i++) //set strategy
{
if(rand.nextBoolean())
ra.set(i);
else
ra.clear(i);
}
Players[f][j] = new Prisoner(ra);
}
}
return Players;
}
/**
*Return which color to render the prisoner (based on it's strategy)
*