0

I've a line in the bottom part of the main screen of the game, that every time the scene is loaded, it shows a different tip (how to play, how to change music...).

The question is that I'm using Random.Range for that but, honestly, I'll prefer a way where all tips are showed, one by one in a random way, but without repeating any of them.

My code is as follows:

int randNum;
void Start () {
    randNum = Random.Range(0,5);
}

void Update () {

    switch (randNum)
    {
        case 0:
       // blah, blah, blah...
        case 1...

How can I achieve what I want?

Thans for yout timeeee :)

Stefan
  • 17,448
  • 11
  • 60
  • 79

3 Answers3

3

You can remove the switch statement and store each message in a list.

var tips = new List<string>();
tips.Add("The clouds are white");
...

Then you can randomize the elements in the list (more on that here) and show tips one by one. All you need is to keep track of the index. Example:

// This needs to be a field.
int index = 0;

void ShowTip() 
{ 
    // TODO: make sure index is not equal or greater than tips.Count

    tip = tips[index]; 
    index++; 

    // Display the tip
}
Selman Genç
  • 100,147
  • 13
  • 119
  • 184
1

What you can do is to shuffle your list of tip. The Fisher-Yates shuffle is one of the most common.

static Random _random = new Random();

static void Shuffle<T>(T[] array)
{
    int n = array.Length;
    for (int i = 0; i < n; i++)
    {
        // Use Next on random instance with an argument.
        // ... The argument is an exclusive bound.
        //     So we will not go past the end of the array.
        int r = i + _random.Next(n - i);
        T t = array[r];
        array[r] = array[i];
        array[i] = t;
    }
}

public static void Main()
{
        string[] array = { "tip 1", "tip 2", "tip 3" };
        Shuffle(array);
        foreach (string value in array)
        {
            Console.WriteLine(value);
        }
}

output

net
dot
perls

source

aloisdg
  • 22,270
  • 6
  • 85
  • 105
1

Suppose your messages are stored in a list of string declared at the global level together with your random class and with an additional List of strings initially empty

List<string> needToDisplayMessages = new List<string>();
List<string> base_messages = new List<string>{"message1","message2","message3","message4","message5"};
Random rnd = new Random();

In your update method check if the list of messages to be displayed is empty and if yes copy the messages from the list with the predefined message. Now use the random instance to choose the index of the message to display and get it from the dynamic list. Finally remove the message from the list of message still to be displayed.

void Update () {

    // We refill the list if it is empty
    if(needToDisplayMessages.Count == 0)
        needToDisplayMessages.AddRange(base_messages);

    // Choose a random number topped by the count of messages still to be displayed
    int index = rnd.Next(0, needToDisplayMessages.Count);

    string message = needToDisplayMessages[index];
    ..... display the message someway .....

    // Remove the message from the list
    needToDisplayMessages.RemoveAt(index);

}

Of course, if you want to display the messages in sequential order there is no need of this but (as already explained) just an index. But if you want to randomly choose the message until you have shown all of them and then restart the cycle, perhaps this approach is not too much complex.

Steve
  • 213,761
  • 22
  • 232
  • 286