/// <summary>
        /// Adds score by checking values which are more than 10. Only tiles that got matched will have it's value > 10
        /// </summary>
        /// <param name="score"></param>
        /// <param name="board2Test"></param>
        /// <param name="initial"></param>
        /// <returns></returns>
        public SolverInterface.Score extractScore(SolverInterface.Score score, int[][] board2Test, Boolean initial)
        {
            int x = 0;
            int y = 0;

            while (y < length)
            {
                x = 0;
                while (x < width)
                {
                    int value = board2Test[y][x];
                    if (value > 9)
                    {
                        score.addScoreFromValue(board2Test[y][x]);
                        board2Test[y][x] = 9;
                        if (initial)
                        {
                            score.staminaCost++;
                        }
                    }
                    x++;
                }
                y++;
            }
            return(score);
        }
        /// <summary>
        /// Recursive function to evaluate score of the board.
        /// First checks matches, then get the score to evaluate.
        /// Trigger gravity for tiles to drop down then recurse
        /// </summary>
        /// <param name="score"></param>
        /// <param name="board2Test"></param>
        /// <param name="initial"></param>
        /// <returns></returns>
        public SolverInterface.Score evalBoard(SolverInterface.Score score, int[][] board2Test, Boolean initial)
        {
            // DEEP COPY
            int[][] board2TestCopy = Array.ConvertAll(board2Test, a => (int[])a.Clone());
            int     sum            = 0;
            int     index          = 0;

            while (index < 63)
            {
                board2TestCopy = checkMatch(index / width, index % width, board2TestCopy[index / width][index % width] % 10, board2TestCopy);
                index++;
            }
            score = extractScore(score, board2TestCopy, initial);
            if (score.wasChanged)
            {
                if (!initial)
                {
                    score.chains++;
                }
                score.resetWasChanged();
                board2TestCopy = gravityFall(board2TestCopy);
                score          = evalBoard(score, board2TestCopy, false);
            }
            return(score);
        }
        public List <SolverInterface.Movement> loopBoard(int[][] board2Test)
        {
            List <SolverInterface.Movement> returnThis = new List <SolverInterface.Movement>();
            int y = 0;
            int x = 0;

            while (y < length)
            {
                x = 0;
                while (x < width)
                {
                    /////////////////////
                    // HORIZONTAL
                    /////////////////////
                    ///
                    // MOVE LEFT
                    int offset = 1;
                    while (x - offset > -1)
                    {
                        // DEEP COPY
                        int[][] board2TestCopy = Array.ConvertAll(board2Test, a => (int[])a.Clone());

                        // MOVE
                        board2TestCopy = moveHorizontal(y, x, -1 * offset, board2TestCopy);
                        int boardHash = getBoardHash(board2TestCopy);

                        // ONLY SAVE IF THERE WAS A MATCH/SCORE
                        SolverInterface.Score result = evalBoard(new SolverInterface.Score(0), board2TestCopy, true);
                        if (result.hasScore())
                        {
                            // CHECK IF BOARD PATTERN ALREADY EXIST. REDUCE DUPLICATE
                            SolverInterface.Movement testExist = returnThis.SingleOrDefault(s => s.boardHash == boardHash);
                            if (!testExist.score.hasScore())
                            {
                                returnThis.Add(new SolverInterface.Movement(x, y, false, -1 * offset, result, boardHash));
                            }
                        }
                        offset++;
                    }
                    // MOVE RIGHT
                    offset = 1;
                    while (x + offset < width)
                    {
                        // DEEP COPY
                        int[][] board2TestCopy = Array.ConvertAll(board2Test, a => (int[])a.Clone());

                        // MOVE
                        board2TestCopy = moveHorizontal(y, x, offset, board2TestCopy);
                        int boardHash = getBoardHash(board2TestCopy);

                        // ONLY SAVE IF THERE WAS A MATCH/SCORE
                        SolverInterface.Score result = evalBoard(new SolverInterface.Score(0), board2TestCopy, true);
                        if (result.hasScore())
                        {
                            // CHECK IF BOARD PATTERN ALREADY EXIST. REDUCE DUPLICATE
                            SolverInterface.Movement testExist = returnThis.SingleOrDefault(s => s.boardHash == boardHash);
                            if (!testExist.score.hasScore())
                            {
                                returnThis.Add(new SolverInterface.Movement(x, y, false, offset, result, boardHash));
                            }
                        }
                        offset++;
                    }

                    /////////////////////
                    // VERTICAL
                    /////////////////////

                    // MOVE UP
                    offset = 1;
                    while (y - offset > -1)
                    {
                        // DEEP COPY
                        int[][] board2TestCopy = Array.ConvertAll(board2Test, a => (int[])a.Clone());

                        // MOVE
                        board2TestCopy = moveVertical(y, x, -1 * offset, board2TestCopy);
                        int boardHash = getBoardHash(board2TestCopy);

                        // ONLY SAVE IF THERE WAS A MATCH/SCORE
                        SolverInterface.Score result = evalBoard(new SolverInterface.Score(0), board2TestCopy, true);
                        if (result.hasScore())
                        {
                            // CHECK IF BOARD PATTERN ALREADY EXIST. REDUCE DUPLICATE
                            SolverInterface.Movement testExist = returnThis.SingleOrDefault(s => s.boardHash == boardHash);
                            if (!testExist.score.hasScore())
                            {
                                returnThis.Add(new SolverInterface.Movement(x, y, true, -1 * offset, result, boardHash));
                            }
                        }
                        offset++;
                    }

                    // MOVE DOWN
                    offset = 1;
                    while (y + offset < length)
                    {
                        // DEEP COPY
                        int[][] board2TestCopy = Array.ConvertAll(board2Test, a => (int[])a.Clone());

                        // MOVE
                        board2TestCopy = moveVertical(y, x, offset, board2TestCopy);
                        int boardHash = getBoardHash(board2TestCopy);

                        // ONLY SAVE IF THERE WAS A MATCH/SCORE
                        SolverInterface.Score result = evalBoard(new SolverInterface.Score(0), board2TestCopy, true);
                        if (result.hasScore())
                        {
                            // CHECK IF BOARD PATTERN ALREADY EXIST. REDUCE DUPLICATE
                            SolverInterface.Movement testExist = returnThis.SingleOrDefault(s => s.boardHash == boardHash);
                            if (!testExist.score.hasScore())
                            {
                                returnThis.Add(new SolverInterface.Movement(x, y, true, offset, result, boardHash));
                            }
                        }
                        offset++;
                    }

                    x++;
                }
                y++;
            }

            return(returnThis);
        }