1с 7.7 генератор случайных чисел. Случайность, совпадение, закономерность. Генератор случайных чисел

21
//Функция формирует удобное для чтения представление значений. // Примеры форматирования чисел ЗначФормат = Формат(123456.789, " ЧЦ=10; ЧДЦ=2"); // ЗначФормат = " 123 456,79" ЗначФормат = Формат(123456.789, " ЧГ=0; ЧДЦ=2"); // Знач 16
Полнотекстовый поиск - позволит найти текстовую информацию, размещенную практически в любом месте используемой конфигурации. При этом искать нужные данные можно либо по всей конфигурации в целом, либо сузив... 8
" Момент времени" - виртуальное поле, не хранится в базе данных. Содержит объект МоментВремени (который включает в себя дату и ССЫЛКУ НА ДОКУМЕНТ) В 7.7 было понятие ПозицияДокумента, а в 8.x Момент времени Для получения... 6
Для 8.х НайтиПоСсылкам (FindDataByRef) Синтаксис: НайтиПоСсылкам (Список ссылок) Параметры: Список ссылок Обязательный Тип: Массив. Массив со списком ссылок на объекты, ссылки на которые нужно найти. ...


Ключевые слова: генератор, случайный, чисел, число, алгоритм, random, randomize, распределение, равномерное, лотерея

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

Нужно: сгенерить некоторое кол-во случайных шестибуквенных сочетаний из любых букв алфвита, к этому примешать некоторые кол-во вариантов, при которых слово все-таки можно сложить, например "ньккоя" - слово складывается, а "кавпры" - явно не подходит.

Дополнительное условие: все эти варианты (правильные и нет) нужно пронумеровать, чтобы при получении "призовой" карточки можно было бы сверить номер (а был ли такой).

Казалось бы, причем здесь 1С? Так вот учет этих карточек и призов желают добавить в учетную прогу, ну и заодно попросили нагенерить случайных комбинаций (ну не вручную же их сочинять).
Для каждой акции комбинации генерятся один раз, потом по ним изготавливают карточки, т.е. в следующий раз слово будет другое и т.д.

В общем задача сводится к следующему:
1. Генерить случайные числа, желательно с большим разбросом.
2. По числу вычислять комбинацию букв (т.е. найти какое-то соответствие между возможныи комбинациями и их номерами).
3. Пункт обратный предыдущему - по слову проверять номер комбинации.

Решение:
1. т.к. генератор от avb и NS давал маленький разброс случайных чисел, пришлось поюзать немного другой алгоритм:

Function Random() if emptyvalue(randSeed) = 1 then randSeed = _getperformancecounter(); endif; randSeed=(a*randSeed+c)%m; return randSeed; endfunction

Здесь:
a=1664525; c=1013904223; m=4294967296;
последняя переменная - 2 в 32-й степени, две другие - рекомендуемые для таких целей коэффициенты

Ограничение по максимальному значению 2^32 выбрано исходя из максимального кол-ва комбинаций (для обрезанного алфавита в 28 букв и слов по 7, т.к. в реальной задаче их именно 7, общее число комбинаций составит 28^7, таким образом выбранное ограничение лежит примерно посередине интервала, что вполне достаточно для выборки 20-30 тыс. вариантов)

Нам также понадобится еще одна вспомогательная функция - возведение в целочисленную положительную степень:

Функция Степень(Знач а,Знач б, Рез=1 ) Если б>0 Тогда Рез=Рез*а; б=б-1 ; Степень(а,б,Рез); Возврат Рез; Иначе Возврат Рез; КонецЕсли; КонецФункции

Здесь: а - основание степени, б - показатель степени, Рез - результат

2. Выявить зависимость между последовательно расположенными комбинациями, оказалось на удивление простым:

расположив, ряд элементов по порядку, я выявил схожесть расположения символов с системой счисления, только не десятичной, а в данном случае "шестиричной" (по кол-ву символов в результирующем "слове").
Таким образом, для вычисления комбинации по ее номеру нужно было преобразовать ее номер в эту самую систему счисления.

Для нашей системы счисления, основанием будут являться степени шестерки, т.е. для получения первого слева разряда, необходимо разделить номер нашей комбинации на 6 в 5-й степени, затем остаток от деления - на 6 в 4-й и т.д.

