Пишем игру 21 (очко). Пример использования 1С и ActiveX

31.08.17

Разработка - Разработка внешних компонент

Пишем игру "очко". Программный код состоит из двух частей: 1.Разработка компоненты работы с графикой на Delphi 2.Логическая реализация игрового процесса на 1С

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Пишем игру 21 (очко). Пример использования 1С и ActiveX (Программный код 1С и Delphi):
.zip 1,49Mb
3
3 Скачать (1 SM) Купить за 1 850 руб.

Часть 1. Пишем компоненту работы с графикой на Delphi.

Для работы с графикой решено использовать внешнюю компоненту, т.к возможности 1С в этом ограничены.

Открываем старый и добрый Дельфи 7, и создаем новый проект.

Переходим на вкладку ActiveX и выбираем ActiveX Form

Вводим имя ActiveX

Для хранения изображений колоды карт будем использовать компонент TImage. Кидаем его на форму.

и загружаем в TImage колоду карт найденную в интернете:

Отображать карты будем на канве формы, предварительно вырезав нужную из TImage. Поэтому, чтобы TImage не светилось - прячем его. Для этого свойство Visible у TImage ставим в False.

Теперь опишем методы работы с изображением. Их будет два:

1. Отображение на канве формы нужной игральной карты.

2. Очистка самой канвы.

Открываем Type Library

И добавляем 2 метода: AddCard и ClearCanvas

у метода AddCard вводим параметры: x,y - это координаты отображения карты. row, column - это номер игральной карты из загруженного нами изображения. Например 0 ряд 2 карта.

Опишем реализацию методов в модуле:

//вырезаем и отображаем на канве нужную нам игральную карту
procedure Tw0rm21.AddCard(x, y, row, colimn: Integer);
const
  h=215; //высота карты
  w=148; //длина карты
begin
  Canvas.CopyRect(Rect(x, y, x+w, y+h), Image1.Canvas, Rect(colimn*w ,row*h, (colimn*w)+w, (row*h)+h));
end;

//Очищаем канву
procedure Tw0rm21.ClearCanvas;
begin
  InvalidateRect(0, nil, true);
end;

На этом реализация компоненты закончена. Вы можете ее в дальнейшем доработать как вам нужно.

Осталось только зарегистировать компоненту.

2. Реализуем игровую логику на 1С

Создаем внешнюю обработку. На форму обработки размещаем наш компонент:

Располагаем контролы (кнопки, надписи) на форме:

И описываем реализацию логики игры:

Перем КолодаКарт, ОбщийСчетИгрок, ОбщийСчетПК;
Перем ИгрокX, ИгрокY,  КомпX, КомпY, ШагКарты;
Перем карта1ПК,	карта2ПК;
Перем СтоимостьКарт;


Процедура КнопкаВыполнитьНажатие(Кнопка)
	Колонка = ПолучитьСлучайноеЧисло(0, 12);
	Ряд = ПолучитьСлучайноеЧисло(0, 3);
	ЭлементыФормы.ЭлементУправления1.AddCard(1,1, Ряд, Колонка);
КонецПроцедуры


Функция ПолучитьСлучайноеЧисло(Мин,Макс) 

	//вместо Randomize 
	Для н = 1 По 100 Цикл 
		Уник = Новый УникальныйИдентификатор; 
	КонецЦикла; 

	//генерируем GUID 
	Уник = СокрЛП(Новый УникальныйИдентификатор); 

	//оставляем только цифры 
	Уник = СтрЗаменить(Уник,"-",""); 
	Уник = СтрЗаменить(Уник,"a",""); 
	Уник = СтрЗаменить(Уник,"b",""); 
	Уник = СтрЗаменить(Уник,"c",""); 
	Уник = СтрЗаменить(Уник,"d",""); 
	Уник = СтрЗаменить(Уник,"e",""); 
	Уник = СтрЗаменить(Уник,"f",""); 

//знаменатель должен иметь такое же количество нулей + 1 
	Знаменатель = 10; 
	Для н = 2 По (СтрДлина(СтрЗаменить(Уник,Символы.НПП,""))) Цикл 
		Знаменатель = Знаменатель * 10; 
	КонецЦикла; 

	Случ = Число(Уник) / Знаменатель; //здесь получается дробное случайное число от 0 до 1 

	//преобразуем его в случайное число из заданного интервала, округляем до целого 
	ЧислоИзИнтервала = Мин(Макс(Окр(Мин + (Макс-Мин)*Случ),Мин),Макс); 

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

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

