private int alphabeta(int depth, int alpha, int beta, char turn)
        {
            // Takes 95% CPU
            int me   = GameEngine.Rules.findCaptured(getColor(), getOpponentColor(), boardCopy, boardCopy.GetLength(0)).Count;
            int oppo = GameEngine.Rules.findCaptured(getOpponentColor(), getColor(), boardCopy, boardCopy.GetLength(0)).Count;

            if (oppo > 0 && me > 0)
            {
                if (turn == getColor())
                {
                    return(-1000000000);
                }
                else
                {
                    return(1000000000);
                }
            }
            else if (oppo + me > 0)
            {
                if (oppo > 0)
                {
                    return(-1000000000);
                }
                else if (me > 0)
                {
                    return(1000000000);
                }
            }

            if (depth == 0)
            {
                return(AiUtil.getLiberties(getColor(), boardCopy) - AiUtil.getLiberties(getOpponentColor(), boardCopy));
            }
            //both player have the same next moves
            //List<Point> nextMoves = AiUtil.getNextMoves(boardCopy, influence, 10); //hard coded horizontal pruning



            IEnumerable <JokerPoint> nextMoves = AiUtil.getNextMoves(boardCopy, 3);

            if (turn == getColor())
            {
                foreach (JokerPoint next in nextMoves)
                {
                    int priorInf = influence[next.x, next.y];
                    updateInfluenceMap(next.x, next.y, boardCopy.GetLength(0));
                    boardCopy[next.x, next.y] = getColor();

                    int temp = alphabeta(depth - 1, alpha, beta, getOpponentColor());

                    boardCopy[next.x, next.y] = '*';
                    restoreInfluenceMap(next.x, next.y, priorInf, boardCopy.GetLength(0));

                    if (alpha < temp)
                    {
                        alpha = temp;
                        if (depth == this._maxDepth)
                        {
                            bestMove = next;
                        }
                    }

                    if (beta <= alpha)
                    {
                        return(alpha);
                    }
                }

                return(alpha);
            }
            else
            {
                foreach (JokerPoint next in nextMoves)
                {
                    int priorInf = influence[next.x, next.y];
                    updateInfluenceMap(next.x, next.y, boardCopy.GetLength(0));
                    boardCopy[next.x, next.y] = getOpponentColor();

                    int temp = alphabeta(depth - 1, alpha, beta, getColor());

                    boardCopy[next.x, next.y] = '*';
                    restoreInfluenceMap(next.x, next.y, priorInf, boardCopy.GetLength(0));

                    if (beta > temp)
                    {
                        beta = temp;
                        if (depth == this._maxDepth)
                        {
                            bestMove = next;
                        }
                    }

                    if (beta <= alpha)
                    {
                        return(beta);
                    }
                }

                return(beta);
            }
        }