Таким образом, получаем набор из шести чисел, которые по сути являются порядковыми номерами букв в нашем алфавите.

Получившийся код:

Функция ПолучитьСимволы(Поз,ТекСимв=1 ,СимСтр="") Если ТекСимв<к Тогда Делитель=Степень(СтрДлина(Буквы),к-ТекСимв); ТекОст=Поз%Делитель; СимСтр=Строка(СимСтр)+Сред(Буквы,Цел(Поз/Делитель+?(ТекОст>0 ,1 ,0 )),1 ); ПолучитьСимволы(ТекОст,ТекСимв+1 ,СимСтр); Возврат СимСтр; Иначе СимСтр=СимСтр+Сред(Буквы,(?(Поз=0 ,СтрДлина(Буквы),Поз)),1 ); Возврат СимСтр; КонецЕсли; КонецФункции

Здесь:
Поз - номер комбинации (псевдослучайное число)
ТекСимв - текущий обрабатываемый символ
СимСтр - резльтирующая строка символов
Буквы = строка, содержащая буквы алфавита в стандартном порядке ("абв...юя")
к - число символов в искомом слове (в данном случае = 6)

3. Обратное преобразование также тривиально:

Функция ПолучитьКомбинацию(Слово,ТекСимв=0 ,Поз=0 ) НомСимв=Найти(Буквы,Сред(Слово,к-ТекСимв,1 )); Если ТекСимв>0 Тогда Если ТекСимв<к Тогда Поз=Поз+(НомСимв-1 )*Степень(СтрДлина(Буквы),ТекСимв); ПолучитьКомбинацию(Слово,ТекСимв+1 ,Поз); Иначе Возврат Поз; КонецЕсли; Иначе Поз=?(НомСимв=СтрДлина(Буквы),0 ,НомСимв); ПолучитьКомбинацию(Слово,ТекСимв+1 ,Поз); Возврат Поз; КонецЕсли; КонецФункции

Здесь:
Слово - комбинация символов, номер которой ищем
ТекСимв - текущий обрабатываемый символ (по сути разряд шестиричного "числа")
Поз - искомый номер комбинации

Премешать N чисел:

Для а=1 по N цикл массив[а]=а; Конеццикла; Для а=1 по N-1 цикл Сл=Случ(а,N);// Целое случайное число в интервале [а..N] К=массив[а]; массив[а]=массив[Сл]; массив[Сл]=К; КонецЦикла;

Sc = CreateObject("MSScriptControl.ScriptControl "); Sc.language = "VBscript "; sc.executeStatement("randomize "); оноВотТутаБудет=Sc.eval("rnd ");

Как сделать чтобы числа выбирались произвольно от 1 до 100?

Ранд=_GetPerformanceCounter()%(100 +1 );
похоже это лучшеее

Библиотека мат. функций, где есть генератор сл. чисел:
http://1c.proclub.ru/modules/mydownloads/personal.php?cid=92&lid=2688

В 8.0 для получения случайных чисел можно использовать встроенный генератор GUID.
Вот пример простенькой функции:

//только для целых чисел Функция ПолучитьСлучайноеЧисло(Мин,Макс) //вместо Randomize Для н = 1 По 100 Цикл Уник = Новый УникальныйИдентификатор; КонецЦикла; //генерируем GUID Уник = СокрЛП(Новый УникальныйИдентификатор); //оставляем только цифры Уник = СтрЗаменить(Уник,"- ",""); Уник = СтрЗаменить(Уник,"a ",""); Уник = СтрЗаменить(Уник,"b ",""); Уник = СтрЗаменить(Уник,"c ",""); Уник = СтрЗаменить(Уник,"d ",""); Уник = СтрЗаменить(Уник,"e ",""); Уник = СтрЗаменить(Уник,"f ",""); //знаменатель должен иметь такое же количество нулей + 1 Знаменатель = 10 ; Для н = 2 По (СтрДлина(СтрЗаменить(Уник,Символы.НПП,""))) Цикл Знаменатель = Знаменатель * 10 ; КонецЦикла; Случ = Число(Уник) / Знаменатель; //здесь получается дробное случайное число от 0 до 1 //преобразуем его в случайное число из заданного интервала, округляем до целого ЧислоИзИнтервала = Мин(Макс(Окр(Мин + (Макс-Мин)*Случ),Мин),Макс); Возврат ЧислоИзИнтервала; КонецФункции