Процедура РаздатьКартыНажатие(Элемент)
	СтоимостьКарт = "11;2;3;4;5;6;7;8;9;10;2;3;4";
	СтоимостьКарт = СтрЗаменить(СтоимостьКарт, ";", Символы.ПС);
	ЭлементыФормы.ЭлементУправления1.ClearCanvas();
	ИнициализоватьКолоду();
	СчетИгрок = 0;
	СчетПК	= 0;
	ИгрокX = 2; ИгрокY = 3;
	КомпX = 2;  КомпY = 500;
	Шагкарты = 180;
	карта1ПК = Неопределено;
	карта2ПК = Неопределено;	
	
	карта1Игрок =ПолучитьКарту();
	карта2Игрок =ПолучитьКарту();
	СчетИгрок = СчетИгрок + карта1Игрок.Стоимость;
	СчетИгрок = СчетИгрок + карта2Игрок.Стоимость;
	ЭлементыФормы.ЭлементУправления1.AddCard(ИгрокX, ИгрокY, карта1Игрок.Ряд, карта1Игрок.Колонка);
	ИгрокX = ИгрокX + Шагкарты;
	ЭлементыФормы.ЭлементУправления1.AddCard(ИгрокX, ИгрокY, карта2Игрок.Ряд, карта2Игрок.Колонка);
	
	карта1ПК =ПолучитьКарту();
	карта2ПК =ПолучитьКарту();
	ЭлементыФормы.ЭлементУправления1.AddCard(КомпX, КомпY, 4, 2);
	КомпX = КомпX + Шагкарты;
	ЭлементыФормы.ЭлементУправления1.AddCard(КомпX, КомпY, 4, 2);
	
	КомпX = 2;
	
	ОбновитьФорму(Ложь, Истина, Истина);
	
	Если СчетИгрок = 21 Тогда 
		Предупреждение("У ВАС ОЧКО! Вы победили!");
		ОбщийИгрок = ОбщийИгрок + 1;
		ОбновитьФорму(Истина, Ложь, Ложь);
		Возврат;
	КонецЕсли;	

	Если СчетИгрок = 22 Тогда 
		Предупреждение("У ВАС ЗОЛОТОЙ! Вы победили!");
		ОбщийИгрок = ОбщийИгрок + 1;
		ОбновитьФорму(Истина, Ложь, Ложь);
		Возврат;
	КонецЕсли;

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

Процедура ИнициализоватьКолоду()
	Колонка = 13;
	Строк  = 4;
	КолодаКарт = Новый Массив(Строк, Колонка);
	Для а = 0 по Строк-1 Цикл 
		Для б = 0 по Колонка-1 Цикл 
			КолодаКарт[а][б] = 0;
		КонецЦикла;	
	КонецЦикла;	
КонецПроцедуры	

Функция ПолучитьКарту()
	Карта = Новый Структура;
	КартаНайдена = Ложь;
	
	
	Пока КартаНайдена = Ложь Цикл 
		
		Колонка = ПолучитьСлучайноеЧисло(0, 12);
		Ряд = ПолучитьСлучайноеЧисло(0, 3);	

		Если КолодаКарт[Ряд][Колонка] = 0 Тогда 
			Карта.Вставить("Ряд", Ряд);
			Карта.Вставить("Колонка", Колонка);
			Стоимость = СтрПолучитьСтроку(СтоимостьКарт, Колонка+1);
			Карта.Вставить("Стоимость", Число(Стоимость));
			//Сообщить(Стоимость);
			КолодаКарт[Ряд][Колонка] = 1;
			КартаНайдена = Истина;
		КонецЕсли;	
			
	КонецЦикла;	
	
	Возврат(Карта);
КонецФункции	

