Jump to content

# Random number without repeat using a button

## Recommended Posts

I want to do this but I have no idea how to do it

-I will use a button to go to the function

-When I click it, the script must generate a random number

-each time I click it the number must be different

-When I reach the maximum number show a message

-Let's say that the minimum number is 1 and the maximum 5

I found a similar function but can't make it work

\$numbers = 5
Global \$r,\$str
While 1
\$r = String(";"&Random(1,\$numbers,1)&";")
If Not StringInStr(\$str,\$r,1) Then
\$str = \$str&\$r
\$bla = StringSplit(\$str,";;",1)
MsgBox(0,\$bla[0]&"   "&\$str,\$r)
EndIf
If \$bla[0] = \$numbers Then
MsgBox(0,"THE","END")
Exit
EndIf
WEnd

And what i have

Func _Random()
\$numbers = 5
Global \$r,\$str

Do
\$r = String(Random(1,\$Numbers,1))
If Not StringInStr(\$str,\$r,1) Then
\$str = \$str&\$r
\$bla = StringSplit(\$str,1)
MsgBox(0,\$bla[0]&"   "&\$str,\$r)
\$i = 1
EndIf
If \$bla[0] = \$Numbers Then
MsgBox(0,"THE","END")
Exit
EndIf
Until \$i = 1
EndFunc

##### Share on other sites

using an array makes it legible, a bit bloated for counting but legible.

```#include<array.au3>

local \$aArr = [1,2,3,4,5]

for \$i = 1 to UBound(\$aArr)
\$nValue = random(0, ubound(\$aArr) - 1 , 1)
msgbox(0, '' , \$aArr[\$nValue])
_ArrayDelete(\$aArr , \$nValue)
next```

```,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)```

##### Share on other sites
3 hours ago, iamtheky said:

using an array makes it legible, a bit bloated for counting but legible.

```#include<array.au3>

local \$aArr = [1,2,3,4,5]

for \$i = 1 to UBound(\$aArr)
\$nValue = random(0, ubound(\$aArr) - 1 , 1)
msgbox(0, '' , \$aArr[\$nValue])
_ArrayDelete(\$aArr , \$nValue)
next```

I have done something like this, but what I need is that each time that I call the function shows only one number, then when I call the function again show a different number and at the end say that is the end.

##### Share on other sites

This way?

```For \$i = 1 To 7
MsgBox(0, "Button hit", "Number is " & _Surprise())
Next

Func _Surprise()
Local Static \$a = [1, 2, 3, 4, 5], \$n
If \$n = 0 Then _ArrayShuffle(\$a)
\$n += 1
Return (\$n > 5 ? "no more available!" : \$a[\$n - 1])
EndFunc```

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

##### Share on other sites

we almost get it. Just What I need at this point is to change \$a by the result of \$LastCell.

instead of:

`Local Static \$a = [1, 2, 3, 4, 5],\$n`

I need something like this:

`    Local Static \$a = [1 to \$LastCell],\$n`

And this is the code that I have

```#include <Excel.au3>

#include <GUIConstantsEx.au3>

Global \$oAppl = _Excel_Open(@SW_HIDE) ;Abre excel y lo oculta
Global \$oWorkbook = _Excel_BookOpen(\$oAppl, @ScriptDir & "\Example.xlsx") ; your workbook here
Global \$xlUp = -4162
With \$oWorkbook.Sheets(1)
Global \$LastCell = .Cells(.Rows.Count, "A").End(\$xlUp).row        ;Es la ultima celda donde se escribio en el documento
EndWith
_Excel_BookClose(\$oWorkBook)
MsgBox(0, "", \$LastCell)
Example()

Func Example()
; Create a GUI with various controls.
Local \$hGUI = GUICreate("Example")
\$Button = GUICtrlCreateButton("Button", 20, 20, 50, 20)
; Display the GUI.
GUISetState(@SW_SHOW, \$hGUI)

; Loop until the user exits.
While 1
Switch GUIGetMsg()
Case \$GUI_EVENT_CLOSE, \$idOK
ExitLoop

Case \$Button
MsgBox(0, "Button hit", "Number is " & _Random())
EndSwitch
WEnd

; Delete the previous GUI and all controls.
GUIDelete(\$hGUI)
EndFunc   ;==>Example

Func _Random()
Local Static \$a = [1, 2, 3, 4, 5],\$n
If \$n = 0 Then _ArrayShuffle(\$a)
\$n += 1
Return (\$n > 5 ? "no more available!" : \$a[\$n - 1])
EndFunc```

