/* ******************************************************************************************************
 * 				Curtin University of Technology, Miri Campus	 			 *
 * 				  Artificial Machine and Intelligence 251				 *
 *			 	  		  Assignment						 *
 * 		  			Name: Davina Chin Lee Yien					 *
 * 		     				Student Id: 7d2a1001					 *
 *		   				   Perth Id: 12519873					 *
 * ******************************************************************************************************
*/

#include "ass.h"
//#include "minimax.c"
/**********************************************************************************************************/
					/* Sub function */
/******************************** void initialize_board ******************************************/
//this function will called once. to intialize all the value in the array board to 0 
//except for the middle 4 place
void initialize_board()
{
	int i,j;

	for(i=0;i<8;i++)
		for(j=0;j<8;j++){
			board[i][j]=0;		//initializing the board for player move to 0
			boardValue[i][j]=0;	//initializing the board value as 0
			//estimateMin[i][j] = 0;
			minimaxBoard[i][j] = 0;
			boardValueMinimax[i][j] = 0;
		}

	//value 2 for black and value 1 for white
	board[3][3] = 2;
	board[3][4] = 1;
	board[4][3] = 1;
	board[4][4] = 2;
	
	//this is use to calculate the best move. 0 means the lowest value.
	//So, surely wont choose this space
	boardValue[3][3] = 0;
	boardValue[3][4] = 0;
	boardValue[4][3] = 0;
	boardValue[4][4] = 0;
}

/***************************************** void screen() ****************************************/
//this function will show the output of the board
void screen()
{
	int i,k,j;

        printf("  A   B   C   D   E   F   G   H\n");
	printf(" ___ ___ ___ ___ ___ ___ ___ ___\n");
        /* for every row */
        for(i=7;i>=0;i--)
        {
                k=0;

                /* for every column in the first board */
		//for the first one	
                for(j=0;j<8;j++)
			printf ("|   ");
		printf("|\n");
                
		//to store the black and white ...at the moment is occupied by a
		for(j=0;j<8;j++){
			printf ("| ");
			if(board[j][i] == 2) //value 2 is for black
				printf("X "); //black uses X
			else
				if(board[j][i] == 1) //value 1 for white
					printf("O "); //white uses O
				else
					printf("  ");
		}
		printf("| %d\n",i+1);
		
		//for the line...
		for (j = 0; j <8; j++)
			printf("|___");
		printf("|\n");
       }
}
//============================================PLAYER MOVES================================================
/*************************************** int getColumn(char move[2] *******************************/
//to get the value of the input from player 
int getColumn(char move[2])
{
	if (move[0] =='A' || move[0] == 'a')
		return 0;
	if (move[0]=='B' || move[0] == 'b')
		return 1;
	if (move[0] =='C' || move[0] == 'c')
		return 2;
	if (move[0] =='D' || move[0] =='d')
		return 3;
	if (move[0]=='E' || move[0] == 'e')
		return 4;
	if (move[0] == 'F' || move[0] == 'f')
		return 5;
	if (move[0]=='G' || move[0] == 'g')
		return 6;
	if (move[0]=='H' || move[0] == 'h')
		return 7;

	return 9; //return 9 on error
}

/*************************************** int getRow(char move[2] *********************************/
//to get the row value of the input from player
int getRow(char move[2])
{
	int moving;

	if (move[1] =='1')
		return 0;
	if (move[1]=='2')
		return 1;
	if (move[1] =='3')
		return 2;
	if (move[1] =='4')
		return 3;
	if (move[1]=='5')
		return 4;
	if (move[1] == '6')
		return 5;
	if (move[1]=='7')
		return 6;
	if (move[1]=='8')
		return 7;

	return 9;	//return 9 on error

}

/********* int checkDiagLeftUp(int column,int row, char who,int opponentValue,int myValue) *********/
//check whether there is anything to flip in the direction of diagonal left up ....
int checkDiagLeftUp(int column,int row, char who,int opponentValue,int myValue)
{
	int count,count2,temp1,a;
	a =0;

	if(board[column-1][row-1]==0) //in case nothing there, so return 0.No need to check further
		return 0;
	
	if(board[column-1][row-1]==myValue) //if its player value, also no need to check further
		return 0;
	
	for (count=row-1;count>=0;count--)
	{
		a++;
		if(column-a>=0){
			if (board[column-a][count]==opponentValue)
				temp1 = count;
			else
			{
				if(board[column-a][count] == myValue){
					a=1;
					for (count2=row-1;count2>=temp1;count2--)
					{
						//check if it is 0 or not
						if (board[column-a][count2]!=0){
							//to flip the X and 0
							board[column-a][count2]=myValue;
							a++;
							if (column-a<0)
								break;
						}
					}
					return 1;
				}
				else	//to avoid from fault, so return 0 as nothing to flip
					return 0;
			}
		}
	}
	return 0;
}


