Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Getting a Random Choice


  • Please log in to reply
23 replies to this topic
Menixator
  • Members
  • 744 posts
  • Last active: Sep 01 2015 02:54 PM
  • Joined: 10 Jul 2013

Really easy with AHK.
For an example if we are choosing a choice between Rock,Paper and Scissors the most common approach will be to choose a random number and do some if-else statements like so:


Random,Coice_Num,1,3
If (Choice_Num = 1)
	Choice = "Rock"
else if (Choice_Num = 2)
	Choice = "Num"
else if (Choice_Num = 3)
	Choice = "Num"

What if there were like . . 20, 30 choices? Then we would have a problem.
We need to write a lot of if-else statements which can get really messy.
So here is the situation. I got a list of 53 stuff and i need a 20 random Choices. This is how i'd do it:



Loop, 20
	MsgBox % Random_Choice("glow stick", "needle", "stop sign", "blouse", "hanger", "rubber duck", "shovel", "bookmark", "model car", "tampon", "rubber band", "tire swing", "sharpie", "picture frame", "photo album", "nail filer", "tooth paste", "bath fizzers", "tissue box", "deodorant ", "cookie jar", "rusty nail", "drill press", "chalk", "word search", "thermometer ", "face wash", "paint brush", "candy wrapper", "shoe lace", "leg warmers", "wireless control", "boom box", "quilt", "stockings", "card", "tooth pick", "shawl", "speakers ", "key chain", "cork", "helmet", "mouse pad", "zipper", "glasses", "lamp shade", "sketch pad", "gage", "plastic fork", "flag", "clay pot", "check book", "CD")

Random_Choice(Choices*){
	Random,Index,1,% Choices.MaxIndex()
	Return,Choices[Index]
}

I hope this might come in useful in your scripts. happy.png
And btw, should i have posted this in the tutorials forum? or is it okay to post it here?  I wasn't really sure.



MasterFocus
  • Moderators
  • 4323 posts
  • Last active: Jan 28 2016 01:38 AM
  • Joined: 08 Apr 2009

Nice use of the variadic feature. This is similar to GetRandom() (back when there was no AHK 1.1.*)


-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Antonio Fran├ža -- git.io -- github.com -- ahk4.net -- sites.google.com -- ahkscript.org

Member of the AHK community since 08/Apr/2009. Moderator since mid-2012.


mrmike
  • Members
  • 45 posts
  • Last active: Jun 07 2014 04:38 PM
  • Joined: 20 Jan 2007

What if the choices needed to be unique (not repeating)?


Posted Image
Vista 32 Home Premium SP2

strobo
  • Members
  • 359 posts
  • Last active: Mar 10 2015 08:13 PM
  • Joined: 19 Jun 2012

http://www.autohotke...usic-algorithm/


Regards,
Babba

Menixator
  • Members
  • 744 posts
  • Last active: Sep 01 2015 02:54 PM
  • Joined: 10 Jul 2013

Nice use of the variadic feature.

Thanks! happy.png

 

What if the choices needed to be unique (not repeating)?

 

Working on that. :) I have most of the code done but sometimes it's returning empty values.
Will put it up as soon as it's fixed.



Menixator
  • Members
  • 744 posts
  • Last active: Sep 01 2015 02:54 PM
  • Joined: 10 Jul 2013

@mrmike. Here it is. I'm not sure if it will work 100% properly. But i gave it a few test runs.


Choices := ["glow stick", "needle", "stop sign", "blouse", "hanger", "rubber duck", "shovel", "bookmark", "model car", "tampon", "rubber band", "tire swing", "sharpie", "picture frame", "photo album", "nail filer", "tooth paste", "bath fizzers", "tissue box", "deodorant ", "cookie jar", "rusty nail", "drill press", "chalk", "word search", "thermometer ", "face wash", "paint brush", "candy wrapper", "shoe lace", "leg warmers", "wireless control", "boom box", "quilt", "stockings", "card", "tooth pick", "shawl", "speakers ", "key chain", "cork", "helmet", "mouse pad", "zipper", "glasses", "lamp shade", "sketch pad", "gage", "plastic fork", "flag", "clay pot", "check book", "CD"]

Loop,% Choices.MaxIndex()
	MsgBox % Unique_RChoice(Choices)

Unique_RChoice(Array){
	If (Array.MaxIndex() = 0 || Array.MaxIndex() = "")
		return, "ERROR"
	else {
		Random,Rand,1,% Array.MaxIndex()
		Ret := Array[Rand]
		Array.Remove(Rand)
		return, Ret
	}
}

First you create an array. And then pass the array off as a parameter to the function.
It will return a random choice and remove it from the array. It will return "ERROR" either when the values run out or if the parameter passed to the function is not an array.



sinkfaze
  • Moderators
  • 6367 posts
  • Last active: Nov 30 2018 08:50 PM
  • Joined: 18 Mar 2008

What if the choices needed to be unique (not repeating)?


Better to return an array with randomized elements:

For i, choice in randomArr("glow stick", "needle", "stop sign", "blouse", "hanger", "rubber duck", "shovel")
	MsgBox %choice%
return



randomArr(array*) {

	For i, item in array
		l .=	item "`n"
	l :=	Trim(l,"`n"), out :=	[]
	Sort, l, Random
	Loop, parse, l, `n
		out[A_Index] :=	A_LoopField
	return	out

}


Guest10
  • Members
  • 1216 posts
  • Last active: Oct 30 2015 05:12 PM
  • Joined: 27 Oct 2012

how can i modify this so that it returns non-random for items in the array but in the following original order?:

"glow stick", "needle", "stop sign", "blouse", "hanger", "rubber duck", "shovel"

 

Better to return an array with randomized elements:
 

For i, choice in randomArr("glow stick", "needle", "stop sign", "blouse", "hanger", "rubber duck", "shovel")
	MsgBox %choice%
return



randomArr(array*) {

	For i, item in array
		l .=	item "`n"
	l :=	Trim(l,"`n"), out :=	[]
	Sort, l, Random
	Loop, parse, l, `n
		out[A_Index] :=	A_LoopField
	return	out

}


sinkfaze
  • Moderators
  • 6367 posts
  • Last active: Nov 30 2018 08:50 PM
  • Joined: 18 Mar 2008

Unfortunately I don't understand your question.  Could you explain further?



Menixator
  • Members
  • 744 posts
  • Last active: Sep 01 2015 02:54 PM
  • Joined: 10 Jul 2013

how can i modify this so that it returns non-random for items in the array but in the following original order?:
"glow stick", "needle", "stop sign", "blouse", "hanger", "rubber duck", "shovel"

 

Like this?

Choices := ["glow stick", "needle", "stop sign", "blouse", "hanger", "rubber duck", "shovel"]
For Index, Choice in Choices
	MsgBox Item %Index% is %Choice%


Guest10
  • Members
  • 1216 posts
  • Last active: Oct 30 2015 05:12 PM
  • Joined: 27 Oct 2012

sorry, i meant this, which was answered by Menixator:

Choices := ["glow stick", "needle", "stop sign", "blouse", "hanger", "rubber duck", "shovel"]
For Index, Choice in Choices
	MsgBox Item %Index% is %Choice%

 

Unfortunately I don't understand your question.  Could you explain further?



Guest10
  • Members
  • 1216 posts
  • Last active: Oct 30 2015 05:12 PM
  • Joined: 27 Oct 2012

back to the random array! i found an immediate application for the random array script. i have a large list of mp3 files i would like to play randomly from this list but without repeating a single file until all files are played out. the list includes URLs of mp3 files compiled in a text file (let's call it mp3.txt). starting from the top, each line in this text file is the URL of an mp3 audio file. actual mp3 audio files reside in a separate folder. how can i modify the random array script to achieve this?



Menixator
  • Members
  • 744 posts
  • Last active: Sep 01 2015 02:54 PM
  • Joined: 10 Jul 2013

Create an empty array. Read the file using a file parsing loop, Add all lines to array, Get a random choice play it with the music player of your choice, and finally loop until all the songs are played.

;Create the empty array.
Files := Object()

; Write to the array:
Loop, Read, D:\Somefile.txt ; This loop retrieves each line from the file, one at a time.
    Files.Insert(A_LoopReadLine) ; Append this line to the array.

Loop,% Files.MaxIndex() ;Files.MaxIndex() contains the maximum number of items in the Array.
{
	File := Unique_RChoice(Files)
	RunWait,C:\Somedir\Someprogram.exe %File%
	;Runwait is really unlikely to work here. You have to do something to figure out when to resume the loop when the track has finished.
}

Unique_RChoice(Array){
	If (Array.MaxIndex() = 0 || Array.MaxIndex() = "")
		return, "ERROR"
	else {
		Random,Rand,1,% Array.MaxIndex()
		Ret := Array[Rand]
		Array.Remove(Rand)
		return, Ret
	}
}


strobo
  • Members
  • 359 posts
  • Last active: Mar 10 2015 08:13 PM
  • Joined: 19 Jun 2012

Maybe, this is not enough code;)

fileread, x, mp3.txt
sort, x, Random
loop, parse, x, `n, `r
    soundplay,% a_loopfield, 1
 
Regards,
Babba

Menixator
  • Members
  • 744 posts
  • Last active: Sep 01 2015 02:54 PM
  • Joined: 10 Jul 2013

That would work as well. happy.png