Sub list items are not showing in C#

Viewed 106

I am trying to add a list inside a list. But I wasn't able to retrieve the items from the sub list. There is no error, but no data was retrieved from the sub list. Please focus on GenerateClue() I think the error is there.

When I'm trying to access the data using clueList[0][0], There is no data

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

public class TrainingMode : MonoBehaviour {
    private List<int> answerKey;
    private List<int> clue;
    private List<List<int>> clueList;
    private int correct;
    private int wellPlaced;
    public Text answerKeyText;
    System.Random random = new System.Random();

    void Start () {
        answerKey = new List<int>();
        clue = new List<int>();
        clueList = new List<List<int>>();

        GenerateAnswerKey();
        GenerateClue();

        //CheckCorrectAndWellPlaced();

        answerKeyText.GetComponent<Text>().text = answerKey[0] + " "+ answerKey[1] + " "+ answerKey[2];
        foreach (List<int> arrClue in clueList)
        {
            foreach (int item in arrClue)
            {
                Debug.Log(item);
            }
        }
    }

    private void GenerateClue()
    {

        //Generate clue
        for (int j = 0; j <= 5; j++)
        {
            for (int i = 0; i <= 2; i++)
            {
                int randomNumber = random.Next(0, 9);
                if (clue.Contains(randomNumber))
                {
                    i--;
                }
                else
                {
                    clue.Add(randomNumber);
                }

                if (clue.Count == 3)
                {
                    clueList.Add(clue);
                    clue.Clear();
                }
            }
        }
    }

    private void CheckCorrectAndWellPlaced()
    {
        correct = 0;
        wellPlaced = 0;
        //Check for correct and wellplaced numbers
        for (int i = 0; i <= 2; i++)
        {
            if (answerKey.Contains(clue[i]))
            {
                correct++;
            }
            if (clue[i] == answerKey[i])
            {
                wellPlaced++;
            }
        }
    }

    private void GenerateAnswerKey() {
        //Generate answerkey
        for (int i = 0; i <= 2; i++)
        {
            int randomNumber = random.Next(0, 9);
            if (answerKey.Contains(randomNumber))
            {
                i--;
            }
            else
            {
                answerKey.Add(randomNumber);
            }
        }
    }
}
3 Answers

The problem is that when you add the clue to your clue list what it's actually doing is passing a reference because List<> is a class. So you end up having just 2 variables pointing to the same memory. One is your clue variable and the other is the clueList[X]. So when you call clue.Clear() you are clearing the clue list which is ACTUALLY the same memory than your clueList[X].

As as fix just change this:

if (clue.Count == 3)
{
    clueList.Add(clue);
    clue.Clear();
}

into this:

if (clue.Count == 3)
{
    clueList.Add(new List<int>(clue));
    clue.Clear();
}

Your problem is here :

if (clue.Count == 3)
{
    clueList.Add(clue);
    clue.Clear();
}

You're adding clue to the clueList and then clearing the clue which has the same "memory address" ( same object as in the clueList ).

So in general, you're filling the clue list with some random numbers and then you're clearing this up whenever it fills making it empty again.

Instead, try to create a new list of ints on the beginning of your first for-loop.

for (int j = 0; j <= 5; j++)
{
    var list = new List<int>();
    for (int i = 0; i <= 2; i++)
    {
        int randomNumber = random.Next(0, 9);
        if (list.Contains(randomNumber))
        {
            i--;
        }
        else
        {
            list.Add(randomNumber);
        }

        if (list.Count == 3)
        {
            clueList.Add(list);
        }
    }
}

You need to create a copy of the list, so to avoid the Clear() call to act on the element put in the clueList.

if (clue.Count == 3)
   {
       clueList.Add(clue.ToList());
       clue.Clear();
   }

But I also think that there can be cases when the list won't be inserted, because there can be cases when the random number it's always the same and you keep on going out the for loop.

for (int j = 0; j <= 5; j++)
        {
            for (int i = 0; i <= 2; i++)
            {
                int randomNumber = random.Next(0, 9);
                if (clue.Contains(randomNumber))
                {
                    i--;
                }
                else
                {
                    clue.Add(randomNumber);
                }

                if (clue.Count == 3) // EDIT: what if it never reaches 3 ?
                {
                    clueList.Add(clue.ToList());
                    clue.Clear();
                }
            }
        }
Related