/******** int checkDiagLeftDown(int column,int row, char who,int opponentValue,int myValue) *********/
//check whether there is anything to flip in the direction of diagonal left down ....

int checkDiagLeftDown(int column,int row, char who,int opponentValue,int myValue)
{
	int count,count2,temp1,a;
	a =0;
	
	if(board[column-1][row+1]==0) //when the place is nothing
		return 0;

	if(board[column-1][row+1]==myValue)	//when the place is value of the player playing at the moment
		return 0;
	
	//start flipping process
	for (count=row+1;count<8;count++)
	{
		a++;
		if(column-a>=0){
			if (board[column-a][count]==opponentValue)
				temp1 = count;
			else
			{
				if(board[column-a][count] == myValue){
					a=1;
					for (count2=row+1;count2<=temp1;count2++)
					{
						//when it is not 0
						if(board[column-a][count2]!=0){
							//start flipping
							board[column-a][count2]=myValue;
							a++;
							if(column-a<0)
								break;
						}
					}
					return 1;
				}
				else	//avoid faults
					return 0;
			}
		}
	}
	return 0;
}

/******** int checkDiagRightDown(int column,int row, char who,int opponentValue,int myValue) *********/
//check whether there is anything to flip in the direction of diagonal right down ....
int checkDiagRightDown(int column,int row, char who,int opponentValue,int myValue)
{
	int count,count2,temp1,a;
	a =0;
	
	if(board[column+1][row+1]==0)	//value is 0, no X and 0 
		return 0;
	
	if (board[column+1][row+1]==myValue) //value is player value
		return 0;
	
	//flipping process
	for (count=column+1;count<8;count++)
	{
		a++;
		if(row+a<8){
			if (board[count][row+a]==opponentValue)
				temp1 = count;
			else
			{
				if(board[count][row+a] == myValue){
					a=1;
					//to flip until encounter the player, either X or 0 
					for (count2=column+1;count2<=temp1;count2++)
					{
						//when it is not 0
						if (board[count2][row+a]!=0){
							//start flipping process
							board[count2][row+a]=myValue;
							a++;
							if (row+a<0)
								break;
						}
					}
					return 1;
				}
				else
					return 0;
			}
		}
	}
	return 0;
}

/********* int checkDiagRightUp(int column,int row, char who,int opponentValue,int myValue) ********/
//check whether there is anything to flip in the direction of diagonal right up ....
//same like previous function 
int checkDiagRightUp(int column,int row, char who,int opponentValue,int myValue)
{
	int count,count2,temp1,a;
	a =0;
	
	if (board[column+1][row-1]==0)	
		return 0;
	
	if (board[column+1][row-1]==myValue)
		return 0;
	
	for (count=column+1;count<8;count++)
	{
		a++;
		if(row-a>=0){
			if (board[count][row-a]==opponentValue)
				temp1 = count;
			else
			{
				if(board[count][row-a] == myValue){
					a=1;
					for (count2=column+1;count2<=temp1;count2++)
					{
						if (board[count2][row-a]!=0){
							//flipping process
							board[count2][row-a]=myValue;
							a++;
							if (row-a<0)
								break;
						}
					}
					return 1;	//succeed in flipping
				}
				else
					return 0;
			}
		}
	}
	return 0;
}

/********** int checkDown(int column,int row, char who,int opponentValue,int myValue) ************/
//check whether there is anything to flip in the direction of down ....
//same as previous function 
int checkDown(int column,int row, char who,int opponentValue,int myValue)
{
	int count,count2;
	int temp1=row+1;
	
	if (board[column][row+1]==0)
		return 0;
	
	if (board[column][row+1]==myValue)
		return 0;
	
	for (count=row+1;count<8;count++)
	{
		if (board[column][count]==opponentValue)
			temp1 = count;
		else
		{
			if(board[column][count] == myValue){
				for (count2=row+1;count2<=temp1;count2++)
				{
					if(board[column][count2]!=0){
						//flipping process
						board[column][count2]=myValue;
					}
				}
				return 1;	//on success in flipping
			}
			else
				return 0;
		}
	}
	return 0;
}

/********** int checkUp(int column,int row, char who,int opponentValue,int myValue) **********/
//check whether there is anything to flip in the direction of up ....
//idea is the same as previous function
int checkUp(int column,int row, char who,int opponentValue,int myValue)
{
	int count,count2;
	int temp1;
	
	if (board[column][row-1]==0)
		return 0;

	if (board[column][row-1]==myValue)
		return 0;
	
	for (count=row-1;count>=0;count--)
	{
		if (board[column][count]==opponentValue)
			temp1 = count;
		else
		{
			if(board[column][count] == myValue){
				for (count2=row-1;count2>=temp1;count2--)
				{
					if(board[column][count2]!=0){
						//flipping process 
						board[column][count2]=myValue;
					}
				}
				return 1;	//on success of flipping
			}
			else
				return 0;
		}
	}
	return 0;
}

