美文网首页工具类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