| 
				
				Сложный(наверное) алгоритм рандомизации
				 |   |  
| 
Black_Hawk1451
 | 
Дата: Воскресенье, 13.03.2016, 23:26:34 | Сообщение # 1 |  
  
  |  
Сообщений: 11
 
Репутация: 0 [ +/- ]
 |   
 | 
 Итак, представим что у меня есть 48 различных картинок. Среди этих 48 картинок существует 14 картинок в единичном экземпляре а остальные 17 повторяются только 1 раз(т.е. двойной экземпляр). Итого 14 + 17*2 = 48. При этом среди 14 картинок в единичном экземпляре существует еще 10 единичных VIP-картинок.
  Далее, представим что у меня есть 10 телевизоров, среди которых есть один VIP-телевизор. И я хочу чтобы при старте карты происходил такой алгоритм: - в первом телевизоре отображается рандомная картинка из 48 оставшихся - во втором телевизоре отображается рандомная картинка из 47 оставшихся, при этом, она не должна повторяться с первой! - в третьем телевизоре отображается рандомная картинка из 46 оставшихся, при этом, она не должна повторяться с первой и второй! ...и так далее до десятого телевизора. - в десятом, VIP-телевизоре, может отобразиться только одна из 10 VIP-картинок, при этом она, конечно же, не должна повторяться с теми, которые уже могли появиться на предыдущих 9 телевизорах. То есть, должна быть реальна ситуация, когда на всех 9 обычных телевизорах появились VIP-картинки. Однако, повторяться не должен только порядковый номер каждой картинки. Те картинки, которые в двойном экземпляре, имеют бОльший шанс на появление на телевизоре и должны иметь возможность при проходе этого алгоритма появиться, например, на двух разных телевизорах.
  Затем, у меня должна быть возможность один раз активировать второй триггер для каждого телевизора. Его алгоритм должен быть следующим(тут у меня 2 варианта):
  I вариант: - На каждом телевизоре, кроме VIP, я могу нажать, например, на красную кнопку, и после нажатия картинка на этом телевизоре должна смениться на любую из оставшихся 28-38 картинок, так как 10 картинок уже были использованы в первом триггере и еще максимум 10 могут быть использованы. На VIP-телевизоре же кнопка должна выполнять ту же функцию, но выбирать только из оставшихся VIP-картинок(мог ошибиться в подсчетах на единичку, хочется спать, извиняйте )
  II вариант: - На каждом телевизоре я могу нажать, например, на красную кнопку, и таким образом отметить все телевизоры, картинки на которых я хочу поменять. Затем нажать, например, на оранжевую кнопку(она одна) и после этого все картинки на отмеченных телевизорах сменятся на те, которые еще не были использованы.
  Второй вариант мне кажется более геморным, поэтому я его не особо рассматриваю. Но, возможно, я ошибаюсь.
  В общем, на форуме мапперов мне сказали, что сурс движок не очень хорошо ладит с использованием большого количества энтитей(а там по-другому никак :c) и посоветовали написать отдельный плагин под все это дело. Я подумал над этим и примерно набросал как это должно выглядеть:
  1. Первым делом нужно объявить переменные из карты в самом плагине, а также привязать нажатия кнопок и мб что-то еще. 2. Затем, мне нужна такая функция, которая из 48 чисел(от 1 до 48 включительно) выберет 9 штук без повторений. Не знаю, реально ли такое в языке SourcePawn, но раз в редакторе карт такая возможность есть, то скорее всего и в языке должна быть. 3. Когда выбралось какое-то число, то передавать на карту в нужные энтити(через targetname) 2 значения: - номер попытки(от 1 до 9) - число, которое выбралось рандомно и без повторений(от 1 до 48, ноль учитывать не нужно) 4. Еще должен быть случайный выбор из 10 VIP-картинок, без повторений. Кстати, скорее всего именно его нужно провести первым и затем как-то передать полученное число в функцию из пункта 2, чтобы это же число не могло быть выбрано, т.е VIP-картинка никак не повторится. Опять же не знаю, возможно ли это или нет. 5. Теперь к функции перевыбора. Она должна быть привязана к 10 кнопкам. 6. При нажатии на любую не VIP-кнопку, она должна передавать на карту в нужную энтити: - новое рандомное число(все также без повторений) Передавать номер попытки уже не стоит, так как это будет делать своя собственная кнопка на каждом телевизоре. 7. При нажатии на VIP-кнопку происходить должно все то же самое, только новое рандомное число выбирается уже как минимум из 9 вариантов и, конечно же, не должно быть повторений.
  Заранее выложу список энтитей, используемых в этом плагине: 10 штук func_wall - телевизоры, каждый со своим именем, начиная с televisor[1,2,3...10]. 10 штук func_button - кнопки на телевизорах, каждая со своим именем, but[1,2,3...10] 10 штук env_texturetoggle - энтити, отвечающие за смену текстуры на другую. Каждая со своим именем, texture[1,2,3...10] 9 штук math_counter - энтити, отвечающие за выбор правильного телевизора при первом проходе алгоритма рандома. В них передаются попытки. Для VIP-телевизора такая не нужна, потому что он всего лишь один, и работает, по сути, по другому алгоритму рандома. counter[1,2,3...9]. Последние, теоретически, можно убрать если в самый первый проход рандома добавить такую вещь, что выбранное число будет по очереди для каждой texture[1,2,3...10] именно в самом плагине активировать команду SetTextureIndex [число]. Опять же не знаю насколько реально через плагины активировать команды из редактора карт.
  Я честно не знаю насколько муторный должен получиться плагин, мб кто-то тут подобные за пять минут пишет. Тем не менее, я не прошу Вас написать его за меня, мне просто нужны подсказки, мб примеры плагинов с исходниками, где подобный алгоритм уже был реализован и т.д. Если нужен будет исходник карты, то могу кинуть чуть позже. В данный момент он немного не соответствует тому, о чем я написал выше. Заранее очень благодарен за любую помощь! 
 
 Сообщение отредактировал Black_Hawk1451 - Понедельник, 14.03.2016, 00:37:37  | 
 
