Sign in to follow this  
Followers 0
DavidFC3S

Random select from a string array

21 posts in this topic

I'm trying to work out how I can write a script that will pick a random item from an array full of strings. Then pick another random item etc without ever picking one twice. I'm sorry for such a vague question I admit I'm very new to programing of any kind. Even just some psuedo code to steer me in the right direction would be helpfull

Share this post


Link to post
Share on other sites



take an array and put the string values into each index, then use the random function to pick an index, then check if the index has been used and if so skip that index, continue skipping each index that has been used until you have used all the indexs

hope this helps as it is late


All by me:

"Sometimes you have to go back to where you started, to get to where you want to go." 

"Everybody catches up with everyone, eventually" 

"As you teach others, you are really teaching yourself."

From my dad

"Do not worry about yesterday, as the only thing that you can control is tomorrow."

 

WindowsError.gif

WIKI | Tabs; | Arrays; | Strings | Wiki Arrays | How to ask a Question | Forum Search | FAQ | Tutorials | Original FAQ | ONLINE HELP | UDF's Wiki | AutoIt PDF

AutoIt Snippets | Multple Guis | Interrupting a running function | Another Send

StringRegExp | StringRegExp Help | RegEXTester | REG TUTOR | Reg TUTOT 2

AutoItSetOption | Macros | AutoIt Snippets | Wrapper | Autoit  Docs

SCITE | SciteJump | BB | MyTopics | Programming | UDFs | AutoIt 123 | UDFs Form | UDF

Learning to script | Tutorials | Documentation | IE.AU3 | Games? | FreeSoftware | Path_Online | Core Language

Programming Tips

Excel Changes

ControlHover.UDF

GDI_Plus

Draw_On_Screen

GDI Basics

GDI_More_Basics

GDI Rotate

GDI Graph

GDI  CheckExistingItems

GDI Trajectory

Replace $ghGDIPDll with $__g_hGDIPDll

DLL 101?

Array via Object

GDI Swimlane

GDI Plus French 101 Site

GDI Examples UEZ

GDI Basic Clock

GDI Detection

Ternary operator

Share this post


Link to post
Share on other sites

When you say index, does that mean one of the entries in the array or do you just mean declare a variable as a future point of reference.

I think the reason I have so much difficulty asking for help is I don't know the correct terminology.

Could you show some example code of what you mean?

Share this post


Link to post
Share on other sites

Here's a simple example with a zero based array

#include <Array.au3>

Local $Array[5] = ['Jim', 'Paul', 'Sharon', 'Candice', 'Mr. Peanut']
Local $String

While 1
    If UBound($Array) > 1 Then
        $Index = Random(0, UBound($Array), 1)
        If $Index > UBound($Array) - 1 Then $Index = UBound($Array) - 1
        MsgBox(262208, '', 'Current (Random) Index = ' & $Index & @LF & 'Array Elements Left = ' & UBound($Array))
        $String &= $Array[$Index]
        $String &= ' - '
        _ArrayDelete($Array, $Index)
    Else
        $String &= $Array[0]
        ExitLoop
    EndIf
WEnd
MsgBox(262208, 'Final String', $String)

Share this post


Link to post
Share on other sites

Perhaps giving some more information would be helpfull.

I recently started teaching myself to code and have no background in any other languages for reference.

I've written a few basic scripts for work that just use mousemove and mouseclick to automate some of my work.

I've written a visual timer that countsdown to my breaks haha

and the most advanced thing I've written so far is a client/server type program that allows you to send text messages to each other via a socket.

Currently what I'm working on is a simple card game just to further my coding knowledge.

There's 52 cards in a deck and it has to randomly generate a card without ever repeating it.

What I started out doing was declaring 52 individual variables for each of the cards

$1 = 2c

$2 = 2h

$3 = 2s

$4 = 2d

etc etc etc. this is of course psuedo code and not the syntax I used.

I was then just randomly generating a number between 1 and 52 and displaying the corresponding variable.

Since starting this project though I have learned about arrays and can see that makes the system I did have planned ridiculously inefficient.

Share this post


Link to post
Share on other sites

Thanks Varian, I had already made my second post before I noticed your reply, I'll give that a try tonight and let you know how it goes

Share this post


Link to post
Share on other sites

Could you show some example code of what you mean?

#include <Array.au3>; enable showing the array
Local $Textinside[7] = ["Sun", "Mon", "Tue", "Wen", "Thu", "Fry", "Sat"];Add text to array
Dim $ArrayVar
Dim $avArray[1]
Rand_O()
Func Rand_O()
    Do
        $RandNum = Random(0, UBound($Textinside) - 1, 1)
        $Pos = _ArraySearch($avArray, $Textinside[$RandNum], 0, 0, 0)
        If $Pos = -1 Then
            _ArrayAdd($avArray, $Textinside[$RandNum])
        EndIf
    Until UBound($avArray) = UBound($Textinside) + 1
EndFunc   ;==>Rand_O
$avArray[0] = UBound($avArray) - 1
_ArrayDisplay($avArray, "Text array"); Check there is NO duplicates

Share this post


