@Override
    public Move getMove(DraughtsState ds) {
        NodeLVL4 node = new NodeLVL4(ds.clone());
        Move bestMove = null;
        
        // Get moves and shuffle them.
        List<Move> moves = ds.getMoves();
        Collections.shuffle(moves);
        int nrOfMoves = moves.size();
        
        // Determine depth.
        int depth = 6;
        
        if (nrOfMoves < 12){
            depth = 8;
        }
        if (nrOfMoves < 7){
            depth = 10;
        }
        if (nrOfMoves < 5){
            depth = 12;
        }
        if (nrOfMoves == 1){
            return moves.get(0);
        }
        System.out.println("#LVL4 Calculating at depth: " + depth);
        
        // Set alpha, beta and bestScore to (-)infinity.
        int alpha = Integer.MIN_VALUE;
        int beta = Integer.MAX_VALUE;
        int bestScore = Integer.MIN_VALUE;
        
        // Determine best move.
        for (Move move : moves) {
            ds.doMove(move);
            if (bestMove == null) {
                bestMove = move;
            }
            // If timer stopped, exit move calculation and use best found move.
            try {
                alpha = max(alpha, miniMax(new NodeLVL4(ds.clone()), 
                        depth - 1, alpha, beta));
            } catch (AIStoppedException ex) {
                System.out.println("Timer stopped.");
                ds.undoMove(move);
                break;
            }
            if (alpha > bestScore) {
                bestMove = move;
                bestScore = alpha;
            }
            ds.undoMove(move);
        }

        // Return the best move.
        System.out.println("#LVL4 Best score: " + bestScore);
        return bestMove;
    }