Автокликер Clickermann :: Форум

Основной раздел => Общие вопросы => Topic started by: bulgachevarada on September 19, 2017, 05:39:25 PM

Title: Как изменить RND на несколько действий
Post by: bulgachevarada on September 19, 2017, 05:39:25 PM
Подскажите пожалуйста, как сделать чтоб макрос например из восьми действий выполнял в случайном порядке допустим 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

Тогда как сделать задать что б выпадало несколько сразу чисел и выполнить именно номера действий что будут
Title: Re: Как изменить RND на несколько действий
Post by: bulgachevarada on September 20, 2017, 09:23:49 AM
Спасибо большое!!
Title: Re: Как изменить RND на несколько действий
Post by: bulgachevarada 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 не видит, только работает если сменить на буквы переменные, но это очень не удобно(
Title: Re: Как изменить RND на несколько действий
Post by: dramster 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  // выход
Title: Re: Как изменить RND на несколько действий
Post by: Vint on September 22, 2017, 09:09:42 PM
Вместо передвигания всех последующих элементов, можно просто скопировать последний на i-тое место. И pop().
Нам ведь не нужно соблюдать порядок.
Title: Re: Как изменить RND на несколько действий
Post by: dramster on September 22, 2017, 09:52:18 PM
Вместо передвигания всех последующих элементов, можно просто скопировать последний на i-тое место. И pop().
Нам ведь не нужно соблюдать порядок.
Можно пример? Если я правильно понял твою мысль, то из этого ничего хорошего не выйдет.


Тфу ты, как только отправил сообщение, так сразу догнал о чем речь. Да, так намного проще и правильнее, не сразу в голове прокрутил удаление последнего элемента.
Title: Re: Как изменить RND на несколько действий
Post by: tmp~1 on September 22, 2017, 10:54:09 PM
Подобное решение было уже - http://crapware.aidf.org/forum/index.php?topic=1965.msg11828#msg11828
только 23 строку поправить надо, чтобы больше одного раза подряд  скрипт выполнять можно было без ошибок.
Title: Re: Как изменить RND на несколько действий
Post by: Oraven 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
Title: Re: Как изменить RND на несколько действий
Post by: tmp~1 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
Title: Re: Как изменить RND на несколько действий
Post by: Vint on September 24, 2017, 07:32:01 PM
Arrpop должна всегда возвращать значение в переменную, иначе не работает.
Джонни объяснял, что это нормально для функции, но я такого прикола не понял. Обычно функциям плевать куда мы возвращаем значения, хоть в переменную, хоть в поток вывода, хоть в никуда. Как это может влиять на извлечение переменной мне непонятно. Но запомнил и применяю так, как задумал автор.
Title: Re: Как изменить RND на несколько действий
Post by: Oraven on September 24, 2017, 08:31:18 PM
Действительно нужно возвращать куда то иначе не работает. Просто скатал из примера как было, у себя исправил.
Title: Re: Как изменить RND на несколько действий
Post by: tmp~1 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), то весь алгоритм рассыпается. :-\

Title: Re: Как изменить RND на несколько действий
Post by: dramster 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
Title: Re: Как изменить RND на несколько действий
Post by: dramster 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  // выход
Title: Re: Как изменить RND на несколько действий
Post by: Vint on September 25, 2017, 08:38:43 AM
В такие трёхэтажные условия даже вчитываться лень. Тем более что простой ответ привели сразу.
Title: Re: Как изменить RND на несколько действий
Post by: tmp~1 on September 25, 2017, 01:43:23 PM

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


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

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

Спасибо. :) Еще раз убеждаюсь что КМ не ошибается, а ошибается сам пользователь. Условие проверить я почему-то не посчитал нужным, несогласен был только с записью ARRPOP(). Вечером попробую всё это осмыслить..., сейчас нет времени.
Title: Re: Как изменить RND на несколько действий
Post by: tmp~1 on September 26, 2017, 06:46:41 AM
Arrpop должна всегда возвращать значение в переменную, иначе не работает.
Джонни объяснял, что это нормально для функции, но я такого прикола не понял. Обычно функциям плевать куда мы возвращаем значения, хоть в переменную, хоть в поток вывода, хоть в никуда. Как это может влиять на извлечение переменной мне непонятно. Но запомнил и применяю так, как задумал автор.

Спасибо  :)