#include "player.h"
#include "utilities.h"

#include <assert.h>

static int do_history(void) {
	int best,best_length,i,j,num;

	num = my_history[0];
	best = best_length = 0;
	for (i = num - 1; i > best_length; --i) {
		for (j = 0; j < i 
		 && my_history[num - j] == my_history[i - j]
		 && opp_history[num - j] == opp_history[i - j]; ++j) ;
		if (j > best_length) {
			best_length = j;
			best = i;
		}
	}

	return best;
}

int historybot() {
	int best = do_history();
	if (0 == best) return biased_roshambo(1.0/3.0,1.0/3.0);
	return will_beat(opp_history[best + 1]);
}

int metabot() {
	int best = do_history();
	if (0 == best) return biased_roshambo(1.0/3.0,1.0/3.0);
	return will_beat(will_beat(my_history[best + 1]));
}

int iocainebot() {
	static int my_last,opp_last;
	static int my_stats[3],opp_stats[3];

	const int num = my_history[0];
	const int best = do_history();
	int my_guess,opp_guess;
	int i,my_most,opp_most;

	if (0 == num) {
		for (i = 0; i < 3; ++i) my_stats[i] = opp_stats[i] = 0;
		my_last = biased_roshambo(1.0/3.0,1.0/3.0);
		opp_last = biased_roshambo(1.0/3.0,1.0/3.0);
		return will_beat(opp_last);
	}

	if (0 == best) {
		my_guess = my_history[num];
		opp_guess = opp_history[num];
	} else {
		my_guess = my_history[best + 1];
		opp_guess = opp_history[best + 1];
	}

	my_stats[(3 + opp_history[num] - my_last) % 3]++;
	opp_stats[(3 + opp_history[num] - opp_last) % 3]++;
	my_last = my_guess;
	opp_last = opp_guess;

	assert(num == my_stats[0] + my_stats[1] + my_stats[2]);
	assert(num == opp_stats[0] + opp_stats[1] + opp_stats[2]);

	my_most = opp_most = 0;
	for (i = 1; i < 3; ++i) {
		if (my_stats[i] > my_stats[my_most]) my_most = i;
		if (opp_stats[i] > opp_stats[opp_most]) opp_most = i;
	}

	if (opp_stats[opp_most] >= my_stats[my_most])
		return will_beat((opp_guess + opp_most) % 3);
	else
		return will_beat((my_guess + my_most) % 3);
}
