Difficulty typically refers to the amount of unnumbered spaces available at the start from what i've seen in sudoku. Why don't you start with a fully solved randomly created board, then from there start removing numbers, and starting from the most solved row/col/box to the least solved. Then you could have a variable to check to see if the removed spaces has reached the limit.
I would suggest basically starting with a solved world, a predecessor function that finds which row/col/box is the most solved i.e. has the most available correct numbers. And you can determine its meaning across the 3 different areas as you wish. Then a successor function that removes a space from the current row/col/box as well as updates each of those to reflect the update. Like say you have an int array for rows 0-8, another for cols 0-8, and box 0-8. Rows go from 0->8 from top to bot, cols 0->8 left to right, boxes 0->8 to the right then down a row and repeat. Start one off each with 9's in the indices. Each time you remove a number, say you remove (row#,col#). Then put row[row#]--
, col[col#]--
and box[(row#/3)*3 + col#/3]--
. Then increment a removed number counter and check that against your difficulty which is defied by total possible removed numbers. *Notice the (row#/3) is integer division.