Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by imLowe · Feb 25, 2017 at 05:27 PM · c#gamelistrandomquiz

Randomizing numbers on a list.

Im doing a simple Quiz game and I needed a way to get unique random numbers, so I can play the questions in a random order without repeating them. Found the code.

     private int maxNumbers = 6;
     private List<int> uniqueNumbers;
     private List<int> finishedList;
 
   void Start ()
     {
         uniqueNumbers = new List<int>();
         finishedList = new List<int>();
 
         GenerateRandomList();
     }
 
   public void GenerateRandomList()
     {
         for (int i = 0; i < maxNumbers; i++)
         {
             uniqueNumbers.Add(i);
         }
         for (int i = 0; i < maxNumbers; i++)
         {
             int ranNum = uniqueNumbers[Random.Range(0, uniqueNumbers.Count)];
             finishedList.Add(ranNum);
             uniqueNumbers.Remove(ranNum);
         }
 
         //Just to see them in the console
         foreach (int data in finishedList)
         {
             Debug.Log(data);
         }
     }
 

The problem here is that the random numbers appear all in once. I need one number at a time and the next randomization just start when I want to, by pressing a button or whatever. But that's just the way I feel I can do. For sure there's a way to do with the numbers all in once in the list.

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image CarterG81 · Feb 25, 2017 at 11:41 PM 0
Share

They are appearing all at once because youre iterating through every number in those for loops.

Youre just shuffling th around, which is pointless. Just grab a random one from the list, use it, then remove it. No need for a second List unless youre reusing the questions.

4 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by AMU4u · Feb 25, 2017 at 05:35 PM

What you want is the Fisher-Yates Shuffle, my friend!

https://www.dotnetperls.com/fisher-yates-shuffle

...and a video!

https://www.youtube.com/watch?v=H5LGwDanx2U

Edit - I made it so your script works the way you kind of described it wanting.

  private int maxNumbers = 6;
  private List<int> uniqueNumbers;
  private List<int> finishedList;
       
 void Start ()
  {
  uniqueNumbers = new List();
  finishedList = new List();
       
               
   }
       
 public void GenerateRandomList()
  {
 for (int i = 0; i < maxNumbers; i++)
  {
 uniqueNumbers.Add(i);
  }
  for (int i = 0; i < maxNumbers; i++)
  {
  int ranNum = uniqueNumbers[Random.Range(0,uniqueNumbers.Count)];
  finishedList.Add(ranNum);
  Debug.Log(ranNum); 
  uniqueNumbers.Remove(ranNum);
                   
   }
       
               
  }
  void OnGUI()
  {
 if (GUI.Button(new Rect(100, Screen.height - 175, 100, 30), "Print num"))
 {
 GenerateRandomList();
 }
 
 
 
 
Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image imLowe · Feb 25, 2017 at 06:33 PM 0
Share

In the end, the code I showed does the same thing. I'm quite a beginner, so it might be me but I dont see the solution for my problem in there.

avatar image AMU4u imLowe · Feb 25, 2017 at 11:25 PM 0
Share

If you understand the method, than you should really understand how to return the shuffled variable you are looking for.

Your question says it returns them all at the same time. With the Fischer-Yates method, you'll learn to return the unique random variable while shuffling it at the end.

avatar image CarterG81 AMU4u · Feb 25, 2017 at 11:45 PM 0
Share

I must be missing something? why would he ever meed to shuffle the list when he is already randomly picking them using Random.Range(count)?

avatar image toddisarockstar · Mar 21, 2020 at 12:51 PM 0
Share

this function would shuffle a list:

     public List<int> mix(List<int> n){
         List<int> r = new List<int> ();
         while (n.Count>0) {
             int i = Random.Range(0,n.Count);
             r.Add(n[i]);
             n.RemoveAt(i);
         }
         return r;
 
     }


but even easier, why not just randomly pick a number from your list and remove it?

avatar image sacredgeometry · Mar 21, 2020 at 08:22 PM 0
Share

@imLowe

A$$anonymous$$U4U has given you an answer that works ...here is another example of the same algorithm and how to use it.

 public static class IEnumerableExtensions
     {
         private static Random rng = new Random(); 
 
         public static void Shuffle<T>(this IList<T> list)  
         {  
             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;  
             }  
         }
     }
 
     public class QuizItem
     {
         public string Name { get; set; }
         public QuizItem(string name)
         {
             Name = name;
         }
     }
     
     class Program
     {
   
         static void $$anonymous$$ain(string[] args)
         {
             var quiz = new List<QuizItem>{
                 new QuizItem("Question 1"),
                 new QuizItem("Question 2"),
                 new QuizItem("Question 3"),
                 new QuizItem("Question 4"),
                 new QuizItem("Question 5"),
             };
 
             quiz.Shuffle();
             Console.WriteLine(string.Join(", ", quiz.Select(q => q.Name)));
             
             quiz.Shuffle();
             Console.WriteLine(string.Join(", ", quiz.Select(q => q.Name)));
         }
     }
