import java.util.*;

public class Search
{
        private int defaultply;
        private int node = 0;
        private Board myboard;
        private Move bestmove;
        private int val;
        private int score;  // We'll use this to determine if it was a checkmate or stalemate.
                            // Checkmate is infinity. Stalemate is zero.

        
        public Search(int ply) {
            defaultply = ply;
        }
        
        public int getLastScore() {
            return score;
        }

        public Move getMove(Board theboard, boolean whiteTurn) {
            myboard = theboard;
            long before = System.currentTimeMillis();
            bestmove = null;
            score = AlphaBeta(defaultply, Integer.MIN_VALUE + 1, Integer.MAX_VALUE - 1, whiteTurn);
            long difference = System.currentTimeMillis() - before;
            ChessEngine.outWriter.println("Nodes: " + node + ", Seconds: " + difference/1000 + "\n" +
                                          (int)(node/((double)difference/1000)) + " nodes/second" +
                                        "\nScore: " + score);
            node = 0;
            return bestmove;
        }


        public int AlphaBeta(int depth, int alpha, int beta, boolean whiteTurn) {
	        node++;

                if (depth <= 0) {
                        return myboard.evaluate(whiteTurn);
	        }

                Stack s = new Stack();
                myboard.generateMoves(s, whiteTurn);
                Collections.sort(s);
                
                if (s.isEmpty()) {
                    //There are no legal moves
                    // We should check to see if we are in check so that we know that this is
                    // not a stalemate instead of a checkmate.
                    if (myboard.inCheck(whiteTurn)) { // This is a checkmate for the other side.
                        return -ChessPiece.VALUE_KING;
                    } else { // This is a stalemate
                        return 0;
                    }
                }

                while (!s.isEmpty()) {

                        Move curmove = (Move)s.pop();

                        myboard.movePiece(curmove);
                        val = -AlphaBeta(depth - 1, -beta, -alpha, !whiteTurn);
                        myboard.unmakeMove();

                        if (val >= beta)
                                return beta;

                        if (val > alpha) {
                                alpha = val;
                                // If this is the root ply then this is the best move so far.
                                if(depth == defaultply) {
                                    bestmove = curmove;
                                }
                        }
                }
                return alpha;
        }
}