Еще один системный вариант:
Rnd = СоздатьОбъект("System.Random "); Сообщить(Rnd.Next());

Ключевые слова: генератор, случайный, чисел, число, алгоритм, random, randomize, распределение, равномерное, лотерея

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

Нужно: сгенерить некоторое кол-во случайных шестибуквенных сочетаний из любых букв алфвита, к этому примешать некоторые кол-во вариантов, при которых слово все-таки можно сложить, например "ньккоя" - слово складывается, а "кавпры" - явно не подходит.

Дополнительное условие: все эти варианты (правильные и нет) нужно пронумеровать, чтобы при получении "призовой" карточки можно было бы сверить номер (а был ли такой).

Казалось бы, причем здесь 1С? Так вот учет этих карточек и призов желают добавить в учетную прогу, ну и заодно попросили нагенерить случайных комбинаций (ну не вручную же их сочинять).
Для каждой акции комбинации генерятся один раз, потом по ним изготавливают карточки, т.е. в следующий раз слово будет другое и т.д.

В общем задача сводится к следующему:
1. Генерить случайные числа, желательно с большим разбросом.
2. По числу вычислять комбинацию букв (т.е. найти какое-то соответствие между возможныи комбинациями и их номерами).
3. Пункт обратный предыдущему - по слову проверять номер комбинации.

Решение:
1. т.к. генератор от avb и NS давал маленький разброс случайных чисел, пришлось поюзать немного другой алгоритм:

Function Random()
if emptyvalue(randSeed) = 1 then
randSeed = _getperformancecounter();
endif;

RandSeed=(a*randSeed+c)%m;
return randSeed;
endfunction

Здесь:
a=1664525; c=1013904223; m=4294967296;
последняя переменная - 2 в 32-й степени, две другие - рекомендуемые для таких целей коэффициенты

Ограничение по максимальному значению 2^32 выбрано исходя из максимального кол-ва комбинаций (для обрезанного алфавита в 28 букв и слов по 7, т.к. в реальной задаче их именно 7, общее число комбинаций составит 28^7, таким образом выбранное ограничение лежит примерно посередине интервала, что вполне достаточно для выборки 20-30 тыс. вариантов)

Нам также понадобится еще одна вспомогательная функция - возведение в целочисленную положительную степень:

Функция Степень(Знач а,Знач б, Рез=1)
Если б>0 Тогда
Рез=Рез*а;
б=б-1;
Степень(а,б,Рез);
Возврат Рез;
Иначе
Возврат Рез;
КонецЕсли;
КонецФункции

Здесь: а - основание степени, б - показатель степени, Рез - результат

2. Выявить зависимость между последовательно расположенными комбинациями, оказалось на удивление простым:

расположив, ряд элементов по порядку, я выявил схожесть расположения символов с системой счисления, только не десятичной, а в данном случае "шестиричной" (по кол-ву символов в результирующем "слове").
Таким образом, для вычисления комбинации по ее номеру нужно было преобразовать ее номер в эту самую систему счисления.

Для нашей системы счисления, основанием будут являться степени шестерки, т.е. для получения первого слева разряда, необходимо разделить номер нашей комбинации на 6 в 5-й степени, затем остаток от деления - на 6 в 4-й и т.д.

Таким образом, получаем набор из шести чисел, которые по сути являются порядковыми номерами букв в нашем алфавите.

Получившийся код:

Функция ПолучитьСимволы(Поз,ТекСимв=1,СимСтр="")
Если ТекСимв Делитель=Степень(СтрДлина(Буквы),к-ТекСимв);
ТекОст=Поз%Делитель;
СимСтр=Строка(СимСтр)+Сред(Буквы,Цел(Поз/Делитель+?(ТекОст>0,1,0)),1);
ПолучитьСимволы(ТекОст,ТекСимв+1,СимСтр);
Возврат СимСтр;
Иначе
СимСтр=СимСтр+Сред(Буквы,(?(Поз=0,СтрДлина(Буквы),Поз)),1);
Возврат СимСтр;
КонецЕсли;
КонецФункции

