1

I developed a card deck to play board game on Visio, but my friends and I have the "feeling" the cards are not well shuffled.

The code I am using is the following (I simplified but I am using the same algorithm for the verso of the cards which contains numbers, if needed I can add it):

    # Actions
    $CONFIG_ACTIONS = @{
        "pool"=9
        "interim"=9
        "bis"=9
        "parc"=18
        "sell"=18
        "barrier"=18
    }
    $unshuffeledListAction = [System.Collections.ArrayList]@()
    foreach ($actionToAdd in $CONFIG_ACTIONS.Keys) {
        [int]$howManyTime = $($CONFIG_ACTIONS[$actionToAdd])
        for($i=0;$i -lt $howManyTime;$i++) {
            $unshuffeledListAction.Add($actionToAdd) | out-null
        }
    }
    # Request random number between 0 and 65535
    $requestURI = "https://qrng.anu.edu.au/API/jsonI.php?length=1&type=uint16"
    # Randomize Cards: Try WebService
    Try {
        $random = $(Invoke-RestMethod -Uri $requestURI -Method GET).data 
        $shuffeledListActions = $unshuffeledListAction | Get-Random -Count $unshuffeledListAction.Count -SetSeed ($random[0])       
    } Catch {
        Write-warning "Failed to called QRNG@ANU JSON API switching to local pseudo-random"
        $shuffeledListActions = $unshuffeledListAction | Get-Random -Count $unshuffeledListAction.Count
    }

I have no special needs on security as this is for personal use without sensitive information, so I am OK to work with WebServices and I already made a try.

My first shuffle attempt was simply:

$shuffeledListActions = $unshuffeledListAction | Get-Random -Count $unshuffeledListAction.Count

Can it be improved? Is the second attempt with calling a quantum random number generator service better?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Brice
  • 786
  • 4
  • 16
  • 3
    `Sort-Object { Get-Random }` performs much worse than `Get-Random -Count`. – mklement0 May 02 '20 at 12:20
  • 1
    As a side note: Try to [avoid using the increase assignment operator (+=) to create a collection](https://stackoverflow.com/questions/60708578/why-should-i-avoid-using-the-increase-assignment-operator-to-create-a-colle/60708579#60708579), it is very expensie especially for larger arrays. – iRon May 02 '20 at 12:21
  • @iRon of course ! completely forgot about this. Thanks. I edited the code including mklement suggestion's too – Brice May 02 '20 at 12:32

2 Answers2

4

Get-Random -Count is fine. I'd probably ditch the web service call entirely. A PRNG is perfectly fine and taking the seed from somewhere else doesn't change much here.

mklement0
  • 382,024
  • 64
  • 607
  • 775
Joey
  • 344,408
  • 85
  • 689
  • 683
  • 4
    Just as an aside: Powershell 7.1 will introduce a `-Shuffle` switch to simplify shuffling (no need to know the collection size ahead of time); already available in the current preview. – mklement0 May 02 '20 at 12:18
0

Tried to add this as a comment but can't format it properly that way.

I tried these variations randomizing an ArrayList of characters just for fun:

Get-Random with -count  
Ran 50 times, collection size = 10000, average = 20.960288 ms  
Sort-Object with Get-Random  
Ran 50 times, collection size = 10000, average = 110.135096 ms  
Get-Random with -Shuffle  
Ran 50 times, collection size = 10000, average = 78.4861906666667 ms

Get-Random with -count
Ran 50 times, collection size = 100000, average = 161.216678 ms
Sort-Object with Get-Random
Ran 50 times, collection size = 100000, average = 1167.048285 ms
Get-Random with -Shuffle
Ran 50 times, collection size = 100000, average = 831.058309333333 ms
statikuz
  • 797
  • 7
  • 11