Author Topic: Как изменить RND на несколько действий  (Read 5900 times)

0 Members and 1 Guest are viewing this topic.

bulgachevarada

  • Зашел в гости
  • *
  • Posts: 15
    • View Profile
Подскажите пожалуйста, как сделать чтоб макрос например из восьми действий выполнял в случайном порядке допустим 4 действия не повторяющихся, на примере:
$random = RND(1,8) // генерация случайного числа 1-8
SWITCH($random)
CASE(1)
   // выполнние  действие№ 1
CASE(2)
   // выполнние  действие№ 2
CASE(3)
   // выполнние  действие№ 3
CASE(4)
   // выполнние  действие№ 4
CASE(5)
   // выполнние  действие№ 5
CASE(6)
   // выполнние  действие№ 6
CASE(7)
   // выполнние  действие№ 7
CASE(8)
   // выполнние  действие№ 8
DEFAULT
END_SWITCH


или лучше делать через ?

$random = RND(1,3) // генерация случайного числа 1-3
 
 
    IF($random = 1)
      // выполнние   действие№ 1
    END_IF
 
 
    IF($random = 2)
      // выполнние   действие№ 2
    END_IF
 
 
    IF($random = 3)
      // выполнние   действие№ 3
    END_IF

Тогда как сделать задать что б выпадало несколько сразу чисел и выполнить именно номера действий что будут
« Last Edit: September 19, 2017, 08:20:44 PM by bulgachevarada »

bulgachevarada

  • Зашел в гости
  • *
  • Posts: 15
    • View Profile
Re: Как изменить RND на несколько действий
« Reply #1 on: September 20, 2017, 09:23:49 AM »
Спасибо большое!!

bulgachevarada

  • Зашел в гости
  • *
  • Posts: 15
    • View Profile
Re: Как изменить RND на несколько действий
« Reply #2 on: September 22, 2017, 06:59:03 PM »
укороченный вариант с циклом число не повторяющихся действий можно изменять.
Code: (clickermann) [Select]

// для Clickermann v4.13.004
//  цикл из вАСьми действий
// выполнял в случайном порядке  указанное число не повторяющихся действия:

$str="12345678" //объявляет переменную
$var1 = 4 //указать число выполняемых действий
FOR($a=0,$a<$var1) // повторяем $var1 раз
   $simv= STRCUT($str,RND(1,STRLEN($str)),1)// возвращает случайный символ строки
   $str=STRFILTER($str,$simv, 0) //удаляет выпавший символ из строки
   SWITCH($simv)
   CASE(1)
      LOGWRITE ("выполнение  действие № 1")  // выполнение  действие№ 1
   CASE(2)
      LOGWRITE ("выполнение  действие № 2")  // выполнение  действие№ 2
   CASE(3)
      LOGWRITE ("выполнение  действие № 3")  // выполнение  действие№ 3
   CASE(4)
      LOGWRITE ("выполнение  действие № 4")  // выполнение  действие№ 4
   CASE(5)
      LOGWRITE ("выполнение  действие № 5")  // выполнение  действие№ 5
   CASE(6)
      LOGWRITE ("выполнение  действие № 6")  // выполнение  действие№ 6
   CASE(7)
      LOGWRITE ("выполнение  действие № 7")  // выполнение  действие№ 7
   CASE(8)
      LOGWRITE ("выполнение  действие № 8")  // выполнение  действие№ 8   
   END_SWITCH
END_CYC
HALT  // выход


