偶久网

 找回密码
 注册会员

QQ登录

只需一步,快速开始

搜索

网站魔兽热门地图

查看: 11109|回复: 9

JASS进阶-随机系统

  [复制链接]
ou99孽缘 title=
发表于 2010-12-16 18:32:18
什么是随机能力系统?
这个系统主要是用来处理增加随机能力给单位,最早源于我在 ROC 时代发现的一个 BUG ~~在这个 BUG 基础上~~我做了一个像 DIABLO 那样的拥有随机能力的道具系统。
现在看来,这个系统的主要作用是如“增加 0~999 之间的任意数值的伤害给单位”等。

 
随机能力系统基本思想!
基本思想就是利用道具技能,比如用攻击之爪的技能来增加额外的伤害,用防守指环的技能来增加额外的防御等等。要达到增加任意的额外能力,在 1.14B 里面同一个技能不能累加效果~~也就是说添加两个 +3 伤害的技能也只有 +3 伤害~~而不是 +6 ~~所以循环添加 +1 的技能来达到任意期望数值的做法是不可行的,另外~~即使可行~~循环添加上百的技能对于计算机也是一种考验,所以我们并不提倡。于是问题就来了~~如何最高效率的达成我们的目标。
无论如何,利用不同的数值的同类技能来组合出期望数值的想法成为实现这个问题的主导思想。
下面我们将以增加额外伤害作为说明对象。

关于能力组合与问题!
开门见山的我问一个问题~~如何让计算机来统一有效的识别一个整数,然后分析出相应的技能组合,然后用这些技能添加给单位以达到效果呢?~
上面说的可能比较难懂~~那我做个比方~~
假设我们想 +5 ~~那么我们可以用不重复的技能 +1 和 +4 来组合出 +5 ~~将 +1 和+4 两个技能添加给单位那么我们就得到了 +5 的额外伤害。
但是计算机如何知道 想 +5 就用 +1 和 +4 来组合 呢?~~这是个问题~~
计算机没有逻辑推递能力(至少现在的民用计算机没有,不过递归等算法是可以模拟的:)~~所以不能理性的分析出这个结果~~
另外一个问题~~我们想在上面 +5 的基础上面再 +1 ~~那么我们就不可能直接添加一个 +1 的技能上去~~因为上面的 +5 是用 +1 和 +4 来得到的~~我们已经不能再使用 +1 了~~由于不能累加同种技能~~所以这么个简单的 +1 目前来看是难以实现的~~
所以我们必须重构 组合方式~~也就是说先删除之前 +1 和 +4 两个技能~~然后让计算机分析出如何构造出 +6 的组合~~这也是个问题~~
值得注意的是:
作为配方的技能~~我们必须先定义~~我们不可能在实际需要的时候才去创造一些技能~~而就是说~~我们必须要先定义出 +1 和 +4 两个技能~~才有可能处理 +5 这种需求~~所以新的问题来了:我们如何预先定义一批作为配方的技能来组合出我们可能要求的任意目标数值,比如区间内的随机数。
关于编码,解码,十进制与二进制转换!
我们要用最少的自己定义技能达到尽可能大的取值区间,要用到一些简单的编码解码思想,这里的编码解码的目的仅仅是为了利于控制。
要想作到用一组特定的不重复的技能来组合出连续数值空间~~让我很容易的想到二进制~~为什么是二进制?~~因为二进制有这么些特性:
1] 每一位只有 0 和 1 两个值~~
2] 每一位上的 1 表示的数值不同(级差)~~
3] 二进制 是一个连续的数值空间~~
说到这里~~有心的人肯定已经有点感觉了~~我们如何通过二进制来解决我们的问题。
先看第一条~~只有 0 和 1 两个可能值~~我们的每一个用于组合的技能是不是也只有拥有不拥有两种情况呢?
然后看第二条,如果我们用二进制中每一位的十进制表达来作为每一个技能的增加点数,那么配合第三条的结论——一个连续的数值空间~~发现没有~~我们的问题其实很简单!
我们可以简单的用一组不同数值的技能来表达一个连续数值空间~~
好了~~下面我们就先说说这个每一位 二进制数的十进制表达 吧~~
我们假设一个 12 位的二进制数 111111111111 ~~他的十进制表达就是:
2048+ 1024+ 0512+ 0256+ 0128+ 0064+ 0032+ 0016+ 0008+ 0004+ 0002+ 0001
二进制数中的每一位对应了上面十进制表达式中的每一项~~
用这些十进制数可以不重复的表示任意一个 1~4095 之间的十进制数~~
同样的~~任意一个 1~4095 之间的数都可以用一段 12位二进制数 来表示~~
那么我们用二进制数做简单编码~~可以得到一个用于解码的标记序列(FLAGARRAY)~~
比如我们需要 +9 ~~那么我们需要 +1 和 +8 两个技能~~这两个技能分别是第 1 位和第 4 位(左为高位)~~那么用二进制表达就是 1001 ~~我们就知道第 1 位与第 4 位表示的两个技能我们要添加~~
如果我们按照如下的方式先将技能保存在数组里面:
udg_ability_damage[1] = +1
udg_ability_damage[2] = +2
udg_ability_damage[3] = +4
udg_ability_damage[4] = +8
……
…………
………………
udg_ability_damage[11] = +1024
udg_ability_damage[12] = +2048
那么我们直接取 1 和 4 作为下标就取到 +1 和 +8 两个技能了~~所谓解码~~就是将我们的二进制表达转换成我们需要的技能~~
说道这里~~我想大家都有一个大概的理解了吧~~最后我给出一个简单的十进制转二进制的函数:
 

D - 需要转换的十进制数,作为第一参数
F - 第二参数,是得到的二进制数的长度,比如将 9 转换后~~如果长度为 7 那么得到 ”0001001“

以下内容为程序代码:

function D2B takes integer D, integer F returns string
    local integer _D = D
    local integer _M = 0
    local integer Count = 0
    local string _B = ""
    local string _FB = ""

 
    loop
        set _M = _D - ( _D / 2 ) * 2
        set _D = _D / 2
        set _B = I2S( _M ) + _B
        set Count = Count + 1
        exitwhen _D < 2
    endloop
    set _B = _B + I2S( _D )

    if ( F > Count ) then
        set _D = 1
        set _M = F - Count
        loop
            exitwhen _D > _M
            set _FB = _FB + "0"
            set _D = _D + 1
        endloop
    endif
    set _FB = _FB + _B
    return _FB
endfunction



注意:以上函数是我直接在帖子里面写的~~没有在WE里面测试过~~所以不保证严密性~~也不保证可以通过编译~~不过主要算法是清楚给出了的~~大家可以看看自己理解~~:)
ou99孽缘 title=
 楼主| 发表于 2010-12-16 18:33:21
{:6_325:}
ou99老大
发表于 2010-12-26 01:07:07
{:6_325:}
极道神光
发表于 2011-1-31 21:19:52
你们看得懂吗?,。。。{:6_331:}
asd3605039
发表于 2011-5-8 19:49:06
{:6_256:}实在复杂,有没有视频区的
guizhuwu2
发表于 2011-7-7 15:20:43
路过第N次……顶&¥@#%
879558831 该用户已被删除
发表于 2012-12-30 03:23:40
提示: 作者被禁止或删除 内容自动屏蔽
快速回复 返回顶部 返回列表