Здесь:
Поз - номер комбинации (псевдослучайное число)
ТекСимв - текущий обрабатываемый символ
СимСтр - резльтирующая строка символов
Буквы = строка, содержащая буквы алфавита в стандартном порядке ("абв...юя")
к - число символов в искомом слове (в данном случае = 6)

3. Обратное преобразование также тривиально:

Функция ПолучитьКомбинацию(Слово,ТекСимв=0,Поз=0)
НомСимв=Найти(Буквы,Сред(Слово,к-ТекСимв,1));
Если ТекСимв>0 Тогда
Если ТекСимв Поз=Поз+(НомСимв-1)*Степень(СтрДлина(Буквы),ТекСимв);
Иначе
Возврат Поз;
КонецЕсли;
Иначе
Поз=?(НомСимв=СтрДлина(Буквы),0,НомСимв);
ПолучитьКомбинацию(Слово,ТекСимв+1,Поз);
Возврат Поз;
КонецЕсли;
КонецФункции

Здесь:
Слово - комбинация символов, номер которой ищем
ТекСимв - текущий обрабатываемый символ (по сути разряд шестиричного "числа")
Поз - искомый номер комбинации


************************

Премешать N чисел:

Для а=1 по N цикл
массив[а]=а;
Конеццикла;
Для а=1 по N-1 цикл
Сл=Случ(а,N);// Целое случайное число в интервале [а..N]
К=массив[а];
массив[а]=массив[Сл];
массив[Сл]=К;
КонецЦикла;

//********************************************************************************
************************

Sc = CreateObject("MSScriptControl.ScriptControl");
Sc.language = "VBscript";
sc.executeStatement("randomize");
оноВотТутаБудет=Sc.eval("rnd");

Как сделать чтобы числа выбирались произвольно от 1 до 100?

Ранд=_GetPerformanceCounter()%(100+1);

похоже это лучшеее

//********************************************************************************
************************

В 8.0 для получения случайных чисел можно использовать встроенный генератор GUID.
Вот пример простенькой функции:

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

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

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

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

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

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

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

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

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

Взято [необходимо зарегистрироваться для просмотра ссылки]

//********************************************************************************
************************

ЗЫ. я набрёл на эту статью в поисках генератора случайных чисел. Так вот для себя я выбрал вариант
Ранд=_GetPerformanceCounter()%(100+1);

Я не просто так начал статью с этого возгласа. Свершилось, есть в арсенале программиста удобный инструмент, который позволяет получить случайное целое число в заданном интервале. Стандартные функции в других языках программирования генерировали дробное число в интервале от 0 до 1. Не слишком удобное число для использования, приходится дополнительно напрягаться, для получения случайной последовательности в заданном интервале, например, от 1 до 5.

Удобный инструмент нужно проверить, зачастую ГСЧ не слишком качественные и приходится дополнительно упражняться в математике, чтоб повысить случайность генерируемых чисел, во имя избавления от плохо перемешанных псевдопоследовательностей. Зачастую случайным числам мы доверяем секреты, финансовые средства, развлечения, моделирование, испытания ответственных АСУ систем, тестирование программ, поэтому очень важно иметь уникальную последовательность ряда с разнообразными заданными характеристиками от интервалов значений, до степени перемешивания чисел последовательности.

Приведу пример неудачной генерации случайных чисел. В далеком 1993 году, когда хорошим считался нецветной VGA монитор c разрешением 640х480, от него меньше уставали глаза программистов, была распространена СУБД Paradox. Жадины из Borland International решили заработать побольше денег и для сетевого доступа требовали ключ, состоящий из 10 цифр. Чем больше ключей ввел, тем больше пользователей могут одновременно подключится к базе.

