Author Topic: рандомизация - создание случайного порядка выполнения действий  (Read 2575 times)

0 Members and 1 Guest are viewing this topic.

gsukhado

  • Активный участник
  • ***
  • Posts: 104
    • View Profile
День добрый.
Предположим есть 10 переключателей. Каждый из них может принимать значения 0 или 1, причем независимо друг от друга.
Задача: выбрать только те переключатели, у которых значение =1, и расставить именно такие переключатели в случайном порядке.

Поясню исходную задачу, в рамках скрипта к игре - при заходе на поляну надо сделать 10 разных действий, причем по ряду причин некоторые надо делать на конкретной поляне, а некоторые не надо. Надо или не надо делать конкретное действие - проверяется в момент входа на поляну. Не хочется повторяться, и делать один и тот же цикл при каждом входе на поляну, а хотелось бы его рандомизировать.
Как вариант, пока приходит в голову только прописать жестко несколько стандартных циклов, и рандомно выбирать какой-то из них. Причем рандом естественно с разным весом у разных вариантов, что-то типа rnd(variant1,variant1,variant1,variant2,variant3,variant3)
Но вот можно ли сделать действительно рандомный алгоритм?...

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Если "Предположим есть 10 переключателей" действительно не больше десяти:

Code: (clickermann) [Select]
LOGCLEAR

// сгенерируем массив переключателей (у тебя он просто уже есть)
FOR($i=0, $i < 10)
    ARRPUSH($switches, RND(0, 1))
END_CYC

// Отобразим, переключатели
$str = $switches[0]
FOR($i=1, $i < ARRSIZE($switches))
    $str = STRCONCAT($str, ", ", $switches[$i])
END_CYC
LOGWRITE($str)

// здесь начинается код который будет использоваться у тебя
// создадим строку, в который сложим ИНДЕКСЫ только включенных переключателей
$switches_on = ""
FOR($i=0, $i < ARRSIZE($switches))
    IF($switches[$i] = 1)
        $switches_on = STRCONCAT($switches_on, $i)
    END_IF
END_CYC
print($switches_on)

// Проходим по всем включенным значениям и выполняем соответствующие действия
WHILE(STRLEN($switches_on) > 0)
    $d = STRCUT($switches_on, RND(1, STRLEN($switches_on)), 1)
    $switches_on = STRREPLACE($switches_on, $d, "")
    LOGWRITE("случайное число ", $d)
    SWITCH($d)
        CASE(0)
            // случай 0
        CASE(1)
            // случай 1
        CASE(2)
            // случай 2
        // и т.д.
    END_SWITCH   
END_CYC

HALT

Quote
12:05:42 0, 0, 1, 1, 0, 0, 0, 1, 1, 1
12:05:42 23789
12:05:42 случайное число 7
12:05:42 случайное число 3
12:05:42 случайное число 8
12:05:42 случайное число 2
12:05:42 случайное число 9

Если больше 10, то то же самое, но не со строкой, а с массивом. Или сразу с массивом, как удобнее.


Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Вот через массив.
Пример, с 15 переключателями
Code: (clickermann) [Select]
LOGCLEAR

// сгенерируем массив переключателей (у тебя он просто уже есть)
FOR($i=0, $i < 15)
    ARRPUSH($switches, RND(0, 1))
END_CYC

// Отобразим, переключатели
$str = $switches[0]
FOR($i=1, $i < ARRSIZE($switches))
    $str = STRCONCAT($str, ", ", $switches[$i])
END_CYC
LOGWRITE($str)

// здесь начинается код который будет использоваться у тебя
// создадим новый массив, в который сложим ИНДЕКСЫ только включенных переключателей
UNDEFINE($switches_on)
FOR($i=0, $i < ARRSIZE($switches))
    IF($switches[$i] = 1)
        ARRPUSH($switches_on, $i)
    END_IF
END_CYC

// Отобразим, что отобрали (только для демонстрации или отладки)
$str = $switches_on[0]
FOR($i=1, $i < ARRSIZE($switches_on))
    $str = STRCONCAT($str, ", ", $switches_on[$i])
END_CYC
LOGWRITE($str)