|   | 
 |    |  
| 
barcelona58341
 | 
Дата: Понедельник, 14.03.2016, 10:23:00 | Сообщение # 2 |  
  
  |  
Сообщений: 18
 
Репутация: 0 [ +/- ]
 |   
 | 
Цитата Заранее выложу список энтитей, используемых в этом плагине:  Реализация, можно сделать но по другими функциями без некоторых энтитей, а подобный плагин наверно нету 
 | 
 
|   | 
 |    |  
| 
BarD
 | 
Дата: Понедельник, 14.03.2016, 12:51:57 | Сообщение # 3 |  
  
  |  
Сообщений: 943
 
Репутация: 137 [ +/- ]
 |   
 | 
Не очень понял, что тебе нужно. Попробуй затолкать в массив все картинки и отсортируй через
 Код SortIntegers(array[], array_size, Sort_Random);  Затем выцепляй по одной. Гарантированно будет без повторений. 
 
 Сообщение отредактировал BarD - Понедельник, 14.03.2016, 12:52:17  | 
 
|   | 
 |    |  
| 
_wS_
 | 
Дата: Понедельник, 14.03.2016, 13:40:09 | Сообщение # 4 |  
  
 | 
Цитата BarD (  )  Не очень понял, что тебе нужно  +1, как-то запутан(н?)о. Говоришь что одни картинки повторяются, другие нет, но на каждом телевизоре должна быть уникальная картинка без повторений, зачем тогда инфа о том что какие-то повторяются, а какие-то нет? Исходя из того что я понял, вот пару строк кода:
 
 Код // Текущая картинка на телевизоре new Handle:g_hCurrentTvImageAr;
  // Номера картинок new Handle:g_hImageAr;
  public OnPlubinStart() {     decl i;
      // по умолчанию у каждого телевизора (от 1 до 10) картинка отключена (0)     g_hCurrentTvImageAr = CreateArray(1);     for (i = 1; i < 11; i++) PushArrayCell(g_hCurrentTvImageAr, 0);
      // номера картинок от 1 до 48 (вип картинки от 1 до 10)     g_hImageAr = CreateArray(1);     for (i = 1; i < 49; i++) PushArrayCell(g_hImageAr, i); }
  // Меняем картинку (на телевизорах всегда разные картинки) // Tv - номер телевизора от 1 до 10 stock wS_SetRandomTvImage(Tv) {     decl image;     new max = Tv == 10 ? 10 : 48;
      new Handle:hAr = CreateArray(1);     for (new i = 0; i < max; i++)     {         image = GetArrayCell(g_hImageAr, i);         if (FindValueInArray(g_hCurrentTvImageAr, image) < 0)         {             PushArrayCell(hAr, image);         }     }     image = GetArrayCell(hAr, GetRandomInt(0, GetArraySize(hAr) - 1));     CloseHandle(hAr);
      SetArrayCell(g_hCurrentTvImageAr, --Tv, image);
      SetVariantInt(image);     AcceptEntityInput(env_texturetoggle_ENTITY_INDEX, "SetTextureIndex");
      --     вместо AcceptEntityInput(env_texturetoggle_ENTITY_INDEX, "SetTextureIndex");     можно попробовать так:
      decl String:info[65];     new entity = CreateEntityByName("info_target");     FormatEx(info, 65, "env_texturetoggle_%d,SetTextureIndex,%d,0,1", Tv, image);     DispatchKeyValue(entity,  "OnUser1", info);     AcceptEntityInput(entity, "FireUser1");     AcceptEntityInput(entity, "Kill");     -- }  
 | 
 
