public static final Move getBestMove() {
		Iterator<Move> possibleMoves = findMoves(Board.getInstance().isPlayerWhite());
		ArrayList<Move> bestMoves = new ArrayList<Move>();
		
		if (possibleMoves.hasNext()) {
			bestMoves.add(possibleMoves.next());
			bestMoves.get(0).setHeuristicValue(alphaBeta(bestMoves.get(0), treeDepth - 1, Double.MIN_VALUE, Double.MAX_VALUE, false));
		}
		
		Move currentMove;
		
		while (possibleMoves.hasNext()) {
			currentMove = possibleMoves.next();
			currentMove.setHeuristicValue(alphaBeta(currentMove, treeDepth - 1, bestMoves.get(0).getHeuristicValue(), Double.MAX_VALUE, false));
			
			if (currentMove.getHeuristicValue() > bestMoves.get(0).getHeuristicValue()) {
				bestMoves.removeAll(bestMoves);
				bestMoves.add(currentMove);
			} else if (currentMove.getHeuristicValue() == bestMoves.get(0).getHeuristicValue()) {
				bestMoves.add(currentMove);
			}
		}
		
		Iterator<Move> itrBestMoves = bestMoves.iterator();
		ArrayList<Move> bestBestMoves = new ArrayList<Move>();
		
		while (itrBestMoves.hasNext()) {
			Move possibleBestMove = itrBestMoves.next();
			Board.getInstance().makeMove(possibleBestMove);
			possibleBestMove.setHeuristicValue(BoardEvaluator.getHeuristicValue(Board.getInstance().isPlayerWhite()));
			
			if (bestBestMoves.size() == 0) {
				bestBestMoves.add(possibleBestMove);
			} else {
				if (possibleBestMove.getHeuristicValue() > bestBestMoves.get(0).getHeuristicValue()) {
					bestBestMoves.removeAll(bestBestMoves);
					bestBestMoves.add(possibleBestMove);
				} else if (possibleBestMove.getHeuristicValue() == bestBestMoves.get(0).getHeuristicValue()) {
					bestBestMoves.add(possibleBestMove);
				}
			}
			
			Board.getInstance().undoLastMove();
		}
		
		Random random = new Random();
		return bestBestMoves.isEmpty() ? null : bestBestMoves.get(random.nextInt(bestBestMoves.size()));
	}