Shuffle List

Hi, everyone!

I’m currently making a card game, more specifically a partial clone of Inscryption, and I’m now programming the logic for the deck.
For now, I just have an empty Game Object with a script attached to it with a list.
The list works correctly as I want to fill it manually through the inspector.
I made the cards using Scriptable Objects.

Here’s the thing, I want to shuffle this list without changing the number of times a card is in the list. For example:
A deck with 30 card that contains:

  • 10 Wizards
  • 10 Warriors
  • 10 Assasins
    All I have found for now are people randomizing the list, but the problem is that I’m unable to control the how many cards of a specific type are in the deck.

Here’s the code I have right now:

For the Deck:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerDeck : MonoBehaviour
{
    public List<PlayableCard> deck = new List<PlayableCard>();
}

For the Scriptable Objects I use for the cards:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]

[CreateAssetMenu(fileName = "New Playable Card", menuName = "Playable Card")]
public class PlayableCard : ScriptableObject
{
    public new string name;

    public int scriptableCardPower;
    public int scriptableCardHealth;

    public bool scriptableCardIsMox;
    public bool scriptableCardEmeraldCost;
    public bool scriptableCardRubyCost;
    public bool scriptableCardSapphireCost;

    public Sprite scriptableCardImage;
}

1 Answer

1

You can shuffle a list using LINQ with OrderBy and a random number generator. Here’s an example of how to do it:

List<int> shuffledList = list.OrderBy(x => rng.Next()).ToList();

Alternatively, you can use the Fisher-Yates Shuffle Algorithm. This algorithm works by iterating through the list from the last element to the first. For each element, it swaps the current element with a randomly chosen earlier element (or with itself). This method ensures an unbiased shuffle and is more efficient than sorting-based approaches.

Edit: I added an example code for the Preformatted textFisher-Yates Algorithm

Random rng = new Random();
int n = list.Count;
while (n > 1)
{
    n--;
    int k = rng.Next(n + 1);
    T value = list[k];
    list[k] = list[n];
    list[n] = value;
}

I've tried the first method but it gives me an error for "rng" (doesn't exist in this context). I think I'm missing something, plus im really new to Unity so I don't understand the code enough to fix the issue or know what is missing.

@ElSuperMagikarp You need to define a random generator first. Add this line of code on top of your code: Random rng = new Random();