Процедура ВзятьКартуНажатие(Элемент)
	ИгрокX = ИгрокX + Шагкарты;
	карта = ПолучитьКарту();
	ЭлементыФормы.ЭлементУправления1.AddCard(ИгрокX, ИгрокY, карта.Ряд, карта.Колонка);
	СчетИгрок = СчетИгрок + карта.Стоимость;
	Если СчетИгрок > 21 Тогда 
		Предупреждение("У ВАС ПЕРЕБОР! Вы проиграли!");
		ОбщийПК = ОбщийПК + 1;
		ОбновитьФорму(Истина, Ложь, Ложь);
	КонецЕсли;	
КонецПроцедуры

Процедура ХватитНажатие(Элемент)
	ОбновитьФорму(Ложь, Ложь, Ложь);	
	Пауза(2);
	ЭлементыФормы.ЭлементУправления1.AddCard(КомпX, КомпY, карта1ПК.Ряд, карта1ПК.Колонка);
	СчетПК = СчетПК + карта1ПК.Стоимость;
	Пауза(2);
	КомпX = КомпX + Шагкарты;
	ЭлементыФормы.ЭлементУправления1.AddCard(КомпX, КомпY, карта2ПК.Ряд, карта2ПК.Колонка);
	СчетПК = СчетПК + карта2ПК.Стоимость;
	
	Если СчетПК = 22 Тогда 
		Предупреждение("У Меня ЗОЛОТОЙ! Я Победил!");
		ОбщийИгрок = ОбщийИгрок + 1;
		ОбновитьФорму(Истина, Ложь, Ложь);
		Возврат;
	КонецЕсли;

	
	Пока СчетПК < 17 Цикл  
		Пауза(2);
		КомпX = КомпX + Шагкарты;
		картаПК =ПолучитьКарту();
		ЭлементыФормы.ЭлементУправления1.AddCard(КомпX, КомпY, картаПК.Ряд, картаПК.Колонка);
		СчетПК = СчетПК + картаПК.Стоимость;
	КонецЦикла;
	
	ОбновитьФорму(Истина, Ложь, Ложь);
	
	Если СчетПК > 21 Тогда 
		Предупреждение("У меня перебор! ВЫ ВЫЙГРАЛИ!");
		ОбщийИгрок = ОбщийИгрок + 1;
		Возврат;
	КонецЕсли;	
	
	Если СчетПК = 21 Тогда 
		Предупреждение("У меня ОЧКО! Я победил!");
		ОбщийПК = ОбщийПК + 1;
		Возврат;
	КонецЕсли;
	
	Если СчетПК = СчетИгрок Тогда 
		Предупреждение("Ничья!");
		Возврат;
	КонецЕсли;	
	
	Если СчетПК > СчетИгрок Тогда 
		Предупреждение("Я победил!"); 
		ОбщийПК = ОбщийПК + 1;
		Возврат;
	КонецЕсли;	
	
	Если СчетПК < СчетИгрок Тогда 
		Предупреждение("Вы Победили!");
		ОбщийИгрок = ОбщийИгрок + 1;
		Возврат;
	КонецЕсли;	


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

Процедура Пауза(Секунд)
	
  КонДата = ТекущаяДата() + Секунд;
  Пока ТекущаяДата() < КонДата Цикл
      // ждемссс....
  КонецЦикла;	
  
КонецПроцедуры	

Процедура ПриОткрытии()
	ОбщийИгрок = 0;
	ОбщийПК = 0;
	ОбновитьФорму(Истина, Ложь, Ложь);
КонецПроцедуры

Процедура ОбновитьФорму(РаздатьКарты, ВзятьКарту, Хватит)
	ЭлементыФормы.РаздатьКарты.Доступность = РаздатьКарты;
	ЭлементыФормы.ВзятьКарту.Доступность   = ВзятьКарту;
	ЭлементыФормы.Хватит.Доступность       = Хватит;
КонецПроцедуры

Вызов наших методов из компоненты написанной на Delphi выглядит так: ЭлементыФормы.ЭлементУправления1.AddCard(1,1, Ряд, Колонка); и ЭлементыФормы.ЭлементУправления1.ClearCanvas();

запускаем и проверяем

На этом у меня все! Вы можете сами доработать правила игрового процесса, так как считаете нужным.

Архив с примером выкладываю ниже.

Перед тем как запустить обработку из архива необходимо зарегистрировать компоненту w0rm21Proj1.ocx. 

