Загрузка данных


////////////////////////////////////////////////////////////////////////////////
// СОЗДАНИЕ ФОРМЫ
////////////////////////////////////////////////////////////////////////////////

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    СоздатьИгровоеПоле();

КонецПроцедуры


////////////////////////////////////////////////////////////////////////////////
// СОЗДАНИЕ ИГРОВОГО ПОЛЯ 9 X 9
////////////////////////////////////////////////////////////////////////////////

&НаСервере
Процедура СоздатьИгровоеПоле()

    ДополнительныеРеквизиты = Новый Массив;

    Для НомерЯчейки = 1 По 81 Цикл

        ИмяРеквизита = "Ячейка" + Строка(НомерЯчейки);

        НовыйРеквизит = Новый РеквизитФормы(
            ИмяРеквизита,
            Новый ОписаниеТипов("Число"));

        ДополнительныеРеквизиты.Добавить(НовыйРеквизит);

    КонецЦикла;

    ИзменитьРеквизиты(ДополнительныеРеквизиты);

    ГруппаПоля = Элементы.Добавить(
        "ИгровоеПоле",
        Тип("ГруппаФормы"));

    ГруппаПоля.Вид = ВидГруппыФормы.ОбычнаяГруппа;
    ГруппаПоля.Группировка =
        ГруппировкаПодчиненныхЭлементовФормы.Горизонтальная;

    Для СтрокаПоля = 1 По 9 Цикл

        Для СтолбецПоля = 1 По 9 Цикл

            НомерЯчейки =
                (СтрокаПоля - 1) * 9 + СтолбецПоля;

            ИмяЭлемента = "Поле" + Строка(НомерЯчейки);
            ИмяРеквизита = "Ячейка" + Строка(НомерЯчейки);

            ПолеВвода = Элементы.Добавить(
                ИмяЭлемента,
                Тип("ПолеФормы"),
                ГруппаПоля);

            ПолеВвода.Вид = ВидПоляФормы.ПолеВвода;
            ПолеВвода.ПутьКДанным = ИмяРеквизита;
            ПолеВвода.Заголовок = "";

        КонецЦикла;

    КонецЦикла;

КонецПроцедуры


////////////////////////////////////////////////////////////////////////////////
// НАЧАТЬ ИГРУ
////////////////////////////////////////////////////////////////////////////////

&НаКлиенте
Процедура НачатьИгру(Команда)

    ОчиститьПолеНаСервере();

    ПодключитьОбработчикОжидания(
        "АвтоматическиСохранитьИгру",
        60,
        Истина);

    Сообщить("Новая игра началась!");

КонецПроцедуры


////////////////////////////////////////////////////////////////////////////////
// ОЧИСТИТЬ ПОЛЕ
////////////////////////////////////////////////////////////////////////////////

&НаКлиенте
Процедура ОчиститьПоле(Команда)

    ОчиститьПолеНаСервере();

    Сообщить("Игровое поле очищено.");

КонецПроцедуры


&НаСервере
Процедура ОчиститьПолеНаСервере()

    Для НомерЯчейки = 1 По 81 Цикл

        ИмяРеквизита = "Ячейка" + Строка(НомерЯчейки);

        ЭтаФорма[ИмяРеквизита] = 0;

    КонецЦикла;

КонецПроцедуры


////////////////////////////////////////////////////////////////////////////////
// ПРОВЕРКА ДОПУСТИМОСТИ ЧИСЛА
////////////////////////////////////////////////////////////////////////////////

&НаСервере
Функция ЧислоДопустимо(НомерСтроки, НомерСтолбца, ЧислоДляПроверки)

    Если ЧислоДляПроверки < 1
        Или ЧислоДляПроверки > 9 Тогда

        Возврат Ложь;

    КонецЕсли;

    Для Столбец = 1 По 9 Цикл

        Если Столбец <> НомерСтолбца Тогда

            НомерЯчейки =
                (НомерСтроки - 1) * 9 + Столбец;

            ЗначениеЯчейки =
                ЭтаФорма["Ячейка" + Строка(НомерЯчейки)];

            Если ЗначениеЯчейки = ЧислоДляПроверки Тогда

                Возврат Ложь;

            КонецЕсли;

        КонецЕсли;

    КонецЦикла;

    Для Строка = 1 По 9 Цикл

        Если Строка <> НомерСтроки Тогда

            НомерЯчейки =
                (Строка - 1) * 9 + НомерСтолбца;

            ЗначениеЯчейки =
                ЭтаФорма["Ячейка" + Строка(НомерЯчейки)];

            Если ЗначениеЯчейки = ЧислоДляПроверки Тогда

                Возврат Ложь;

            КонецЕсли;

        КонецЕсли;

    КонецЦикла;

    НачалоСтрокиКвадрата =
        Цел((НомерСтроки - 1) / 3) * 3 + 1;

    НачалоСтолбцаКвадрата =
        Цел((НомерСтолбца - 1) / 3) * 3 + 1;

    Для СмещениеСтроки = 0 По 2 Цикл

        Для СмещениеСтолбца = 0 По 2 Цикл

            СтрокаКвадрата =
                НачалоСтрокиКвадрата + СмещениеСтроки;

            СтолбецКвадрата =
                НачалоСтолбцаКвадрата + СмещениеСтолбца;

            Если СтрокаКвадрата = НомерСтроки
                И СтолбецКвадрата = НомерСтолбца Тогда

                Продолжить;

            КонецЕсли;

            НомерЯчейки =
                (СтрокаКвадрата - 1) * 9
                + СтолбецКвадрата;

            ЗначениеЯчейки =
                ЭтаФорма["Ячейка" + Строка(НомерЯчейки)];

            Если ЗначениеЯчейки = ЧислоДляПроверки Тогда

                Возврат Ложь;

            КонецЕсли;

        КонецЦикла;

    КонецЦикла;

    Возврат Истина;