|   | 
 |    |  
| 
Black_Hawk1451
 | 
Дата: Понедельник, 14.03.2016, 15:28:24 | Сообщение # 5 |  
  
  |  
Сообщений: 11
 
Репутация: 0 [ +/- ]
 |   
 | 
Цитата _wS_ (  )  +1, как-то запутан(н?)о. Говоришь что одни картинки повторяются, другие нет, но на каждом телевизоре должна быть уникальная картинка без повторений, зачем тогда инфа о том что какие-то повторяются, а какие-то нет? Исходя из того что я понял, вот пару строк кода: 
  Сорри если запутал, просто считал должным донести эту информацию. Еще раз более подробно объясню: Всего 31 картинка, из них: 14 - в единичном экземпляре, среди которых 10 являются VIP-картинками 17 - в двойном экземпляре. Каждой картинке присвоен свой порядковый номер, в том числе и двойным, именно из-за этого условия общее количество возможных картинок вырастает до 48. Надеюсь, сейчас стало более понятно.
   _wS_, по коду есть несколько вопросов: 1. Я не много не понял в каком месте я должен подставить имена своих энтитей в код, чтобы плагин работал корректно.
  2. Не понял вот эту строку:
 Код // номера картинок от 1 до 48 (вип картинки от 1 до 10)     g_hImageAr = CreateArray(1);     for (i = 1; i < 49; i++) PushArrayCell(g_hImageAr, i);  То есть для этого кода я должен буду заранее обозначить все вип картинки под порядковыми номерами от 1 до 10?
  3. По поводу этой строки:
 Код     // по умолчанию у каждого телевизора (от 1 до 10) картинка отключена (0)     g_hCurrentTvImageAr = CreateArray(1);     for (i = 1; i < 11; i++) PushArrayCell(g_hCurrentTvImageAr, 0);  А есть ли в ней смысл? Если я заранее на карте могу сделать так, что картинки будут отключены.
  4. Вот в этой функции очень много непонятных для меня вещей, был бы признателен если бы Вы смогли оставить хотя бы комментарий рядом с каждой строчкой:
 Код stock wS_SetRandomTvImage(Tv) {     decl image;     new max = Tv == 10 ? 10 : 48;
      new Handle:hAr = CreateArray(1);     for (new i = 0; i < max; i++)     {         image = GetArrayCell(g_hImageAr, i);         if (FindValueInArray(g_hCurrentTvImageAr, image) < 0)         {             PushArrayCell(hAr, image);         }     }     image = GetRandomInt(0, GetArraySize(hAr) - 1);     CloseHandle(hAr);
      SetArrayCell(g_hCurrentTvImageAr, --Tv, image);
      SetVariantInt(image);     AcceptEntityInput(env_texturetoggle_ENTITY_INDEX, "SetTextureIndex"); 
  Пока попробую сам разобраться в Вашем коде, но, чувствую, это будет ооочень долго :< 
 | 
 
|   | 
 |    |     
		
		
 
 |