// predator12202003.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "math.h"


#define BITON(aa, bb) (aa |= (bb))
#define BITOFF(aa, bb) (aa = ((aa&(bb)) == (bb) ? (aa^(bb)) : aa))

#define BLACK 1
#define WHITE 2

#define bp 1
#define wp 2
#define bk 3
#define wk 4
#define np 5

void newgame();
int evaluation(struct postype pos);
int max(int value1, int value2);
int getlegalmoves(struct postype pos, struct movetype movelist[]);
int alphabeta(struct postype pos, int depth, int alpha, int beta);

struct postype
{
	int blacks;
	int whites;
	int kings;
	int colour;
	int hashval;
}game;

struct movetype
{
	int blacks;
	int whites;
	int kings;
	int from;
	int to;
};

int movecounts[4][32] = { // Number of legal moves for each piece on each square
    {2,2,2,1,
     1,2,2,2,
     2,2,2,1,
     1,2,2,2,
     2,2,2,1,
     1,2,2,2,
     2,2,2,1,
     0,0,0,0},

	{0,0,0,0,
     1,2,2,2,
     2,2,2,1,
     1,2,2,2,
     2,2,2,1,
     1,2,2,2,
     2,2,2,1,
     1,2,2,2},

    {2,2,2,1,
     2,4,4,4,
     4,4,4,2,
     2,4,4,4,
     4,4,4,2,
     2,4,4,4,
     4,4,4,2,
     1,2,2,2},
		
    {2,2,2,1,
     2,4,4,4,
     4,4,4,2,
     2,4,4,4,
     4,4,4,2,
     2,4,4,4,
     4,4,4,2,
     1,2,2,2}
};
int legalmoves[4][32][4] = { // Destination squares for all moves for all pieces on all squares
	// Black pieces
	{
		{4, 5, 0, 0}, {5, 6, 0, 0}, {6, 7, 0, 0}, {7, 0, 0, 0}, 
		{8, 0, 0, 0}, {8, 9, 0, 0}, {9, 10, 0, 0}, {10, 11, 0, 0},
		{12, 13, 0, 0}, {13, 14, 0, 0}, {14, 15, 0, 0}, {15, 0, 0, 0},
		{16, 0, 0, 0}, {16, 17, 0, 0}, {17, 18, 0, 0}, {18, 19, 0, 0},
		{20, 21, 0, 0}, {21, 22, 0, 0}, {22, 23, 0, 0}, {23, 0, 0, 0},
		{24, 0, 0, 0}, {24, 25, 0, 0}, {25, 26, 0, 0}, {26, 27, 0, 0},
		{28, 29, 0, 0}, {29, 30, 0, 0}, {30, 31, 0, 0}, {31, 0, 0, 0},
		{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}
	},
	// White pieces
	{
		{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, 
		{0, 0, 0, 0}, {0, 1, 0, 0}, {1, 2, 0, 0}, {2, 3, 0, 0},
		{4, 5, 0, 0}, {5, 6, 0, 0}, {6, 7, 0, 0}, {7, 0, 0, 0},
		{8, 0, 0, 0}, {8, 9, 0, 0}, {9, 10, 0, 0}, {10, 11, 0, 0},
		{12, 13, 0, 0}, {13, 14, 0, 0}, {14, 15, 0, 0}, {15, 0, 0, 0},
		{16, 0, 0, 0}, {16, 17, 0, 0}, {17, 18, 0, 0}, {18, 19, 0, 0},
		{20, 21, 0, 0}, {21, 22, 0, 0}, {22, 23, 0, 0}, {23, 0, 0, 0},
		{24, 0, 0, 0}, {24, 25, 0, 0}, {25, 26, 0, 0}, {26, 27, 0, 0}
	},
	// Black kings	
	{
		{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, 
		{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, 
		{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, 
		{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, 
		{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, 
		{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, 
		{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, 
		{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}
	},
	// White kings
	{
		{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, 
		{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, 
		{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, 
		{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, 
		{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, 
		{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, 
		{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, 
		{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0} 
	}
};
int legaljumps[4][32][4][2] =  {// Jumped and destination squares for all jumps for all 
	                            // pieces on all squares
	// Black pieces
	{
		{{5, 9}, {0, 0}, {0, 0}, {0, 0}},
		{{5, 8}, {6, 10}, {0, 0}, {0, 0}},
		{{6, 9}, {7, 11}, {0, 0}, {0, 0}},
		{{7, 10}, {0, 0}, {0, 0}, {0, 0}},

		{{8, 13}, {0, 0}, {0, 0}, {0, 0}},
		{{8, 12}, {9, 14}, {0, 0}, {0, 0}},
		{{9, 13}, {10, 15}, {0, 0}, {0, 0}},
		{{10, 14}, {0, 0}, {0, 0}, {0, 0}},

		{{13, 17}, {0, 0}, {0, 0}, {0, 0}},
		{{13, 16}, {14, 18}, {0, 0}, {0, 0}},
		{{14, 17}, {15, 19}, {0, 0}, {0, 0}},
		{{15, 18}, {0, 0}, {0, 0}, {0, 0}},

		{{16, 21}, {0, 0}, {0, 0}, {0, 0}},
		{{16, 20}, {17, 22}, {0, 0}, {0, 0}},
		{{17, 21}, {18, 23}, {0, 0}, {0, 0}},
		{{18, 22}, {0, 0}, {0, 0}, {0, 0}},
				
		{{21, 25}, {0, 0}, {0, 0}, {0, 0}}, 
		{{21, 24}, {22, 26}, {0, 0}, {0, 0}},
		{{22, 25}, {23, 27}, {0, 0}, {0, 0}},
		{{23, 26}, {0, 0}, {0, 0}, {0, 0}},

		{{24, 29}, {0, 0}, {0, 0}, {0, 0}},
		{{24, 28}, {25, 30}, {0, 0}, {0, 0}},
		{{25, 29}, {26, 31}, {0, 0}, {0, 0}},
		{{26, 30}, {0, 0}, {0, 0}, {0, 0}},

		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},

		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}}
	},
	// White pieces
	{
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},

		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},

		{{5, 1}, {0, 0}, {0, 0}, {0, 0}},
		{{5, 0}, {6, 2}, {0, 0}, {0, 0}},
		{{6, 1}, {7, 3}, {0, 0}, {0, 0}},
		{{7, 2}, {0, 0}, {0, 0}, {0, 0}},

		{{8, 5}, {0, 0}, {0, 0}, {0, 0}},
		{{8, 4}, {9, 6}, {0, 0}, {0, 0}},
		{{9, 5}, {10, 7}, {0, 0}, {0, 0}},
		{{10, 6}, {0, 0}, {0, 0}, {0, 0}},
				
		{{13, 9}, {0, 0}, {0, 0}, {0, 0}},
		{{13, 8}, {14, 10}, {0, 0}, {0, 0}},
		{{14, 9}, {15, 11}, {0, 0}, {0, 0}},
		{{15, 10}, {0, 0}, {0, 0}, {0, 0}},

		{{16, 13}, {0, 0}, {0, 0}, {0, 0}},
		{{16, 12}, {17, 14}, {0, 0}, {0, 0}},
		{{17, 13}, {18, 15}, {0, 0}, {0, 0}},
		{{18, 14}, {0, 0}, {0, 0}, {0, 0}},

		{{21, 17}, {0, 0}, {0, 0}, {0, 0}},
		{{21, 16}, {22, 18}, {0, 0}, {0, 0}},
		{{22, 17}, {23, 19}, {0, 0}, {0, 0}},
		{{23, 18}, {0, 0}, {0, 0}, {0, 0}},

		{{24, 21}, {0, 0}, {0, 0}, {0, 0}},
		{{24, 20}, {25, 22}, {0, 0}, {0, 0}},
		{{25, 21}, {26, 23}, {0, 0}, {0, 0}},
		{{26, 22}, {0, 0}, {0, 0}, {0, 0}}
	},
	// Black kings
	{
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},

		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},

		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},

		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
				
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},

		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},

		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},

		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}}
	},
	// White kings
	{
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},

		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},

		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},

		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
				
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},

		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},

		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},

		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
		{{0, 0}, {0, 0}, {0, 0}, {0, 0}}
	}
};

