Friday, May 15, 2020

safely shuffling an associative array in php

I'm making game server endpoints in PHP because it's convenient to deploy, but I'm sort of regretting it. I should really get my node mojo working...

Anyway, I thought I had a problem with json encoding / decoding because of PHP's ambiguity of regular arrays and associative arrays, because what I wanted to be a map of keys to values was coming across as a regular array in javascript land. 

After some cursing and debugging, I realized it was because I was calling "shuffle()" on the PHP array. (Leaving aside the meh-ness of hoping to get an order of a javascript map). Anyways, shuffle() doesn't respect string keys, it just drops the keys and treats it as an ordered array. Which sort of makes sense but you think there would be a warning or something...

Anyway, this function lets you shuffle the keys of an associative array (I assume without the shuffle it's usually insertion order?)

function shuffle_assoc_array($orig) {
    $shuffled = array();
    $keys = array_keys($orig);
    shuffle($keys);
    foreach ($keys as $key) {
    $shuffled[$key] = $orig[$key];
    }
    return $shuffled;
}

Eh, good enough.

UPDATE: The above was needed for shuffling a collection of player objects (so as to not bias the judge). The main deck is a regular array... for reference here is some code that regenerates the deck (each card is a number from 1-350) after removing the cards that are already in the players hands:

#do a reshuffle if we have less than ten players per deck... 
$playercount = sizeof($game["players"]);
if(sizeof($game["deck"]) < ($playercount * 10)){
    #all cards but those currently in players' hands
    $cardsinhands = array();
    foreach($game["players"] as $player){
        $cardsinhands = array_merge($cardsinhands,$player["cards"]);
    }
    #remake entire deck, but take out the ones in players hands...
    $deck = array();
    for($i = 1; $i <= $DECKSIZE; $i++){
        array_push($deck,$i);
    }
    $deck = array_values(array_diff( $deck,$cardsinhands ));
    shuffle($deck);
    $game["deck"] = $deck;
}

No comments:

Post a Comment