1 (изменено: to4er, 2015-02-14 13:22:43)

Тема: AHK: Random, настройка вероятности выпадения двух чисел

В общем, надо написать функцию которая бы брала диапазон в пределах не целого значения переменной и генерерировала бы несколько округленных до целого значений. Пока теряюсь с чего вообще начать, но выглядеть это должно так:
1. Значение переменной, к примеру, 7.600
2. Вывод 10 случайных результатов таков: 7, 7, 7, 7, 8, 8, 8, 8, 8, 8 (в случайном порядке, естественно)

2

Re: AHK: Random, настройка вероятности выпадения двух чисел

Так, наверно:


Random, Number, 7.0, 7.6
Number := Round(Number)

3 (изменено: to4er, 2015-02-14 13:26:47)

Re: AHK: Random, настройка вероятности выпадения двух чисел

Аргумент должен быть один. Его значение после запятой должно регулировать вероятность выпадения одного из двух чисел. То есть, если это 7.6 - то 60%, что выпадет 8, и 40% - что 7.

4 (изменено: to4er, 2015-02-14 09:40:01)

Re: AHK: Random, настройка вероятности выпадения двух чисел

Разобрался:

#NoEnv
#Warn
SendMode Input
var := 1.7
F12::
roundvar := Round(var, 0)
if roundvar > var
{
difvar := roundvar - var
limvar := var - difvar
}
else
{
difvar := var - roundvar
limvar := var + difvar
}
Random, randvar, limvar, roundvar
randvar := Round(randvar, 0)

SendInput %randvar%

Но рэндом работает очень странно, допустим если я укажу var := 1.8, то при большом количестве генераций он выдаст не 20% результата равного 1 и 80% равного двум - а 100% равного 2. И только игра коэффициентами около х.5 значений выдает какие-то результаты.

5

Re: AHK: Random, настройка вероятности выпадения двух чисел

Так это ваш скрипт в целом, наверно, странно работает, а не Random.

6

Re: AHK: Random, настройка вероятности выпадения двух чисел

Извиняюсь, сам не понял что написал. Вот исправленная версия:

#NoEnv
#Warn
SendMode Input
var := 5.5
F12::
roundvar := Round(var, 0)
if roundvar > %var%
{
difvar := 1 + var - roundvar
procvar := 0.5 / difvar
limvar := roundvar - procvar
}
else
{
difvar := 1 - var + roundvar
procvar := 0.5 / difvar
limvar := roundvar + procvar
}
Random, randvar, limvar, roundvar
randvar := Round(randvar, 0)
SendInput %randvar%

Но, вот, только как мне обуздать этот рэндом? Чтобы, если я указал, к примеру 5.9 то вылетало из 10 - 9 шестерок и 1 пятерка? Это необходимо, а выходит очень уж случайно.

7 (изменено: Alectric, 2015-02-14 13:44:23)

Re: AHK: Random, настройка вероятности выпадения двух чисел

Не знаю подойдет ли:

