使用编译原理,把逻辑编排交给策划

作为一个U3D程序员,写一行if语句很容易。然而,这一行if语句里包含的逻辑,对其进行修改,是需要重新编译的,是写死在代码里的。那么问题来了,策划说:“来,按我的思路把这里改一下”。好了,原来写好的if(A or B),可能就要被改成if(A and B),甚至是if(A and(B or C)),重复编译与修改……这时你一定想说:“好呀,想改的话,自己改啊”。那么如何把这一逻辑问题,合理地交给策划呢?答案是——使用编译原理,公式由策划输入。


笔者大学还留了点儿编译原理知识没忘,依稀记得编译原理有一种利于计算机分析运算公式的式子——逆波兰式。所谓的逆波兰表示法(Reverse Polish notation,RPN,或逆波兰记法),是一种数学表达式方式,在逆波兰记法中,所有操作符置于操作数的后面,因此也被称为后缀表示法。逆波兰记法不需要括号来标识操作符的优先级。举个简单的例子,平常我们写的数学表达式a+b,就是一种中缀表达式,写成后缀表达式就是ab+。再举一个复杂的例子,中缀表达式(a+b)*c-(a+b)/e的逆波兰式是ab+c*ab+e/-。逆波兰式的转化与运算算法:
(--------一大篇算法来袭-----------)
将一个表达式转换为逆波兰式的具体算法思想:
1.首先,需要分配2个栈,栈s1用于临时存储运算符(含一个结束符号),此运算符在栈内遵循越往栈顶优先级越高的原则;栈s2用于输入逆波兰式,为方便起见,栈s1需先放入一个优先级最低的运算符,在这里假定为'#';
2.从中缀式的左端开始逐个读取字符x,逐序进行如下步骤:
         (1)若x是操作数,则分析出完整的运算数(在这里为方便,用字母代替数字),将x直接压入栈s2;
         (2)若x是运算符,则分情况讨论:
                   (A)若x是'(',则直接压入栈s1;
                   (B)若x是')',则将距离栈s1栈顶的最近的'('之间的运算符,逐个出栈,依次压入栈s2,最后抛弃'(';
                   (C)若x是除'('和')'外的运算符,则再分如下情况讨论:
                            (a)若当前栈s1的栈顶元素为'(',则将x直接压入栈s1;
                            (b)若当前栈s1的栈顶元素不为'(',则将x与栈s1的栈顶元素比较,
                                   若x的优先级大于栈s1栈顶运算符优先级,则将x直接压入栈s1;
                                   否则,将栈s1的栈顶运算符弹出,压入栈s2中,
                                   直到栈s1的栈顶运算符优先级别低于(不包括等于)x的优先级,
                                   或栈s2的栈顶运算符为'(',此时则再将x压入栈s1;
3.在进行完步骤2后,检查栈s1是否为空,若不为空,则将栈中元素依次弹出并压入栈s2中(不包括'#');      
4.完成上述步骤后,栈s2便为逆波兰式输出结果。但是栈s2应做一下逆序处理,因为此时表达式的首字符位于栈底;

计算逆波兰式方法:
观察逆波兰式的栈顶,如果当前字符为变量或者常数,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。
(---------------算法完了--------------------)
算法中提到的所有字符,其实是为了方便描述,我们可以使用class这样复合结构,包含类型、取值等信息,并做关于这个类的List列表。
算法中提到的运算符,是“加减乘除”,其实换成“与或非”,是一样一样的,无非就是把四则运算,变成了逻辑运算。双目运算符优先级:与>异或>或。
算法中提到的操作数,实际操作中主要应该是未知变量,而不是常量,所以应当分给每个未知变量一个id,直到必须要算出变量值的时候,再凭id去计算,由变量转常量(注意,这些变量能不计算就不计算,比如true和变量A做或运算,则不计算A也能知道结果为true)。另外,数据结构方面,除了要使用上面算法中谈到的两个栈,还需要一个字典结构,用来记录已经算过结果的操作数变量,避免对其进行重复计算。
 
笔者在做某游戏技能系统的时候,就用到了这一解决方法。技能系统,包括三大块:触发技能的指令集合、技能施放目标对象集合、技能触发需要满足的条件集合。其中,条件集合的若干条件如何组合就需要让策划配置。最后,放编辑器截图供大家参详:

原文地址:http://www.manew.com/blog-27966-2587.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值