import java.util.*;

public class Tournament {

	private Agent[] competitors;
	private int numGames;
	private Random generator = new Random();
	private Map<String, List<Double>> stats = new Hashtable<String, List<Double>>();

	public Tournament(int numGames, int numAgents) {
		competitors = new Agent[numAgents];
		this.numGames = numGames;
		initStrategies();
	}

	public Tournament() {
		this(100, 100);
	}

    // can override in a subclass
	protected void initStrategies() {
		for(int i = 0; i < competitors.length; i++) {
			Agent next = new Agent();
			competitors[i] = next;
			switch(i % 5) {
				case 0: next.setStrategy(new UnforgivingStrategy(next)); break;
				case 1: next.setStrategy(new Tit4TatStrategy(next)); break;
				case 2: next.setStrategy(new SelfishStrategy(next)); break;
				case 3: next.setStrategy(new NaiveStrategy(next)); break;
				default: next.setStrategy(new RandomStrategy(next));
			}
		}
	}


	public void run() {

		for(int index = 0; index < competitors.length; index++) {
			for(int j = 0; j < numGames; j++) {
				int randomIndex = generator.nextInt(competitors.length);
				if (index == randomIndex) {
					randomIndex = (randomIndex + 1) % competitors.length;
				}
				competitors[index].compete(competitors[randomIndex]);
			}
		}

		initStats();
	}




	public void initStats() {
		for(int index = 0; index < competitors.length; index++) {
			Agent next = competitors[index];
			//System.out.println(next);
			double avg = 100 * next.getFitness()/(5 * next.getNumGames());
			String strategy = next.getStrategy().toString();
			List<Double> scores = stats.get(strategy);
			if (scores == null) {
				scores = new ArrayList<Double>();
				stats.put(strategy, scores);
			}
			scores.add(avg);
		}
	}

	private double average(List<Double> scores) {
		double sum = 0;
		for(Double next: scores) {
			sum += next;
		}
		return sum/scores.size();
	}

	public void displayStats() {
		Set<String> strategies = stats.keySet();
		for(String strategy: strategies) {
			List<Double> scores = stats.get(strategy);
			System.out.println(strategy + ": " + average(scores) + "%");
		}
	}

	public static void main(String[] args) {
		Tournament tournament = new Tournament();
		tournament.run();
		tournament.displayStats();
	}



}