Сейчас начну хвастаться своими успехами:). Разными способами ко мне попало 3 ключа и меня озарило, что последовательность псевдослучайная и плохо перемешанная. Без всякой техники, сложных вычислений и даже без калькулятора мне удалось подобрать любое количество этих ключей. Конечно компания Borland не понесла больших убытков, но раз уж занялся защитой, то делай это хорошо, либо не трать время на бесполезную работу. Не буду выводить из этого мораль, надеюсь становиться понятнее, что ГСЧ дело важное.

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

Вывод такой: замки и запоры ставят от честных людей.

Работает объект в платформе 1С исключительно просто, хотя есть некоторые особенности.

ГСЧ = Новый ГенераторСлучайныхЧисел(Инициализация); //Здесь можно изменить работу геренатора случайных чисел, изменение Инициализации числа дает разные результаты Возврат ГСЧ.СлучайноеЧисло(1, ВариантНастройки);

Если не задавать Инициализацию, тогда последовательности рождаются случайным образом, инициализируясь самостоятельно. Заданное число инициализации возвратит предсказуемую последовательность, что иногда бывает нужно и полезно. А если каждый раз задавать разное число, то получается весьма неплохое перемешивание последовательности чисел.

Для исследования работы генератора случайных чисел в 1С, создал пару обработок и чтоб было интереснее одна в виде игры, но игра позже, сначала дело.

Сгенерировано 500 случайных чисел, в интервале от 0 до 10000, при постоянной инициализации генератора функцией ТекущаяУниверсальнаяДатаВМиллисекундах(). На диаграмме видо хорошее распределение значений. Причудливый узор. По оси У величина значения числа, по оси Х номер итерации.

Положения точек довольно разряжены, они почти не липнут друг к другу, что очень хорошо, значит числа сгенерированы весьма разнообразные.

Искусственно создам плохой вариант диаграммы:

При хорошей генерации так быть не должно.

Настройки генератора случайных чисел очень важный момент. Их немного, но от них все зависит.

При данной настройке формируется последовательность из 500 чисел в интервале от 0 до 10000 и постоянной инициализации генератора новым числом.

Заглянем в сформированную таблицу значений, предварительно отсортировав ее по значениям, чтоб увидеть, есть ли повторяющиеся числа, выданные генератором.

Беглый визуальный просмотр отсортированного списка показал, что есть повторения, хотя вероятность его невысока. Задан широкий интервал чисел для генерации, но на 10 и 30 шаге числа повторились.

Делаем вывод: объект ГенераторСлучайныхЧисел может генерировать повторяющиеся числа.

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

Зачем нужна случайная нумерация? Допустим мы выдаем нашим партнерам номера документов к сданному в ремонт оборудованию. Можно выдавать номера сквозной последовательной нумерации, но клиент, обладая одним номером может посмотреть как минимум соседние и зная интервал нумерации может просмотреть все документы. В приведенном примере это не ахти какой секрет, но бывает нужно сохранить в тайне информацию из других документов.

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

Решением может стать проверка сгенерированного числа на уникальность, но при очень длинных последовательностях это будет занимать много времени. Придется думать над более сложными перемешиваниями, но тем и интереснее задача;).

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

Генератору можно задать определенное значение инициализации, тогда сколько не нажимай генерировать, результат будет одинаковый. При установке поля обработки "Число инициализации ГСЧ" в 0, происходит псевдослучайная инициализация при генерации последовательности чисел.

Скорость работы генератора хорошая, к примеру 100 000 чисел сгенерировались меньше чем за 0,5 секунд.

Пример применения ГСЧ на маленьком интервале чисел, покажу на примере игры Камень, Ножницы, Бумага.

Правила простые: два игрока жестами показывают указанные предметы. У кого в данный момент сильнее фигура, тот и победил.

Камень побеждает Ножницы.

Ножницы побеждают Бумагу.

Бумага побеждает Камень.

В данном варианте все равнозначны и вероятности победы одинаковые.

Сыграв 99 игр, я произвел одинаковое количество нажатий на каждую фигуру, по 33 раза, это видно по правой нижней диаграмме. Компьютер выигрывал чаще меня, немного обидно. Компьютер чаще использовал бумагу, это видно по левой нижней диаграмме. График в середине показывает, что в выигрыше я не был. Красный график выигрышей компьютера выше зеленого (моих выигрышей).

