public AlphaBetaReturnValue MinValue(CheckersBoard board, int alphaValue, int betaValue, PieceColor color, ref int currentDepth, ref int maxDepth, int maxDepthToSearchFor)
        {
            NodesGenerated++;

            var v = new AlphaBetaReturnValue(PositiveInfinity, null, currentDepth + 1);
            var moves = board.GetAllAvailableMoves(color).ToList().OrderByDescending(mr => mr.JumpResults.Count()).ToList();
            var coTest = CutoffTest(board, currentDepth, maxDepthToSearchFor);

            if (coTest.HasValue && coTest.Value || !moves.Any())
            {
                v.Value = Evaluate(board, color);
                v.Depth = currentDepth;

                return v;
            }
            if (!coTest.HasValue)
            {
                return null;
            }

            for (var i = 0; i < moves.Count; i++)
            {
                var m = moves[i];
                board.MovePiece(m, color);

                if (currentDepth == 0 && moves.Count == 1)
                {
                    v.Move = m;
                    v.Value = Evaluate(board, color);

                    board.RevertMove(m, color);
                    return v;
                }

                var newDepth = currentDepth;

                newDepth++;
                var retVal = MaxValue(board, alphaValue, betaValue,
                                  color == PieceColor.Black ? PieceColor.Red : PieceColor.Black, ref newDepth,
                                  ref maxDepth, maxDepthToSearchFor);

                if (retVal == null)
                    return null;

                retVal.Move = m;

                board.RevertMove(m, color);

                if (retVal.Depth > maxDepth)
                    maxDepth = retVal.Depth;

                if(retVal.Value < v.Value)
                {
                    v.Value = retVal.Value;
                    v.Move = retVal.Move;
                }

                if (v.Value <= alphaValue)
                {
                    NumberOfMinPrunes++;
                    return retVal;
                }

                betaValue = Math.Min(betaValue, v.Value);
            }

            return v;
        }
        // the evaluation function sums up the values of the pieces for each color and the available moves
        // the available moves is weighted more, and the value of the piece is determined by how close the piece is to the center of the board [favors pieces that are in the center]
        public int Evaluate(CheckersBoard state, PieceColor color)
        {
            int pOne = 0, pTwo = 0;

            for (var i = 0; i < state.Pieces.AlivePlayerOnePieces.Count; i++)
            {
                var piece = state.Pieces.AlivePlayerOnePieces[i];
                pOne += 3*(state.TileBoard.Height >> 1 - Math.Abs(state.TileBoard.Height >> 1 - piece.Y)) +
                        3*(state.TileBoard.Width >> 1 - Math.Abs(state.TileBoard.Width >> 1 - piece.X));
            }
            for (var i = 0; i < state.Pieces.AlivePlayerTwoPieces.Count; i++)
            {
                var piece = state.Pieces.AlivePlayerTwoPieces[i];
                pTwo += 3*(state.TileBoard.Height >> 1 - Math.Abs(state.TileBoard.Height >> 1 - piece.Y)) +
                        3*(state.TileBoard.Width >> 1 - Math.Abs(state.TileBoard.Width >> 1 - piece.X));
            }

            pOne += state.GetAllAvailableMoves(PieceColor.Black).Count()*10;
            pTwo += state.GetAllAvailableMoves(PieceColor.Red).Count()*10;

            return (Color == PieceColor.Black ? pOne - pTwo : pTwo - pOne);
        }