I have an array of images. Each image has a "rarity" key that tells me whether it's "common", "uncommon", or "rare". So for instance, the array might look something like this:
Array
(
[0] => Array
(
[image] => photo1.jpg
[rarity] => common
)
[1] => Array
(
[image] => photo2.jpg
[rarity] => uncommon
)
.
.
.
[x] => Array
(
[image] => photo(x).jpg
[rarity] => rare
)
)
I want to select 'y' number of images from the list, almost like creating a deck of cards, but with images instead. The rarity, of course, defines how likely that card will be selected. How do I go about doing this? I figure I start with array_rand(), but am stuck as to where to go with it.
EDIT FOR CLARIFICATION: Each image in the array can only occur in the final deck once.
I would do this with three different arrays. One for each rarity type.
Lets say the probabilities are: common = 70%, uncommon = 25%, rare = 5%.
Your three arrays are $commonArray, $uncommonArray and $rareArray.
Your target deck is $deck.
Then you generate a random number from 1 to 100 and choose one of the three arrays:
<?php
$rand = rand(1,100);
if ($rand <= 70) {
$cardArray = &$commonArray;
} else if ($rand <= 95) {
$cardArray = &$uncommonArray;
} else {
$cardArray = &$rareArray;
}
Now choose one card from the selected array:
$chosen = array_rand($cardArray);
$deck[] = $cardArray[$chosen];
unset($cardArray[$chosen]); //remove the chosen card from the array to prevent duplicates
Repeat this until your $deck is the size you want it to be.
Here's my attempt. In $chances you have to define the chances that a common, uncommon or rare card will be chosen to appear in a deck as an int between 0-100. Also you have to provide the deck size.
Presenting an answer where the cards are unique and cannot appear multiple times in the same deck:
$cards = array(/* your array from above */);
$deck = array();
$deck_size = 52;
$chances = array('common' => 90, 'uncommon' => 30, 'rare' => 5);
$max_attempts = 3;
$tmp_cards = $cards; // copied
while(count($deck) < $deck_size) {
$roll = rand(0, 100);
for($a = 0; $a < $max_attempts; $a++) {
$index = array_rand($tmp_cards);
$card = $tmp_cards[$index];
$rarity = $card['rarity'];
$image = $card['image'];
if(isset($deck[$image])) {
continue;
}
if($roll <= $chances[$rarity]) {
// if the roll is lower than the required probability
// we can put this card in
$deck[$image] = $card;
unset($tmp_cards[$index]); // delete the card so it's not picked again
break;
}
}
}
$deck = array_values($deck);
Update
Improved the code and provided definite exits to all branches.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With