美文网首页工具类Unity基础入门分享搭建自己的Unity知识体系
一、随机数——2、每次和之前随机到的数不一样

一、随机数——2、每次和之前随机到的数不一样

作者: GameObjectLgy | 来源:发表于2020-07-16 10:24 被阅读0次
    提高随机数不重复概率的种子生成方法:

    Unity写法:

    Random.InitState(seed);
    seed = (int)System.DateTime.Now.Ticks;
    if (isFirstMeet)
    {
          Num = Random.Range(1, 3);//1-2
    }
    

    C#写法:

    static int GetRandomSeed( )
    {
          byte[] bytes = new byte[4];
          System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider( );
          rng.GetBytes( bytes );
          return BitConverter.ToInt32( bytes , 0 );
    }
    Random random = new Random( GetRandomSeed( ) );
    
    使用算法和数据结构产生不重复随机数方法:
    • 方法一
        private List<int> temp_List = new List<int>();
        private int[] target_num = new int[] {100, 200, 300, 400, 500, 600, 700, 800, 900};
    
        private int GetRandomNum()
        {
            int rangeI;
            do
            {
                rangeI = UnityEngine.Random.Range(0, target_num.Length);
                //注意这里边界
                if (temp_List.Count >= target_num.Length)
                {
                    temp_List.Clear();
                }               
            }
            while (isContains(rangeI));
            return target_num[rangeI];
        }
    
        private bool isContains(int rangi)
        {
            for (int m = 0; m < temp_List.Count; m++)
            {
                if (temp_List[m] == rangi)
                    return true;
            }
            temp_List.Add(rangi);
            return false;
        }
    
        public void OnClickBtn()
        {
            Debug.Log(GetRandomNum());
        }      
    
    测试结果

    全部都随机一遍之后才会重新从头随机
    上面的方法实际就是使用双数组的方法类确保随机不重复。下面是更简洁的写法:

    /// <summary>
    /// 方法一 使用随机抽取数组index中的数,填充在新的数组array中,使数组array中的数是随机的
    /// 方法一思路:用一个数组来保存索引号,先随机生成一个数组位置,然后把随机抽取到的位置的索引号取出来,
    ///             并把最后一个索引号复制到当前的数组位置,然后使随机数的上限减一,具体如:先把这100个数放在一个数组内,
    ///             每次随机取一个位置(第一次是1-100,第二次是1-99,...),将该位置的数用最后的数代替。
    /// </summary>
    static int[] UseDoubleArrayToNonRepeatedRandom(int length, int minValue, int maxValue)
    {
        int seed = Guid.NewGuid().GetHashCode();
        Random radom = new Random(seed);
        int[] index = new int[length];
        for (int i = 0; i < length; i++)
        {
            index[i] = i + 1;
        }
    
        int[] array = new int[length]; // 用来保存随机生成的不重复的数 
        int site = length;             // 设置上限 
        int idx;                       // 获取index数组中索引为idx位置的数据,赋给结果数组array的j索引位置
        for (int j = 0; j < length; j++)
        {
            idx = radom.Next(0, site - 1);  // 生成随机索引数
            array[j] = index[idx];          // 在随机索引位置取出一个数,保存到结果数组 
            index[idx] = index[site - 1];   // 作废当前索引位置数据,并用数组的最后一个数据代替之
            site--;                         // 索引位置的上限减一(弃置最后一个数据)
        }
        return array;
    }
    
    • 方法二
    /// <summary>
    /// 检查生成的随机数据是否重复
    /// 如果重复则继续递归调用
    /// 如果不重复则返回该数
    /// </summary>
    /// <param name="arr">生成的非重复随机数数组</param>
    /// <param name="temp">随机数</param>
    /// <param name="minValue">最大值</param>
    /// <param name="maxValue">最小值</param>
    /// <param name="random">生成随机数对象</param>
    /// <returns>返回一个不重复的随机数</returns>
    static int getNumberNonRepeatedRandom(int[] arr, int temp, int minValue, int maxValue, Random random)
    {
        int n = 0;
        while (n <= arr.Length - 1)
        {
            if (arr[n] == temp) //利用循环判断是否有重复 
            {
                temp = random.Next(minValue, maxValue); //重新随机获取。 
                getNumberNonRepeatedRandom(arr, temp, minValue, maxValue, random);//递归:如果取出来的数字和已取得的数字有重复就重新随机获取。 
            }
            n++;
        }
        return temp;
    }
    /// <summary>
    /// 递归,用它来检测生成的随机数是否有重复,如果取出来的数字和已取得的数字有重复就重新随机获取。
    /// </summary>
    static int[] RecursiveMethodToNonRepeatedRandom(int length, int minValue, int maxValue)
    {
        int seed = Guid.NewGuid().GetHashCode();
        Random random = new Random(seed);
        int[] array = new int[length];
        int temp = 0;
        for (int i = 0; i < length; i++)
        {
            temp = random.Next(minValue, maxValue); // 随机取数 
            array[i] = getNumberNonRepeatedRandom(array, temp, minValue, maxValue, random); // 取出值赋到数组中 
        }
        return array;
    }
    
    • 方法三
    /// <summary>
    /// 利用Hashtable
    /// </summary>
    static int[] UseHashTableToNonRepeatedRandom(int length, int minValue, int maxValue)
    {
        Hashtable hashtable = new Hashtable();
        int seed =  Guid.NewGuid().GetHashCode();
        Random random = new Random(seed);
        for (int i = 0; hashtable.Count < length; i++)
        {
            int nValue = random.Next(minValue, maxValue);
            if (!hashtable.ContainsValue(nValue) && nValue != 0)
            {
                hashtable.Add(i, nValue);
                //hashtable.Add(nValue, nValue);        // 将 key 和 value设置成一样的值,导致hashtable无法按添加顺序输出数组
                //Console.WriteLine(nValue.ToString());
            }
        }
        int[] array = new int[hashtable.Count];
        hashtable.Values.CopyTo(array, 0);
        return array;
    }
    

    相关文章

      网友评论

        本文标题:一、随机数——2、每次和之前随机到的数不一样

        本文链接:https://www.haomeiwen.com/subject/psiwhktx.html