import java.util.*;

/** This is the board object that will hold references to pieces in the
arrangement they are found on the chess board.  It is implemented using an
array of ChessPiece references.  It also has a copy() method that is used to
make copies of it for the tree used in deciding how to move. */
public class Board
{
	/** This is the array of ChessPieces.  It is an 8 by 8 array of ChessPiece
	references.  Nothing more, nothing less. */
	protected ChessPiece[][] board = new ChessPiece[8][8];
        
        // These Stacks store a history of the game for unmaking moves
        private Stack captureStack, moveStack;
        
        private int whitePieces, blackPieces;
    	
	/** Builds a new board setup to start a new game of chess. */
	public Board()
	{
                // Initialize the stacks;
                captureStack = new Stack();
                moveStack = new Stack();
                whitePieces = 16;
                blackPieces = 16;
                
                // Associate references of the board[][] object with appropriate chess
                // pieces.  I hope this will be good enough for pseudocode.
                
                // Add the pawns for both sides
                for (int i = 0; i < 8; i++) {
                        setPiece(1, i, new ChessPiece(0 /*pawn*/, true /*white*/));
                        setPiece(6, i, new ChessPiece(0 /*pawn*/, false /*black*/));
                }
                
                // Add the rooks for each side
                setPiece(0, 0, new ChessPiece(3 /*rook*/, true /*white*/));
                setPiece(0, 7, new ChessPiece(3 /*rook*/, true /*white*/));
                setPiece(7, 0, new ChessPiece(3 /*rook*/, false /*black*/));
                setPiece(7, 7, new ChessPiece(3 /*rook*/, false /*black*/));
                
                // Add the knights for each side
                setPiece(0, 1, new ChessPiece(1 /*knight*/, true /*white*/));
                setPiece(0, 6, new ChessPiece(1 /*knight*/, true /*white*/));
                setPiece(7, 1, new ChessPiece(1 /*knight*/, false /*black*/));
                setPiece(7, 6, new ChessPiece(1 /*knight*/, false /*black*/));
                
                // Add the bishops for each side
                setPiece(0, 2, new ChessPiece(2 /*bishop*/, true /*white*/));
                setPiece(0, 5, new ChessPiece(2 /*bishop*/, true /*white*/));
                setPiece(7, 2, new ChessPiece(2 /*bishop*/, false /*black*/));
                setPiece(7, 5, new ChessPiece(2 /*bishop*/, false /*black*/));
                
                // Add the king and queen for each side
                setPiece(0, 3, new ChessPiece(4 /*queen*/, true /*white*/));
                setPiece(0, 4, new ChessPiece(5 /*king*/, true /*white*/));
                setPiece(7, 3, new ChessPiece(4 /*queen*/, false /*black*/));
                setPiece(7, 4, new ChessPiece(5 /*king*/, false /*black*/));
	}
	
	/** Builds a new board based on the given board.  This constructor is used in
	copy(). 
        @param <CODE>b</CODE>
                The board to copy. This method no longer works correctly.
        */
	public Board(Board b)
	{
                /* pseudocode
                for all squares s in b
                        setPiece(s, a copy of b.getPiece(s))
                */
                
                for (int i = 0; i < 8; i++) {
                        for (int j = 0; j < 8; j++) {
                                if (b.getPiece(i, j) != null)
                                        this.setPiece(i, j, b.getPiece(i, j).copy());
                        }
                }
	}
	
	/** Returns the piece at the specified location.
        @param <CODE>row</CODE>
                The row of the piece.
        @param <CODE>col</CODE>
                The column of the piece.
        @return The <CODE>ChessPiece</CODE> at <CODE>row</CODE>, <CODE>col</CODE>.
        */
	public ChessPiece getPiece(int row, int col)
	{
                // Returns null if there is no piece
		return board[row][col];
	}
	