А как прописать если переменных больше 10 штук? через запятую 10,11,12 не видит, только работает если сменить на буквы переменные, но это очень не удобно(

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Как изменить RND на несколько действий
« Reply #3 on: September 22, 2017, 07:42:38 PM »
вот тоже самое, только с помощью массива. STRSEPARATE ("4,5,6,7,8,9,10,11", ",", $arr) - через запятую любые числа... можно и не числа


Code: (clickermann) [Select]
STRSEPARATE ("4,5,6,7,8,9,10,11", ",", $arr)  //массив из чисел


$var1 = 5 //указать число выполняемых действий

FOR($a=0,$a<$var1) // повторяем $var1 раз

   $i = rnd(0,ARRSIZE ($arr)-1)    //рандомный элемент массива.
   $simv = $arr[$i]
   
   FOR($i,$i<ARRSIZE ($arr)-1)  // исключаем элемент из массива
      $arr[$i] = $arr[$i+1]
   END_CYC
   $del = ARRPOP($arr)
   
   
   SWITCH($simv)
   CASE(4)
      LOGWRITE ("выполнение  действие № 4") 
   CASE(5)
      LOGWRITE ("выполнение  действие № 5") 
   CASE(6)
      LOGWRITE ("выполнение  действие № 6")
   CASE(7)
      LOGWRITE ("выполнение  действие № 7") 
   CASE(8)
      LOGWRITE ("выполнение  действие № 8") 
   CASE(9)
      LOGWRITE ("выполнение  действие № 9") 
   CASE(10)
      LOGWRITE ("выполнение  действие № 10") 
   CASE(11)
      LOGWRITE ("выполнение  действие № 11")
   END_SWITCH
END_CYC
HALT  // выход

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Re: Как изменить RND на несколько действий
« Reply #4 on: September 22, 2017, 09:09:42 PM »
Вместо передвигания всех последующих элементов, можно просто скопировать последний на i-тое место. И pop().
Нам ведь не нужно соблюдать порядок.


dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Как изменить RND на несколько действий
« Reply #5 on: September 22, 2017, 09:52:18 PM »
Вместо передвигания всех последующих элементов, можно просто скопировать последний на i-тое место. И pop().
Нам ведь не нужно соблюдать порядок.
Можно пример? Если я правильно понял твою мысль, то из этого ничего хорошего не выйдет.


Тфу ты, как только отправил сообщение, так сразу догнал о чем речь. Да, так намного проще и правильнее, не сразу в голове прокрутил удаление последнего элемента.
« Last Edit: September 22, 2017, 09:54:43 PM by dramster »

tmp~1

  • Освоившийся
  • **
  • Posts: 31
    • View Profile
Re: Как изменить RND на несколько действий
« Reply #6 on: September 22, 2017, 10:54:09 PM »
Подобное решение было уже - http://crapware.aidf.org/forum/index.php?topic=1965.msg11828#msg11828
только 23 строку поправить надо, чтобы больше одного раза подряд  скрипт выполнять можно было без ошибок.

Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
Re: Как изменить RND на несколько действий
« Reply #7 on: September 24, 2017, 08:51:49 AM »
Code: (clickermann) [Select]
$count = 4 // Количество рандомных действий 4 из 12

FOR($a=0,$a<12) // создаем массив из 12 номеров
   ARRPUSH($arr,$a+1)
END_CYC
FOR($i=ARRSIZE($arr)-1,($i>-1)&($i>ARRSIZE($arr)-($count+1)),-1)
   $n = RND(0,$i)
   SWITCH($arr[$n])
   CASE(1)
      LOGWRITE ("выполнение  действие № 1")
   CASE(2)
      LOGWRITE ("выполнение  действие № 2")
   CASE(3)
      LOGWRITE ("выполнение  действие № 3")
   CASE(4)
      LOGWRITE ("выполнение  действие № 4")
   CASE(5)
      LOGWRITE ("выполнение  действие № 5")
   CASE(6)
      LOGWRITE ("выполнение  действие № 6")
   CASE(7)
      LOGWRITE ("выполнение  действие № 7")
   CASE(8)
      LOGWRITE ("выполнение  действие № 8")
   CASE(9)
      LOGWRITE ("выполнение  действие № 9")
   CASE(10)
      LOGWRITE ("выполнение  действие № 10")
   CASE(11)
      LOGWRITE ("выполнение  действие № 11")
   CASE(12)
      LOGWRITE ("выполнение  действие № 12")
   END_SWITCH
   $arr[$n] = $arr[$i]
   $tmp = ARRPOP($arr)
END_CYC

HALT
« Last Edit: September 24, 2017, 08:27:03 PM by Oraven »

tmp~1

  • Освоившийся
  • **
  • Posts: 31
    • View Profile
Re: Как изменить RND на несколько действий
« Reply #8 on: September 24, 2017, 06:55:46 PM »
Кто нибудь может объяснить как работает ARRPOP($arr)? Эта функция должна удалять из массива последний элемент. Но делает это не всегда. Почему? И как надо её применять, чтобы код был верным?

Пояснения в коде ниже - строки 36-38 и 42

Code: (clickermann) [Select]
$count = 4 // Количество рандомных действий 4 из 12

FOR($a=0,$a<12) // создаем массив из 12 номеров
   ARRPUSH($arr,$a+1)
END_CYC
FOR($i=ARRSIZE($arr)-1,($i>-1)&($i>ARRSIZE($arr)-($count+1)),-1)
   $n = RND(0,$i)
   SWITCH($arr[$n])
   CASE(1)
      LOGWRITE ("выполнение  действие № 1")
   CASE(2)
      LOGWRITE ("выполнение  действие № 2")
   CASE(3)
      LOGWRITE ("выполнение  действие № 3")
   CASE(4)
      LOGWRITE ("выполнение  действие № 4")
   CASE(5)
      LOGWRITE ("выполнение  действие № 5")
   CASE(6)
      LOGWRITE ("выполнение  действие № 6")
   CASE(7)
      LOGWRITE ("выполнение  действие № 7")
   CASE(8)
      LOGWRITE ("выполнение  действие № 8")
   CASE(9)
      LOGWRITE ("выполнение  действие № 9")
   CASE(10)
      LOGWRITE ("выполнение  действие № 10")
   CASE(11)
      LOGWRITE ("выполнение  действие № 11")
   CASE(12)
      LOGWRITE ("выполнение  действие № 12")
   END_SWITCH
   $arr[$n] = $arr[$i]
   
   ARRPOP($arr) // скрипт работает правильно; массив НЕ очищается
   //   $del = ARRPOP($arr) // скрипт работает НЕ правильно; массив очищается
   //   LOGWRITE (ARRPOP($arr)) // скрипт работает НЕ правильно; массив очищается
   
END_CYC

TFWRITEARR("file.txt", $arr) // почему в файле остался мусор?

HALT

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Re: Как изменить RND на несколько действий
« Reply #9 on: September 24, 2017, 07:32:01 PM »
Arrpop должна всегда возвращать значение в переменную, иначе не работает.
Джонни объяснял, что это нормально для функции, но я такого прикола не понял. Обычно функциям плевать куда мы возвращаем значения, хоть в переменную, хоть в поток вывода, хоть в никуда. Как это может влиять на извлечение переменной мне непонятно. Но запомнил и применяю так, как задумал автор.


Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
Re: Как изменить RND на несколько действий
« Reply #10 on: September 24, 2017, 08:31:18 PM »
Действительно нужно возвращать куда то иначе не работает. Просто скатал из примера как было, у себя исправил.

tmp~1

  • Освоившийся
  • **
  • Posts: 31
    • View Profile
Re: Как изменить RND на несколько действий
« Reply #11 on: September 24, 2017, 09:46:58 PM »
[spoiler=Цитата]

Code: (clickermann) [Select]
$count = 4 // Количество рандомных действий 4 из 12

FOR($a=0,$a<12) // создаем массив из 12 номеров
   ARRPUSH($arr,$a+1)
END_CYC
FOR($i=ARRSIZE($arr)-1,($i>-1)&($i>ARRSIZE($arr)-($count+1)),-1)
   $n = RND(0,$i)
   SWITCH($arr[$n])
   CASE(1)
      LOGWRITE ("выполнение  действие № 1")
   CASE(2)
      LOGWRITE ("выполнение  действие № 2")
   CASE(3)
      LOGWRITE ("выполнение  действие № 3")
   CASE(4)
      LOGWRITE ("выполнение  действие № 4")
   CASE(5)
      LOGWRITE ("выполнение  действие № 5")
   CASE(6)
      LOGWRITE ("выполнение  действие № 6")
   CASE(7)
      LOGWRITE ("выполнение  действие № 7")
   CASE(8)
      LOGWRITE ("выполнение  действие № 8")
   CASE(9)
      LOGWRITE ("выполнение  действие № 9")
   CASE(10)
      LOGWRITE ("выполнение  действие № 10")
   CASE(11)
      LOGWRITE ("выполнение  действие № 11")
   CASE(12)
      LOGWRITE ("выполнение  действие № 12")
   END_SWITCH
   $arr[$n] = $arr[$i]
   $tmp = ARRPOP($arr)
END_CYC

HALT

[/spoiler]

Странно вот что. Если возвращать из ARRPOP() в переменную - $tmp = ARRPOP($arr), то код перестает работать как задумано. :(
В логе:
Code: [Select]
21:34:27 выполнение  действие № 8
21:34:27 выполнение  действие № 10
21:34:27 выполнение  действие № 4
21:34:27 выполнение  действие № 1
21:34:27 выполнение  действие № 2
21:34:27 выполнение  действие № 3
21:34:27 выполнение  действие № 11
21:34:27 выполнение  действие № 5
21:34:27 выполнение  действие № 7
21:34:27 выполнение  действие № 6
21:34:27 выполнение  действие № 9
21:34:27 выполнение  действие № 12

Может это только у меня так работает?
Clickermann v4.12 (build 001); Windows 7(x64)


UPD: Попробовал создавать массив другими способами. Есть такая беда с массивами.

Code: (clickermann) [Select]
// Так
$arr[0] = 1
$arr[1] = 2
$arr[2] = 3
$arr[3] = 4
$arr[4] = 5
$arr[5] = 6
$arr[6] = 7
$arr[7] = 8
$arr[8] = 9
$arr[9] = 10
$arr[10] = 11
$arr[11] = 12

// И так
STRSEPARATE("1:2:3:4:5:6:7:8:9:10:11:12", ":", $arr)

Но не помогло. :(
А если получать элементы массива не через ARRPOP($arr), то весь алгоритм рассыпается. :-\

« Last Edit: September 24, 2017, 10:30:13 PM by tmp~1 »

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Как изменить RND на несколько действий
« Reply #12 on: September 24, 2017, 11:22:29 PM »

Странно вот что. Если возвращать из ARRPOP() в переменную - $tmp = ARRPOP($arr), то код перестает работать как задумано. :(


дело тут совсем не в ARRPOP(). он всегда работал и работает как задумывалось.

тут дело в неправильном условии цикла for. ($i>ARRSIZE($arr)-($count+1)) - а никто не заметил, что количество элементов массива постоянно уменьшается? нужно ведь отталкивакться от первоначального значения количества элементов. в данном случае это $a. правильно - ($i>$a-($count+1))

Code: (clickermann) [Select]
$count = 5 // Количество рандомных действий 4 из 12
 
FOR($a=0,$a<12) // создаем массив из 12 номеров
   ARRPUSH($arr,$a+1)
END_CYC
FOR($i=ARRSIZE($arr)-1,($i>-1)&($i>$a-($count+1)),-1)
   $n = RND(0,$i)
   SWITCH($arr[$n])
   CASE(1)
      LOGWRITE ("выполнение  действие № 1")
   CASE(2)
      LOGWRITE ("выполнение  действие № 2")
   CASE(3)
      LOGWRITE ("выполнение  действие № 3")
   CASE(4)
      LOGWRITE ("выполнение  действие № 4")
   CASE(5)
      LOGWRITE ("выполнение  действие № 5")
   CASE(6)
      LOGWRITE ("выполнение  действие № 6")
   CASE(7)
      LOGWRITE ("выполнение  действие № 7")
   CASE(8)
      LOGWRITE ("выполнение  действие № 8")
   CASE(9)
      LOGWRITE ("выполнение  действие № 9")
   CASE(10)
      LOGWRITE ("выполнение  действие № 10")
   CASE(11)
      LOGWRITE ("выполнение  действие № 11")
   CASE(12)
      LOGWRITE ("выполнение  действие № 12")
   END_SWITCH
   $arr[$n] = $arr[$i]
   $tmp = ARRPOP($arr)
END_CYC
 
HALT

Code: [Select]
23:14:40 выполнение  действие № 3
23:14:40 выполнение  действие № 11
23:14:40 выполнение  действие № 5
23:14:40 выполнение  действие № 4
23:14:40 выполнение  действие № 10

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Как изменить RND на несколько действий
« Reply #13 on: September 25, 2017, 12:22:35 AM »

Code: (clickermann) [Select]
$count = 5 // Количество рандомных действий 4 из 12
 
FOR($a=0,$a<12) // создаем массив из 12 номеров
   ARRPUSH($arr,$a+1)
END_CYC
FOR($i=ARRSIZE($arr)-1,($i>-1)&($i>$a-($count+1)),-1)
   $n = RND(0,$i)
   SWITCH($arr[$n])
   CASE(1)
      LOGWRITE ("выполнение  действие № 1")
   CASE(2)
      LOGWRITE ("выполнение  действие № 2")
   CASE(3)
      LOGWRITE ("выполнение  действие № 3")
   CASE(4)
      LOGWRITE ("выполнение  действие № 4")
   CASE(5)
      LOGWRITE ("выполнение  действие № 5")
   CASE(6)
      LOGWRITE ("выполнение  действие № 6")
   CASE(7)
      LOGWRITE ("выполнение  действие № 7")
   CASE(8)
      LOGWRITE ("выполнение  действие № 8")
   CASE(9)
      LOGWRITE ("выполнение  действие № 9")
   CASE(10)
      LOGWRITE ("выполнение  действие № 10")
   CASE(11)
      LOGWRITE ("выполнение  действие № 11")
   CASE(12)
      LOGWRITE ("выполнение  действие № 12")
   END_SWITCH
   $arr[$n] = $arr[$i]
   $tmp = ARRPOP($arr)
END_CYC
 
HALT


но както сложно для понимания вы тут это все замутили. можно же проще и без кучи условий.
Code: (clickermann) [Select]
STRSEPARATE ("4,5,6,7,8,9,10,11", ",", $arr)  //массив из чисел


$n = 5 //указать число выполняемых действий

FOR($a=0,$a<$n) // повторяем $n раз
   
   $i = rnd(0,ARRSIZE($arr)-1)    //рандомный элемент массива.
   
   SWITCH(int($arr[$i]))
   CASE(4)
      LOGWRITE ("выполнение  действие № 4")
   CASE(5)
      LOGWRITE ("выполнение  действие № 5")
   CASE(6)
      LOGWRITE ("выполнение  действие № 6")
   CASE(7)
      LOGWRITE ("выполнение  действие № 7")
   CASE(8)
      LOGWRITE ("выполнение  действие № 8")
   CASE(9)
      LOGWRITE ("выполнение  действие № 9")
   CASE(10)
      LOGWRITE ("выполнение  действие № 10")
   CASE(11)
      LOGWRITE ("выполнение  действие № 11")
   END_SWITCH
   
   
   IF($i = ARRSIZE($arr)-1
      $del = ARRPOP($arr) //если это последний элемент, то делит
   ELSE
      $arr[$i] = ARRPOP($arr)   //последний элемент в место ипользованного
   END_IF
   
   
   
END_CYC
HALT  // выход

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Re: Как изменить RND на несколько действий
« Reply #14 on: September 25, 2017, 08:38:43 AM »
В такие трёхэтажные условия даже вчитываться лень. Тем более что простой ответ привели сразу.