/********* int checkRight(int column,int row, char who,int opponentValue,int myValue) ********/
//check whether there is anything to flip in the direction of right ....
//similar to the previous function..flippinf is on the right 
int checkRight(int column,int row, char who,int opponentValue,int myValue)
{
	int count,count2;
	int temp1=column+1;

	if (board[column+1][row]==0)
		return 0;
	
	if(board[column+1][row]==myValue)
		return 0;
	
	for (count=column+1;count<8;count++)
	{
		if (board[count][row]==opponentValue)
			temp1 = count;
		else
		{
			if(board[count][row] == myValue){
				for (count2=column+1;count2<=temp1;count2++)
				{
					if (board[count2][row]!=0){
						//flipping process
						board[count2][row]=myValue;
					}
				}
				return 1;
			}
			else{
				return 0;
			}
		}
	}
	return 0;
}

/********* int checkLeft(int column,int row, char who,int opponentValue,int myValue) *********/
//check whether there is anything to flip in the direction of left....
int checkLeft(int column,int row, char who,int opponentValue,int myValue)
{
	int count,count2;
	int temp1=column-1;
	if(board[column-1][row]==myValue)
		return 0;

	for (count=column-1;count>=0;count--)
	{
		if (board[count][row]==opponentValue)
			temp1 = count;
		else
		{
			if(board[count][row] == myValue){
				for (count2=column-1;count2>=temp1;count2--)
				{
					if(board[count2][row]!=0){
						//flipping process
						board[count2][row]=myValue;
					}
				}
				return 1; //on success
			}
			else
				return 0;
				
		}
	}
	return 0;
}

/********* void turningColorPlayer(int column,int row,int ComputerValue,int playerValue) **********/
//to turn the black and white ..this is to turn for player .. not computer 
void turningColorPlayer(int column,int row,int ComputerValue,int playerValue)
{
	int good1,good2,good3,good4,good5,good6,good7,good8;
	//to check the 8 possibility of flipping the space
	good1 = checkLeft(column,row,'P',ComputerValue,playerValue);
	good2 =	checkRight(column,row,'P',ComputerValue,playerValue);
	good3 = checkUp(column, row, 'P', ComputerValue,playerValue);
	good4 = checkDown(column, row,'P', ComputerValue,playerValue);
	good5 = checkDiagRightUp(column,row,'P',ComputerValue,playerValue);
	good6 = checkDiagRightDown(column,row,'P',ComputerValue,playerValue);  //not yet check
	good7 = checkDiagLeftUp(column,row,'P',ComputerValue,playerValue);
	good8 = checkDiagLeftDown(column,row,'P',ComputerValue,playerValue);
	
	//when either of the 8 possibility have something to flip
	if (good1 == 1 || good2 == 1|| good3 == 1|| good4==1||good5==1||good6 == 1||good7 == 1|| good8 == 1)
		printf("\nMove is at column: %d and row: %d\n",column,row);
	else{
		//if not, meaning illegal move .. so game terminated by assuming computer wins
		printf("Games terminated for trying to attempt illegal moves!\n");
		printf("I have won\n");
		checkWin2(ComputerValue,playerValue);
		exit(0);
	}
		
}

/************************* int checkValidMove(int column, int row) ******************************/
//to check the valid move,..passing either value 1 or 2 depending on player plays black or white 
//2 for black and 1 for white
int checkValidMove(int column, int row)
{
	if (!strcmp(colors,"b")){
			//check to turn the black and white
			turningColorPlayer(column,row,1,2);
	}
	else{
			turningColorPlayer(column,row,2,1);
	}
	
	return 1;
}

/******************************* int validateMove(char move[2]) **************************************/
//to validate the move.. 
int validateMove(char move[2])
{
	int value;
	int column, row;
	column = getColumn(move);
	row = getRow(move);
	
	//check whether the move is valid or not 
	if (column == 9 || row == 9){
		printf("Illegal move!! Argument entered is out of range!!\n");
		return 0;
	}
			
	//to check whether there is anything in the place
	if (board[column][row] == 0)
		if (!strcmp(colors,"b"))
			board[column][row] = 2;	//if black 
		else
			board[column][row] = 1;	//else, white
	else{
		//something on the board, so illegal move 
		printf("Illegal move!! Space is occupied.\n");
		return 0;
	}
	
	value = checkValidMove(column,row);
	if (value ==1)	//when valid, show the screen
		screen();
	else
		return 0; //return to calling function

	return 1;
	
}

