Sudoku на Unity. Часть 3.

В этой части я реализую 2 проверки во время генерации: наличие единственного значения внутри группы ячеек, и единственного значения внутри ячейки.

1. Проверка единственного значения внутри группы.

При каждом этапе генерации будет происходить проверка всех групп на наличие единственных значений. На изображении ниже, слева в результате проверки групп было найдено единственное значение. Среди всех ячеек в большой ячейке 9 может быть только в одной ячейке, по этому на следующем этапе генерации установим 9 в соответствующую ячейку.

Sudoku на Unity. Часть 3.

Реализую это в коде:

Добавлю новый класс NextCell, это как раз таки ячейка которая обязательно должна быть следующей на этапе генерации, как на изображении выше вариант 9 был только у одной ячейки в группе.
cell - ячейка, куда устанавливать значение
color - по сути не нужное поле, но я его сделал для демонстрации работы алгоритма, т.е. единственный вариант внутри группы буду делать синим цветом
value - значение, которое будет установлено в ячейку

Sudoku на Unity. Часть 3.

Далее добавлю в CellsController очередь из NextCell и инициализирую.

Sudoku на Unity. Часть 3.

Немного изменил метод SetRandom() в CellsController, добавил проверку на наличие _nextCells, теперь первым делом будут устанавливать значения из очереди.

Sudoku на Unity. Часть 3.

Так же метод SetValueToCell() в CellsController доработал.
- Теперь из принимаемых параметров появился color, так как SetValue() в Cell тоже требует color, для изменения цвета значения. рандомные значения будут черным цветом, а единственные значения в группе ячеек будут синим цветом.
- И добавлен цикл который проходится по всем группам и проверяет наличие единственных значений в них.

Sudoku на Unity. Часть 3.
Sudoku на Unity. Часть 3.

Класс CellGroup увеличился. Теперь он требует _nextCells и размер игрового поля.

Sudoku на Unity. Часть 3.

Остановимся по подробнее на каждом изменении

_variantsValue - размер массива это количество всех возможных вариантов, если поле 9x9 то размер массива будет 9. А значения в этих массивах. Эти значения будут уменьшаться с добавлениям значений в ячейку. Для примера вернемся к первому изображению в статье, где синим контуром выделена большая ячейка. _variantsValue будут такими:_variantsValue[0] = 3 - все 1 в группе, иными словами в трех ячейках в группе в качестве варианта есть 1
_variantsValue[1] = 8
_variantsValue[2] = 8
...
_variantsValue[8] = 1, как раз у нас там была одна 9 в группе.
В AddCell() появилась подписка на OnRemoveVariant внутри класса Cell. Событие вызывается при удалении варианта из ячейки. И как раз в методе RemoveVariant() уменьшается количество этого варианта. Не пугайтесь что нет отписки от события, сейчас весь код рассчитан на один запуск.
Метод CheckForSingleValue(). Тут идет проверка на наличие единственного значения в группе и после нахождения добавляем новый NextCell в очередь. IsNext в Cell для избегания повторного добавления ячейки в очередь.

2. Проверка единственного значения в ячейке.

При каждом этапе генерации будет происходить проверка всех ячеек на наличие единственных значений. На изображении ниже выделенная ячейка из вариантов имеет только 4.

Sudoku на Unity. Часть 3.

Реализую это в коде:

Измененный класс Cell

Sudoku на Unity. Часть 3.

Теперь для Инициализации требуется Queue<NextCell>, так же как для CellsGroup
Разбил метод RemoveVariant() на 2 метода.
TryRemoveVariant() - вызывается в CellGroup вместо RemoveVariant(), и если в _variants содержится вариант, то он удаляется. После происходит проверка, не остался ли только один вариант, если да, то в _nextCells добавляется новый элемент. Цвет красный.
А RemoveVariant() теперь вызывается на прямую тогда, когда нужно удалить варианты при установки значения в ячейку, и соответственно проверять эту ячейку на наличие единственного варианта не нужно.

В Unity ничего настраивать не нужно.

Демонстрация работы генератора.

На данном этапе генератор еще не готов, и весь кроссворд он сгенерировать не всегда сможет. Нужны еще более сложные проверки. На видео вы можете заметить что он генерирует пока с ошибками. Но иногда он может сгенерировать все правильно, где-то в 20% случаев.

4 комментария