找回密码
 点一下
查看: 3570|回复: 14

用模2法实现随机数攻击力加成的函数~~

[复制链接]
发表于 2008-4-17 21:56:25 | 显示全部楼层 |阅读模式
另起一贴吧~~

用2进制来标识技能组合的we技术~~在国外叫位标识技术~~不过该技术其实是由我们的Danexx大魔王发明然后发布到国外的~~

这里顺便帖下我自己通常用的模2法技能组合函数吧~~


其实就跟feelerly同学想实现的效果一样~~但是其实用模2法的话效率更高~~

而且~~整个过程(包括模2计算和攻击力设置)全部可以包括在以下这个小小的函数中~~省去了循环算出数值以后又要循环一次设置攻击力的过程~~



[jass]
function AtkSet takes unit u,integer value returns nothing
      local integer x
      local integer i=0
      loop
            exitwhen i>5
            set x=value/2
            call SetUnitAbilityLevel(u,udg_AtkSpell,value-x*2+1)
            set value=x
            set i=i+1
      endloop
endfunction
[/jass]

没有用bj中的取余函数也没有用自定义的取余函数~~因为过程中同时需要取余和取商~~而取余函数必然会多运算一次商~~因此这里直接运算商然后用这个商去取余~~就省去了多算一步商的问题~~

而这里用的设置技能的方法也并非传统的添加和删除~~而是每个位元技能本身都设置了2级~~1级时效果为0~~2级才有加成效果~~这样~~该位为0时自动置1级~~为1时自动置2级~~就非常的方便~~

这样一来省去了一次if判断~~可以无视结果是0还是1而用SetUnitAbilityLevel()直接通杀~~另外调整技能等级所涉及的游戏数据变动也比添加和删除技能操作来的少和高效~~


随便放个用这个函数写的小演示~~由于里面做了6个位元技能~~因此攻击力调整范围在0-63之间~~用聊天信息输入任何0-63之间的数字~~测试单位就会受到相应数字的攻击加成~~输入数据大于63而又不是特别特别的大的话会对64取模~~因此输入65的话就变成加成1点~~

Mod2ATkSet.w3x

17 KB, 下载次数: 106

 楼主| 发表于 2008-4-17 21:59:51 | 显示全部楼层
但是其实该函数并非最高效的~~因为并不是每次都需要运算6次才能得到结果~~

因此其实
[jass]
function AtkSet takes unit u,integer value returns nothing
      local integer x
      local integer i=0
      loop
            exitwhen i>5
            if value!=0 then
            set x=value/2
            call SetUnitAbilityLevel(u,udg_AtkSpell,value-x*2+1)
            set value=x
            else
            call SetUnitAbilityLevel(u,udg_AtkSpell,1)
            endif
            set i=i+1
      endloop
endfunction
[/jass]
才是最快的~~当除到value为0的时候就不需要除下去了~~接下去几位全部设0就可以了(注意不能忘记设0,否则会导致攻击力降不下去的bug老)~~

但是虽然这个函数才最快~~但从代码的美观和简约上却不及上面那个函数~~因此我实际使用的时候还是喜欢用上面那个~~
回复

使用道具 举报

发表于 2008-4-17 22:10:30 | 显示全部楼层
MB头目~~
回复

使用道具 举报

发表于 2008-4-17 22:11:16 | 显示全部楼层

Re:模2法实现随机数攻击力的函数~~

Pow()函数的效率偶不太清楚呃。
看了LZ的Mod(x,2)方法设置攻击力,效率上似乎不错。不过在技能的设置方面就稍有些麻烦。
分解整数的方法是偶临时想到的,呵呵,可能是误打误撞吧。
回复

使用道具 举报

 楼主| 发表于 2008-4-17 22:20:29 | 显示全部楼层
其实一点都不麻烦~~

毕竟设置等级的话效率比添加删除高~~而且这种有2级位元技能~~每个技能的设置和只有1级的位元并没有什么区别~~

其实你只要做出一个有2个等级的攻击加成技能模板~~然后将其第一级数值设为0~~按Ctrl+C和Ctrl+V5次~~就有6个1级数值是0的2等级攻击技能了~~然后你再调整六个技能的第二等级数值就可以了~~