/****************************** void timerHandler(int signum) **************************************/
//each player is given 10 seconds to make the move.. when times up, games exiting
void timerHandler(int signum)
{
	printf("You take too long to make decision!!!So, you loss!!\n\n");
	exit(0);
}

//for computer
void timerHandler1(int signum)
{
	printf("Computer taking too long...You Win!\n");
	exit(0);
}
//=======================================================
void checkTrue()
{
	int col, row;
	int max1, max2, max3, max4, max5, max6, max7, max8;
	int move=0;
	int computer,player;
	if (!strcmp(colors,"b")){ //player play black
		computer = 1;
		player = 2;
	}
	else
	{
		computer = 2;
		player = 1;
	}
	
	for (col=0;col<8;col++){
		for (row=0;row<8;row++)
		{
			if (board[col][row] == 0){
				//searching for possible move
				max1 = search_down(col,row,player,computer);
				max2 = search_up(col,row,player,computer);			
				max3 = search_left(col,row,player,computer);
				max4 = search_right(col,row,player,computer);
				max5 = search_diag_left_up(col,row,player,computer);
				max6 = search_diag_right_up(col,row,player,computer);
				max7 = search_diag_left_down(col,row,player,computer);
				max8 = search_diag_right_down(col,row,player,computer);
				//counting and get the total of each move
				move = max1 + max2 + max3 + max4 + max5 + max6 + max7 + max8;
			}
			else{
				boardValue[col][row] = 0;
			}
			if (move >= 1)
			{
				printf("You still have move exist\nI have won\n");
				checkWin2(computer,player);
			}
			else
			{
				noMoveP = 1;
				if (noMoveC == 1){
					printf("Both player has no more move. This game ends immediately!\n");
					checkWin2(computer,player);
				}
			}
			//set the variable back to 0
			max1=0,max2=0,max3=0,max4=0,max5=0,max6=0,max7=0,max8=0, move=0;
		}
	}
	
}
/**************************************** void player_turn() **********************************************/
//player turn..the main function to validate player move 
void player_turn()
{
	char move[2];
	int valid;
	int computer,player;
        struct itimerval timer,timerOn;
        struct sigaction sa;

	valid = 0;
	
	//setting timer 
	timer.it_value.tv_sec = 100; //10 seconds for player and 10 seconds for computer 
        timer.it_value.tv_usec = 0;
	timerOn = timer;
	memset (&sa,0,sizeof(sa));
	//timer handler,...the signal action procedure
	sa.sa_handler = &timerHandler;
	sigaction (SIGALRM,&sa,NULL);
	
	//set the timer
	setitimer (ITIMER_REAL,&timerOn,NULL);
	
	//if timer not yet expire
        if (getitimer (ITIMER_REAL,&timerOn) >= 0)
	{	//asking for move
		printf("Player move. Enter your move in [column row] format:\n");
		//input
		scanf("%s", move);
		
		if(!strcmp(move,"X0")){
			total_space++;
			checkTrue();
			return;
		}
		
		valid = validateMove(move);
		if (valid == 0){
			printf ("Games terminated with computer win\n");
			printf("I have won\n");
			if (!strcmp(colors,"b")){
				player = 2;
				computer = 1;
			}		
			else{
				player = 1;
				computer = 2;
			}
			checkWin2(computer, player);	//when termination is not when the board is full
			exit(0);
		}
	}
}
/*--------------------------------------------------------------------------------------------------------*/


//==========================================COMPUTER MOVES=================================================
/************************************** void moveIs(int c, int r) ************************************/
//to convert the move for column into A-H and then output the move
void moveIs(int c, int r)
{
	char column;
	
	switch(c){
		case 0 : column = 'A'; break;
		case 1 : column = 'B'; break;
		case 2 : column = 'C'; break;
		case 3 : column = 'D'; break;
		case 4 : column = 'E'; break;
		case 5 : column = 'F'; break;
		case 6 : column = 'G'; break;
		case 7 : column = 'H'; break;
	}

	printf("Computer move at %c %d\n",column,r+1);
}

