Prisoners Delemma

<< RumorSimulation | OtherProjectsTrailIndex | GreedGameSim >>

During the Cold War, they used computers to test strategies. This is a famous scenario that Robert Axelrod used which blossomed a whole bunch of Game Theory and using computers to model Political Science theories. Here is the Wikipedia link If you have 12 minutes to spare, an entertaining way to get introduced to this is to listen to Dr Axelrod in an interview about it 40 min and 37 seconds into this RadioLab Episode.

Jesus.java

public class Jesus extends Prisoner
{
	public Jesus(){
		super ("Jesus");
	}
	public boolean choose(){
		return Prisoner.COOP;
	}
}

Lucifer.java

public class Lucifer extends Prisoner{
	public Lucifer(){
		super ("Lucifer");
	}
	public boolean choose(){
		return Prisoner.BETRAY;
	}

}

TitForTat.java

public class TitForTat extends Prisoner 
{
	public TitForTat(){
		super("Tit for Tat");
	}
	public boolean choose(){
		if (firstTurn())
			return Prisoner.COOP;
		if (this.lastTurn()==Prisoner.BETRAY)
			return Prisoner.BETRAY;
		return Prisoner.COOP;
	}
}

BasicPDTest.java

import java.util.ArrayList;

public class BasicPDTest {

	public static void main(String[] args) {
		System.out.println("Basic Prisoner's Delemma Test");
		ArrayList<Prisoner> list = new ArrayList<Prisoner>();
		list.add(new Lucifer());
		list.add(new TitForTat());
		list.add(new Jesus());

		for(int i=0; i< list.size(); i++)
			for(int j=i;j<list.size(); j++){
				Judge judy=new Judge(list.get(i), list.get(j));
				System.out.println(judy.iterate(200));
			}	
	}
}

Prisoner.java

import java.util.ArrayList;

public abstract class Prisoner
{
	/**
	 * Constants
	 */
	public static final boolean BETRAY=false;
	public static final boolean DEFECT=false;
	public static final boolean SILENT=true;
	public static final boolean COOP=true;
	/**
	 * instance variables
	 */
	private String name;
	private ArrayList<Boolean> history; 
	/**
	 * Constructors
	 */
	public Prisoner(String name){
		this.setName(name);
		this.history = new ArrayList<Boolean>();
	}
	public Prisoner(){
		this("No Name");
	}
	/**
	 * Abstract methods that subclasses need to implement
	 */
	public abstract boolean choose();

	/**
	 * Methods that will be inherited by all subclasses
	 */

	public void record(boolean opponentsChoice){
		history.add(opponentsChoice);
	}
	public void reset(){
		history=new ArrayList<Boolean>();
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}

	public ArrayList<Boolean> getHistory() {
		return history;
	}
	public boolean lastTurn(){
		if (history.size()==0) return Prisoner.COOP;
		return history.get(history.size()-1);
	}
	public boolean firstTurn(){
		return history.size()==0;
	}	
}

Judge.java

public class Judge {
	private Prisoner p1;
	private Prisoner p2;
	private double score1,score2;
	private double reward; //mutual cooperation
	private double punishment; // for mutual betrayal
	private double temptation; // to betray
	private double suckerReward; //for being betrayed 

	/**
	 * Constructors
	 */
	public Judge(Prisoner p1, Prisoner p2){
		setP1(p1);
		setP2(p2);
		this.setReward(0.5);
		this.setPunishment(5.0);
		this.setTemptation(0.0);
		this.setSuckerReward(10.0);	
		this.setScore1(0);
		this.setScore2(0);
	}

	/**
	 * Methods
	 */
	public void judge(){
		boolean c1=p1.choose();
		boolean c2=p2.choose();
		if (c1==c2){
			if(c1==Prisoner.BETRAY){
				p1.record(c2);
				p2.record(c1);
				score1+=punishment;
				score2+=punishment;
			}else{
				p1.record(c2);
				p2.record(c1);
				score1+=reward;
				score2+=reward;
			}
		}
		if (c1!=c2){
			if(c1==Prisoner.BETRAY){
				p1.record(c2);
				p2.record(c1);
				score1+=temptation;
				score2+=suckerReward;
			}else{
				p1.record(c2);
				p2.record(c1);
				score1+=suckerReward;
				score2+=temptation;
			}

		}
	}
	public String iterate(int times){
		String result="";
		p1.reset();
		p2.reset();
		this.setScore1(0);
		this.setScore2(0);
		for(int i=0; i<times; i++)
			judge();
		if (score1>score2){
			result=p1.getName()+": "+score1;
			result+=" "+p2.getName()+": "+score2;
		} else {
			result=p2.getName()+": "+score2;
			result+=" "+p1.getName()+": "+score1;
		}
		return result;
	}
	public void setP1(Prisoner p1) {
		this.p1 = p1;
	}
	public Prisoner getP1() {
		return p1;
	}
	public void setP2(Prisoner p2) {
		this.p2 = p2;
	}
	public Prisoner getP2() {
		return p2;
	}
	public void setReward(double reward) {
		this.reward = reward;
	}
	public double getReward() {
		return reward;
	}
	public void setPunishment(double punishment) {
		this.punishment = punishment;
	}
	public double getPunishment() {
		return punishment;
	}
	public void setSuckerReward(double suckerReward) {
		this.suckerReward = suckerReward;
	}
	public double getSuckerReward() {
		return suckerReward;
	}
	public void setTemptation(double temptation) {
		this.temptation = temptation;
	}
	public double getTemptation() {
		return temptation;
	}

	public void setScore2(double score2) {
		this.score2 = score2;
	}

	public double getScore2() {
		return score2;
	}

	public void setScore1(double score1) {
		this.score1 = score1;
	}

	public double getScore1() {
		return score1;
	}

}

What to try:

  1. Make "Massive Retaliatory Strike" prisoner that plays nice until it is betrayed.
  2. Make a "Tester" prisoner that would start being mean, and would not betray if the opponent retaliates, start cooperating, until another retaliatory strike is made.
  3. Make a "Random" prisoner that behaves randomly.
  4. Make you own strategy that looks at more than just the last outcome, for example, based on the the last five.
  5. Make a class to record simulations against various opponents so you can see the overall success of the strategy (The average against all opponents, for example)
  6. Make an Applet to show the outcomes of the various strategies graphically.
  7. Make a subclass of Judge that has different rewards, like some of the rewards and punishments mentioned in the Wikipedia article.