我们来对比一下传统的只有一个等级的攻击加成位元技能~~其实也要Ctrl+C和Ctrl+V5次~~再调整六个技能的第一等级的数值~~

看出来了吧?~~其实两者的区别仅仅是你多按了2个数值~~我的方法只是手工上多按了个2(模板技能的等级那里)~~还有个0(1级时的数值)~~总共也就多了点两下的操作而已~~因为这些全部是可以直接copy的呢~~根本不会麻烦~~


另外~~我习惯把位元技能的ID排在一起~~比方说这个演示里是'A000'到'A005'~~这样给udg_AtkSpell[]数组赋值的时候只要for i 1到5~~设置udg_AtkSpell[i]='A000'+i就可以了~~又节省好多代码和人工~~
回复

使用道具 举报

发表于 2008-4-18 12:38:51 | 显示全部楼层
if  value-x*2 !=0 then
    call SetUnitAbilityLevel(u,udg_AtkSpell,2)
endif
和楼主的直接
call SetUnitAbilityLevel(u,udg_AtkSpell,value-x*2+1)
相比哪个效率高?
虽然楼主的写法比较省事,但据说调用函数的效率比条件表达式慢得多
回复

使用道具 举报

 楼主| 发表于 2008-4-18 13:18:24 | 显示全部楼层
明显我的高~~你的要条件判断再调用函数~~而我的只要调用函数~~你说哪个效率高?~~

而且你要明白~~你这个判断可是还得加else~~为1的时候设2级~~难道为0的时候就不设了嘛?~~这样前一次的改动不重置自然会造成bug~~
回复

使用道具 举报

发表于 2008-4-18 14:29:59 | 显示全部楼层
调用函数的效率应该是比较低的,但
call SetUnitAbilityLevel(u,udg_AtkSpell,value-x*2+1)
除了SetUnitAbilityLevel之外貌似没有调用其他函数吧,只有运算额

而且
if  value-x*2 !=0 then
    call SetUnitAbilityLevel(u,udg_AtkSpell,2)
endif
这样的话还有if判断,如果跳转预测失败的话效率会更低的吧
回复

使用道具 举报

发表于 2008-4-18 17:48:48 | 显示全部楼层
事实上。不一定必须模2。模任何大于1的整数都可以。
回复

使用道具 举报

 楼主| 发表于 2008-4-18 17:57:16 | 显示全部楼层
可惜jass不能位移~~否则就更快了~~
回复

使用道具 举报

发表于 2008-4-18 20:59:13 | 显示全部楼层
引用第6楼Renee于2008-04-18 13:18发表的  :
明显我的高~~你的要条件判断再调用函数~~而我的只要调用函数~~你说哪个效率高?~~

而且你要明白~~你这个判断可是还得加else~~为1的时候设2级~~难道为0的时候就不设了嘛?~~这样前一次的改动不重置自然会造成bug~~
普遍来说,if语句为真的概率为50%,也即需要执行if后面的函数为你的方法的一半.
至于你说的要用else,可以干脆用一个布尔数组记录上一次的设置结果,比如说由+6攻击变成+7攻击,6和7写成二进制就是
110
111
只有个位的设置不同,那么比较异同后只需要调用一次重设技能等级函数
......表达有点混乱,希望能看明白......
回复

使用道具 举报

 楼主| 发表于 2008-4-18 21:28:16 | 显示全部楼层
原来你是这个意思~~ 那样确实比较快~~

不过这函数本身的定位就是用在一种不能确定前值前提下的普适设定法啊~~也就是说一开始就将前提设定为前值不可知了~~毕竟要考量到函数引用者写了其他攻击调整函数存在的可能~~方便移植的说~~

所以~~用获取技能等级函数来现取现判断的话~~会更加慢老~~
回复

使用道具 举报

发表于 2008-4-18 22:16:38 | 显示全部楼层
简单有效! 很好,很强大。
回复

使用道具 举报

发表于 2008-6-2 21:12:51 | 显示全部楼层
正好我的地图也用到了,但是我的那个算法太烂了..
回复

使用道具 举报

发表于 2008-6-4 21:00:09 | 显示全部楼层
研究下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-11-24 18:22 , Processed in 0.117055 second(s), 21 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表