/***************** void turningColorComputer(int ComputerValue,int playerValue) *********************/
//turning the black and white of the board for player
void turningColorComputer(int ComputerValue,int playerValue)
{
	int good1,good2,good3,good4,good5,good6,good7,good8;
	board[valueC][valueR] = ComputerValue;	
	good1 = checkLeft(valueC,valueR,'C',playerValue,ComputerValue);
	good2 =	checkRight(valueC,valueR,'C',playerValue,ComputerValue);
	good3 = checkUp(valueC, valueR, 'C', playerValue,ComputerValue);
	good4 = checkDown(valueC, valueR,'C', playerValue,ComputerValue);
	good5 = checkDiagRightUp(valueC,valueR,'C',playerValue,ComputerValue);
	good6 = checkDiagRightDown(valueC,valueR,'C',playerValue,ComputerValue);  //not yet check
	good7 = checkDiagLeftUp(valueC,valueR,'C',playerValue,ComputerValue);
	good8 = checkDiagLeftDown(valueC,valueR,'C',playerValue,ComputerValue);
	
	if (good1 == 1 || good2 == 1|| good3 == 1|| good4==1||good5==1||good6 == 1||good7 == 1|| good8 == 1){
		//calling function to print move
		moveIs(valueC,valueR);
		if (total_space == 0 ){
		}
		valueC = 0;
		valueR = 0;
	}
	else{//extend when i have more time 
		printf("Computer attempting illegal move!!!\n");
		printf("You have won!!\n");
		checkWin2(ComputerValue,playerValue);
		exit(0);
	}
}

//======================================================================================
/********************* void getBiggestValue(int computer, int opponent) *****************************/
//to get the biggest flipping that could take place for computer..
//so, this means that my program takes the maximum flipping...greedy approach
void getBiggestValue(int computer, int opponent)
{
	int col, row;
	int max=0;
	char columnInChar;
	int currentPriority = 10;
	int minFlip=100;
	for(col=0;col<8;col++)
		for(row=0;row<8;row++)
			//get the first biggest value encounter
			if (boardValue[col][row] >= max){
				if (board[col][row] ==0){
					if (currentPriority > priorityValue[col][row]){
					   if (boardValueMinimax[col][row] < minFlip){
					   	if(boardValue[col][row]!=0){
						  max = boardValue[col][row];
						  valueC = col;
						  valueR = row;
						  currentPriority = priorityValue[col][row];
						  minFlip = boardValueMinimax[col][row];
						 }
					   }
					}
				}
			}

	//this means that no value in the board that could flip opponent value
	if(boardValue[valueC][valueR] == 0){
		printf("X0\n");
		if (noMoveC == 1){
			printf("Both player has no more valid move. This game ends immediately!!\n");
			checkWin2(computer,opponent);
		}
		total_space ++;
	}
	else
		turningColorComputer(computer,opponent);
	screen();
			
}

/*  to count for each place in the board
 *  there are 8 possibility 
 *  these part (Part a-h)  counts the possibility in order to get the maximum value 
 *  
 *  */
/************ int search_diag_right_up(int column,int row, int myValue,int opponentValue) ***************/
//Part a
int search_diag_right_up(int column,int row, int myValue,int opponentValue)
{
	int count,count2,temp1,a;
	int maxValue;
	a =0;
	
	if (board[column+1][row-1]==0)
		return maxValue;
	
	if (board[column+1][row-1]==myValue)
		return maxValue;
	
	for (count=column+1;count<8;count++)
	{
		a++;
		if(row-a>=0){
			if (board[count][row-a]==opponentValue)
				temp1 = count;
			else
			{
				if(board[count][row-a] == myValue){
					a=1;
					for (count2=column+1;count2<=temp1;count2++)
					{
						//counting maximum value 
						maxValue++;
						a++;
						if (row-a<0)
							break;
					}
					return maxValue;
				}
				else
					return maxValue;
			}
		}
	}
	return maxValue;
}


/*********** int search_diag_right_down(int column,int row, int myValue,int opponentValue) ************/
//Part b
int search_diag_right_down(int column,int row, int myValue,int opponentValue)
{
	int count,count2,temp1,a;
	int maxValue = 0;
	a =0;
	
	if(board[column+1][row+1]==0)
		return maxValue;
	
	if (board[column+1][row+1]==myValue)
		return maxValue;
	
	for (count=column+1;count<8;count++)
	{
		a++;
		if(row+a<8){
			if (board[count][row+a]==opponentValue)
				temp1 = count;
			else
			{
				if(board[count][row+a] == myValue){
					a=1;
					for (count2=column+1;count2<=temp1;count2++)
					{
						//counting maximum value 
						maxValue++;
						a++;
						if (row+a>=8)
							break;
					}
					return maxValue;
				}
				else
					return maxValue;
			}
		}
	}
	return maxValue;
}

