0

I'm new to coding and the answer is probably simple. I am making a pairs memory game in unity and I want the cards to spawn randomly each time the player loads the game. I have a gameobject list of cards and a transform list of spawning positions that I want the cards to spawn in. So far I have managed to shuffle the cards into a random order. But to do this I've converted the card gameobject list into integers.

public List<GameObject> cardsToSpawn;
public List<Transform> cardPositions = new List<Transform>();
public int cardCount;
public int someNum;
public List<GameObject> cards;
public GameObject empty;

void Awake()
{


    // list of the card gameobjects.
    List<int> cardsToSpawn = new List<int>();

        cardsToSpawn.Add(1);
        cardsToSpawn.Add(2);
        cardsToSpawn.Add(3);
        cardsToSpawn.Add(4);

        //Randomises the order. A, B, C, D = C, D, B, A for example.
        //cardsToSpawn is assigned a random number (1-18(length of cardsToSpawn list)).

    for (int i = 0; i < cardsToSpawn.Count; i++) 
      {
        int temp = cardsToSpawn[i];
        int randomIndex = Random.Range(i, cardsToSpawn.Count);
        cardsToSpawn[i] = cardsToSpawn[randomIndex];
        cardsToSpawn[randomIndex] = temp;

        //spawn card i=1 in cardPositions[1], card i=2 in cardPositions[2]... 
        temp = cards
        Instantiate(cardsToSpawn[i], cardPositions[i].position, transform.rotation);
        // but this refers back to the original list declared at the beginning of the script rather than the new randomIndex int.
      }
    // randomises the order. A, B, C, D = C, D, B, A for example.
    //tell me the order (i.e. make sure it is randomised.)
    cardsToSpawn.ForEach(i => Debug.Log("{0}\t"+ i));   


}

1 Answers1

0

In your for loop you are generating a new Random.Range ... this does not exclude duplicates and on the other side also doesn't guarantee that all of the cards get placed.

What you rather want to do is randomize one of the lists (of course you can randomize both but this wouldn't gain any more randomness actually) and then iterate through all elements for placing them.

For the shuffling there are multiple options. you can either use an extension method like this one or (because it is easier for me to explain for now) use Linq OrderBy as described here

E.g. like

using System.Linq;

public List<GameObject> cardsToSpawn;
public List<Transform> cardPositions = new List<Transform>();

void Awake()
{
    // First make sure both lists have the same length
    if(cardsToSpawn.Count != cardPositions.Count) 
    {
        Debug.LogError("List length are different! Make sure you have the same amount of elements in both lists!");
        return;
    }

    // get the cards in randomized order
    Random rnd = new Random();
    // OrderBy returns an IEnumerable ordered by the given predicate
    // since our given predicate returns a random value each time
    // the elements get shuffled 
    var shuffledCards = cardsToSpawn.OrderBy(c => rnd.Next()).ToArray();    

    for (int i = 0; i < shuffledCards.Length; i++) 
    {
        // since the cards are already shuffled you can simply iterate
        // over this array in order now
        var card = shuffledCards[i];
        var position = cardPositions[i];

        Instantiate(card, position, transform.rotation);
    }
}
derHugo
  • 83,094
  • 9
  • 75
  • 115