0

超级宏论坛

分类导航全部

温馨提示

站内问题请先查看帮助中心
每一位侠士都有过小白经历,希望大家多一点耐心,互相帮助,江湖有你随行,步步惊(喜)心

发帖说明

  1. 求助类问题请在提问前请先搜索已解决方案,并描述清楚问题。
  2. 宏与工具的提问时请在帖子中“@ 用户名”,以便作者收到通知,否则作者可能无法知晓。
关闭生成文章|
无色幽明 关注 发布时间: 2014-03-26 最后更新: 2014-03-26 19241 0
打印
分享
正序查看
无色幽明 40 认证团队 认证玩家 签约作者 1# 最后更新 2014-03-26
更多 回复
第三章·第7节:表达式优化

主稿:楚玄枫



在进入本节之前,我们的重点内容依然是注意事项:
注意:请在阅读本节前,仔细阅读并确保自己已经明确不同的判断参数返回值的类型属于true、false和num中的何种,并确保自己知道true、false、num之间的区别。请在阅读本节前,尽可能掌握变量命令/var的基本用法。

1.变量
前文已经对变量进行了最基本的介绍,那么请读者在此处回忆一下变量的几种情况,以及各种基本运算符号。
注意:本节中所有的变量,意指由宏定义的,以v_开头的具有相应数值的量。相应的,所有数字、true或false,以及通过参数引入的数值或真值(如:buff:调息,bufftime:风·灭气>5),均视为常量。
我们为什么要引入一个变量?
最主要也是最广泛使用的作用,就是引入变量开关,使使用者可以通过调整变量的值来控制宏的语句执行。
第二个比较广泛的应用,是通过将复杂的条件定义为一个新的变量,来方便对这个条件进行引用。通常此类变量拥有一个十分有意义的名字,如某知名唐门宏中的v_队里有一堆唐门,v_救命啊他要放追命了,等等。
变量的另一个广泛应用,就是用来存储一些中间结果,以应用到后面的宏或变量表达式中。如不少宏,通过开关定义了加速阈值等级,再通过计算获得对应的技能的时间,以用于后文的计算。

2.变量表达式
变量表达式是区别于常量表达式的一个概念。表达式的概念请右转百度百科。
我们在写宏的时候,每个语句中,使用中括号[]所括起来的整个部分,就是一个表达式。当用于/skill、/if、/dia等等语句的时候,以表达式的真值来决定其运行;用于/var或/print时,则是对相应表达式的值进行赋值或打印。
常量表达式指表达式的所有量均为常量的表达式;使用了变量的表达式则称为变量表达式。

3.表达式优化
本节的重点,是如何针对宏中的大量表达式进行优化。
本节所有例子将均从本站知名宏中节选,部分内容可能有删改。
3-1 常量表达式优化
常量表达式通常不需要进行大量优化,但在超级宏的架构上,可以将部分庞大的表达式进行合并。
例如:
/skill [tpre:掷锤>0.5,nobuff:镇山河] 打断,后撤
/skill [tar:何莘涯,dis<10,nobuff:镇山河,tpre:力拔千钧>0.7] 打断,后撤