// Проходим по всем включенным значениям и выполняем соответствующие действия
WHILE(ARRSIZE($switches_on))
    $ind = RND(0, ARRSIZE($switches_on) - 1)
    $d = $switches_on[$ind]
    LOGWRITE("случайное число ", $d)
    $switches_on[$ind] = $switches_on[ARRSIZE($switches_on) - 1]
    $temp = ARRPOP($switches_on)

    SWITCH($d)
        CASE(0)
            // случай 0
        CASE(1)
            // случай 1
        CASE(2)
            // случай 2
        // и т.д.
    END_SWITCH
END_CYC

HALT

Quote
12:23:41 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1
12:23:41 1, 2, 7, 13, 14
12:23:41 случайное число 14
12:23:41 случайное число 13
12:23:41 случайное число 1
12:23:41 случайное число 2
12:23:41 случайное число 7


dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
День добрый.
Предположим есть 10 переключателей. Каждый из них может принимать значения 0 или 1, причем независимо друг от друга.
Задача: выбрать только те переключатели, у которых значение =1, и расставить именно такие переключатели в случайном порядке.

Это равносильно вот этому - берем десять переключателей, и рандомо включаем какоето количестов от 0 до 10 (rnd(0,10)), получаем какоето число от 0 до 10. Далее из массива вариантов рандомно выбираем это количество вариантов, при этом, следим чтоб они не повторились. Это все было на флруме, просто нужно было соеденить:
Code: (clickermann) [Select]
FOR($a=0,$a < 10)  //создаем количество вариантов действий, в нашем случае - 10
   arrpush($var,$a)
END_CYC

$amount = rnd(0,10) // выбираем рандомное количество вариантов выполнения этих действий от 0 до 10

print("выполнится ",$amount, " действий")//смотрим, сколько действий у нас выполнится

//далее, циклом, выбирае  рандомные действия столько раз, сколько у нас получилось ранее.
FOR($a=0, $a < $amount)
   
   $rnd_var = rnd(0,arrsize($var)-1)   
   arrpush($action, $var[$rnd_var])//берем рандомный вариант
   
   //и удаляем его
   $var[$rnd_var] = $var[arrsize($var)-1]
   $del = arrpop($var)
   
END_CYC


//---------------------------
//cмотрим редультат
print(" ")
FOR($a=0,$a<arrsize($action))
   print("действие ",$a+1," - ", $action[$a], " вариант")
END_CYC

halt

Code: (text) [Select]
23:27:40 выполнится 7 действий
23:27:40 
23:27:40 действие 1 - 8 вариант
23:27:40 действие 2 - 6 вариант
23:27:40 действие 3 - 0 вариант
23:27:40 действие 4 - 7 вариант
23:27:40 действие 5 - 3 вариант
23:27:41 действие 6 - 1 вариант
23:27:41 действие 7 - 4 вариант
Code: (text) [Select]
23:51:45 выполнится 8 действий
23:51:45 
23:51:45 действие 1 - 7 вариант
23:51:45 действие 2 - 5 вариант
23:51:45 действие 3 - 9 вариант
23:51:45 действие 4 - 1 вариант
23:51:45 действие 5 - 4 вариант
23:51:45 действие 6 - 8 вариант
23:51:45 действие 7 - 0 вариант
23:51:45 действие 8 - 6 вариант

23:52:35 выполнится 5 действий
23:52:35 
23:52:35 действие 1 - 1 вариант
23:52:35 действие 2 - 5 вариант
23:52:35 действие 3 - 9 вариант
23:52:35 действие 4 - 3 вариант
23:52:35 действие 5 - 2 вариант

23:52:52 выполнится 2 действий
23:52:52 
23:52:52 действие 1 - 5 вариант
23:52:52 действие 2 - 4 вариант

23:53:01 выполнится 10 действий
23:53:01 
23:53:01 действие 1 - 8 вариант
23:53:01 действие 2 - 1 вариант
23:53:01 действие 3 - 3 вариант
23:53:01 действие 4 - 4 вариант
23:53:01 действие 5 - 6 вариант
23:53:01 действие 6 - 7 вариант
23:53:01 действие 7 - 2 вариант
23:53:01 действие 8 - 9 вариант
23:53:02 действие 9 - 5 вариант
23:53:02 действие 10 - 0 вариант

Я надеюсь, правильно понял задачу, покажу еще пару результатов выше:


« Last Edit: September 23, 2019, 11:46:47 PM by dramster »

gsukhado

  • Активный участник
  • ***
  • Posts: 104
    • View Profile
Спасибо за комментарии, идею понял!