	/** Used to add pieces to the board.  Should only be needed by the
	constructors and the copy() method. 
        @param <CODE>row</CODE>
                The row of the piece.
        @param <CODE>col</CODE>
                The column of the piece.
        @param <CODE>piece</CODE>
                The <CODE>ChessPiece</CODE> to be added to this <CODE>Board</CODE>
        */
	protected void setPiece(int row, int col, ChessPiece piece)
	{
                // Board[row][col] will be set to null if piece is null
                board[row][col] = piece;
	}
	
	/** Makes a move according to the specified Move object, taking pieces if
	needed (by simply overwriting their spot in the array), leaving a null
	reference behind where the piece was originally located. 
        @param <CODE>theMove</CODE>
                The <CODE>Move</CODE> to be applied to this board.  
                The move should be logical for this board, but does 
                not necessarily have to be legal.
        */
        
        // Precondition: the move must be logical for this board
        //               (i.e. the source should not be null/empty, and the Move
        //                should be on this board.)
        // Postcondition: the move's source is null/empty and the dest is non-null
	public void movePiece(Move theMove)
	{
                        
                // Push this move onto the stack
                moveStack.push(theMove);
                
                // Just for the sake of ease
                int sourceRow = theMove.getSourceRow();
                int sourceCol = theMove.getSourceCol();
                int destRow = theMove.getDestRow();
                int destCol = theMove.getDestCol();
                
                // If the destination isn't empty push onto the capture stack
                // the piece that was there.  Otherwise push something else onto the stack
                // and make the destination square point to the piece that was the 
                // source and make the source null.  
		
			// castling, make sure we know it is a king and it is a castle move
		if (board[sourceRow][sourceCol].type() == ChessPiece.TYPE_KING){
		    if(sourceRow == destRow && Math.abs(sourceCol-destCol) > 1){
			if (destCol ==2)//move rook and king on left side of board
			{
			    board[sourceRow][3] = board[sourceRow][0]; //move rook
			    board[sourceRow][3].addMove();
			    board[sourceRow][0] = null;
			    //handle king later
			}	
			if (destCol == 6)//move rook and king on right side of board
			{
			    board[sourceRow][5] = board[sourceRow][7]; //move rook
			    board[sourceRow][5].addMove();
			    board[sourceRow][7] = null;
			    //handle king later
			}
		    }
		}
                if (board[destRow][destCol] != null) {
                        captureStack.push(board[destRow][destCol]);
                        //Update piece count
                        if (board[destRow][destCol].isWhite()) {
                            whitePieces--;
                        } else {
                            blackPieces--;
                        }
                } else {
                        // Make sure that we don't think the last move yielded a capture.
                        captureStack.push(new Object() /* Any old object */);
                }
                board[destRow][destCol] = board[sourceRow][sourceCol];
                board[sourceRow][sourceCol] = null;
		board[destRow][destCol].addMove();
	}
        
        /** Makes a move. Calls movePiece with theMove.  This shouldn't ever be used.*/
        public void makeMove(Move theMove) {
                        movePiece(theMove);
        }
        
        /** Unmakes the last move made via movePiece() on this <CODE>Board</CODE>.
        If no move was previously made does nothing.
        */
        public void unmakeMove() {
                // Get the most recent move if the stack is not empty
                Move theMove;
                if (!moveStack.isEmpty()) {
                        theMove = (Move)moveStack.pop();
                } else {
                        return;
                }

                // Reverse the process of movePiece
                int sourceRow = theMove.getSourceRow();
                int sourceCol = theMove.getSourceCol();
                int destRow = theMove.getDestRow();
                int destCol = theMove.getDestCol();

			// castling handler
		if (board[destRow][destCol].type() == ChessPiece.TYPE_KING && sourceRow == destRow && Math.abs(sourceCol-destCol) > 1){
			if (destCol == 2)//move rook and king on left side of board
			{
			    board[sourceRow][3].subMove();
			    board[sourceRow][0] = board[sourceRow][3]; //move rook
			    board[sourceRow][3] = null;
			    //handle king later
			}	
			if (destCol == 6)//move rook and king on right side of board
			{
			    board[sourceRow][5].subMove();
			    board[sourceRow][7] = board[sourceRow][5]; //move rook
			    board[sourceRow][5] = null;
			    //handle king later
			}
		}
                
		board[destRow][destCol].subMove();
       		board[sourceRow][sourceCol] = board[destRow][destCol];
		

                
                // We try to cast the item on the top of the stack to a ChessPiece
                // If it is not a ChessPiece just set the square to null.
                try {
                        board[destRow][destCol] = (ChessPiece)captureStack.pop();
			if (board[destRow][destCol].isWhite()) {
                            whitePieces++;
                        } else {
                            blackPieces++;
                        }
                } catch (ClassCastException ex) {
                        board[destRow][destCol] = null;
                }
        }
	