КонецФункции


////////////////////////////////////////////////////////////////////////////////
// ПОДСКАЗКА
////////////////////////////////////////////////////////////////////////////////

&НаКлиенте
Процедура НеЗнаю(Команда)

    Элемент = ЭтаФорма.ТекущийЭлемент;

    Если Элемент = Неопределено Тогда

        Сообщить("Сначала выберите ячейку.");
        Возврат;

    КонецЕсли;

    Если Лев(Элемент.ПутьКДанным, 6) <> "Ячейка" Тогда

        Сообщить("Выберите ячейку игрового поля.");
        Возврат;

    КонецЕсли;

    ИмяРеквизита = Элемент.ПутьКДанным;

    НомерЯчейки = Число(
        Сред(ИмяРеквизита, 7));

    НомерСтроки = Цел((НомерЯчейки - 1) / 9) + 1;

    НомерСтолбца =
        НомерЯчейки - (НомерСтроки - 1) * 9;

    Если ЭтаФорма[ИмяРеквизита] <> 0 Тогда

        Сообщить("Ячейка уже заполнена.");
        Возврат;

    КонецЕсли;

    ВозможныеЧисла = "";

    Для ЧислоДляПроверки = 1 По 9 Цикл

        Если ЧислоДопустимо(
            НомерСтроки,
            НомерСтолбца,
            ЧислоДляПроверки) Тогда

            Если ВозможныеЧисла <> "" Тогда

                ВозможныеЧисла =
                    ВозможныеЧисла + ", ";

            КонецЕсли;

            ВозможныеЧисла =
                ВозможныеЧисла
                + Строка(ЧислоДляПроверки);

        КонецЕсли;

    КонецЦикла;

    Если ВозможныеЧисла = "" Тогда

        Сообщить("Нет допустимых чисел для этой ячейки.");

    Иначе

        Сообщить(
            "Возможные числа: " + ВозможныеЧисла);

    КонецЕсли;

КонецПроцедуры


////////////////////////////////////////////////////////////////////////////////
// СОХРАНЕНИЕ ИГРЫ
////////////////////////////////////////////////////////////////////////////////

&НаКлиенте
Процедура СохранитьИгру(Команда)

    СохранитьИгруНаСервере();

    Сообщить("Игра сохранена.");

КонецПроцедуры


&НаСервере
Процедура СохранитьИгруНаСервере()

    ДанныеИгры = Новый Массив;

    Для НомерЯчейки = 1 По 81 Цикл

        ИмяРеквизита =
            "Ячейка" + Строка(НомерЯчейки);

        ДанныеИгры.Добавить(
            ЭтаФорма[ИмяРеквизита]);

    КонецЦикла;

    ХранилищеИгры =
        Новый ХранилищеЗначения(ДанныеИгры);

    ЗаписьРегистра =
        РегистрыСведений.Результаты.СоздатьМенеджерЗаписи();

    ЗаписьРегистра.Ключ = "Судоку";
    ЗаписьРегистра.Игра = ХранилищеИгры;

    ЗаписьРегистра.Записать();

КонецПроцедуры


////////////////////////////////////////////////////////////////////////////////
// ВОССТАНОВЛЕНИЕ ИГРЫ
////////////////////////////////////////////////////////////////////////////////

&НаКлиенте
Процедура ВосстановитьИгру(Команда)

    ВосстановитьИгруНаСервере();

    Сообщить("Восстановление игры завершено.");

КонецПроцедуры


&НаСервере
Процедура ВосстановитьИгруНаСервере()

    ЗаписьРегистра =
        РегистрыСведений.Результаты.СоздатьМенеджерЗаписи();

    ЗаписьРегистра.Ключ = "Судоку";
    ЗаписьРегистра.Прочитать();

    Если Не ЗаписьРегистра.Выбран() Тогда

        Сообщить("Сохранённая игра не найдена.");
        Возврат;

    КонецЕсли;

    ДанныеИгры = ЗаписьРегистра.Игра.Получить();

    Если ДанныеИгры = Неопределено Тогда

        Сообщить("Сохранение пустое.");
        Возврат;

    КонецЕсли;

    Если ДанныеИгры.Количество() <> 81 Тогда

        Сообщить("Сохранённые данные повреждены.");
        Возврат;

    КонецЕсли;

    Для НомерЯчейки = 1 По 81 Цикл

        ИмяРеквизита =
            "Ячейка" + Строка(НомерЯчейки);

        ЭтаФорма[ИмяРеквизита] =
            ДанныеИгры[НомерЯчейки - 1];

    КонецЦикла;

КонецПроцедуры


////////////////////////////////////////////////////////////////////////////////
// АВТОМАТИЧЕСКОЕ СОХРАНЕНИЕ РАЗ В МИНУТУ
////////////////////////////////////////////////////////////////////////////////

&НаКлиенте
Процедура АвтоматическиСохранитьИгру()

    СохранитьИгруНаСервере();

КонецПроцедуры