How do I get random item based on percentage?

Nick R 66 Reputation points
2022-09-01T12:46:58.84+00:00

Hello!

I'm working on a card pack project, where I have 3 packs, Bronze, Silver and Gold.

User buys bronze pack, will only get bronze cards.
User buys silver pack, most of the time it'll be bronze cards, with silver cards popping up 1 out of 50 times, give or take and maybe a gold card 1 out of 1000.
User buys gold pack, mostly bronze cards, a little more silver cards with the possibility of getting a gold card is higher.

Any info on how I would code this would be greatly appreciated.

Thank you!

Developer technologies | ASP.NET | ASP.NET Core
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. Michael Taylor 60,326 Reputation points
    2022-09-01T13:41:32.78+00:00

    Here's the start of an algorithm but you'll have to test it and make adjustments. We'll assume that you're using a good random # generator that truly generates arbitrary values.

    Let's assume that we're building for the silver pack and that you said 1 in 50 are silver and 1 in 1000 are gold. Normalize to 1000 so 20 in 1000 are silver, 1 in 1000 are gold and the remaining are bronze. Generate a random number between 1 and 1000. You can partition your cards up as much as you want but somehow you'll need to decide where the 20 silver and 1 gold card sit in the 1-1000 range. Suppose, for example, that you specify that the gold card is at 1000 and the silver are 1-20. If the random # is in either range then you use that value. However I think you'll find that 1 in 1000 is extremely rare even on the best days.

    There are quite a few variants you can use to adjust the behavior to your liking such as pre-selecting the cards and randomizing from there or using some custom rules such as a gold pack always having at least 1 gold card.

    1 person found this answer helpful.
    0 comments No comments

  2. Bruce (SqlWork.com) 78,006 Reputation points Volunteer Moderator
    2022-09-01T15:37:10.94+00:00

    simple brand picker:

        static Random brandRand = new Random();  
    	public static string GetBrand()  
    	{  
    		var value = brandRand.NextDouble();  
    		if (value <= 1.0/1000.0)  
    			return "Gold";  
    		else if (value <= 1.0/50.0)  
    			return "Silver";  
    		return "Bronze";  
    	}  
    
    1 person found this answer helpful.
    0 comments No comments

  3. Nick R 66 Reputation points
    2022-09-01T15:19:37.96+00:00

    So let's say I want to grab 4 cards at random from bronze, all cards will of course be bronze when I buy the bronze pack. If I buy a silver pack, any or all 4 can be silver, but still have bronze cards, based on percentage. If I buy a gold pack, any of the 4 will be gold, some silver and mostly bronze.

    My code as I have as follows. It will need some modification, for sure.

    var random = new Random();  
    var items = (await _cardService.GetAllItemsAsync()).Where(c => c.Level == pack.Level);  
      
    var userPack = new UserPack  
    {  
       Item1Id = items.OrderBy(c => random.Next()).FirstOrDefault().Id,  
       Item2Id = items.OrderBy(c => random.Next()).FirstOrDefault().Id,  
       Item3Id = items.OrderBy(c => random.Next()).FirstOrDefault().Id,  
       Item4Id = items.OrderBy(c => random.Next()).FirstOrDefault().Id  
    }  
    

    pack.Level would be equal to Bronze, Silver or Gold.

    I hope this clears up some of what I'm trying to accomplish.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.