Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Bitya

Pages: [1]
1
Есть скрипт 1. Далее идет развлетвление. Если нажать на Ctrl, он идет по одному сценарию, если Alt, то другой сценарий. Возможно?
Нажимать на Ctrl и Alt будет человек так понимаю, и таким способом управлять логикой работы скрипта?

2
2 dramster
Да, описанный тобой метод $rnd_x= $x + rnd(rnd(-100, 0),rnd(0, 100)) действительно даёт хорошие результаты, как-то даже и не приходил в голову подобный подход. Конечно, имитирует реальные клики он несколько хуже (вероятность попасть в конкретную точку, от края к центру, наростает линейно), но это с лихвой компенсируется и лучшей производительностью(выборка 5к чисел, 4 секунды против 12) и даже в большей степени - простотой реализации.
В общем, по сравнению с обычным рандомом $rnd_x= $x + rnd(-100,100) очень даже отличное решение.

Немного сравнительный тестов, для трёх вариантов рандомизации чисел. Первый рисунок - график вероятности получения конкретного числа(выборка 10к чисел, для наглядности отличий), из описанного выше тобой кода. У меня оно работает несколько кривовато, но общую суть показывает. Второй рисунок - как бы эти клики выглядели на плоскости(выборка 5к чисел).
Code: (clickermann) [Select]
//будет стремиться попасть в точку ($x, $y)
FOR($a=0,$a<5000)
   //1 вариант
   LCLICK($x + rnd(-100,100),$y + rnd(-100,100))
   //2 вариант
   LCLICK($x + rnd(rnd(-100, 0),rnd(0, 100)),$y + rnd(rnd(-100, 0),rnd(0, 100)))
   //3 вариант
   NormalDistribution("$x",$x,100)
   NormalDistribution("$y",$y,100)
   LCLICK($x,$y)
END_CYC
1) $rnd_x= $x + rnd(-100,100)
     
2) $rnd_x= $x + rnd(rnd(-100, 0),rnd(0, 100))
     
3) NormalDistribution("$rnd_x",$x,100)
     

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

p.s.:
Расчет по 5000 чисел (считает уж очень долго, нужно потерпеть).
В моём изначальном коде подправил параметр $n со 192 до 6(11-ая строка кода). На качество результата влият не особо, а с его увеличением производительность падает значительно.
График красивый, прям как на рисунках по твоим ссылкам. Только почему-то наблюдается небольшой сдвиг влево.
Проблема смещения в другом - ты в своём коде в блоке "//подсчет  вероятности попадания в одно число" используешь arrpush($graf, $b). В общем случае это вызывает неточность, т.к. оно просто накидывает сверху в массив количество уникальных результатов. Дело в том, что при 5000 выборке, мы не гарантированно получаем все возможные 200 уникальных чисел(из диапазона [-100;100]), и в таком случае итоговый массив $graf имеет меньшую длину чем 200, что в конечном итоге выражается в том что график сьезжает "влево".
А так как в моём варианте генерации случайных чисел, граничные значения имеют очень низкий шанс попастся(на порядки ниже, чем у тебя), то в выборке из 5000 их на много больше, и график сьезжает влево значительно ощутимей, что видно даже невооруженным глазом. Если же использовать $graf[$arr_target[$a]] = $b (т.е. на индекс сгенерированного числа будем записывать количество его появлений), то всё будет отображатся на графике правильно.
Я то понимаю что это всё писалось на коленке (и это не в коем случае не "предьява" :) ), но "сдвиг графика влево" это исключительно неточность визуализации полученного результата, а не его самого.


2 kiril
Прямоугольные сектора при обычном рандоме, дают гораздо более реалистичный разброс конечных координат передвижения.
Прямоугольные сектора при обычном рандоме, дают результаты описанные в варианте 1, а именно -

Где тут реалистичность - я не знаю.

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

