Загрузка данных
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ШиринаИгровогоПоля = 9;
ВысотаИгровогоПоля = 9;
КонецПроцедуры
#Область СозданиеИгровогоПоля
&НаСервере
Процедура НачатьИгруНаСервере()
// Удаляем старое игровое поле, если оно существует
ИгровоеПоле = Элементы.Найти("ИгровоеПоле");
Если ИгровоеПоле <> Неопределено Тогда
ЭтаФорма.Элементы.Удалить(ИгровоеПоле);
КонецЕсли;
// Создаем корневую группу игрового поля
ИгровоеПоле = ЭтаФорма.Элементы.Добавить("ИгровоеПоле", Тип("ГруппаФормы"), ЭтаФорма);
ИгровоеПоле.Вид = ВидГруппыФормы.ОбычнаяГруппа;
ИгровоеПоле.Отображение = ОтображениеОбычнойГруппы.Нет;
ИгровоеПоле.ОтображатьЗаголовок = Ложь;
ИгровоеПоле.Группировка = ГруппировкаПодчиненныхЭлементовФормы.ГоризонтальнаяВсегда;
ИгровоеПоле.РазрешитьИзменениеСостава = Истина;
// Динамическое создание сетки 9x9
Для X = 1 По ШиринаИгровогоПоля Цикл
Группа = ЭтаФорма.Элементы.Добавить("Ряд" + X, Тип("ГруппаФормы"), Элементы.ИгровоеПоле);
Группа.Вид = ВидГруппыФормы.ОбычнаяГруппа;
Группа.Видимость = Истина;
Для Y = 1 По ВысотаИгровогоПоля Цикл
ИмяЯчейки = "кн_" + Y + "_" + X;
НоваяКнопка = ЭтаФорма.Элементы.Добавить(ИмяЯчейки, Тип("ДекорацияФормы"), Группа);
НоваяКнопка.Вид = ВидДекорацииФормы.Картинка;
НоваяКнопка.Высота = 1;
НоваяКнопка.Ширина = 2;
НоваяКнопка.Видимость = Истина;
НоваяКнопка.КонтекстноеМеню.Видимость = Истина;
НоваяКнопка.Рамка = Новый Рамка(ТипРамкиЭлементаУправления.Выпуклая, 3);
НоваяКнопка.Гиперссылка = Истина;
НоваяКнопка.УстановитьДействие("Нажатие", "КнопкаНажатие");
// Добавление пункта контекстного меню "НеЗнаю"
КомандаНеЗнаю = ЭтаФорма.Элементы.Добавить(ИмяЯчейки + "КонтекстноеМенюНеЗнаю", Тип("КнопкаФормы"), НоваяКнопка.КонтекстноеМеню);
КомандаНеЗнаю.ИмяКоманды = "НеЗнаю";
КомандаНеЗнаю.Картинка = БиблиотекаКартинок.Справка;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура НачатьИгру(Команда)
НачатьИгруНаСервере();
КонецПроцедуры
#КонецОбласть
#Область ВводДанныхИПодсказки
&НаКлиенте
Процедура КнопкаНажатие(Элемент)
Если Элемент.Заголовок <> "" Тогда
// Ввод или очистка ячейки
КонецЕсли;
Цифра = "";
ВвестиСтроку(Цифра, "Введите цифру (1-9):", 1);
// Проверка корректности ввода
Если Цифра <> "" И (Число(Цифра) < 1 Или Число(Цифра) > 9) Тогда
ПоказатьПредупреждение(, "Введите цифру от 1 до 9!");
Возврат;
КонецЕсли;
Элемент.Заголовок = Цифра;
Элемент.ТекстНеВыбраннойКартинки = Цифра;
Тек_X = Сред(Элемент.Имя, 6, 1); // Колонка
Тек_Y = Сред(Элемент.Имя, 4, 1); // Строка
ИзменитьСостояниеПоляИгры(Тек_X, Тек_Y, Цифра);
КонецПроцедуры
&НаКлиенте
Процедура НеЗнаю(Команда)
Тек_X = Сред(ТекущийЭлемент.Имя, 6, 1); // Колонка
Тек_Y = Сред(ТекущийЭлемент.Имя, 4, 1); // Строка
ИмяПоля = "кн_" + Тек_Y + "_" + Тек_X;
Если Элементы[ИмяПоля].Заголовок <> "" Тогда
Сообщить("Нельзя менять значение заполненной ячейки");
Возврат;
КонецЕсли;
// Массив возможнастей (1..9)
М = Новый Массив(10);
Для ИНД = 1 По 9 Цикл
М[ИНД] = Строка(ИНД);
КонецЦикла;
// Исключаем цифры из текущей строки
Для X = 1 По ШиринаИгровогоПоля Цикл
ИмяПоляПроверки = "кн_" + Тек_Y + "_" + X;
ЗначЦифра = Элементы[ИмяПоляПроверки].Заголовок;
Если ЗначЦифра <> "" Тогда
М[Число(ЗначЦифра)] = "";
КонецЕсли;
КонецЦикла;
// Исключаем цифры из текущего столбца
Для Y = 1 По ВысотаИгровогоПоля Цикл
ИмяПоляПроверки = "кн_" + Y + "_" + Тек_X;
ЗначЦифра = Элементы[ИмяПоляПроверки].Заголовок;
Если ЗначЦифра <> "" Тогда
М[Число(ЗначЦифра)] = "";
КонецЕсли;
КонецЦикла;
// Исключаем цифры из текущего квадрата 3x3
НачX = Цел((Число(Тек_X) - 1) / 3) * 3 + 1;
НачY = Цел((Число(Тек_Y) - 1) / 3) * 3 + 1;
Для X = НачX По НачX + 2 Цикл
Для Y = НачY По НачY + 2 Цикл
ИмяПоляПроверки = "кн_" + Y + "_" + X;
ЗначЦифра = Элементы[ИмяПоляПроверки].Заголовок;
Если ЗначЦифра <> "" Тогда
М[Число(ЗначЦифра)] = "";
КонецЕсли;
КонецЦикла;
КонецЦикла;
// Формируем список возможных значений
СПС = Новый СписокЗначений;
Для ИНД = 1 По 9 Цикл
Если М[ИНД] <> "" Тогда
СПС.Добавить(М[ИНД]);
КонецЕсли;
КонецЦикла;
ДопПараметры = Новый Структура;
ДопПараметры.Вставить("Тек_X", Тек_X);
ДопПараметры.Вставить("Тек_Y", Тек_Y);
Оповещение = Новый ОписаниеОповещения("ПослеВыбораЭлемента", ЭтотОбъект, ДопПараметры);
СПС.ПоказатьВыборЭлемента(Оповещение, "Выберите доступную цифру");
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораЭлемента(ВыбранныйЭлемент, СписокПараметров) Экспорт
Если ВыбранныйЭлемент = Неопределено Тогда
Сообщить("Цифра не выбрана");
Иначе
Цифра = ВыбранныйЭлемент.Значение;
ИмяПоля = "кн_" + СписокПараметров.Тек_Y + "_" + СписокПараметров.Тек_X;
Элементы[ИмяПоля].Заголовок = Цифра;
Элементы[ИмяПоля].ТекстНеВыбраннойКартинки = Цифра;
ИзменитьСостояниеПоляИгры(СписокПараметров.Тек_X, СписокПараметров.Тек_Y, Цифра);
КонецЕсли;
КонецПроцедуры
#КонецОбласть
#Область СохранениеИВосстановление
&НаСервере
Процедура СохранитьИгруНаСервере()
М = Новый Массив(ВысотаИгровогоПоля, ШиринаИгровогоПоля);
Для X = 1 По ШиринаИгровогоПоля Цикл
Для Y = 1 По ВысотаИгровогоПоля Цикл
ИмяПоля = "кн_" + Y + "_" + X;
М[Y - 1][X - 1] = Элементы[ИмяПоля].Заголовок;
КонецЦикла;
КонецЦикла;
МенеджерЗаписи = РегистрыСведений.Результаты.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Игра = Новый ХранилищеЗначения(М);
МенеджерЗаписи.Записать();
КонецПроцедуры
&НаКлиенте
Процедура СохранитьИгру(Команда)
СохранитьИгруНаСервере();
ПоказатьОповещениеПользователя("Успешно", , "Состояние игры сохранено!");
КонецПроцедуры
&НаСервере
Процедура ВосстановитьИгруНаСервере()
МенеджерЗаписи = РегистрыСведений.Результаты.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Прочитать();
Если Не МенеджерЗаписи.Выбран() Тогда
Возврат;
КонецЕсли;
М = МенеджерЗаписи.Игра.Получить();
Если ТипЗнч(М) <> Тип("Массив") Тогда
Возврат;
КонецЕсли;
Для X = 1 По ШиринаИгровогоПоля Цикл
Для Y = 1 По ВысотаИгровогоПоля Цикл
ИмяПоля = "кн_" + Y + "_" + X;
ЗначениеЯчейки = М[Y - 1][X - 1];
Элементы[ИмяПоля].Заголовок = ЗначениеЯчейки;
Элементы[ИмяПоля].ТекстНеВыбраннойКартинки = ЗначениеЯчейки;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ВосстановитьИгру(Команда)
ВосстановитьИгруНаСервере();
ИзменитьСостояниеПоляИгры(1, 1, ""); // Перерасчет подсветки
КонецПроцедуры
&НаКлиенте
Процедура ОчиститьПоле(Команда)
Для X = 1 По ШиринаИгровогоПоля Цикл
Для Y = 1 По ВысотаИгровогоПоля Цикл
ИмяПоля = "кн_" + Y + "_" + X;
Элементы[ИмяПоля].Заголовок = "";
Элементы[ИмяПоля].ТекстНеВыбраннойКартинки = "";
Элементы[ИмяПоля].ЦветФона = ЦветаСтиля.ФормаЦветФона;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
#КонецОбласть
#Область ВалидацияИПодсветка
&НаКлиенте
Процедура ИзменитьСостояниеПоляИгры(Тек_X, Тек_Y, Цифра)
// 1. Сброс цвета фона ячеек к исходному
Для X = 1 По 9 Цикл
Для Y = 1 По 9 Цикл
Элементы["кн_" + Y + "_" + X].ЦветФона = ЦветаСтиля.ФормаЦветФона;
КонецЦикла;
КонецЦикла;
// 2. Проверка дубликатов в строках
Для Y = 1 По 9 Цикл
Встреченные = Новый Соответствие;
ЕстьДубликат = Ложь;
Для X = 1 По 9 Цикл
Val = Элементы["кн_" + Y + "_" + X].Заголовок;
Если Val <> "" Тогда
Если Встреченные[Val] <> Неопределено Тогда
ЕстьДубликат = Истина;
Иначе
Встреченные.Вставить(Val, Истина);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ЕстьДубликат Тогда
Для X = 1 По 9 Цикл
Элементы["кн_" + Y + "_" + X].ЦветФона = WebЦвета.СветлоРозовый;
КонецЦикла;
КонецЕсли;
КонецЦикла;
// 3. Проверка дубликатов в столбцах
Для X = 1 По 9 Цикл
Встреченные = Новый Соответствие;
ЕстьДубликат = Ложь;
Для Y = 1 По 9 Цикл
Val = Элементы["кн_" + Y + "_" + X].Заголовок;
Если Val <> "" Тогда
Если Встреченные[Val] <> Неопределено Тогда
ЕстьДубликат = Истина;
Иначе
Встреченные.Вставить(Val, Истина);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ЕстьДубликат Тогда
Для Y = 1 По 9 Цикл
Элементы["кн_" + Y + "_" + X].ЦветФона = WebЦвета.СветлоРозовый;
КонецЦикла;
КонецЕсли;
КонецЦикла;
// 4. Проверка дубликатов в блоках 3x3
Для BlkRow = 0 По 2 Цикл
Для BlkCol = 0 По 2 Цикл
Встреченные = Новый Соответствие;
ЕстьДубликат = Ложь;
Для Y = BlkRow * 3 + 1 По BlkRow * 3 + 3 Цикл
Для X = BlkCol * 3 + 1 По BlkCol * 3 + 3 Цикл
Val = Элементы["кн_" + Y + "_" + X].Заголовок;
Если Val <> "" Тогда
Если Встреченные[Val] <> Неопределено Тогда
ЕстьДубликат = Истина;
Иначе
Встреченные.Вставить(Val, Истина);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Если ЕстьДубликат Тогда
Для Y = BlkRow * 3 + 1 По BlkRow * 3 + 3 Цикл
Для X = BlkCol * 3 + 1 По BlkCol * 3 + 3 Цикл
Элементы["кн_" + Y + "_" + X].ЦветФона = WebЦвета.СветлоРозовый;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЦикла;
// 5. Окрашивание корректных заполненных областей в зеленый цвет
Для Y = 1 По 9 Цикл
ЗаполненоПолностью = Истина;
Для X = 1 По 9 Цикл
Если Элементы["кн_" + Y + "_" + X].Заголовок = "" Тогда
ЗаполненоПолностью = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Если ЗаполненоПолностью И Элементы["кн_" + Y + "_1"].ЦветФона <> WebЦвета.СветлоРозовый Тогда
Для X = 1 По 9 Цикл
Элементы["кн_" + Y + "_" + X].ЦветФона = WebЦвета.СветлоЗеленый;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
#КонецОбласть