int main(int argc, char* argv[])
{
	newgame();
	return 0;
}

void newgame()
{
	int i;
	// Load the initial position
	for(i=1; i<=12; i++)
	{
		BITON(game.blacks, i-1);
	}
	for(i=21; i<=32; i++)
	{
		BITON(game.whites, i-1);
	}
	// Black to move first
	game.colour = BLACK;

	int value;

	value = alphabeta(game, 5, -1000, 1000);

	return;
}

int alphabeta(struct postype pos, int depth, int alpha, int beta)
{
	struct movetype movelist[20];
	int i, n, value, localalpha, bestvalue;
	struct postype localpos;
	
	bestvalue = -1000;
	localpos = pos;
	localalpha = alpha;
	
	if (depth==0)
	{
		value=evaluation(pos);
		return value;
	}
	
	//n = getlegaljumps(pos, movelist);
	if (n==0)
	{
		n = getlegalmoves(pos, movelist);
	}

	for(i=0; i<n; i++)
	{
		pos.blacks = movelist[i].blacks;
		pos.whites = movelist[i].whites;
		pos.kings = movelist[i].kings;
		pos.colour = abs(pos.colour - 3);
				
		value = -alphabeta(pos, depth-1, -beta, -localalpha);

		pos = localpos;

		bestvalue = max(value, bestvalue);

		if (bestvalue>=beta)
		{
			break;
		}

		if (bestvalue>localalpha)
		{
			localalpha = bestvalue;
		}
	}
	
	return bestvalue;
}

int max(int value1, int value2)
{
	if(value1>value2)
	{
		return value1;
	}
	else
	{
		return value2;
	}
}

int evaluation(struct postype pos)
{
	int i;
	int eval;
	for(i=0; i<32; i++)
	{
		if(pos.blacks & i)
		{
			if(!pos.kings & i)
			{
				eval+=100;			
			}
			else
			{
				eval+=125;
			}
		}
		else if(pos.whites & i)
		{
			if(!pos.kings & i)
			{
				eval-=100;
			}
			else
			{
				eval-=125;
			}
		}
	}
	if (pos.colour == WHITE){
	{
		eval = -eval;
	}
	return eval;
}

//int getlegaljumps(struct postype pos, struct movetype movelist[20])
//{
//	return 0;
//}

int getlegalmoves(struct postype pos, struct movetype movelist[])
{
	int i, j;
	int totalmoves;
	int sqrfrom, sqrto;

	totalmoves=0;

	if(pos.colour == BLACK)
	{
		for(i=0;i<32;i++)
		{
			sqrfrom=i;
			if((pos.blacks & i) && !(pos.kings & i))
			{
				for(j=0; j<movecounts[bp][sqrfrom]; j++)
				{
					sqrto = legalmoves[bp][sqrfrom][j];
					if (!(pos.blacks & sqrto) && !(pos.whites & sqrto))
					{
						// This is a valid move
						movelist[totalmoves].blacks = pos.blacks;
						movelist[totalmoves].whites = pos.whites;
						movelist[totalmoves].kings = pos.kings;
						movelist[totalmoves].from = sqrfrom;
						movelist[totalmoves].to = sqrto;
						
						totalmoves++;
					}
				}
			}
		}
	}
	return totalmoves;
}