4
2 Gluecat21
По картинке не находит вероятней всего потому, что либо сам камень немного меняет форму, либо меняется его фон. В любом случае - 100%-ого совпадения не получаем.
Кодом не помогу, но могу подсказать примерный алгоритм:
1) Скриним требуемый камень через colormod с нужной цветокоррекцией(тут только на практике подбирать), сохраняем скрин
2) Далее работаем уже со скрином. Через лупу выбираем цвет пикселей и их количество, которые одновременно:
а). Наиболее точно и полно характеризуют данный камень
б). Как можно меньше коррелируют(совпадают\попадаются) со всей остальной картинкой, дабы избежать ложных обнаружений
3). Таким образом мы получаем "цветовую характеристику" этого камня - например 150 желтых пикселей, 73 зелёных и 230 красных.
4). Всё что выше - подготовка и просто сбор данных, далее уже код в итоговом скрипте
5). Во время игры сканируем экран на наличие тех самых ранее отобранных цветных пикселей
6). В случае нахождения требуемых цветов расчитываем область, относительно найденного пикселя, скажем 100*100 пикселей(по размеру того самого нужного камня)
7). В этой области, 100*100, посчитываем количество наших характеризующих цветных пикселей. Далее варианты:
а). Если количество пикселей совпадает с тем что мы заранее насчитали в шаге 2), не точно конечно, а скажем +-10% - 144 желтых, 77 зелёных и 217 красных, то с больной доле вероятности можно сказать, что в нашей области 100*100 реально находится нужный камень, кликаем по нему и т.д.
б). Если количество пикселей не совпадает, то мы просто попали на пиксели такого же цвета, относящиеся к другим элементам картинки. Ничего не делаем, продолжаем поиск\другие_действия и т.д.

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

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

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

Мне кажется, что авторы зачастую если и задаются данным вопросом, то решают его через рандом - задаётся конечная точка+-какоето расстояние по бокам. И в целом это не плохой подход, т.к. размазывает места кликов, но есть одно но - rand() генерирует равномерно распределённую случайную величину. Простыми словами для людей не особо знакомых с теорвером - в примере rand(1,10) шанс того что выпадет любой из возможных результатов одинаков(в данном случае 10%), т.е. получаем "1" с шансом в 10%, "2" с шансом в 10%, и т.д.

Когда же мы, люди, передвигаем кудато курсор, мы целимся априори в "центр" мишени. Но изза того что мы люди (а человеку свойственно ошибатся ;D), почти всегда промазываем попадая всё таки в некоторую окрестность центра. И при множественном повторении, случаев когда курсор в итоге оказался "ближе" к центру намного больше, чем тех где он в итоге оказался "дальше". И такое поведение очень хорошо, и в то же время довольно просто, моделируется нормальным распределением. Для человека не знакомому с теорвером обьяснить его суть в двух словах наверное будет проблематично, но если просто и вкратце(на примере первого рисунка в вики, красный график) - по оси Х то куда по факту будет попадать курсор, центр мишени в данном случае - 0, по оси Y - вероятность того что мы получим соответствующее значение Х(конечную точку для курсора). Как видим - чем ближе к центру(в примере красного графика - 0), тем выше вероятность получить такое значение. Собственно то что нам и требуется - целимся в центр мишени, но в итоге получаем значение с некоторым отклонением, в то же время чем ближе к центру, тем выше вероятность получить данное значение.

На практике данный способ я реализовал через численный метод, описанный здесь, "Метод генерации нормально распределенных чисел, использующий центральную предельную теорему"...вдруг ктото захочет ознакомится с первоисточником. Собственно, сам код:
Code: (clickermann) [Select]
SUB(NormalDistribution, $y_nd, $a_nd, $sigma_max)//немного слов о параметрах
                                                 //$y_nd - "ссылка" на переменную куда запишем результат
                                                 //$a_nd - "математическое ожидание", или простыми словами - центр мишени
                                                 //$sigma_max - три "средних отклонения", или простыми словами -
                                                 //радиус в который смоделированное итоговое значение попадет с шансом в 99+%.
                                                 //другими словами - $sigma_max задает интервал, относитительно центра,
                                                 //вокруг которого будем получать значения
                                                 
                                                 
   $result = 0
   $n = 6                                       //на сколько понял, n задаёт точность приближения к нормальному распределению
                                                 //чем больше тем лучше, но на практике вероятно хватит и меньших значений
                                                 //не уверен что можно брать любое число, я бы брал кратное 6
                                                 
   $sigma_nd = $sigma_max/3                      //переводим человеко-понятное значение интервала +-значений в "среднее отклонение"
                                                 //далее просто реализация алгоритма
   label_nd:
   $V = 0
   FOR($i=0, $i < $n)
      $r_i = RND(0,10000)
      $V = $V + $r_i
   END_CYC
   $V = $V/10000
   $Z = ($V - $n/2)/SQRT($n/12)
   $result = ROUND($Z*$sigma_nd + $a_nd,0)
   IF(ABS($result - $a_nd)>$sigma_max)           //проверка на то, что в итоге мы попали в заданный $sigma_max интервал
                                                 //т.к. есть шанс около ~0.3% что полученное значение будет лежать
                                                 //за его пределами, то в таком случае просто пересчитываем по новой
      LOGWRITE("")
      LOGWRITE("Выход случайного числа за заданный предел!")
      LOGWRITE("Ожидали ",$a_nd,"+-",$sigma_max,"; Получили ", $result)
      LOGWRITE("")
      GOTO(label_nd)
   END_IF
   SETVAR($y_nd, $result)