Готов ответить на вопросы.

Спасибо за внимание!

 

ActiveX Delphi программирование Игры

См. также

Разработка внешних компонент Программист Платформа 1С v8.3 Платформа 1C v8.2 Платные (руб)

Внешняя компонента, позволяющая посылать команды и получать ответы по GraphQL протоколу из 1С.Может быть использована при интеграции. В 1С работает на стороне "клиента".

4600 руб.

27.06.2023    3805    3    0    

5

Разработка внешних компонент Программист Платформа 1С v8.3 1C:Бухгалтерия Платные (руб)

Позволяет автоматизировать работу с картинками. С помощью компоненты можно измерять размер изображений, поворачивать их, наносить водяные знаки, конвертировать из одного формата в другой. Будет очень полезна для интернет-магазинов и всех, кому постоянно требуется работать с различными графическими форматами. Выполнена по технологии NativeAPI. Работает с форматами: jpg (jpeg), png, bmp, gif, tif

3600 руб.

02.09.2010    77773    73    257    

191

Разработка внешних компонент Программист Платформа 1С v8.3 1C:Бухгалтерия Платные (руб)

Внешняя компонента позволяет печатать PDF файлы непосредственно из 1С, не используя при этом сторонних программ. Прекрасно работает на сервере, тонком клиенте и веб-клиенте. Основана на проекте PDFium из состава проекта Chromium/Chrome

1500 руб.

17.09.2018    37125    115    128    

116

Разработка внешних компонент Программист Платформа 1С v8.3 1C:Бухгалтерия 1С:Управление торговлей 11 Платные (руб)

Внешняя компонента для конвертации PDF файлов в картинки без использования дополнительных программ. Работает на сервере и в тонком клиенте.

2400 руб.

25.06.2024    1304    3    4    

3

Разработка внешних компонент Системный администратор Программист Стажер Бесплатно (free)

Библиотека для работы с базами SQLite из 1С на основе внешней компоненты. Для Linux и Windows, бесплатно и с открытым исходным кодом!

14.01.2025    2612    bayselonarrend    14    

48

Разработка внешних компонент Программист Платформа 1С v8.3 1C:Бухгалтерия Россия Бесплатно (free)

В статье описывается приложение-конструктор внешних компонент (native API). Конструктор упрощает процесс разработки за счет удобного добавления всех нужных функций и процедур в графическом режиме, с указанием их параметров и типов параметров. На выходе приложение генерирует готовый код на С++ и Rust и позволяет сразу приступить к реализации, без настройки API компоненты вручную.

04.12.2024    5368    kovalevdmv    26    

77

Разработка внешних компонент Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Некоторые практические аспекты создания внешних компонент на языке С++ для платформы 1С 8.3++.

26.01.2024    7814    starik-2005    40    

47
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. rpgshnik 3838 23.05.17 10:29 Сейчас в теме
Это круто!
Прикрепленные файлы:
DrAku1a; Tolpinski; Romakon92; CyberCerber; TDAlleaMebeli; Smirnov1980; +6 Ответить
2. BackinSoda 23.05.17 10:39 Сейчас в теме
Что это за правило такое - "Золотой" ?
CyberCerber; Smirnov1980; +2 Ответить
3. user621724_Dimav1979 412 23.05.17 10:52 Сейчас в теме
(2) в данном случае это когда два туза сразу выпало...
Smirnov1980; +1 Ответить
7. CyberCerber 879 23.05.17 13:01 Сейчас в теме
(3) Не заметил в коде, а где-то проверяется, что это именно два туза, а не, например 10 + 10 + 2?
8. user621724_Dimav1979 412 23.05.17 17:48 Сейчас в теме
(7) Проверка на Золотой сразу после раздачи первых двух карт, если счет будет 22 - то это и есть 2 туза
4. smirnov.es 21 23.05.17 11:17 Сейчас в теме
Респект таким парням. Ждем реализации на мобильной платформе
CyberCerber; Smirnov1980; madonov; rpgshnik; +4 Ответить
5. Smirnov1980 7 23.05.17 12:07 Сейчас в теме
Это cool !

