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

31.08.17

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

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

Файлы

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

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

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

Оформите подписку на компанию для решения рабочих задач

Оформить подписку и скачать решение со скидкой

Часть 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:Бухгалтерия 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия 3.0 Платные (руб)

Внешняя компонента позволяет работать c TWAIN-совместимым оборудованием (сканерами, камерами) . Полностью совместима со стандартной TWAIN-компонентой из БСП и может применяться как ее замена без изменения вызовов, при этом может работать с 64-разрядной платформой, а так же имеет расширенную функциональность, например, сохранение результата непосредственно в PDF без использования сторонних утилит. Прекрасно работает на сервере, тонком клиенте и веб-клиенте (проверена работа в браузерах Google Chrome, Mozilla Firefox и Microsoft Internet Explorer).

3600 руб.

12.05.2020    30175    140    100    

96

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

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

3600 руб.

02.09.2010    78883    74    280    

192

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

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

3000 руб.

17.09.2018    37904    116    128    

119

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

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

14.01.2025    3578    bayselonarrend    14    

52

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

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

04.12.2024    6982    kovalevdmv    27    

81

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

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

2400 руб.

25.06.2024    1671    3    5    

3

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

А давайте запилим 8.3.26 до релиза, или оповещение с сервера...

19.02.2024    7585    starik-2005    38    

59

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

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

26.01.2024    8715    starik-2005    40    

48
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. rpgshnik 3882 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 414 23.05.17 10:52 Сейчас в теме
(2) в данном случае это когда два туза сразу выпало...
Smirnov1980; +1 Ответить
7. CyberCerber 886 23.05.17 13:01 Сейчас в теме
(3) Не заметил в коде, а где-то проверяется, что это именно два туза, а не, например 10 + 10 + 2?
8. user621724_Dimav1979 414 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 886 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 414 24.05.17 04:41 Сейчас в теме
(9) Если кому интересно, могу статью опубликовать отлавливание событий из формы ActiveX в 1С...можно на примере игры морской бой или на примере ведения карты склада ячеистого газобетона
smirnov.es; user657734_YGREEN; Rain88; Trancer64; monsterZE; inf012; +6 Ответить
12. rpgshnik 3882 24.05.17 17:45 Сейчас в теме
(10) Нужно бооооольше уроков
Прикрепленные файлы:
11. user621724_Dimav1979 414 24.05.17 08:11 Сейчас в теме
Выкладываю обработку с компонентой
Прикрепленные файлы:
21_example.zip
wowik; monsterZE; +2 Ответить
13. PerlAmutor 160 24.05.17 21:35 Сейчас в теме
Немного полезной критики =) Delphi? Гхм, пора бы ей уже на покой. Компонента не переносима на другие платформы, про веб-клиент, можно забыть. В безопасном режиме работать не будет. Тут возникает главный вопрос, зачем было связывать это вообще с 1С? Хотите того же самого - используйте HTML5 и JavaScript. К сожалению тоже будет не переносимо, т.к. Internet Explorer нет в Linux. Легких путей, к сожалению, разработчики 1С нам не предлагают. Управляемые Формы, опять же к сожалению, оказались менее управляемые чем Обычные. Надеюсь они когда нибудь встроят в свою платформу браузер Chromium и позволят управлять всем исходным кодом страницы при использовании веб-клиента.

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


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

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

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

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