#NoEnv
;#Warn
SendMode Input
var := 5.5
F12::
avar:=(var-var//1)*10
loop,% avar
  rand.=Round(var//1) "`n"
loop,% 10-avar
  rand.=Round(var//1+1) "`n"
Sort,rand,Random

stringreplace,rand,rand,`n,`,,all
msgbox,% rand
return

Win 7 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

8

Re: AHK: Random, настройка вероятности выпадения двух чисел

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


#NoEnv
SendMode Input
var := 5.5
rand := Correct(var)
F12::
SendInput %rand%

Correct(x)
{
roundvar := Round(var, 0)
if roundvar > %var%
{
difvar := 1 + var - roundvar
procvar := 0.5 / difvar
limvar := roundvar - procvar
}
else
{
difvar := 1 - var + roundvar
procvar := 0.5 / difvar
limvar := roundvar + procvar
}
Random, randvar, limvar, roundvar
randvar := Round(randvar, 0)
return randvar
}

9 (изменено: Alectric, 2015-02-14 14:20:25)

Re: AHK: Random, настройка вероятности выпадения двух чисел

Correct(x)

Внутри функции объявлена переменная x, но нигде далее не использована.

Correct(var)
Win 7 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

10 (изменено: Irbis, 2015-02-14 18:06:18)

Re: AHK: Random, настройка вероятности выпадения двух чисел

Функция:

Rand(t) {
   Random, b, 0, 1.0
   Return Floor(t) + ((t-Floor(t)) > b)
}

Проверка работы:

V := 2.7 ; (2 - 30%, 3 - 70% на большой дистанции)
loop 10
   SendInput % Rand(V) " " 
; проверка среднего значения на 1000 итераций
count := 0
Loop 1000 {
   count+=Rand(V)
}
MsgBox % count/1000
Return

Rand(t) {
   Random, b, 0, 1.0
   Return Floor(t) + ((t-Floor(t)) > b)
}

11

Re: AHK: Random, настройка вероятности выпадения двух чисел

v := 7.600

RegExMatch(v, "(.*)\.(.)", p)  
loop 10
   r .= (A_Index > p2 ? p1 : p1 + 1) . (A_Index < 10 ? "," : "")
Sort, r, Random D,
StringReplace, r, r, `,, `,%A_Space%, 1
MsgBox % r
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.09 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

12 (изменено: Alectric, 2015-02-15 00:12:38)

Re: AHK: Random, настройка вероятности выпадения двух чисел

Так работает, но первое нажатие не считается.

#NoEnv
SendMode Input

var := 5.5
avar:=(var-var//1)*10
loop,% avar
  rand.=Round(var//1) "`n"
loop,% 10-avar
  rand.=Round(var//1+1) "`n"

F12::
now:=now="" ? 1 : now=10 ? 1 : now+1
if now=1
{
  Sort,rand,Random
  loop,parse,rand,`n
    rand%a_index%:=a_loopfield
send,{enter}  ; -------------------------для проверки---------------------
}
SendInput % rand%now%
return


Win 7 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

13

Re: AHK: Random, настройка вероятности выпадения двух чисел

Какие мудреные конструкции, вместо функции из пары строк. А если соотношение вероятностей не кратно 10, например для 6.425?

14 (изменено: serzh82saratov, 2015-02-15 01:46:53)

Re: AHK: Random, настройка вероятности выпадения двух чисел

Так в шапке речь только про 10 случайных результатов. Значит 6.425 = 6.4.
Ну ещё можно тут добавить округление до десятых.

v := 6.425
RegExMatch(Round(v, 1), "(.*)\.(.)", p)  
loop 10
   r .= (A_Index > p2 ? p1 : p1 + 1) . (A_Index < 10 ? "," : "")
Sort, r, Random D,
StringReplace, r, r, `,, `,%A_Space%, 1
MsgBox % r

А вот про необходимость тысячи результатов, я видимо где то далее непрочитал.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.09 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

15

Re: AHK: Random, настройка вероятности выпадения двух чисел

Хм..  О таком варианте я не подумал, что нужна просто последовательность с определенным соотношением чисел, хотя это наиболее очевидно из ТЗ. В моей же функции соотношение выполняется для больших последовательностей, а для 10 чисел разброс может быть значительным в обе стороны. Тогда ваш вариант правильный.

16

Re: AHK: Random, настройка вероятности выпадения двух чисел

Возможно, хотя ТЗ конечно немного размытое.
Да, и RegEx тут излишний.

v := 6.425
p1 := Floor(v), p2 := Round(v - p1, 1) * 10 
loop 10
   r .= (A_Index > p2 ? p1 : p1 + 1) . (A_Index < 10 ? "|" : "")
Sort, r, Random D|
StringReplace, r, r, |, `,%A_Space%, 1
MsgBox % r
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.09 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

17

Re: AHK: Random, настройка вероятности выпадения двух чисел

Так лучше, все-таки RegEx'ы не так очевидны в работе. А зачем StringReplace? (Он тут лишний, на мой взгляд).
И все это дело обернуть в функцию, как хотел ТС.

MsgBox % Rand(6.4)

Rand(v)
{
   p1 := Floor(v), p2 := Round(v - p1, 1) * 10 
   loop 10
      r .= (A_Index > p2 ? p1 : p1 + 1) . (A_Index < 10 ? "," : "")
   Sort, r, Random D,
   Return r
}

18

Re: AHK: Random, настройка вероятности выпадения двух чисел

Так лучше, все-таки RegEx'ы не так очевидны в работе.

В первую очередь из соображений производительности.

А зачем StringReplace?

Как зачем, в ТЗ после запятых пробелы.

И все это дело обернуть в функцию, как хотел ТС.

Ну, это нелёгкое дело, можно переложить и на плечи ТС.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.09 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

19

Re: AHK: Random, настройка вероятности выпадения двух чисел

В первую очередь из соображений производительности.

Не думаю, что мат.операции проиграют в скорости RegEx, конечно можно устроить "полевые испытания", но вряд ли это имеет большое значение - скорость не относится к числу сильных сторон AHK.

Как зачем, в ТЗ после запятых пробелы.

Сейчас понятно, хотя посты #4 и #6 указывают, что готовая строка не нужна, a  нужно элементы выводить по одному посредством SendInput. Все-таки сумбурность изложения ТЗ располагает к полету фантазии помогающих решить задачу. Так что можно обратно парсить строку для поэлементного вывода, или использовать массив:

F12::
   if !(Arr.MaxIndex())
   {
      Arr:=Rand(6.4)
      SendInput % " " ; для наглядности
   }
   SendInput % Arr.Remove()
Return

Rand(v) {
   r := [], b := 1, p1 := Floor(v), p2 := Round(v - p1, 1) * 10 
   loop 10
      Random, b, r.Insert(b, p1+(A_Index > p2)), r.MaxIndex() ? r.MaxIndex()+1 : 1
   Return r
}

В этом примере каждые 10 элементов (1-10, 11-20 и т.д.) строго в указанной пропорции, в отличие от поста #10.

20 (изменено: to4er, 2015-02-15 16:01:21)

Re: AHK: Random, настройка вероятности выпадения двух чисел

Спасибо огромное за количество вариантов, объясню ТЗ . Нужен no recoil для шутера. Чтобы прицел не дергался, я указываю  задержку в 25 мс. Но количества пикселей, на которые корректируется прицел при такой задержке, не всегда достаточно для точной правки отдачи. То есть, если если я укажу для определенного ствола 2, то прицел может уходить вверх, а укажу 3 - может чрезмерно крениться вниз. Поэтому мне нужны более мягкие коэффициенты, в пределах одного знака после запятой достаточно. Я не видел решения, как разделить пиксели, и хотел это сделать через Random. Есть один минус - рэндом такой рэндом, что может в пределах очереди в 5 выстрелов, при указании коэффициента 2.5 выдать пять двоек или пять троек, но все же в долгосрочной перспективе будет более точным, чем указать 2 или 3. Я просто не могу осилить, как написать функцию, чтобы при указании 2.7 вне зависимости от количества итераций у меня выходило в среднем приближенно к 2.7 и при этом функция выдавала бы правильный результат даже если сделано всего два выстрела.
Вывод в виде sendinput  тут только для наглядности, чтобы увидеть как оно работает в блокноте, на самом деле нужна именно функция, которая обрабатывает переменную.

21

Re: AHK: Random, настройка вероятности выпадения двух чисел

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

F12::
loop 10
   SendInput % Rand(2.75) " "
   SendInput |{Space}
Return

Rand(t) {
   static d := 0
   r := Round(t+d), d += t - r
   Return r
}

22

Re: AHK: Random, настройка вероятности выпадения двух чисел

Irbis, это золото, я в шоке. Alectric, serzh82saratov так же огромное спасибо. Благодаря таким людям как вы хаос немного упорядочивается .

23 (изменено: serzh82saratov, 2015-02-15 22:59:55)

Re: AHK: Random, настройка вероятности выпадения двух чисел

Да, отлично, ничего нескажешь. Но ещё одну строку уберём:

Rand(t) {
   static d := 0 
   Return r := Round(t+d), d += t - r
}

Не думаю, что мат.операции проиграют в скорости RegEx, конечно можно устроить "полевые испытания"

Ты наверное понял меня наоборот, мат.операции вместо RegEx, увеличат скорость раз в пять. А испытания уже были, как то обсуждалось. При "простом" поиске, связка SubStr и InStr работают минимум в 2 раза быстрее RegEx.

+ Хотя:

В данном случае, всего 15%.

SetBatchLines -1 
v := 6.425

Start := A_TickCount
loop 1000000
    p1 := Floor(v), p2 := Round(v - p1, 1) * 10 
MsgBox % A_TickCount - Start  
 
Start := A_TickCount
loop 1000000
    RegExMatch(Round(v, 1), "(.*)\.(.)", p)  
MsgBox % A_TickCount - Start   

, но вряд ли это имеет большое значение - скорость не относится к числу сильных сторон AHK.

Тогда тем более получается, что такие мелочи, могут местами сильно повлиять.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.09 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

24 (изменено: to4er, 2015-02-16 03:12:52)

Re: AHK: Random, настройка вероятности выпадения двух чисел

Всё отлично работает в таком виде:

var := 2.75
F12::
rvar := Rand(var)
SendInput %rvar%

Rand(t) {
   static d := 0 
   Return r := Round(t+d), d += t - r
}

также, составил функцию по рэндому:

Rand(x)
{
r := Round(x, 0)
if r > %x%
{
z := r - 0.5 / (1 + x - r)
}
else
{
z := r + 0.5 / (1 - x + r)
}
Random, v, z, r
Return v := Round(v, 0)
}