#include "history.h"

static int hindex(const uMOVE * m){
	assert((Ox88to64(m->data.from) << 6) + Ox88to64(m->data.dest) < 64*64);
	assert((Ox88to64(m->data.from) << 6) + Ox88to64(m->data.dest) >= 0);
	return (Ox88to64(m->data.from) << 6) + Ox88to64(m->data.dest);
}

static int ahindex(const uMOVE * m){
	assert((Ox88to64(m->data.from) << 6) + Ox88to64(m->data.dest) < 64*64);
	assert((Ox88to64(m->data.from) << 6) + Ox88to64(m->data.dest) >= 0);
	return (Ox88to64(m->data.dest) << 6) + Ox88to64(m->data.from);
}

/*
	1. It seems the 'value' of an Nply search is 2+ times an N-1ply  (ie use 1<<depth)
		But too large!!!
	2. Diminish ALL history values when PV changes (eg hist >>= (idepth/4))
*/

int damp_history(int d)
{
    int i, x=0;
    if(d<2) return -1;
    for(i=0; i < 64*64; ++i)
    {
	    history[stm][i] = (history[stm][i]) / d;
	    histcnt[stm][i] = (histcnt[stm][i]+d) / d; 
    }
    return x;
}

void hflat(int c, const uMOVE * m, int d){
	history[c][hindex(m)] /= d;
}

/*
void hflat(int d){
	sHISTDATA * h = mhs - 1;
	int i;
	
	for(; h > mhs-ply; h -= 2)
	{
		if(h->move.data.type > CAQ)
		{
			i = hindex(&h->move);
			history[stm^1][i] /= d;
			
		}
		
	}
}
*/


void hbump(const uMOVE * m, int d){
	int i = hindex(m);
	history[stm][i] += d * d;
	histcnt[stm][i] += d * d; 
	if(history[stm][i] > 4000000) damp_history(2);
}


void htry(const uMOVE * m, int d){
	int i = hindex(m);
	histcnt[stm][i] += d * d;
	if(histcnt[stm][i] > 4000000) damp_history(2);
}


int hget(const uMOVE * m){
	int i = hindex(m);
	int s = 8192 * history[m->data.piece & 1][i] / histcnt[m->data.piece & 1][i]; 
	assert(s < 4000000);
	return s;
}

int ahget(const uMOVE * m){
	return history[m->data.piece & 1][ahindex(m)];
}

void hclear()
{
	int i;
	for(i=0; i < 64*64; ++i)
	{
		history[0][i] = 0;
		history[1][i] = 0;
		
		
		histcnt[0][i] = 1;
		histcnt[1][i] = 1;
		
	}
}