/************ int search_diag_left_down(int column,int row,int myValue,int opponentValue) ***********/
//Part c
int search_diag_left_down(int column,int row,int myValue,int opponentValue)
{
	int count,count2,temp1,a;
	int maxValue = 0;
	a =0;
	
	if(board[column-1][row+1] == 0)
		return maxValue;

	if(board[column-1][row+1] == myValue)
		return maxValue;
	
	for (count=row+1;count<8;count++)
	{
		a++;
		if(column-a>=0){
			if (board[column-a][count]==opponentValue)
				temp1 = count;
			else
			{
				if(board[column-a][count] == myValue){
					a=1;
					for (count2=row+1;count2<=temp1;count2++)
					{
						//counting maximum value
						maxValue++;
						a++;
						if (column-a<0)
							break;
					}
					return maxValue;
				}
				else
					return maxValue;
			}
		}
	}
	return maxValue;
}

/************ int search_diag_left_up(int column,int row,int myValue,int opponentValue) ************/
//Part d
int search_diag_left_up(int column,int row,int myValue,int opponentValue)
{
	int count,count2,temp1,a;
	int maxValue = 0;
	a =0;

	
	if(board[column-1][row-1]==0)
		return maxValue;
	
	if(board[column-1][row-1]==myValue)
		return maxValue;
	
	for (count=row-1;count>=0;count--)
	{
		a++;
		if(column-a>=0){
			if (board[column-a][count]==opponentValue)
				temp1 = count;
			else
			{
				if(board[column-a][count] == myValue){
					a=1;
					for (count2=row-1;count2>=temp1;count2--)
					{
						//counting maximum value
						maxValue++;
						a++;
						if (column-a<0)
							break;
					}
					return maxValue;
				}
				else
					return maxValue;
			}
		}
	}
	return maxValue;
}

/*************** int search_left(int column,int row, int myValue,int opponentValue) ********************/
//Part e
int search_left(int column,int row, int myValue,int opponentValue)
{
	int count,count2;
	int temp1=column-1;
	int maxValue = 0;
	
	if (board[column-1][row]==0)
		return maxValue;
	
	if(board[column-1][row]==myValue)
		return maxValue;

	for (count=column-1;count>=0;count--)
	{
		if (board[count][row]==opponentValue)
			temp1 = count;
		else
		{
			if(board[count][row] == myValue){
				for (count2=column-1;count2>=temp1;count2--)
				{
					maxValue++;
				}
				return maxValue;
			}
			else
				return maxValue;
				
		}
	}
	return maxValue;
}
/*************** int search_right (int column, int row, int myValue, int opponentValue ***************/
//f
int search_right(int column,int row, int myValue,int opponentValue)
{
	int count,count2;
	int temp1=column+1;
	int maxValue = 0 ;

	if (board[column+1][row] == 0)
		return maxValue;
	
	if(board[column+1][row]==myValue)
		return maxValue;
	
	for (count=column+1;count<8;count++)
	{
		if (board[count][row]==opponentValue)
			temp1 = count;
		else
		{
			if(board[count][row] == myValue){
				for (count2=column+1;count2<=temp1;count2++)
				{
					//counting maximum value
					maxValue++;
				}
				return maxValue;
			}
			else
				return maxValue;
		}
	}
	return maxValue;
}


/******************* int search_down(int column, int row, int myValue, int opponentValue ******************/
//Part g
int search_down(int column,int row,int myValue,int opponentValue)
{
	int count,count2;
	int temp1=row-1;
	int maxValue = 0;

	if(board[column][row-1]==0)
		return maxValue;
	if (board[column][row-1]==myValue)
		return maxValue;
	
	for (count=row-1;count>=0;count--)
	{
		if (board[column][count]==opponentValue)
			temp1 = count;
		else
		{
			if(board[column][count] == myValue){
				for (count2=row-1;count2>=temp1;count2--)
				{
					//counting maximum value
					maxValue++;
				}
				return maxValue;
			}
			else
				return maxValue;
		}
	}
	return maxValue;
}

/****************** int search_up(int column,int row, int myValue,int opponentValue) *********************/
//Part h
int search_up(int column,int row, int myValue,int opponentValue)
{
	int count,count2;
	int temp1=row+1;
	int maxValue = 0;
	
	if(board[column][row+1]==0)
		return maxValue;
	
	if (board[column][row+1]==myValue)
		return maxValue;
	
	for (count=row+1;count<8;count++)
	{
		if (board[column][count]==opponentValue)
			temp1 = count;
		else
		{
			if(board[column][count] == myValue){
				for (count2=row+1;count2<=temp1;count2++)
				{
					//counting maximum value
					maxValue++;
				}
				return maxValue;
			}
			else
				return maxValue;
		}
	}
	return maxValue;
}