Попытайте свою удачу! Несмотря на одинаковую вероятность выпадения фигур, результат всегда разный.

Статистика игр отображается в середине, в верху в розовой группе элементов.

Нажав мышкой на кнопку один раз, можно в дальнейшем пользоваться цифрами клавиатуры (не дополнительной), для выбора нужной фигуры. Нажатием на клавиши получается немного быстрее вводить данные, особенно если нужно провести неосмысленные игры для накопления статистики.

Усложним игру. К классическим фигурам добавим еще Колодец.

Камень побеждает Ножницы.

Ножницы побеждают Бумагу.

Бумага побеждает Камень и Колодец.

Колодец побеждает Камень и Ножницы.

В данном варианте появляется неравнозначность фигур и теоретически больше шансов победить, выбирая Бумагу и Колодец, так как в их арсенале победа над двумя коллегами фигурами. Проверим на практике:

Я нажимал только на сильные фигуры и выиграл. Теория подтвердилась практикой.

Нажатие только на слабые фигуры тоже дало свой результат, я проиграл.

Еще более сложный вариант игры при введении пятой фигуры, Огонь.

Камень побеждает Ножницы и Колодец проигрывает Бумаге и Огню.

Ножницы побеждают Бумагу и Огонь проигрывают Камню и Колодцу.

Бумага побеждает Камень и Колодец проигрывает Огню и Ножницам.

Колодец побеждает Огонь и Ножницы проигрывает Камню и Бумаге.

Огонь побеждает Бумагу и Камень проигрывает Ножницам и Колодцу.

В данном варианте фигуры равнозначны, но выигрывают и проигрывают двум фигурам, это вносит некоторую интригу и снижает вероятность ничьих.

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

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

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

Флаг "Не использовать инициализацию ГСЧ", включает/выключает режим инициализации. Если при создании объекта ГенераторСлучайныхЧисел не задать инициализацию, то генерируется перемешанная последовательность, я так понимаю, заложена некая инициализация, мне показалось вполне эффективная.

ГСЧ = Новый ГенераторСлучайныхЧисел();

Также, в обработке, можно задать свое число инициализации, тогда предсказуемо генерируется одно и тоже число.

При написании процедуры расчета выигрыша столкнулся с проблемой описания результата, особенно для игры с пятью фигурами. Прикинув понял, что будет много букв, так как много вариантов при таком количестве фигур. Комбинаторика подсказывает нам, что при трех фигурах у нас максимально есть 9 вариантов, при четырех 16 вариантов, то при пяти 25 вариантов. Откинув ничьи, это когда выбрана одинаковая фигура, я понял, что придется написать 19 вариантов условий.

Я задумался, так как явно получится плохо читаемый код, и нашел как я считаю красивое решение. Всего с 9 условиями.

Рез = Игрок - Комп; Если ВариантНастройки = 3 Тогда Если (Рез = -1) ИЛИ (Рез = 2) Тогда Возврат 1; //Победа Иначе Возврат 2; //Поражение КонецЕсли; ИначеЕсли ВариантНастройки = 4 Тогда Если (Рез = -1) ИЛИ (Рез = 2) ИЛИ (Рез = 3) Тогда Возврат 1; //Победа Иначе Возврат 2; //Поражение КонецЕсли; ИначеЕсли ВариантНастройки = 5 Тогда Если (Рез = -1) ИЛИ (Рез = 2) ИЛИ (Рез = -3) ИЛИ (Рез = 4) Тогда Возврат 1; //Победа Иначе Возврат 2; //Поражение КонецЕсли; КонецЕсли;

Компактно, понятно, легко редактировать.

Я прикинул что каждая фигура имеет свой номер: 1 - Камень, 2 - Ножницы, 3 - Бумага, 4 - Колодец, 5 - Огонь. В результате игры я вычисляю разницу между номерами фигур, и эта разница дает мне однозначный ответ, на вопрос кто победил.

Обработки, помогающие исследовать свойства случайных последовательностей для управляемого приложения и написаны без привязки к конфигурации. Тестировались на платформе 8.3.10, 8.3.11 на тонком клиенте.

Данной статьей я надеялся донести важность и серьезное отношение при генерации последовательностей случайных чисел.