не выбирать рандомно текст, если он уже был использован

Помощь в написании скриптов
sotona11
Posts: 1
Joined: 25 May 2022, 15:29

не выбирать рандомно текст, если он уже был использован

Post by sotona11 » 25 May 2022, 15:36

Здравствуйте.
иногда делаю простенькие скрипты на ahk для автоматизации рутины. У меня есть скрипт, в нём на все клавиши нумпада есть по 4 текста, один из них выбирается случайным образом и пишется, но мне нужно сделать так, чтобы после того как текст использовался, его больше не выбирало бы рандомным образом. Желательно, чтобы эту функцию (чтобы текст больше не писался) можно было бы отменить другим хоткеем и использованный текст снова писался.

вот пример:

Code: Select all

Numpad0::
   Random, Var, 1, 4
   SendInput, {Y down}{Y up}
   Sleep, 100
   SendInput, % TextArray[Var] . "{Enter}"

TextArray := ["Text1"
            ,"Text2"
            ,"Text3"
            ,"Text4"]

Exit

Numpad1::
 Random, Var, 1, 4
   SendInput, {Y down}{Y up}
   Sleep, 100
   SendInput, % TextArray2[Var] . "{Enter}"

TextArray2 := ["Text5"
            , "Text6"
            , "Text7"
            , "Text8]
и т.д.


нужно, чтобы было так:

я нажимаю Num0. рандомно пишется текст.
я нажимаю Num0. текст, который уже был написан ранее не выбирается, заместо него пишется другой текст из этого же TextArray.

как это сделать? пытался что-то с If, но я не настолько хорош в ahk.

mcl
Posts: 355
Joined: 04 May 2018, 16:35

Re: не выбирать рандомно текст, если он уже был использован

Post by mcl » 27 May 2022, 01:19

Уточните: вы хотите, чтобы текст не писался два раза подряд, или два раза вообще? Если вообще − то рано или поздно элементы закончатся, что тогда?

В любом случае, есть как минимум два варианта:
1. Сделать копию оригинального массива и при выборе элемента убирать его:

Code: Select all

TextArray := ["Text1", "Text2", "Text3", "Text4"]
rndArray := TextArray.Clone()            ; Делаем копию оригинального массива

Loop 10 {
	Random, ix, 1, % rndArray.Length()   ; Выбираем число от 1 до количества элементов в массиве
	
	randomElem := rndArray.RemoveAt(ix)  ; Вырезаем элемент из массива и сохраняем его в переменную
	Msgbox %randomElem%
	
	If (rndArray.Length() == 0)          ; Если больше элементов не осталось,
		rndArray := TextArray.Clone()    ; делаем новую копию
}
2. Предопределить порядок, в котором элементы будут показываться, в другом массиве:

Code: Select all

TextArray := ["Text1", "Text2", "Text3", "Text4"]

rndOrder := ""                       ; Создаём переменную со списком номеров элементов: 1 2 3 ...

Loop % TextArray.Length() {          ; Повторяем по числу элементов в исходном массиве
	rndOrder .= A_Index . "`n"       ; Дописываем к переменной число-счётчик и разделитель (перенос строки)
}

Sort, rndOrder, Random               ; Перемешиваем элементы в списке
rndOrder := Trim(rndOrder, "`n")     ; Убираем последний перенос строки, иначе последний элемент будет пустым
rndOrder := StrSplit(rndOrder, "`n") ; Разбиваем текстовый список в обычный массив

ir := 1
Loop 10 {
	ix := rndOrder[ir]               ; Берём число из перемешанного списка
	randomElem := TextArray[ix]      ; Берём элемент исходного массива с номером выбранного числа
	MsgBox %randomElem%
	
	ir++                             ; Увеличиваем счётчик
	If (ir > rndOrder.Length())      ; Если он больше числа элементов,
		ir := 1                      ; начинаем с начала.
}
github://oGDIp - GDI+ wrapper for AHK v1.1

Post Reply

Return to “Помощь”