Тоже задался этим вопросом (да знаю, опять археология, но вопрос на сколько понимаю всё еще открытый). Задача поистине нетривиальная и комплексная, по этому решил решать её по частям, начиная с более простого.
Может я конечно что-то пропустил, но не видел отсылок в данной теме, а тем не менее аспект не менее важный - любое реалистичное перемещение из точки А в точку Б по определению зависит от самих этих точек А и Б. т.к. начальная точка почти всегда известна, то остаётся конечная - другими словами: в основе реалистичного передвижения курсора лежит реалистичный выбор "конечного пункта назначения".
Мне кажется, что авторы зачастую если и задаются данным вопросом, то решают его через рандом - задаётся конечная точка+-какоето расстояние по бокам. И в целом это не плохой подход, т.к. размазывает места кликов, но есть одно но - rand() генерирует
равномерно распределённую случайную величину. Простыми словами для людей не особо знакомых с теорвером - в примере rand(1,10) шанс того что выпадет любой из возможных результатов одинаков(в данном случае 10%), т.е. получаем "1" с шансом в 10%, "2" с шансом в 10%, и т.д.
Когда же мы, люди, передвигаем кудато курсор, мы целимся априори в "центр" мишени. Но изза того что мы люди (а человеку свойственно ошибатся
), почти всегда промазываем попадая всё таки в некоторую окрестность центра. И при множественном повторении, случаев когда курсор в итоге оказался "ближе" к центру намного больше, чем тех где он в итоге оказался "дальше". И такое поведение очень хорошо, и в то же время довольно просто, моделируется
нормальным распределением. Для человека не знакомому с теорвером обьяснить его суть в двух словах наверное будет проблематично, но если просто и вкратце(на примере первого рисунка в вики, красный график) - по оси Х то куда по факту будет попадать курсор, центр мишени в данном случае - 0, по оси Y - вероятность того что мы получим соответствующее значение Х(конечную точку для курсора). Как видим - чем ближе к центру(в примере красного графика - 0), тем выше вероятность получить такое значение. Собственно то что нам и требуется - целимся в центр мишени, но в итоге получаем значение с некоторым отклонением, в то же время чем ближе к центру, тем выше вероятность получить данное значение.
На практике данный способ я реализовал через численный метод, описанный
здесь, "Метод генерации нормально распределенных чисел, использующий центральную предельную теорему"...вдруг ктото захочет ознакомится с первоисточником. Собственно, сам код:
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. мат. ожидание будет взята точка на краю мишени)
По этому в случаях динамичных целей применять данный метод нужно с осторожностью и полным пониманием того, что при неправильном выборе центра и отклонения, мы можем промазать.
В то же время, дабы не плодить лишний код, динамические случаи можно спокойно обрабатывать просто задавая "отклонение"(последний параметр, три "сигмы") равным нулю. При таком варианте получаем вырожденный случай, когда клик будет ровно в том месте, которое задано в качестве "центра мишени"(второй параметр, мат. ожидание "а")