avatar image
0

Answer by CarterG81 · Feb 25, 2017 at 11:26 PM

Perhaps I am not understanding the question, but...

Wouldnt this be as simple as....

 int PickAndRemoveOneRandom()
 {
 int randomNum = Random.Range(0, myList.Count); //Pick one random number based on total numbers.
 int theNumber = myList[randomNum]; //store the number
 myList.Remove(randomNum); //Remove number so it cant be used again.
 return theNumber; //return the number
 }

Then use the method in your code

 int theNumber = PickAndRemoveOneRandom();

Or onClick event on a Unity UI Button --> PickAndRemoveOneRandom() and add your " //do stuff code" in the function instead of returning an int

Options:

  • You could pass the list as parameter: void myMethod(List myList) { }

  • You could make this support generic types (return & remove ANY type from any List, insuring uniqueness

  • Keep used numbers in a second List (just add one line before return. usedNumberList.Add(theNumber)

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image CarterG81 · Feb 25, 2017 at 11:53 PM 0
Share

To create the list, you could simply use Unity editor.

public List myQuestions = new List()

Create a gameobject, attach script. In the Inspector add elements to the List, type in your questions, and save them as prefab Gameobjects.

avatar image CarterG81 CarterG81 · Feb 25, 2017 at 11:55 PM 0
Share

And thr function:

 void PickAndRemoveOneQuestion()
 {
 int randomNum = Random.Range(0, myQuestions.Count);
 string theQuestion = myQuestions[randomNum];
 DisplayQuestion(theQuestion);
 myQuestions.Remove(theQuestion);
 }
avatar image
0

Answer by Nailon_amstronic · Mar 21, 2020 at 11:55 AM

This is preety old but I was looking for an answer to the same question and I ended writing an algorithm my self. Seems to work preety well.

 //"from" and "to" are inclusive
    public List<int> GenerateRandomIntegerList(int from, int to) 
     {
         List<int> numbersDone = new List<int>();
 
         while (true)
         {
             int i = Random.Range(from, to + 1);
 
             bool isNew = true;
             foreach (int num in numbersDone)
             {
                 if (num == i)
                 {
                     isNew = false;
                 }
             }
 
             if(isNew)
             {
                 numbersDone.Add(i);
 
                 if(numbersDone.Count == to + 1)                
                     break;
                 
             }
         }
 
         return numbersDone;
     }
 
 
 
 


Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by TCMOREIRA · Mar 21, 2020 at 11:22 PM

Just for the sake of completeness, since all the other answers seem to be pretty good already, but I usually do this using a Set structure (HashSets of int in particular).


If you know your numbers beforehand: Here's some pseudo-code:

  - Let there be an empty Set of type Set of Integers called 'SortitionSet'
  - Let there be an Integer Array containing the numbers we want to Sortition called 'IntegersArray'
 
   Generate the SortitionSet:
     While(Length of  IntegersArray > 0)
          Let there be an auxiliary variable which receives a the resulting element from the deletion of the first element of the array called 'aux'
          Try to insert aux into SortitionSet (It should return false in case of a repeated number)
           In case the insertion was successful continue, otherwise throw exception
 
     Return SortitionSet


 Give a Random Number from the Set by Removing it:
      Return SortitionSet.Remove(Random Index)
     

 </end>


If you don't know your numbers beforehand:

Here's some pseudo-code:

 <begin/>
 
  - Let there be an empty Set of type Set of Integers called 'SortitionSet'
  - Let there be a positive Integer number greater than zero called 'AmountOfNumbersToGenerate'
 
   Then:
     While(AmountOfNumbersToGenerate > 0)
          Let there be an auxiliary variable which receives a randomly generated number called 'aux'
          Try to insert aux into SortitionSet (It should return false in case of a repeated number)
           In case the insertion was successful reduce AmountOfNumbersToGenerate by 1
 
     Return SortitionSet
 
 </end>


Hope this helps someone! Cheers!

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

12 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Pick between two floats 2 Answers

Random element from the list 1 Answer

Printing a GUI selection grid in order 1 Answer

How can I display 4 items in random order but never double? 2 Answers

A node in a childnode? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges