//player_functions.cpp
//by John Ahlschwede
//defines member functions for player and livePlayer classes

#include "grammar.h"


////////////////////////////////////////////////////////////////////////////////
// player functions
////////////////////////////////////////////////////////////////////////////////

player::player()
{
	return;
}

int player::exe(int game[14])
{
	cout << "!!!!!!!!!!!player base class exe function has been run!!!!!!!!!!!!"
		<< endl << "!!!!!!!!!!YOU SHOULD NOT SEE THIS!!!!!!!!!!!";
	return 0;
}



////////////////////////////////////////////////////////////////////////////////
// livePlayer
////////////////////////////////////////////////////////////////////////////////

livePlayer::livePlayer()
{
	return;
}




int livePlayer::exe(int game[14])
{
	int moveValue=0;
	while((moveValue < 1)||(moveValue > 6)||(game[moveValue]<1))
	{
		cout << endl << endl << "BOARD STATE: ";
		printBoard(game);
		cout << "ENTER YOUR MOVE (1-6)";
		cin >> moveValue;
	}


	return moveValue;
}

void livePlayer::printBoard(int game[14])
{
	cout << endl 
		 << ".--------------------------------------------." << endl 
		 << "| .---. .--. .--. .--. .--. .--. .--. .---.  |" << endl
		 << "| |   | |";
		
	for(int i=13; i>7; i--)
	{
		if(game[i] < 10)
			cout << " ";
		cout << game[i] << "| |";
	}
	cout << "   |  |" << endl
         << "| | " << game[0];
	if(game[0] < 10)
		cout << " ";
	cout << "| `--' `--' `--' `--' `--' `--' | " << game[7];
	if(game[7] <10)
		cout << " ";
	cout << "|  |" << endl
		 << "| |   | .--. .--. .--. .--. .--. .--. |   |  |" << endl
		 << "| |   | |";

	for(int j=1; j<7; j++)
	{
		if(game[j] < 10)
			cout << " ";
		cout << game[j] << "| |";
	}
	cout << "   |  |" << endl
		 << "| `---' `--' `--' `--' `--' `--' `--' `---'  |" << endl
		 << "'--------------------------------------------'" << flush << endl;
}






////////////////////////////////////////////////////////////////////////////////
// optimalPlayer
////////////////////////////////////////////////////////////////////////////////

optimalPlayer::optimalPlayer()
{
	depth=8;
	return;
}


int optimalPlayer::exe(int game[14])
{
	return search(depth, game, true);
}

int optimalPlayer::search(int levelsDeep, int theBoard[14], bool firstPTurn)
{
	if(levelsDeep < 1)
	{
		return (theBoard[7] - theBoard[0]);
	}

	else // begin procesing
	{
		int possibleMoves[2][6]; 
		// if [0][x] == 0, the board has no stones at location theBoard[x+1],
		// and no move is possible
		// if [0][x] == 1, a move is possible
		
		for(int n=0; n<6; n++)  // this loop determines which moves are possible
		{
			if(firstPTurn)						
			{									
				if(theBoard[n+1] > 0)			// THIS PART IS FOR
					possibleMoves[0][n] = 1;	//	WHEN IT'S THE FIRST
				else							//	PLAYER'S TURN
					possibleMoves[0][n] = 0;	//  .....
			}									

			else
			{
				if(theBoard[n+8] > 0)			// THIS PART
					possibleMoves[0][n] = 1;	// IS FOR 
				else							// THE 
					possibleMoves[0][n] = 0;	// SECOND PLAYER'S TURN
			}
		} // end of loop that determines possible moves


		board tempBoard[6];
		for(int k=0; k<6; k++)
		{
			tempBoard[k].setCups(theBoard);
			tempBoard[k].setTurn(firstPTurn);
		}

		for(int m=0; m<6; m++) //gets rating for each possible move
		{
			if(possibleMoves[0][m] == 1) // a move is possible
			{
				bool nextTurn = false;
				if(firstPTurn)
				{
					tempBoard[m].move(m+1);
				}
				else
				{
					tempBoard[m].move(m+8);
				}
				
				if(!tempBoard[m].gameOver())
					possibleMoves[1][m] = search(levelsDeep - 1, tempBoard[m].getCups(), tempBoard[m].getTurn());
				else
					possibleMoves[1][m] = tempBoard[m].getRating();
			}

			else // no move is possible
			{
				possibleMoves[1][m] = 0;
			}


		}


		//determine best move
		bool foundMove = false;
		int bestMove = 0;

		for(int j=0; j<6; j++)
		{
			if(possibleMoves[0][j] == 1)//if there is a move
			{
				if(foundMove == false) //if this is first found
				{
					bestMove = j;		//accept it as best
					foundMove = true;   // a move is found
				}
				else // if there is already a move found
				{
				//compare with previous best move

					if(firstPTurn)
					{
						if(possibleMoves[1][j] > possibleMoves[1][bestMove])
							bestMove = j;
					}
					else
					{
						if(possibleMoves[1][j] < possibleMoves[1][bestMove])
							bestMove = j;
					}


				}//end else for already found move

			}//end for what to do for a possible move
			
		}
		

		if(levelsDeep == depth) //if this is top level, return cup place
			return bestMove+1;
		//else return best rating
		else
		{
			if(foundMove)
				return possibleMoves[1][bestMove];
			else
				return (theBoard[7] - theBoard[0]);
		}




	}//end processing 



}