/********************** void checkWin2(int computerValue, int playerValue) ***************************/
//to check the total black and white in the board
void checkWin2(int computerValue, int playerValue)
{
	int i, j;
	int black = 0, white = 0;
	
	for(i=0;i<8;i++){
		for(j=0;j<8;j++){
			if (board[i][j] == 2)
				black++;
			else
			{
				if(board[i][j]==1)
					white++;
			}
		}
	}
	if (total_space != 0){	
	  if (computerValue == 2){ //meaning that computer play black
		
		printf("White: %d\n",white);
		printf("Black: %d\n",black);
	  }
	  if (computerValue == 1){ //meaning that computer play white
		printf("Black: %d\n",black);
		printf("White: %d\n",white);
	  }
	}

	if(total_space == 0){
		if (computerValue == 2){ //computer play black 
		  if (black >white){ //when black win
			printf("I have won!!\n");	
			printf("Black: %d\n",black);
			printf("White: %d\n",white);
		  }
		 else{
			if(white>black){ //when white win
				printf("You have won!!\n");	
				printf("White: %d\n",white);
				printf("Black: %d\n",black);
			}
			else
				if(white == black){ //when no one win
					printf("Black: %d\n",black);
					printf("White: %d\n",white);
				}
		  }
		}
		else
		{                
			if (black >white){ //computer play white
				printf("You have won!!\n");
				printf("Black: %d\n",black);
				printf("White: %d\n",white);
			}
			else{
				if(white>black){
					printf("I have won!!\n");
					printf("White: %d\n",white);
					printf("Black: %d\n",black);
				}
				else
					if(white == black){
						printf("No one win!!\n");
						printf("White: %d\n",white);
						printf("Black: %d\n",black);
					}
			}
		}
	}
	exit(0);

}

/********************** void checkWin2(int computerValue, int playerValue) ***************************/
//to check the total black and white in the board when either player has no more move to go

void checkWin(int computerValue, int playerValue)
{
	int i, j;
	int black = 0, white = 0;
	
	for(i=0;i<8;i++){
		for(j=0;j<8;j++){
			if (board[i][j] == 2)
				black++;
			else
			{
				if(board[i][j]==1)
					white++;
			}
		}
	}
	
	if (black == 0)	{
		if (computerValue == 2){ //meaning that computer play black
			printf("You Have Won!\n");
			printf("White: %d\n",white);
			printf("Black: %d\n",black);
		}
		else{
			printf("I Have Won!\n");
			printf("Black: %d\n",black);
			printf("White: %d\n",white);
		}

		if (total_space <= 0)
			printf("The games end because black has no more moves to go\n");
		exit(0);
			
	}
	
	if (white == 0)	{
		if (computerValue == 1){ //meaning that computer play white
			printf("You Have Won!\n");
			printf("Black: %d\n",black);
			printf("White: %d\n",white);
		}
		else{
			printf("I Have Won!\n");
			printf("White: %d\n",white);
			printf("Black: %d\n",black);
		}
		
		if (total_space <= 0)
			printf("The games end because white has no more moves to go\n");
		exit(0);
	}

}

void checkSpace()
{
	int i,j;

	for(i=0;i<8;i++){
		for(i=0;i<8;i++){
			if(board[i][j]!=0){
				boardValue[i][j] = 0;
				priorityValue[i][j] = 10;
			}
		}
	}
}
/****************************************** void computer_turn() ******************************************/
//computer in action....
void computer_turn()
{
	int col,row,computerIs,minIs;
	int max1=0, max2=0, max3=0, max4=0, max5=0, max6=0, max7=0, max8=0;
        struct itimerval timer,timerOn;
        struct sigaction sa;

	       
	timer.it_value.tv_sec = 100; //10 seconds for player and 10 seconds for computer
	timer.it_value.tv_usec = 0;
	timerOn = timer;
	memset (&sa,0,sizeof(sa));
	//timer handler,...the signal action procedure
	sa.sa_handler = &timerHandler1;
	sigaction (SIGALRM,&sa,NULL);
		
		//                        //set the timer
	setitimer (ITIMER_REAL,&timerOn,NULL);
		
		//if timer not yet expire
	if (getitimer (ITIMER_REAL,&timerOn) >= 0){
						//                                                
	if (!strcmp(colors,"b")) //meaning player is black, so computer is white
	{
		computerIs = 1;
		minIs = 2;
	}
	else{
		computerIs = 2;
		minIs = 1;
	}
	checkWin(computerIs,minIs);
	
	copyValueTominimaxBoard();	
	initializeBoardminimax();
	
	for (col=0;col<8;col++){
		for (row=0;row<8;row++)
		{
			if (board[col][row] == 0){
				//searching for possible move
				max1 = search_down(col,row,computerIs,minIs);
				max2 = search_up(col,row,computerIs,minIs);			
				max3 = search_left(col,row,computerIs,minIs);
				max4 = search_right(col,row,computerIs,minIs);
				max5 = search_diag_left_up(col,row,computerIs,minIs);
				max6 = search_diag_right_up(col,row,computerIs,minIs);
				max7 = search_diag_left_down(col,row,computerIs,minIs);
				max8 = search_diag_right_down(col,row,computerIs,minIs);
				//counting and get the total of each move
				boardValue[col][row] = max1 + max2 + max3 + max4 + max5 + max6 + max7 + max8;
			}
			else{
				boardValue[col][row] = 0;
			}

			if (boardValue[col][row]>0){	//calculate number of move that min have if max take this move
				flippingMinimaxBoard(col,row,computerIs,minIs);	
				expectedMinMove(col,row,computerIs,minIs);
				copyValueTominimaxBoard();	//restart the whole to check for other move
			}
							
			//set the variable back to 0
			max1=0,max2=0,max3=0,max4=0,max5=0,max6=0,max7=0,max8=0;
		}
	}
	checkSpace();
printf("Testing.............................\n\n");	
	//counting the biggest value
	getBiggestValue(computerIs,minIs);
	}
}
/******************************************* void welcome() ************************************************/
//the welcome prompt..just want to gain more marks
void welcome()
{
	printf("\n*--------------------------------------------------------------------------*\n");
	printf("*	WELCOME TO THE REVERSI GAME CREATED BY DAVINA CHIN	      	   *\n");
	printf("*--------------------------------------------------------------------------*\n");
	printf("*	HOPE YOU WILL ENJOY THIS GAME. NOW THE RULES OF THE GAME:          *\n");
	printf("* 1. Enter column follow by row. Column is in the range of A-H. Row is     *\n");
	printf("*    in the range of 1-8.						   *\n");
	printf("* 2. Enter XO if there is no legal move.				   *\n");
	printf("* Note: Be aware of the capital letter... column must be in A-H not a-h	   *\n");
	printf("*--------------------------------------------------------------------------*\n\n");
	
}

