Я бы написал интерфейс с функциями, которые получают поле sudoku и возвращают true / false, если это решение.
Затем реализуйте ограничения как отдельные классы проверки для каждого ограничения.
Для проверки просто переберите все классы ограничений, и когда все пройдут, судоку будет правильным. Для ускорения поместите те, которые, скорее всего, потерпят неудачу, и остановитесь на первом результате, который указывает на недопустимое поле.
Довольно общий шаблон. ; -)
Конечно, вы можете улучшить это, чтобы получить подсказки, какое поле предположительно неверно и т. Д.
Первое ограничение, просто проверьте, все ли поля заполнены. (Простой цикл)
Вторая проверка, все ли числа в каждом блоке (вложенные циклы)
Третья проверка полных строк и столбцов (почти та же процедура, что и выше, но другая схема доступа)