Link to post
Share on other sites

I'm not working out the code right now, I'm on the wrong machine for that but I think this ahould be fairly simple using 2 randoms 1-4 (representing suits) and 1-13 representing face values and using some conditionals and either a switch or a select to get the proper return value. I did something similar for a lottery game I did a few years ago but it only required a single random and a conditional check.


George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

Here is one way to shuffle the cards

#include <Array.au3>

Local $Cards[52], $Count = 0
Local $Suits[4] = ['Clubs', 'Spades', 'Diamonds', 'Hearts']
Local $Faces[13] = ['Ace', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'Jack', 'Queen', 'King']

For $Element2 In $Suits
    For $Element1 In $Faces
        $Cards[$Count] = $Element1 & ' of ' & $Element2 ;Combine the Face and Suit to make one card
        $Count += 1
    Next
Next

_ArrayDisplay($Cards, '"Brand New" Deck of Cards')

Local $String
While 1
    If UBound($Cards) > 1 Then
        $Index = Random(0, UBound($Cards), 1)
        If $Index > UBound($Cards) - 1 Then $Index = UBound($Cards) - 1
        $String &= $Cards[$Index] & @LF
        _ArrayDelete($Cards, $Index)
    Else
        $String &= $Cards[0]
        ExitLoop
    EndIf
WEnd
MsgBox(262208, 'Your Shuffled Deck', $String)

Share this post


Link to post
Share on other sites

Some more on card shuffle:


Share this post


Link to post
Share on other sites

The technical term is random permutation.

about it.


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 this post


Link to post
Share on other sites

#Include<array.au3>;For display purposes only
$aCards = _DrawCards()
If NOT @Error Then
    _ArrayDisplay($aCards)
Else
    MsgBox(4096, "Error", $aCards)
EndIf

Func _DrawCards($iMax_Cards = 5)
    Local $sFace, $iSuit, $sDrawn = "", $iCards = 0, $sVal, $sSuit, $aRtn
    Do
        $iSuit = Random(1, 4, 1)
        $sFace = Random(1, 13, 1)
        $sSuit = ""

        Switch $iSuit
            Case 1
                $sSuit = " of Hearts"
            Case 2
                $sSuit = " of Diamonds"
            Case 3
                $sSuit = " of Spades"
            Case Else
                $sSuit = " of Clubs"
        EndSwitch
        Switch $sFace
            Case 1
                $sFace = "Ace"
            Case 11
                $sFace = "Jack"
            Case 12
                $sFace = "Queen"
            Case 13
                $sFace = "King"
        EndSwitch
        If StringInStr($sDrawn, "|" & $sFace & $sSuit) Then ContinueLoop
        $sDrawn &= "|" & $sFace & $sSuit
        $iCards += 1
    Until $iCards = $iMax_Cards
    $aRtn = StringRegExp($sDrawn, "\|([\w\s]+)", 3)
    If NOT @Error Then Return ($aRtn)
    Return (SetError(1, 1, "Houston; We have a problem!"))
EndFunc   ;==>_DrawCards


George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

This one is a bit more flexible and gives a better example of the results. of course there is always room for improvement.

#Include<array.au3>;For array display purposes only
Local $iDeal = 5, $iPlayrs[4] = ["", "", "", ""];;  Adjust these according to the number of cards each player gets and the number of players
$aCards = _DrawCards(UBound($iPlayrs) * $iDeal)
If NOT @Error Then
    _ArrayDisplay($aCards)
    FOR $i = 0 To UBound($aCards) - UBound($iPlayrs) Step UBound($iPlayrs)
        FOR $x = 0 To UBound($iPlayrs) - 1
            $iPlayrs[$x] &= $aCards[$i + $x] & "|"
        Next
    Next
    FOR $i = 0 To UBound($iPlayrs) - 1
        $iPlayrs[$i] = StringSplit(StringTrimRight($iPlayrs[$i], 1), "|", 2)
        _ArrayDisplay($iPlayrs[$i], "Player " & $i + 1)
    Next
Else
    MsgBox(4096, "Error", $aCards)
EndIf

Func _DrawCards($iMax_Cards = 20)
    Local $sFace, $iSuit, $sDrawn = "", $iCards = 0, $sVal, $sSuit, $aRtn
    Do
        $iSuit = Random(1, 4, 1)
        $sFace = Random(1, 13, 1)
        $sSuit = ""

        Switch $iSuit
            Case 1
                $sSuit = " of Hearts"
            Case 2
                $sSuit = " of Diamonds"
            Case 3
                $sSuit = " of Spades"
            Case Else
                $sSuit = " of Clubs"
        EndSwitch
        Switch $sFace
            Case 1
                $sFace = "Ace"
            Case 11
                $sFace = "Jack"
            Case 12
                $sFace = "Queen"
            Case 13
                $sFace = "King"
        EndSwitch
        If StringInStr($sDrawn, "|" & $sFace & $sSuit) Then ContinueLoop
        $sDrawn &= "|" & $sFace & $sSuit
        $iCards += 1
    Until $iCards = $iMax_Cards
    $aRtn = StringRegExp($sDrawn, "\|([\w\s]+)", 3)
    If NOT @Error Then Return ($aRtn)
    Return (SetError(1, 1, "Houston; We have a problem!"))