END_SUB


$target = 0//результирующее значение
NormalDistribution("$target",950,800)//передаём его в процедуру по "ссылке", что позволит
                                     //нам его  использовать дальше в том же блоке кода.
                                     //на выходе получаем уже число с нормальным распределением
                                     
$target = ROUND($target,0)           //округляем до целых
MOVE($target,500)                    //перемещаем курсор и кликаем
LDOWN($target, 500)
WAITMS(50)
LUP($target, 500)
WAITMS(50)

HALT

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

!!Важно - заданные в примере параметры "мат. ожидания" и "3*отклонения"(950 и 800 соответственно) выбраны для Full HD разрешения(1920 пикселов по иксу) - будем получать значения в интервале от 150 до 1750, с центром в 950. Для других разрешений выбирайте соответствующие параметры(для HD например 640 и 500)!!

Еще важно: данный подход хорошо подходит для кликанья по статичным элементам, для которых заранее известны их размеры(чтобы знать какое отклонение брать). В случае же динамичных и\или движущихся целей эффективность его под вопросом:
1). Некоторый элемент случайности места нажатия задаётся самой случайностью местонахождения цели, т.е. мы уже по определению не кликаем в "одну и ту же точку на кнопке"
2). т.к. итоговую координату мы всё же получаем в некоторой окрестности, то в случае динамической цели невозможно точно расчитать отклонение чтобы оно со 100% попадало в пределы цели, и есть шанс кликнуть мимо (например если за "центр" a.k.a. мат. ожидание будет взята точка на краю мишени)
По этому в случаях динамичных целей применять данный метод нужно с осторожностью и полным пониманием того, что при неправильном выборе центра и отклонения, мы можем промазать.
В то же время, дабы не плодить лишний код, динамические случаи можно спокойно обрабатывать просто задавая "отклонение"(последний параметр, три "сигмы") равным нулю. При таком варианте получаем вырожденный случай, когда клик будет ровно в том месте, которое задано в качестве "центра мишени"(второй параметр, мат. ожидание "а")

6
Ошибки / Re: Параметры подпрограммы
« on: January 30, 2020, 05:04:57 PM »
Уже давно есть GETVAR/SETVAR
Да, тоже решение. Но как по мне - обращатся к элементам массива через array[index] всё же поудобней чем через конструкции GETVAR/SETVAR.
В прочем, описанный ранее мною способ подходит только для передачи данных "в". Для возвращения значений, вообще любых и массивов в частности, "из" процедуры без GETVAR/SETVAR не обойтись.

Так уже все есть  - ARRCONCAT

На деле это будет как-то так (не совсем то что требовалось, но работать должно быстро и без лишних заморочек):
В данном примере всёравно процедура обращается к глобальной переменной. Суть темы же в том, чтобы передавать массив в процедуру параметром.

p.s. А что за функция ARRCONCAT такая? В версии 4.13 об ней не слова нету в справке.

7
Ошибки / Re: Параметры подпрограммы
« on: January 21, 2020, 07:02:24 PM »
Не знаю на сколько актуально, и заранее извиняюсь за археологию, но даже при одной мысли о массовом использовании нечто подобного, сразу хочется ударить себя молотком по пальцам ;D
Зачем вообще нужно передавать массив в вызов саба, если внутри саба ваш заранее инициилизированый массив и так будет доступен, ведь в кликермане все переменные изначально публичны/глобальны.
Всё же не кошерно везду и всюду работать с глобальными переменными.

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

В коде это должно выглядеть примерно так

Code: (clickermann) [Select]
SUB(ArrSmpl, $LocalString)
   STRSEPARATE($LocalString,"_",$LocalArray) //парсим сроку в УЖЕ локальный массив по заранее заданному разделителю
   FOR($i=0, $i < ARRSIZE($LocalArray))
      LOGWRITE($LocalArray[$i]) //ну и дальше можно работать с элементами массива как нам удобно
   END_CYC
END_SUB


$GlobalArray[0] = 1 //инициализируем переменные
$GlobalArray[1] = 2
$GlobalArray[2] = 3
$GlobalArray[3] = 4
$GlobalArray[4] = 5

$string = ""
FOR($i=0, $i < ARRSIZE($GlobalArray)) //запихиваем элементы массива в строку
   $string = STRCONCAT($string,$GlobalArray[$i],"_") //разделителем в данном случае выступает нижнее подчеркивание
END_CYC
ArrSmpl($string)

HALT

По идее, аналогичным способом можно и возвращать массивы из процедур. Надеюсь кому-то будет полезным.

Pages: [1]