	/** Returns the current material value of the board.  Treating white pieces
	as negetive and black as positive. */
	public int evaluate(boolean whiteTurn)
	{ChessPiece piece; //Variable only used for readability
         
         int total=0; //return value of total points
                      //negative #'s are a good score for white
                      //positive #'s are a good score for black
         
         //go through every piece on the board
         for (int x=0; x<8; x++)
          for (int y=0; y<8; y++)
           if (board[x][y] != null)
           {
            piece=board[x][y]; //improve readability
           
            // This is a really bad temporary fix because I'm lazy
            if (whiteTurn) {
                if (piece.isWhite()) //subtract values if white
                {total += piece.value();
                
                if (piece.type() == ChessPiece.TYPE_PAWN)
                total += WPawn_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_KNIGHT)
                total += Knight_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_BISHOP)
                total += Bishop_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_ROOK)
                total += WRook_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_QUEEN)
                total += Queen_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_KING)
                total += WKing_PosValue[x][y];
                
                }//end of if the piece is white
                
                else //piece is black
                {total -= piece.value();
                
                if (piece.type() == ChessPiece.TYPE_PAWN)
                total -= BPawn_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_KNIGHT)
                total -= Knight_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_BISHOP)
                total -= Bishop_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_ROOK)
                total -= BRook_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_QUEEN)
                total -= Queen_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_KING)
                total -= BKing_PosValue[x][y];
                }//end of else piece is black          
    
            } else {  // It's black's turn.
                if (piece.isWhite()) //subtract values if white
                {total -= piece.value();
                
                if (piece.type() == ChessPiece.TYPE_PAWN)
                total -= WPawn_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_KNIGHT)
                total -= Knight_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_BISHOP)
                total -= Bishop_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_ROOK)
                total -= WRook_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_QUEEN)
                total -= Queen_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_KING)
                total -= WKing_PosValue[x][y];
                
                }//end of if the piece is white
                
                else //piece is black
                {total += piece.value();
                
                if (piece.type() == ChessPiece.TYPE_PAWN)
                total += BPawn_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_KNIGHT)
                total += Knight_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_BISHOP)
                total += Bishop_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_ROOK)
                total += BRook_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_QUEEN)
                total += Queen_PosValue[x][y];
                else if (piece.type() == ChessPiece.TYPE_KING)
                total += BKing_PosValue[x][y];
                }//end of else piece is black          
            }
           }//end of for loop
         //check to see if your in check
         /*this may be skipped to increase simplicity in our project
         if (MyKingInCheck())
          if (WhitesTurn)
           total += 15;
          else
           total -= 15;
         */
         
         return total;
	}//end of Evaluate
	
	/** Returns a field for field copy of this object.  It calls the copy() method
	of ChessPiece, making copies of the pieces on the board as well.  This is so
	the entire board can be manipulated independently from the actual chess board.
        This method no longer works.
        @return A copy of this <CODE>Board</CODE>.
	*/
	public Board copy()
	{
                // Using the copy constructor idea elaborated by the design team we
                // should just call the copy constructor with this board instance.
                return new Board(this);
	}
	
        /** Constructs the string representation of this board. 
        @return The string representation of this <CODE>Board</CODE>.
        */
        public String toString() {
                String s = "";
                // I decided to switch to counting down so that white is at the
                // bottom, but still in the right rank/file/whatever.
                for (int i = 7; i >= 0; i--) {
                        s = s + (i + 1) + " ";
                        for (int j = 0; j < 8; j++) {
                                if (board[i][j] == null) {
                                        s = s + ". ";
                                } else {
                                        s = s + board[i][j] + " ";
                                }
                        }
                        s = s + "\n";
                }
                s = s + "  a b c d e f g h\n";
                return s;
        }
        
        // Precondition: The move is in bounds and the source is not null.
        //               See below for the reason why.
        public boolean isLegal(Move move) {
                ChessPiece source, dest;
                
                source = board[move.getSourceRow()][move.getSourceCol()];
                dest = board[move.getDestRow()][move.getDestCol()];
                
                // This method has been reduced for performance's sake.  This will make no
                // difference to the move generation method, but it may now have some problems
                // testing the legality of moves not generated by the engine (i.e. usermoves).
                // I envision a seperate method called isUsermoveLegal() which calls into this
                // method after making the other the other necessary checks.  The precondition
                // for this method is now that the move is in bounds and the source is not null.
                // If the move source is null or the source and dest refer to
                // the same piece then it really isn't a move at all.
                
                // If the move tries to capture a friend then it is not legal
                if (dest != null) {
                        if (source.isWhite() == dest.isWhite()) {
                                // Fail quickly.
                                return false;
                        }
                }
                
                int sr = move.getSourceRow();
                int dr = move.getDestRow();
                int sc = move.getSourceCol();
                int dc = move.getDestCol();
                
                // Evaluate all of the possible moves based on the piece type
                // The remainder of this code is extremely inelegant.
                // I should be ashamed of myself for even thinking of writing it.
                // We should please use this method sparingly.
                // Update: I changed from an iterative to a recursive solution
                // for the slides.  It makes the code no smaller, but I believe
                // that it is a great deal easier to read.  Also the remainder
                // of the code is no less inelegant.
                if (source.type() == ChessPiece.TYPE_KNIGHT) {
                        int colAbsDif = Math.abs(dc - sc);
                        int rowAbsDif = Math.abs(dr - sr);
                        if ((rowAbsDif == 2  && colAbsDif == 1) ||
                            (rowAbsDif == 1  && colAbsDif == 2)) {
                                return true;
                        }
               } else if (source.type() == ChessPiece.TYPE_PAWN) {
                        // check for forward moves and kill moves
                        int colAbsDif = Math.abs(dc - sc);
                        if ((dest != null && ((source.isWhite() && dr - sr == 1) ||
                                              (!source.isWhite() && dr - sr == -1)) && 
                             colAbsDif == 1) ||
                            (dest == null && (((source.isWhite() && (dr - sr == 1 || 
                                               (dr - sr == 2 && sr == 1 &&
                                                board[sr + 1][sc] == null))) ||
                                              (!source.isWhite() && (dr - sr == -1 || 
                                               (dr - sr == -2 && sr == 6 &&
                                                board[sr - 1][sc] == null)))) && 
                             dc == sc))) {
                                return true;
                        }

	       } else if (source.type() == ChessPiece.TYPE_KING) {  //check moves of one space
                        int colAbsDif = Math.abs(dc - sc);
                        int rowAbsDif = Math.abs(dr - sr);
                        if ((rowAbsDif == 1 || rowAbsDif == 0) &&
                            (colAbsDif == 1 || colAbsDif == 0)) {
                                return  true;
                        }
			//check for castling moves
			if(sr == dr && !source.hasMoved() && !attacked(source.isWhite(),sr,sc))
			    {
				//queenside
				if(dc == 2 && getPiece(sr,0) != null && getPiece(sr,1) == null && getPiece(sr,2) == null && getPiece(sr,3) == null && getPiece(sr,0).type() ==  ChessPiece.TYPE_ROOK && !getPiece(sr,0).hasMoved())
				    {
					for (int i = 0; i<4;i++)
					    { 
						if(attacked(source.isWhite(),sr,i))//make sure the rook and empty spots 
						                                   //aren't under attack
						    return false;
					    }
						return true;
				    }
				//kingside
				if(dc == 6 && getPiece(sr,7) != null && getPiece(sr,5) == null && getPiece(sr,6) == null && getPiece(sr, 7).type() == ChessPiece.TYPE_ROOK && !getPiece(sr,7).hasMoved())
				    {
					for (int i = 7; i>4;i--)
					    {
						if(attacked(source.isWhite(),sr,i))//make sure the rook and empty spots
						                                   //aren't under attack
						    return false;
					    }
						return true;
				    }
			    }
                } else if (source.type() == ChessPiece.TYPE_ROOK) {
                        return canSlideStraight(sr, sc, dr, dc, true);
                } else if (source.type() == ChessPiece.TYPE_BISHOP) {
                        return canSlideDiagonal(sr, sc, dr, dc, true);
                } else if (source.type() == ChessPiece.TYPE_QUEEN) {
                        return (canSlideStraight(sr, sc, dr, dc, true) ||
                                canSlideDiagonal(sr, sc, dr, dc, true));
                }
                
                
                
                return false;
        }
        
        // I believe that the two following methods could be combined into one because
        // they share much code in common, but I am lazy, and that might be more 
        // difficult to understand.
        private boolean canSlideDiagonal(int sr, int sc, int dr, int dc, boolean endOfSlide) {
                // Grounding conditions for recursion
                if (sr == dr && sc == dc) {
                        // We have finished checking intervening moves
                        return true;
                }
                
                
                if (board[dr][dc] != null && !endOfSlide) {
                        // Somebody is in the way of this move
                        return false;
                }
                
                
                // Recursively call this function for each move between the given move
                // in order to see if the move jumps over anybody.
                if ((dr - sr) == (dc - sc)) {
                        if (dc - sc > 0) {
                                // Sliding right and up
                                return canSlideDiagonal(sr, sc, dr - 1, dc - 1, false);
                        } else {
                                // Sliding left and down
                                return canSlideDiagonal(sr, sc, dr + 1, dc + 1, false);
                        }
                } else if (-(dr - sr) == (dc - sc)) {
                        if (dr - sr > 0) {
                                // Sliding left and up
                                return canSlideDiagonal(sr, sc, dr - 1, dc + 1, false);
                        } else {
                                // Sliding right and down
                                return canSlideDiagonal(sr, sc, dr + 1, dc - 1, false);
                        }
                }
                
                // We get here in the event that the slide is not valid at all
                // (i.e. the quotient of the differences between the rank and file
                // are not one)
                return false;
        }
        
        private boolean canSlideStraight(int sr, int sc, int dr, int dc, boolean endOfSlide) {
                // Refer to comments for diagonal slides
                if (sr == dr && sc == dc) {
                        return true;
                }
                
                if (board[dr][dc] != null && !endOfSlide) {
                        // Somebody is in the way of this move
                        return false;
                }

                
                if (dr == sr) {
                        if (dc - sc > 0) {
                                // Sliding right
                                return canSlideStraight(sr, sc, dr, dc - 1, false);
                        } else {
                                // Sliding left
                                return canSlideStraight(sr, sc, dr, dc + 1, false);
                        }
                } else if (dc == sc) {
                        if (dr - sr > 0) {
                                // Sliding up
                                return canSlideStraight(sr, sc, dr - 1, dc, false);
                        } else {
                                //Sliding down
                                return canSlideStraight(sr, sc, dr + 1, dc, false);
                        }
                }
                
                return false;
        }
        
        public void generateMoves(Stack s, boolean whiteTurn) {
	    ChessPiece piece;
	    int count = 0;
	    int kingr = 0;
	    int kingc = 0;
	    for (int i = 0; i < 8; i++) {
                for (int j = 0; j < 8; j++) {
		    if(getPiece(i, j) != null && getPiece(i, j).type() == ChessPiece.TYPE_KING && getPiece(i, j).isWhite() == whiteTurn)
			{
			    kingr = i;
			    kingc = j;
			    break;
			}
		}
	    }

            for (int i = 0; i < 8; i++) {
                for (int j = 0; j < 8; j++) {
                    // Only generate moves for the side under consideration
		    piece = getPiece(i, j);
                    if (piece != null &&
                        whiteTurn == piece.isWhite()) {
                            count++;
			    for (int k = 0; k < 8; k++) {
                                for (int l = 0; l < 8; l++) {
                                    Move m = new Move(i, j, k, l, getPiece(k, l) != null);
                                    if (isLegal(m)) {
                                        // A move is only legal if, after making the move,
                                        // the king is not in check.

					//if source is the king check if king in dest square is in check after we move
					if(piece.type() == ChessPiece.TYPE_KING && piece.isWhite() == whiteTurn)
					    {
						movePiece(m);
						if (!attacked(whiteTurn,k,l)) 
						    {
						    s.push(m);
						}
						unmakeMove();
					    }
					else   //check if king is in check
					    {
					    movePiece(m);
						if (!attacked(whiteTurn,kingr, kingc)) 
						    {
						    s.push(m);
						}
						unmakeMove();
					    }
                                    }
                                }
                            }
                            
                            // Once we've found all of the pieces for this side we can quit.
                            if ((whiteTurn && count == whitePieces) ||
                                (!whiteTurn && count == blackPieces)) {
                                    return;
                            }
                    }
                }
            }
        }
        
        boolean attacked(boolean white ,int row, int col) {
                    // Only generate moves for the side under consideration
                    if (getPiece(row,col) != null && white == getPiece(row, col).isWhite()) {
                        for (int k = 0; k < 8; k++) {
                            for (int l = 0; l < 8; l++) {
                                // Lazy evaluation causes the condition to fail if the source
                                // would be null.  This preserves isLegal()'s precondition.
                                if ((getPiece(k, l)  != null) && isLegal(new Move(k, l, row, col, false)))
                                    return true;
                            }
                        }
                        // Once we've looked at all of the people attacking the square
                        // we can quit.
                        return false;
            }
            return false;  // We shouldn't ever get here.
        }
        
        private final int[][] BPawn_PosValue = { // Add value to the position of the pawn
          {14,14,14,14,14,14,14,14},
          {12,12,12,12,12,12,12,12},
          {10,10,10,10,10,10,10,10},
          { 8, 8, 8,10,10, 8, 8, 8},
          { 5, 5, 6, 9, 9, 6, 5, 5},
          { 4, 4, 4, 6, 6, 4, 4, 4},
          { 2, 2, 2, -2, -2, 2, 2, 2},
          { 0, 0, 0, 0, 0, 0, 0, 0}
         };
        
         private final int[][] WPawn_PosValue = {  // Add value to the position of the pawn
          { 0, 0, 0, 0, 0, 0, 0, 0},
          { 2, 2, 2, -2, -2, 2, 2, 2},
          { 4, 4, 4, 6, 6, 4, 4, 4},
          { 5, 5, 6, 9, 9, 6, 5, 5},
          { 8, 8, 8,10,10, 8, 8, 8},
          {10,10,10,10,10,10,10,10},
          {12,12,12,12,12,12,12,12},
          {14,14,14,14,14,14,14,14}
         };
         
         private final int[][] Knight_PosValue = {        // Add value to the position of the knight
          { 0, 1, 2, 2, 2, 2, 1, 0},
          { 1, 2, 3, 3, 3, 3, 2, 1},
          { 2, 3, 7, 5, 5, 7, 3, 2},
          { 2, 3, 5, 8, 8, 5, 3, 2},
          { 2, 3, 5, 8, 8, 5, 3, 2},
          { 2, 3, 7, 5, 5, 7, 3, 2},
          { 1, 2, 3, 3, 3, 3, 2, 1},
          { 0, 1, 2, 2, 2, 2, 1, 0}
         };
        
         
         private final int[][] BRook_PosValue = {        // Add value to the position of the Rook
          {4 , 4 , 4 , 4 , 4 , 4 , 4 , 4},
          {4 , 4 , 4 , 4 , 4 , 4 , 4 , 4},
          {2 , 2 , 2 , 4 , 4 , 2 , 2 , 2},
          {2 , 2 , 2 , 4 , 4 , 2 , 2 , 2},
          {2 , 2 , 2 , 4 , 4 , 2 , 2 , 2},
          {2 , 2 , 2 , 4 , 4 , 2 , 2 , 2},
          {2 , 2 , 2 , 6 , 6 , 2 , 2 , 2},
          {2 , 2 , 2 , 6 , 6 , 2 , 2 , 2}
         };
        
          private final int[][] WRook_PosValue = {        // Add value to the position of the Rook
           {2 , 2 , 2 , 6 , 6 , 2 , 2 , 2},
           {2 , 2 , 2 , 6 , 6 , 2 , 2 , 2},
           {2 , 2 , 2 , 4 , 4 , 2 , 2 , 2},
           {2 , 2 , 2 , 4 , 4 , 2 , 2 , 2},
           {2 , 2 , 2 , 4 , 4 , 2 , 2 , 2},
           {2 , 2 , 2 , 4 , 4 , 2 , 2 , 2},
           {4 , 4 , 4 , 4 , 4 , 4 , 4 , 4},
           {4 , 4 , 4 , 4 , 4 , 4 , 4 , 4}
          };
         
         private final int[][] Bishop_PosValue = {        // Add value to the position of the bishop
          {1 , 1 , 1 , 1 , 1 , 1 , 1 , 1},
          {1 , 2 , 2 , 2 , 2 , 2 , 2 , 1},
          {1 , 2 , 4 , 4 , 4 , 4 , 2 , 1},
          {1 , 2 , 4 , 6 , 6 , 4 , 2 , 1},
          {1 , 2 , 4 , 6 , 6 , 4 , 2 , 1},
          {1 , 2 , 4 , 4 , 4 , 4 , 2 , 1},
          {1 , 2 , 2 , 2 , 2 , 2 , 2 , 1},
          {1 , 1 , 1 , 1 , 1 , 1 , 1 , 1}
         };
         
          private final int[][] Queen_PosValue = {  // Add value to the position of the Queen
          {2 , 2 , 2 , 2 , 2 , 2 , 2 , 2},
          {2 , 3 , 3 , 3 , 3 , 3 , 3 , 2},
          {2 , 3 , 4 , 4 , 4 , 4 , 3 , 2},
          {2 , 3 , 4 , 5 , 5 , 4 , 3 , 2},
          {2 , 3 , 4 , 5 , 5 , 4 , 3 , 2},
          {2 , 3 , 4 , 4 , 4 , 4 , 3 , 2},
          {2 , 3 , 3 , 3 , 3 , 3 , 3 , 2},
          {2 , 2 , 2 , 2 , 2 , 2 , 2 , 2} 
         };
           
         private final int[][] BKing_PosValue = {        // Add value to the position of the king
           {-8,-8,-8,-8,-8,-8,-8,-8},
           {-8,-8,-8,-8,-8,-8,-8,-8},
           {-8,-8,-8,-8,-8,-8,-8,-8},
           {-8,-8,-8,-8,-8,-8,-8,-8},
           {-8,-8,-8,-8,-8,-8,-8,-8},
           {-8,-8,-8,-8,-8,-8,-8,-8},
           { 1, 1, 1, 1, 1, 1, 1, 1},
           { 1, 1, 9, 1, 1, 2, 9, 2}
         };
        
         private final int[][] WKing_PosValue = {        // Add value to the position of the king
          { 1, 1, 9, 1, 1, 2, 9, 2},
          { 1, 1, 1, 1, 1, 1, 1, 1},
          {-8,-8,-8,-8,-8,-8,-8,-8},
          {-8,-8,-8,-8,-8,-8,-8,-8},
          {-8,-8,-8,-8,-8,-8,-8,-8},
          {-8,-8,-8,-8,-8,-8,-8,-8},
          {-8,-8,-8,-8,-8,-8,-8,-8},
          {-8,-8,-8,-8,-8,-8,-8,-8}
         };

}