可以优化为
/skill [nobuff:镇山河,(tpre:掷锤>0.5;tar:何莘涯,dis<10,tpre:力拔千钧>0.7] 打断,后撤


又如:
/skill [tnopre:掷锤|吞云吐纳|骨牢|皇之怒,buff:莺鸣,nobuff:夜雨,sktest:四季剑法|三柴剑法,tbufftime:梅隐香>3] 风来吴山
/skill [tnopre:掷锤|吞云吐纳|骨牢|皇之怒,buff:莺鸣,nobuff:夜雨,sktest:四季剑法|三柴剑法,!tar:boss] 风来吴山


可以优化为:
/skill [tnopre:掷锤|吞云吐纳|骨牢|皇之怒,buff:莺鸣,nobuff:夜雨,sktest:四季剑法|三柴剑法,(tbufftime:梅隐香>3;!tar:boss)] 风来吴山


此类例子较多,但有时合并会导致表达式变得冗长不利于阅读。

3-2 /if下的/skill(/dia、/return等等)优化
实际上,由于除/var和/print以外的语句表达式的真值即决定其是否执行,因此在实际应用中,如果不是需要降低表达式长度以利阅读,此类语句可以通过优化不使用/if即完成判断。/var也可以使用相应的表达式算法来优化使之不需要/if。唯有/print,由于种种原因,必须使用/if来限制其执行与否以防止刷屏。
在进行带有/else的/if的优化时,需要预先计算好,优化后的语句真值是否与优化前相同。
针对/if下的/skill优化举例:
/if [mount:问水诀,cdtime:平湖断月>1.5]
/skill [tarisem,mount:问水诀,rage>82,fight,sktest:四季剑法|三柴剑法,cd:黄龙吐翠] 啸日
/else
/skill [tarisem,mount:问水诀,rage>82,fight,sktest:四季剑法|三柴剑法] 啸日
/end
/if [(rage<17,v_剑气=1);(rage<20,v_剑气=2)]
/skill [tarisem,mount:山居剑意,cdtime:雪断桥>1.5&雪断桥<60&莺鸣柳>1.5&莺鸣柳<110] 啸日
/end


可以优化为:

/skill [tarisem,mount:问水诀,rage>82,fight,sktest:四季剑法|三柴剑法,(cd:黄龙吐翠,cdtime:平湖断月>1.5;!cdtime:平湖断月>1.5)] 啸日
/skill [tarisem,mount:山居剑意,cdtime:雪断桥>1.5&雪断桥<60&莺鸣柳>1.5&莺鸣柳<110,(rage<17,v_剑气=1;rage<20,v_剑气=2)] 啸日


当然,本例中的两个语句可以通过合并为一个语句,但那样将会导致语句过长。
一般情况下,通过/if的优化获得的语句还可以进一步优化。

3-3 真值表达式的优化
在深入本节之前,请再次确认自己已经明白三种基本逻辑运算(或、且、非;超级宏中分别为’;'、’,'、’!')的关系。
观察上例中的(cd:黄龙吐翠,cdtime:平湖断月>1.5;!cdtime:平湖断月>1.5)。如果我们定义:

/var [cd:黄龙吐翠] v_a
/var [cdtime:平湖断月>1.5] v_b


那么这个表达式可以写作(v_a,v_b;!v_b)。可以很清楚的明确,这个表达式只有当v_a与!v_b同为假时才为假,其他时候均为真。因此这个表达式可以写作(v_a;!v_b),也即(cd:黄龙吐翠;cdtime:平湖断月<=1.5)
绝大多数情况下,只涉及到两个量的布尔表达式,都可以进行一定程度上的简化。

3-4 数值表达式的优化
超级宏中,数值型变量均可参与简单的加减乘除计算,如上例中的(rage<17,v_剑气=1;rage<20,v_剑气=2),可以简单的简化为rage<14+v_剑气*3(前提是v_剑气只能取为1或2)。
又例如,计算花间在梦歌状态下的加速,可以写作:

/var [6.26] v_speed –无BUFF的面板加速
/var [v_speed+(buff:梦歌;0)*0.9765625] v_nowspeed


3-5 混合表达式算法
在超级宏中,涉及到数值的计算,以及数值与真值的混合计算,参考下面的规则:

true and 3=3
2 and 3=3
3 and 2=2
false and 3=false
true or 3=true
2 or 3=2
3 or 2=3
false or 3=3


根据这一点,我们可以简化很多混合表达式。最常用的简化形式是(a,b;c)型表达式,意为当a为真是,值为b,否则为c。


3-6 /if下的/var优化
最简单的情况是下面这种情况,在很多宏中都有这样的情况:
/if [v_快雪>0.15;v_快雪=0;noota:快雪时晴]
/var [true] v_快雪可断
/else
/var [false] v_快雪可断
/end


此种情况可以很直接的写成:
/var [v_快雪>0.15;v_快雪=0;noota:快雪时晴] v_快雪可断


另一种可以优化的情况是如下的情况:
/if [v_动态打断,ping<0.5]
/var [ping] v_动态变量
/else
/var [0.02] v_动态变量
/end


该情况可以利用上文所述的(a,b;c)型表达式简单的优化成:
/var [v_动态打断,ping<0.5,ping;0.02] v_动态变量


有的时候,/if语句是对/var有着执行约束,如下例:
/if [cdtime:芙蓉并蒂>=5]
/var [false] v_ind
/end


该语句限制了只有在cdtime:芙蓉并蒂>=5时才对v_ind修改数值,因此此例可以同样写为:

/if [cdtime:芙蓉并蒂>=5]
/var [false] v_ind
/else
/var [v_ind] v_ind
/end


从而可以优化为
/var [cdtime:芙蓉并蒂>=5,false;v_ind] v_ind


再根据真值优化可以进一步简化为
/var [cdtime:芙蓉并蒂<5,v_ind] v_ind


下面是一个针对变量的综合优化例子,是某宏中的一个限定执行模块,只在当前循环中v_st9=1时执行一次:
【声明:此模块及其优化结果引自变速箱-花间宏,直接转载或引用请注明引用来源】
/if [v_st9=1]
/var [false] v_mention
/var [false] v_tomention
/else
/var [!v_mention] v_tomention
/end
/if [v_tomention]
/print [v_st9=2,string:xxx]
/var [true] v_mention
/var [false] v_tomention
/end


前面的一个/if块可以简单的优化为

/var [v_st9=2,v_mention] v_mention
/var [v_st9=2,!v_mention] v_tomention


后面一个/if因为限制了只有当v_tomention为真的时候才执行,而当v_tomention为假时,需要保持原来的值,因此可以写为

/var [v_tomention;v_mention] v_mention
/var [false] v_tomention


根据上下文语句,由于当v_mention置为true时,v_tomention会在下一个循环置为false,因此最后一个语句可以被省略。
全文优化结果为:
/var [v_st9=2,v_mention] v_mention
/var [v_st9=2,!v_mention] v_tomention
/if [v_tomention]
/print [v_st9=2,string:xxx]
/end
/var [v_tomention;v_mention] v_mention






评分

参与人数 1 +1 收起 理由
+ 1 终于明白离散数学是用来干啥的了··.

查看全部评分

点击开关回复楼层
没有更多了
请先登录

试一试@用户名 立即召唤神龙 小伙伴会收到通知喔:)无需加好友即可通知到

您需要登录后才可以回帖 登录 | 立即注册  

本版积分规则


您当前使用的浏览器版本过低,网站部分功能可能失效,请更换合适的浏览器。了解更多