EndFunc   ;==>_DrawCards

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

To make it simple so you can understand:

$Array[3] Is made by: $Array[0] $Array[1] $Array[2]

As the count of an array starts from 0 everytime.

So if I want to put A, B, C in an array i must declare it like this

$Array[3]=[A,B,C]

OR

$Array[0]="A",$Array[1]="B",$Array[2]="C"

Those 0, 1, 2 are called "indexes", so that's what is an Index.

To call an element randomly you can do this

$x=$Array[Random(0,2,1)] and it will call a random value included from 0 to 2.

By the way, this can call more than once the same value, as a random number cal can draw numbers like this: 1,0,2,2,2,0,0,1,2,2,1,0 and so on. To extract one element only once look at the useful "Deck Shuffle" function that is listed above. I used it and it was very useful. Hope to have made it clear.

1 person likes this

I'm a compulsive poster. When I post something, come to read it at least 5 minutes later after the posting, because I will edit it. I edited even this signature a few minutes later after I wrote it.

Share this post


Link to post
Share on other sites

$Array[3]=[A,B,C]

Don't forget to quote string values when you do that.

$Array[3]=["A","B","C"]

Yes you can draw the same value more than once with Random and that's precisely why I put it into a string then check to see if the card has already been drawn.

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

Wow, thanks for so many answers guys.

Looks like I have some studying to do because most of this is chinese to me at the moment.

I didn't know what an array was a few days ago haha

Share this post


Link to post
Share on other sites

Is there a specific reason I should have 2 seperate arrays for face value and suit instead of just having an array with 52 entries ['2c','2h','2s','2d'] etc etc?

Is it just to do with efficiency and making handling the indexes faster? or are their some rules about storing integers and characters in the same array?

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

Why try to randomize 52 elements when you can randomize 17? It's faster with 17 and if you look at it It's random for 13 cards and another random for 4 suits.

I should have added that doing it with just random numbers you don't have to prefill the arrays.

Edited by GEOSoft

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

#19 ·  Posted (edited)

Oddly enough, I just finished doing much the same thing, but to pick files up to a maximum aggregate file size or a user specified number ($desired):

Do

    If GUIGetMsg() = $cancelbutton Then Exit
    If $i = $array[0] + 1 Then
        $replacemode = 0
        ;MsgBox(0, "debug", "no more than " & $array[0] & " files to pick")
        ExitLoop
    EndIf
    $unique = 1
    $randidx[$i] = Random(1, $array[0], 1) ; pick a random integer between 1 and $array[0] (number of files in array)
    ;MsgBox(4096, "debug", $i & " " & $randidx[$i])

    For $a = 1 To $i - 1
        If ($randidx[$i] = $randidx[$a]) And ($i > 1) Then
            ;MsgBox(4096, "debug", "duplicate found")
            $i = $i - 1 ; decrement $i so the same $i value runs again
            $unique = 0
            ExitLoop
        EndIf
    Next

    If $unique Then
        ;$msg = $msg & @CRLF & $i & " " & $randidx[$i] & ":" & @TAB & $array[$randidx[$i]] ; message for debug box
        $totsize = $totsize + (FileGetSize($array[$randidx[$i]]) / 1048576)
    EndIf

    If (($totsize) > $maxsize) Then
        ;MsgBox(4096, "debug", "max size " & $totsize & " reached at file no. " & $i)
        $totsize = $totsize - (FileGetSize($array[$randidx[$i]]) / 1048576)
        $i = $i - 1
        ;$desired = $i-1
        ExitLoop
    EndIf


    $i = $i + 1
Until $i = $desired + 1

In the above example $array[0] is the available number of files and the remaining elements in $array are the file names; the loop stops when either that number or $desired is reached, or the total size ($totsize) reaches the limit ($maxsize).

As somebody pointed out, yours could be made faster by checking suits and numbers separately in two arrays rather than one array containing all 52 cards, but I suspect you wouldn't see the difference... even with over 8000 files my above routine is reasonably fast, and with fewer elements (say a hundred or two) it's so fast you hardly even see it happening.

Edited by Dana

Share this post


Link to post
Share on other sites

Dana that's true, I have one project that has to handle an array of almost 89 thousand elements and there is no way to split it down to less. It appears to run slow however considering the number of elements it really isn't too bad. In the OPs case I would still go with 2 arrays. One of the upsides is better randomization and I'm sure that one of the math wizards will come along and calculate the difference in odds. I remember doing one (a lottery) where I had to return 20 numbers out of 80 and in order to get the odds to where I needed them to be the function first randomly drew 40 numbers at random and then from that 40 element array it drew the final 20 at random. With a bit more manipulation, the odds of winning are within .01% of the government version and it displays pretty much the same as the governments version. The same thing applied to a second where I need 7 numbers out of 49 (6/49 plus a bonus number), level of randomness can be important at times and I think this would apply in a card game.


George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

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
Sign in to follow this  
Followers 0