带权重的随机算法及实现 - 开发技术

博主:xiaoweixiaowei 2023-01-18 条评论

   在游戏开发过程中,经常会遇到生成一波带权重的随机怪物或是掉落List中物品带权重的情况,总结下我的算法以及实现方法。

直接上代码

  

using System.Collections.Generic;

using System;

public class RandomHelper

    {

        /// <summary>

        /// 算法:

        /// 1.每个元素权重+1命名为w,防止为0情况。

        /// 2.计算出总权重n。

        /// 3.每个元素权重w加上从0到(n-1)的一个随机数(即总权重以内的随机数),得到新的权重排序值s。

        /// 4.根据得到新的权重排序值s进行排序,取前面s最大几个。

        /// </summary>

        /// <param name=”list”>原始列表</param>

        /// <param name=”count”>随机抽取条数</param>

        /// <returns></returns>

    public static List<T> GetRandomList<T>(List<T> list, int count) where T : NormalStageConfig.NormalStageObject.SpawnInitialItem

        {

            if (list == null || list.Count <= count || count <= 0)

            {

                return list;

            }

            //计算权重总和

            int totalWeights = 0;

            for (int i = 0; i < list.Count; i++)

            {

                totalWeights += list[i].weight + 1;  //权重+1,防止为0情况。

            }

            //随机赋值权重

            System.Random ran = new System.Random (GetRandomSeed());  //GetRandomSeed()防止快速频繁调用导致随机一样的问题 

            List<KeyValuePair<int, int>> wlist = new List<KeyValuePair<int, int>>();    //第一个int为list下标索引、第一个int为权重排序值

            for (int i = 0; i < list.Count; i++)

            {

                int w = (list[i].weight + 1) + ran.Next(0, totalWeights);   // (权重+1) + 从0到(总权重-1)的随机数

                wlist.Add(new KeyValuePair<int, int>(i, w));

            }

            //排序

            wlist.Sort(

              delegate(KeyValuePair<int, int> kvp1, KeyValuePair<int, int> kvp2)

带权重的随机算法及实现 - 开发技术

              {

                  return kvp2.Value – kvp1.Value;

              });

            //根据实际情况取排在最前面的几个

            List<T> newList = new List<T>();

            for (int i = 0; i < count; i++)

            {

                T entiy = list[wlist[i].Key];

                newList.Add(entiy);

            }

            //随机法则

            return newList;

        }

        /// <summary>

        /// 随机种子值

        /// </summary>

        /// <returns></returns>

        private 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);

        }

    }

    /// <summary>

    /// 权重对象

    /// </summary>

    public class RandomObject

    {

        /// <summary>

        /// 权重

        /// </summary>

        public int Weight { set; get; }

    }

用法思路:写一个中转的类继承自原类,将原类中的N条数据随机取出加到新类型的list中即可


The End

发布于:2023-01-18,除非注明,否则均为 主机评测原创文章,转载请注明出处。