如果没有Thread.Sleep(300),如何在这个类中获得真正的随机性?

Edw*_*uay 6 c# random

我已经创建了一个类(下面的代码)来处理在测试中创建"匹配"测验项,这是输出:

替代文字

它工作正常.

然而,为了得到它完全随机的,我必须把线程睡眠至少300个计数两列随机洗牌,一切皆有之间低于300个回报以同样的顺序进行排序两根柱子,就好像它是使用随机的相同种子:

LeftDisplayIndexes.Shuffle();
Thread.Sleep(300);
RightDisplayIndexes.Shuffle();
Run Code Online (Sandbox Code Playgroud)

我有什么做的,使两列完全随机没有这个时间的洗牌等待?

完整代码:

using System.Collections.Generic;
using System;
using System.Threading;

namespace TestSort727272
{
    class Program
    {
        static void Main(string[] args)
        {
            MatchingItems matchingItems = new MatchingItems();
            matchingItems.Add("one", "111");
            matchingItems.Add("two", "222");
            matchingItems.Add("three", "333");
            matchingItems.Add("four", "444");
            matchingItems.Setup();

            matchingItems.DisplayTest();
            matchingItems.DisplayAnswers();

            Console.ReadLine();

        }
    }

    public class MatchingItems
    {
        public List<MatchingItem> Collection { get; set; }
        public List<int> LeftDisplayIndexes { get; set; }
        public List<int> RightDisplayIndexes { get; set; }

        private char[] _numbers = { '1', '2', '3', '4', '5', '6', '7', '8' };
        private char[] _letters = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' };

        public MatchingItems()
        {
            Collection = new List<MatchingItem>();
            LeftDisplayIndexes = new List<int>();
            RightDisplayIndexes = new List<int>();
        }

        public void Add(string leftText, string rightText)
        {
            MatchingItem matchingItem = new MatchingItem(leftText, rightText);
            Collection.Add(matchingItem);
            LeftDisplayIndexes.Add(Collection.Count - 1);
            RightDisplayIndexes.Add(Collection.Count - 1);
        }

        public void DisplayTest()
        {
            Console.WriteLine("");
            Console.WriteLine("--TEST:-------------------------");
            for (int i = 0; i < Collection.Count; i++)
            {
                int leftIndex = LeftDisplayIndexes[i];
                int rightIndex = RightDisplayIndexes[i];
                Console.WriteLine("{0}. {1,-12}{2}. {3}", _numbers[i], Collection[leftIndex].LeftText, _letters[i], Collection[rightIndex].RightText);
            }
        }
        public void DisplayAnswers()
        {
            Console.WriteLine("");
            Console.WriteLine("--ANSWERS:-------------------------");
            for (int i = 0; i < Collection.Count; i++)
            {
                string leftLabel = _numbers[i].ToString();
                int leftIndex = LeftDisplayIndexes[i];
                int rightIndex = RightDisplayIndexes.IndexOf(leftIndex);
                string answerLabel = _letters[rightIndex].ToString();

                Console.WriteLine("{0}. {1}", leftLabel, answerLabel);

            }
        }

        public void Setup()
        {
            do
            {
                LeftDisplayIndexes.Shuffle();
                Thread.Sleep(300);
                RightDisplayIndexes.Shuffle();
            } while (SomeLinesAreMatched());
        }

        private bool SomeLinesAreMatched()
        {
            for (int i = 0; i < LeftDisplayIndexes.Count; i++)
            {
                int leftIndex = LeftDisplayIndexes[i];
                int rightIndex = RightDisplayIndexes[i];
                if (leftIndex == rightIndex)
                    return true;
            }
            return false;
        }


        public void DisplayAsAnswer(int numberedIndex)
        {
            Console.WriteLine("");
            Console.WriteLine("--ANSWER TO {0}:-------------------------", _numbers[numberedIndex]);
            for (int i = 0; i < Collection.Count; i++)
            {
                int leftIndex = LeftDisplayIndexes[i];
                int rightIndex = RightDisplayIndexes[i];

                Console.WriteLine("{0}. {1,-12}{2}. {3}", _numbers[i], Collection[leftIndex].LeftText, _letters[i], Collection[rightIndex].RightText);
            }
        }
    }

    public class MatchingItem
    {
        public string LeftText { get; set; }
        public string RightText { get; set; }

        public MatchingItem(string leftText, string rightText)
        {
            LeftText = leftText;
            RightText = rightText;
        }
    }

    public static class Helpers
    {
        public static void Shuffle<T>(this IList<T> list)
        {
            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;
            }
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

Alb*_*nbo 10

移动Random rng = new Random();到静态变量.

MSDN说"默认种子值来自系统时钟并具有有限的分辨率".当您Random在很小的时间范围内创建许多对象时,它们都会获得相同的种子,第一个值将等于所有Random对象.

通过重用相同的Random对象,您将前进到给定种子的下一个随机值.


Jak*_*son 6

只创建一个Random类的一个实例.当你在没有构造函数的情况下调用它时,它会从计算机时钟中获取随机种子,因此你可以获得两次相同的种子.

public static class Helpers
{
    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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 注意你是否使用多个线程 - 与大多数.net Framework类一样,`Random`对象不保证是线程安全的. (3认同)