thanks in advance and sorry because I'm new with autoit just use it ocasionally and I'm really new with arrays

Edited by luis713
##### Share on other sites
12 hours ago, jchd said:

This way?

```For \$i = 1 To 7
MsgBox(0, "Button hit", "Number is " & _Surprise())
Next

Func _Surprise()
Local Static \$a = [1, 2, 3, 4, 5], \$n
If \$n = 0 Then _ArrayShuffle(\$a)
\$n += 1
Return (\$n > 5 ? "no more available!" : \$a[\$n - 1])
EndFunc```

Thanks it helped me a lot now just I need to change \$a by my variable and don't know how to do it I tried but was unsuccesful

##### Share on other sites

Here's a non-fixed version: just change the \$MaxValue global constant.

```Global Const \$MaxValue = 17

For \$i = 1 To \$MaxValue + 3         ; + 3 is just to go beyond \$MaxValue ans see what happens
MsgBox(0, "Button hit", "Number is " & _Surprise())
Next

Func _Surprise()
Local Static \$a[\$MaxValue], \$n
If \$n = 0 Then
For \$i = 0 To \$MaxValue - 1
\$a[\$i] = \$i + 1
Next
_ArrayShuffle(\$a)
EndIf
\$n += 1
Return (\$n > \$MaxValue ? "no more available!" : \$a[\$n - 1])
EndFunc```

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

##### Share on other sites

Im finding a fun string rabbit hole...not that the array UDF isnt lovely

```\$numbers = "12345"

For \$i = 1 to stringlen(\$numbers) + 3
\$chr = stringmid(\$numbers , random(1 , StringLen(\$numbers) , 1) , 1)
\$numbers = stringsplit(\$numbers , \$chr , 2)[0] & stringsplit(\$numbers , \$chr , 2)[1]

msgbox(0, \$numbers & " -" , \$numbers = "" ? "No Numbers Remain" : \$chr)
Next```

```,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)```

##### Share on other sites

Nice Idea, but you'll need delimiters in there as well otherwise its only good up to 9 and its going to make your lookup function way hairer

##### Share on other sites

How about this?

```Func UniqRandNum(\$iMin, \$iMax)
Static Local \$sNum
Local \$iRange = (\$iMax - \$iMin) + 2
If Not \$sNum Then
\$sNum = "0"
While StringLen(\$sNum) <= \$iRange
\$sNum &= "11"
WEnd
EndIf
Local \$iSt  = Random(2, \$iRange, 1)
Local \$iRnd = StringInStr(\$sNum, "1", 1, -1, \$iSt);<<Search left
If \$iRnd = 0 Then \$iRnd = StringInStr(\$sNum, "1", 1, 1, \$iSt);>>Search right

If \$iRnd <= \$iRange Then
\$sNum = StringReplace(\$sNum, \$iRnd, "0")
Return (\$iRnd + \$iMin) - 2
Else
\$sNum = Null
Return \$sNum
EndIf
EndFunc

\$iTest = UniqRandNum(-10, 12)
While True
MsgBox(0, "Unique Rand", \$iTest = Null ? "No Numbers Remain" : \$iTest)
If \$iTest = Null Then ExitLoop
\$iTest = UniqRandNum(-10, 12)
WEnd```

I added range to it as well

Updated to make it bit more robust (and faster)

Edited by Bilgus
Added Range
##### Share on other sites

On 2/22/2018 at 5:14 PM, Bilgus said:

Nice Idea, but you'll need delimiters in there as well otherwise its only good up to 9 and its going to make your lookup function way hairer

orly, thats the only edge case you could find or just the edgiest?

I believe delimiters would be unnecessary with any smoosh of strings that are both unique, and have uniform length; just accurate parameters for split and mid (thus the PoC).  And not terribly hairier.

This works chunking via 1,2, or 3...because remainder math can suck it, sanitize your input.

```\$numbers = "123456"

\$chunk = 1

For \$i = 1 to StringLen(\$numbers) / \$chunk

\$chr = stringmid(\$numbers , (stringlen(\$numbers) = \$chunk ? 1 : random(1 , StringLen(\$numbers) - (\$chunk - 1), 1)) , \$chunk)
If \$chr <> "" Then msgbox(0, '' , \$chr)
\$numbers = (stringlen(\$numbers) > \$chunk) ? stringsplit(\$numbers , \$chr , 3)[0] & stringsplit(\$numbers , \$chr , 3)[1] : msgbox(0, '' , 'None Remaining')

Next```

Edited by iamtheky

```,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)```

##### Share on other sites

Thanks now works fine, I'll use this one

2 hours ago, jchd said:

Here's a non-fixed version: just change the \$MaxValue global constant.

```Global Const \$MaxValue = 17

For \$i = 1 To \$MaxValue + 3         ; + 3 is just to go beyond \$MaxValue ans see what happens
MsgBox(0, "Button hit", "Number is " & _Surprise())
Next

Func _Surprise()
Local Static \$a[\$MaxValue], \$n
If \$n = 0 Then
For \$i = 0 To \$MaxValue - 1
\$a[\$i] = \$i + 1
Next
_ArrayShuffle(\$a)
EndIf
\$n += 1
Return (\$n > \$MaxValue ? "no more available!" : \$a[\$n - 1])
EndFunc```

##### Share on other sites

Thank you everybody

##### Share on other sites

Just one thing, If I want to start from the number 2, how can avoid a "1" return?

3 hours ago, jchd said:

Here's a non-fixed version: just change the \$MaxValue global constant.

```Global Const \$MaxValue = 17

For \$i = 1 To \$MaxValue + 3         ; + 3 is just to go beyond \$MaxValue ans see what happens
MsgBox(0, "Button hit", "Number is " & _Surprise())
Next

Func _Surprise()
Local Static \$a[\$MaxValue], \$n
If \$n = 0 Then
For \$i = 0 To \$MaxValue - 1
\$a[\$i] = \$i + 1
Next
_ArrayShuffle(\$a)
EndIf
\$n += 1
Return (\$n > \$MaxValue ? "no more available!" : \$a[\$n - 1])
EndFunc```

##### Share on other sites

Do you want the array to start at 2 (with the value 1 not existing), or to return every item from the array except 1?

The former would be done in the loop that populates the array, if \$i + 1 starts at 1 then...

```For \$i = 0 To \$MaxValue - 1
\$a[\$i] = \$i + 2
Next```

```,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)```

##### Share on other sites
38 minutes ago, iamtheky said:

Do you want the array to start at 2 (with the value 1 not existing), or to return every item from the array except 1?

The former would be done in the loop that populates the array, if \$i + 1 starts at 1 then...

```For \$i = 0 To \$MaxValue - 1
\$a[\$i] = \$i + 2
Next```

I want to get the random number starting from number 2 to my variable

##### Share on other sites

and inserting that code in the place of the existing loop does exactly that.  The only question really was whether you still needed 1 to exist.

```,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)```

##### Share on other sites
13 minutes ago, iamtheky said:

and inserting that code in the place of the existing loop does exactly that.  The only question really was whether you still needed 1 to exist.

I'll try it when I get the computer to test it. Thanks a lot

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account

## Sign in

Already have an account? Sign in here.

Sign In Now
• ### Recently Browsing   0 members

No registered users viewing this page.

×

• Wiki

• Back

• #### Beta

• Git
• FAQ
• Our Picks
×
• Create New...