ps В базовую поставку 1С уже давно требуется пасьянс "косынка" )))).
AlexGroovy; rpgshnik; +2 Ответить
6. CyberCerber 879 23.05.17 13:00 Сейчас в теме
Круто! Лет 10 назад делал тоже 21 на Делфи 7... Интересно, можно будет его теперь в 1С встроить :-)
9. quick 584 23.05.17 22:22 Сейчас в теме
А слабо на делфях в 7-ку сделать форму, да что бы калбэки уходили в 1С? ;)
Если делфи еще интересно, могу посоветовать глянуть https://github.com/WorldException/v7SimpleAddIn
там уже XE2, но сам принцип использовать RTTI для внешних компонент может быть интересен.
rpgshnik; +1 Ответить
10. user621724_Dimav1979 412 24.05.17 04:41 Сейчас в теме
(9) Если кому интересно, могу статью опубликовать отлавливание событий из формы ActiveX в 1С...можно на примере игры морской бой или на примере ведения карты склада ячеистого газобетона
smirnov.es; user657734_YGREEN; Rain88; Trancer64; monsterZE; inf012; +6 Ответить
12. rpgshnik 3838 24.05.17 17:45 Сейчас в теме
(10) Нужно бооооольше уроков
Прикрепленные файлы:
11. user621724_Dimav1979 412 24.05.17 08:11 Сейчас в теме
Выкладываю обработку с компонентой
Прикрепленные файлы:
21_example.zip
wowik; monsterZE; +2 Ответить
13. PerlAmutor 158 24.05.17 21:35 Сейчас в теме
Немного полезной критики =) Delphi? Гхм, пора бы ей уже на покой. Компонента не переносима на другие платформы, про веб-клиент, можно забыть. В безопасном режиме работать не будет. Тут возникает главный вопрос, зачем было связывать это вообще с 1С? Хотите того же самого - используйте HTML5 и JavaScript. К сожалению тоже будет не переносимо, т.к. Internet Explorer нет в Linux. Легких путей, к сожалению, разработчики 1С нам не предлагают. Управляемые Формы, опять же к сожалению, оказались менее управляемые чем Обычные. Надеюсь они когда нибудь встроят в свою платформу браузер Chromium и позволят управлять всем исходным кодом страницы при использовании веб-клиента.

Старайтесь вот так не писать (красиво, но не практично), я обжегся уже на этом
Перем КолодаКарт, ОбщийСчетИгрок, ОбщийСчетПК;


1С настолько тупа, что по Ctrl+Space не находит переменных ОбщийСчетИгрок и ОбщийСчетПК объявленных через запятую.

Только так будет находить:

Перем КолодаКарт;
Перем ОбщийСчетИгрок;
Перем ОбщийСчетПК;
14. DrAku1a 1754 25.05.17 02:34 Сейчас в теме
(13) Delphi - это классика.
HTML5 не обязателен, обычного HTML + JS достаточно будет.
16. orefkov 1156 27.05.17 15:25 Сейчас в теме
(13)
1С настолько тупа, что по Ctrl+Space не находит переменных ОбщийСчетИгрок и ОбщийСчетПК объявленных через запятую.

Ну, может человек снегопат использует и знать не знает ни о ctrl+space, ни о таких тонкостях его использования :)
rpgshnik; +1 Ответить
15. orefkov 1156 27.05.17 13:54 Сейчас в теме
Получение следующей карты сделано конечно плоховато. На такой игре, как очко, конечно сойдёт, так как много карт всё-равно не выходит, но для игр с длинной раздачей - для последних карт может кучу раз цикл вхолостую крутить, пока попадёт в еще не выданные карты. Обычно делают нормальное тасование колоды. Для 1С например, можно сделать ТЗ с колонками ЗначениеКарты и КлючСортировки. Заполнить КлючСортировки случайными числами и отсортировать по ней. Потом брать последовательно карты из отсортированной ТЗ.
rpgshnik; +1 Ответить
17. user621724_Dimav1979 412 27.05.17 16:02 Сейчас в теме
(15) Александр полностью с вами согласен. Алгоритм можно оптимизировать до бесконечности...но главная цель данной статьи не в алгоритме игры...а в навыках применения компоненты актив икс
asmuk; Fox-trot; +2 Ответить
Оставьте свое сообщение