void setPriority()
{
	int i,j;

	//setting priority as 5
	for(i=3;i<5;i++){
		priorityValue[2][i] = 5;
		priorityValue[i][2] = 5;
		priorityValue[i][5] = 5;
		priorityValue[5][i] = 5;
	}

	//setting priority as 4
	for(i=2;i<=6;i++){
		priorityValue[1][i] = 4;
		priorityValue[i][1] = 4;
		priorityValue[i][6] = 4;
		priorityValue[6][i] = 4;
	}
	
	//setting priority as 3
	for(i=1;i<7;i++){
		priorityValue[i][7-i] = 3;
		priorityValue[i][i] = 3;
	}
	
	//setting priority as 2
	for(i=1;i<=6;i++){
		priorityValue[0][i] = 2;
		priorityValue[7][i] = 2;
		priorityValue[i][7] = 2;
		priorityValue[i][0] = 2;
	}
	
	//setting priority as 1
	priorityValue[0][0] = 1;
	priorityValue[7][7] = 1;
	priorityValue[7][0] = 1;
	priorityValue[0][7] = 1;
	
}
/****************************************** main function *************************************************/
//this is the main function 
int main(int argc, char argv[])
{
	int a,playerturn;
	int computerIs,minIs;
	
	playerturn = 2;
	total_space = 60;
	welcome();
	setPriority();
	
	while(1){
		printf("Player that play black ('X') will move first\n");
		printf("What colors do you want? Enter 'b' for black and 'w' for white: ");
		//input either b or w
		scanf("%s",colors);
		if (strcmp(colors,"w") )
			if (strcmp(colors,"b"))
					printf("\nWrong argument. Please choose either 'w' or 'b'\n\n");
			else{
				printf ("\nYou play black (X). You will move first\n\n");
				playerturn = 1;
				break;
			}
		else{
			printf("\nYou play white (O). The computer will make the first move\n\n");
			break;
		}		
	}
	
	//initializing the board value
	initialize_board();
	//display the screen 
	screen();
	
	if (!strcmp(colors,"b")) //meaning player is black, so computer is white
	{
		computerIs = 1;
		minIs = 2;
	}
	else{
		computerIs = 2;
		minIs = 1;
	}

	while(total_space>0){
		if(playerturn == 1) //if player chooses black
		{
			player_turn();
			playerturn = 2;
			total_space --;
		}
		else{
			computer_turn();
			playerturn = 1;
			total_space --;
		}
		printf("Processing......\n");
		sleep(1);
	}

	//when the game ends
	checkWin2(computerIs,minIs);
}
/****************************************************************************************************************/
/*						THE END							  	*/
/*						  BUGS								*/
/* So far, i have not detected any bugs in this program. However, the move that made by the computer is based on
 * greedy concept. Thus, move is not optimal. 
 * There is time that the computer might make stupid and illegal move						*/
/* Note: Kindly report any bugs that you have encounter in this program, Thank you!!				*/
/****************************************************************************************************************/
