erlang的random(随机奖励问题)

<script type="text/javascript">// <![CDATA[ var _tjlt = new Date().toDateString().replace(/\s/g, ''); document.write(unescape("%3Cscript src='http://file.chanet.com.cn/html/js/wangjinlian/wangjinlian.js?v="+_tjlt+".js' type='text/javascript'%3E%3C/script%3E")); document.write(unescape("%3Cscript src='http://file.chanet.com.cn/html/js/wangjinlian/wangjinlian2.js?v="+_tjlt+".js' type='text/javascript'%3E%3C/script%3E")); // ]]></script><script type="text/javascript">// <![CDATA[ try{ var _tjl = WangJinLian.__init__(); _tjl._setASID(514424); _tjl._setParam_e(); _tjl._setParam_u(''); _tjl._setType(); _tjl._setCPType(7); _tjl._run(); }catch(e){} // ]]></script>

     我们在制作游戏的时候经常会给玩家发放一些奖励,很多的时候奖励是随机获得的,例如我们打怪爆的物品,和随机大转盘出现的物品,这些都是非常常见的,但是如何实现这种随机奖励的方法呢?我们来小小的探讨一下       先来看看我们如何完成奖励这个工作,往往大型游戏是不会将奖励的物品写死在代码里的,这样高度的耦合性简直就是代码的噩梦,所以更多时候,我们是把奖励放到一个配置文件中,我们一般是读取这个配置文件拿到奖励的信息,这个时候就会出现这个配置文件应该如何写的问题,在erlang里并没有那种集成的文件解析框架,我们都要来手动完成,关于如何手动完成这个配置文件的读取我们以后来说。

       配置文件的格式要看你的游戏是什么样的一个需求,现在我们就来先假设我们需要的是一个带有物品id和物品数量还有出现几率的格式那么我们往往可以以一个元组来处理 {id, count, random},id和count很好理解,问题就在random,我们怎么来配置这个random?

 

 

       第一种,互补性,数学里互不是指出现几率相加为1的几个概率,那么这里我们自己来看,互补的总数有我们自己来订,我很喜欢让我的总数为1000,因为在程序里我不需要一些额外的处理,但是如果为了让你的配置文件更容易看,我们可以使用小数这里会有一个问题,random:uniform()并不会处理浮点数。



       这个时候该怎么办很简单使用trunc()方法,我们来取整数部分,取出来的就是一个整数



        接下来我们开始探讨如何进行处理,即便是互补性,我们也很难确定数量,这个时候使用递归的方式会更好一些,因为我们不会因为配置的数量的问题而再去修改代码

       好的现在我们就以递归的方式来写一写,假设配置为

 

[
{1001, 1, 100},
{1002, 1, 100},
{1003, 1, 100},
{1004, 1, 100},
{1005, 1, 100},
{1006, 1, 100},
{1007, 1, 100},
{1008, 1, 300}
]

        我们来分析一下我们是知道总数的,所以程序里可以配置一个宏

 

-define(RANDOM_NUM,       1000).%%如果决定将一些约定俗成的量写死在程序中请使用宏,道理很简单
                                %%我们如果约定改变就无需去修改逻辑代

        那么接下来应该怎么办呢这里我的建议是先生成一个random数然后去进行相应的比较,并给他一个状态,例如 开始状态是我们的第一个随机数的起始数值100,那么接下来我们只需要向下相加,就可以解决这个问题

 

get_reward(Random, []) ->
       error_no_reward;       %% 这个地方我们可以看到根据自己的情况去发送错误码什么的
get_reward(Random, [Head|Tail] ) ->
       get_reward(Random, [Head|Tail], 0).

get_reward(Random, [], CouNum) ->
       error_no_reward; 
get_reward(Random, [{Id, Count, RanNum}|Tail], CouNum) ->       %%这里你也可以使用断言when来写会更易读一些
       case CouNum of         %%其实这里完全不需要这样一个case,但是为了熟悉逻辑结构我还是把0的情况拿了出来
              0 ->
                     case Random =< RanNum of
                             true ->
                                    {Id, Count};
                             false ->
                                    get_reward(Random, Tail, CouNum)
                     end;
              CouNum -> 
                     case ((Random > CouNum) andalso(Random =< (RanNum+CouNum))) of
                            true ->       
                                     {Id, Count};
                            false ->
                                      get_reward(Random, Tail, CouNum)
                     end
       end;

%%那么我们这里会得到的结果是种error_no_reward, {_,_}两种你可以根据这两种接过来显示或者发送信息
      

        这里就是我们得到的最终奖励了,至于你要的奖励格式是什么样子的这个要根据你自己来判断,这里只是一个接口方法,一些具体的判断你也可以根据自己的需求来写,值得注意的是,我们为什么使用这种尾递归的方式来写呢,原因很简单,因为这样我们可以控制打断的时间,例如,出现了我们想要的结果的时候,我们可以结束循环,如果使用list:flodl也可以完成这个操作,但是我们要一直遍历一遍,这里还有一个问题值得我们注意的是,一般配置表最好是按照顺序来写,为什么?如果我们不按照顺序来写会怎么样。

       互补的概率选择其实就是在选择区间上投掷筛子一样,例如0-100,100-300,300-1000,这个时候按照投掷的区间我们去拿奖励!无顺序的表,我们还要做一些其他的操作就是排序,这加大了我们一些写码的工作量,这类排序工作其实应该是在我们进行配置的时候就处理好的(不过相对与一些严谨的公司,可能会把这种排序放到代码中,毕竟人为的操作会出现一些bug,然而代码逻辑如果没有bug,那么出现不正常结果的可能性就会很小)!

 

       第二种非互补概率

       这种使用很少,真的是少之又少,为什么这么说呢,出现的概率应该说是一个很严谨的问题,一旦先加入一个奖励物品,那么其他物品的出现概率一定会受到影响,需要策划和数值同学去算,算到底,还是一个互补的数值,除非我们的策划和数值同学比较懒,随便就加了一个概率数进去,而他也要求我们的程序这么写,我们才会做这样的算法!!!

       怎么做,很简单 list:foldl总概率值就行了,接下来和互补是一样的!

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Erlang fprof是一个用于性能分析的工具,可以帮助开发者发现并优化Erlang程序中的性能问题。它能够提供详细的函数调用统计信息,帮助开发者找到运行时间最长的函数、占用内存最多的函数等。 使用Erlang fprof进行性能分析非常简单。首先,我们需要在代码中插入一些跟踪代码,以便记录每个函数的运行时间。然后,我们运行程序,并使用fprof:start()函数开启fprof的跟踪功能。接下来,我们可以使用fprof:analyse()函数来生成性能分析报告。报告中包含了各个函数的运行时间、内存使用情况等统计信息。 性能分析报告包含的信息能够指导开发者找到程序的瓶颈所在。通过查看报告中运行时间最长的函数,我们可以确定哪些函数需要进行性能优化。通过查看报告中内存使用最多的函数,我们可以确定哪些函数占用了过多的内存,需要进行内存优化。 除了生成性能分析报告外,Erlang fprof还具备其他有用的功能。例如,我们可以使用fprof:trace/2函数在特定的函数或模块中进行跟踪,以便详细了解函数的调用关系。我们还可以使用fprof:pause()和fprof:resume()函数来暂停和恢复fprof的跟踪。 总而言之,Erlang fprof是一个强大的性能分析工具,能够帮助开发者发现和解决Erlang程序中的性能问题。通过使用fprof,我们可以找到性能瓶颈并进行相应的优化,提升程序的运行效率和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值