import java.util.Stack;

public class Search
{
        public int defaultply;
        public int node = 0;
        public Board myboard;
        private Move bestmove;
        private static Move curmove, cmove;
        private static int val;

        
        public Search(int ply) {
            defaultply = ply;
        }

        public Move getMove(Board theboard, boolean whiteTurn) {
            myboard = theboard;
            AlphaBeta(defaultply, -ChessPiece.VALUE_KING+1, ChessPiece.VALUE_KING-1, new Stack(), whiteTurn);
            return bestmove;
        }


        public int AlphaBeta(int depth, int alpha, int beta, Stack s, boolean whiteTurn) {
	        node++;
	        //if(depth != 0) System.out.print("\n");
                        //System.out.print(node + "-" + depth + " ");
                if (depth <= 0) {
                        return myboard.evaluate(whiteTurn);
	        }
                //else System.out.print("\n"); 

    	        //if(depth == defaultply-1) {
    		//System.out.print(" <- root node");
	        //}
	        //else System.out.print("\n");
                
                //ChessEngine.outWriter.println("Depth: " + depth);
                //ChessEngine.outWriter.println("Generating moves for white: " + whiteTurn);

                generateMoves(s, whiteTurn);

                while (!s.isEmpty()) {

                        curmove = (Move)s.pop();
                        
                        if(depth == defaultply) {
		                cmove = curmove;
                        }

                        myboard.movePiece(curmove);
                        val = -AlphaBeta(depth - 1, -beta, -alpha, new Stack(), !whiteTurn);
                        myboard.unmakeMove();

                        if (val >= beta)
                                return beta;

                        if (val > alpha) {
                                //ChessEngine.outWriter.println("New biggest alpha: " +
                                //        val);
                                alpha = val;
	                        //System.out.print(" alpha:" + alpha + " ");
                                if(depth == defaultply) {
                                    bestmove = cmove;
                                }
                        }
                }
                //ChessEngine.outWriter.println("Returning alpha: " + alpha + 
                //        " for root level move: " + cmove);
                return alpha;
        }

        private void generateMoves(Stack s, boolean whiteTurn) {
                
                for (int i = 0; i < 8; i++) {
                        for (int j = 0; j < 8; j++) {
                                // Only generate moves for the side under consideration
                                if (myboard.getPiece(i, j) != null &&
                                    (whiteTurn == myboard.getPiece(i, j).isWhite())) {
                                        for (int k = 0; k < 8; k++) {
                                                for (int l = 0; l < 8; l++) {
                                                        Move m = new Move(i, j, k, l);
                                                        if (myboard.isLegal(m)) {
                                                                //ChessEngine.outWriter.println("Found " +
                                                                //        "legal move " + m);
                                                                s.push(m);
                                                        }
                                                }
                                        }
                                }
                        }
                }
        }
}