设为首页收藏本站

万王之王 KOK King of Kings

 找回密码
 加入我们
查看: 1470|回复: 5

默默的纯新手代码教程(二版)

[复制链接]
发表于 2018-1-8 14:06 | 显示全部楼层 |阅读模式
本帖最后由 索菲娅·梵歌 于 2018-1-8 14:16 编辑

第一版由于写的不规范,好多前辈建议改成规范的教学大纲模式- -,所以写了这个版本的,并不清楚到底哪种更好一些,现在两版先都放上来,看大家觉得哪种更通俗易懂,就留哪个版本。
第一课 代码格式
范例
%scene begin
   10::invoke on xxxxx        <--- 执行invoke, 再等10秒
   10::cast fireball on xxxxx <--- 执行cast, 再等10秒
   10::recharge               <--- 执行recharge, 再等10秒
                              <--- 等完10秒,重复执行.
基本格式
%scene begin                 <--- 执行段名称:注1
   <执行时间>::<IKING命令>    <--- 执行时间:注2
   <执行时间>::<IKING命令>
   ....
   <执行时间>::<IKING命令>
注1: 执行段名称begin,具有唯一性和首发性无论你代码中写了多少个%scene 执行段,%scene begin都只能有一个.点运行代码的时候,默认从%scene begin这一段开始执行不管你是把它写在最上边,还是把它写在代码最底下.请注意,如果你的代码中有多个%scene 执行段,却没有在begin之中加入跳转命令那么代码也只循环运行%scene begin中的内容.再次注意并不只是begin,所有%scene 段落都有这个特性如果没有跳转指令,则只段内循环.
注2:“时间”是一个数值,是以秒为单位的.但可以精确到0.1秒特别需要注意,这里的执行时间,是指后面IKING命令的执行时间.即先发命令,再等, 而不是先等,再发命令.
   下面的时间描述是正确的
       5   5.0   5.3   0   0.0   0.5
   下面的时间描述是错误的
       500ms <--- 被认成500秒
   下面的描述将被取舍
       5.43  <--- 被认成5.4秒

第一课深化

正文段是向IKING发送命令的主体,其基本思想是采用“发命令”,等一段时间,再发命令,再等的循环机器.除了call和return之外,正文段是是一直循环执行下去的正文段本身没有控制流程的机制,如何控制执行序列是在行为控制段中描述的.

下面详细介绍正文段的格式

%scene 段

%scene <name>
段实体内容

<name>      定义了该段的名称,不能为空单词!!!.正文段行中用#开头的句子被忽略,可用于写注释信息.

段里的内容定义了执行序列,每行文本定义一个,其格式为
<时间> <判断> <指令>

<时间>      是一个数字,表示该行命令执行要花费的时间, 以秒为单位,但精确到小数点后一位,可以是0.内容可为空
<判断>      每个%scene段定义了一个行为控制段,这是其本的另外,当执行该命令时,可附加一个行为控制段.这个行为控制段的内容只在该命令执行期间有效通常其内容只与该命令有关这
部份内容可为空
<指令>    <指令>是个句子,是具体发送给IKING的执行命令.但如果是以“#”作为开头的,则不发送命令.这部份内容可为空

例如:
30::
空等30秒
30::cast fireball on woman
执行cast fireball on woman, 等待30秒后进入下一个步骤
30: fireball_bc:cast fireball on woman
执行cast fireball on woman, 等待30秒后进入下一个步骤
指定了附加的行为控制段,来控制该命令的执行情况.

*** 注意下面的描述是错误的.
cast fireball on woman
其含义是执行on woman命令,使用名称为fireball的附加行为控制段,执行时间是cast(即0)秒.
应使用下面的定义
::cast fireball on woman

***  !!!需要注意,其内容不是等<timer>秒后,再执行命令,而是执行命令再等<timer>秒后,执行一个步骤.

*** 一个机器人代码必需有名称为begin的%scene段,机器人启动后,会查找begin段,并开始执行其中的内容,如果没有begin段,机器人将什么也不做.
注意:编写代码正文时:
(1) 空行被忽略.
(2) 对于不识别的段标识符,整个段被忽略
(3) 代码区分大小写!!!!!!!!!!!!!!!!!!!

第二课 行为控制%bc段落

OK, 你已经会编写靠时间驱动的机器人了吧.是不是觉得只靠时间, 效率不好.

最典型的. 冥想, 发出去命令, 从失败的立即结束到恢复几百点MP的长时冥想.怎么设时间才好呢? 怎么设时间也不好, 只有通过行为控制.

讲解之前, 介绍通常情况下, 玩家对一个命令的结果有以下几种反应
    (1) 不能做, 等等, 能做了再发一次. (如上次施法没结束)
    (2) 失败了, 那再来一次.
    (3) 失败了, 算了吧, 法力也耗了, 还是做下一步吧.
    (4) 成功了. 等动作结束吧, 结束了, 做下一步.
    (5) 其它.

下面以冥想为例, 讲解.

1. 分析你发送的命令, 会有多少种反应:

    比如当你发冥想的时候, 可能有的情况:
        (1) 你正忙著呢. <---- oh, 上个动作还没完呢.
        (2) 你正在战斗中, 无法冥想.
        (3) 你为精神状态不好, 不能冥想
        (4) 你开始冥想了, 一堆信息传了过来, 最后, 告诉你, 你冥想结束了.

2. 确定对应每种情况, 你想如何处理.

    (1) 你正忙著呢. oh, 上个动作还没完呢.
        当然是等几秒, 再冥想了.
    (2) 你正在战斗中, 无法冥想.
        等战斗结束了再冥想. 做法上可能有区别,这里用的是等待"你得到了( ???? )点经验"这句消息出来后, 再冥想.
    (3) 你为精神状态不好, 不能冥想
        可能有多种作法,比如, 不冥想了,做下一步吧. 这里采用的是等出现"你的精神恢复正常,可以冥想"的消息时, 再开始冥想.
    (4) 你开始冥想了, 一堆信息传了过来, 最后, 告诉你, 你冥想结束了.
        一收到"冥想结束"的消息, 立即开始下一个动作吧.

3. 确定各显示的消息中, 是否存在变化的内容, 这些内容对判断没有影响
    比如:
        "你得到了( ???? )点经验."
    ????是一个数字, 但多少一点关系都没有. 怎么办, 在下一步里, 要把这些用"%*"替换.
        "你得到了( %* )点经验."

3. 把上面的分析结果, 编成Ikok的一组代码.

    先要给这组内容起个名字. 比如是为冥想写的, 可以叫 meditate_bc.将所匹配的文本, 要做的控制动作, 等合成一行代码.结果变成了

    %bc meditate_bc
        retry:1:你正忙著呢.    <--- 等一秒,再重发当前命令
        retry::你得到了( %* )点经验.
                                <--- 战斗结束了,立即重发当前命令
        retry::你的精神恢复正常,可以冥想了.
                                <--- 可以冥想了,立即重发当前命令
        next::你深深地吸了一口气,从深沈的冥思中醒来 !
                                <--- 结束冥想,立即进入下一步.
                                <--- 这是有深冥的显示.要注意.

4. 为你原来的冥想命令添加行为控制.

    原来的机器人:

    %scene begin
        .....
        50::meditate
        ....

    变成
        ...
        50:meditate_bc:meditate
        ...

5. 把原来的%scene begin段, 再加上你这些%bc段, 就构成一个完整的机器人代码了.

%bc段的格式简介

    %bc <名字>
        <行为控制命令>:<命令参数>:<所匹配的IKING显示文本信息>
        <行为控制命令>:<命令参数>:<所匹配的IKING显示文本信息>
        <行为控制命令>:<命令参数>:<所匹配的IKING显示文本信息>
        ......

    <行为控制命令>
        retry   重做当前命令, 如果命令参数是一个数字, 表示等多少秒之后再重做
        next    结束当前命令,开始下一个. 如果命令参数是一个数字, 表示等多少秒之后再进入下一行.

对于有双重施法的角色同样的信息是成双出现的怎么办?

让一个cast命令使用两个%bc段

其方法如下:

%scene begin
    .....
    100:cast1_bc:cast ??? on ???
    .....

%bc cast1_bc
    retry::你上一个动作没有完成,不能施法.
    next::<施法失败的各种信息>
    ...
    change:cast2_bc:你想起动双重施法,但失败了.
    change:cast2_bc:<施展该法术的显示信息>
%bc cast2_bc
    next::这里没有这个人.       <--- 第一个施法结果导致NPC死忙,会出现这种结果
    next::<施展该法术的显示信息> <--- 如果该信息不是法术结束时的消息,
                                        在next后两个冒号之间,加入延迟时间, 如
                                            next:3:.......

大家会想, 要是写多重施放, 是不是设成几, 就得写几个%bc段.
答: 如果你非得用这种方法, 确实要写几个%bc段.
但是.............你为什么不用"你的身体恢正常了"这句话呢?

1. 在%bc段的比较文本一定是完整的IKING显示信息. 如果你希望
    只要头几个文本相同就可以的话, 要在后面加上"%*"

    例如: 一定要写成
        next:5:你喃喃念道%*
    如果你写成
        next:5:你喃喃念道

        那么该行永远也不会被匹配执行了.
   
2. 一定要仔细考虑该命令到底会出现多少种情况?如果漏掉几种, 你的机器人效率会不时的降低.

    比如在双重施法上, 双施成功了, 但第一个法术的实施杀死了NPC, 那么第二个法术就不会启动, 而显示
    "这里没有这个人."

    如果你没注意到这点, 有时机器人就会傻等一段时间.

第二课深化

%bc段

%bc <name>
段实体,行为控制段内容

<name>   指定该行为控制段的名称,不能为空行为控制段中的内容,每一行定义一个行为控制,其格式为

<控制命令> <可用参数> <匹配内容>

如果IKING主屏显示输出的内容与<匹配内容>匹配,则执行<控制命令>, <可用参数>是供<控制命令>使用时的参数,根据<控制命令>的要求,参数可以为空.

下面是个例子,比如:

retry::你正忙著呢!

表示如果遇到“你正忙著呢!”这句消息,就重新执行当前命令

执行命令解释
retry       重做当前运作
            参数是一个时间,表示过多长时间后再重做
next        结束当前动作,开始执行下一步
            参数是一个时间,表示过多长时间后再执行该命令会取消当前命令的附加行为控制段.但下一个命令的附加行为控制段并不被应用.这时候只能使用%scene共用的基本行为控制段.
time      只是改变当前的延迟时间.不关心之前是否有retry/next,不修改原有的附加行为控制段参数是新的延迟时间.
jump     强行停止当前的%scene, 转而开始指定的%scene参数是指定的新的%scene段名
该参数不能为空
call        将当前状态压栈,停止当前的%scene, 转而开始指定的%scene段.参数是指定的新的%scene段名,该参数不能为空, 空会导致机器人停止运行.
特别注意!一直重复用call压栈却没有对应return清理的话,将导致内存过高崩溃.
pop        弹栈,即清除上一个压栈,使用后无法在用return命令返回
return retry: 恢复压栈前的状态, 重做压栈前正在进行的动作.
return: 恢复压栈前的状态, 结束压栈前正在正行的动作,进入下一个动作
log         将匹配的消息存贮的LOG文件中参数被忽略

第三课 代码的运行机制

1. Ikok读入机器人代码(分析并生成内部结构.).
2. 找到名称为"begin"的正文段(%scene段) 开始执行

Ikok的基本执行是以时间来驱动的,但时间的长度定义不计较发送命令 -> 等一段时间 -> 发送下一个命令 -> 再等一段时间...

(上面的内容是在正文段中描述的.)

当在发送命令之后等待的这段时间里.指定的行为控制段开始起作用.Ikok分析每行IKING的显示,如果与某条行为控制行中的内容匹配,则执行该行的行为控制命令.
比如:
“你正忙著呢...” -> 发送的命令没执行,重发送当前命令
“你从冥想状态醒来...” -> 不用再等了,已经结束,快做下一步吧.
“你的法力不够...” -> 当前法力不够,转到负责冥想的正文段吧

注意
* 当Ikok需要跳转到某个正文段开始执行,而该正文段没有找到时,Ikok会
停止机器人的运行.

发送IKING命令
当Ikok向IKING发送命令时,会先对该命令进行一次替换操作.
例如:
%variable d
abbccd
%scene begin
1::kill %vd
那么,真正发送给KOK的就是
1::kill abbcd
命令中,以"%"开始的特定字符串组合将被替换为对应的var中的内容.

对于匹配IKING的主屏显示消息,Ikok并不是简单的比较.还具有一定的模式匹配,替换匹配等内容,可以减少很多代码.如果没有这些匹配方式,有些代码将无法实现.
比如,你希望记录所有人对你TELL的内容.你只需要一行
%bc ...
...
log::%+(%$)对你说:%*
...

或者,你想要记录别人对你的通辑
...
log::%+的%+发布了%K %N(%n)的通辑令,全面通辑$+
...

模式匹配结果的记录与使用

如果你在匹配过程中使用了模式匹配,在有些情况下,你希望用到匹配的结果
例如:
当匹配 “XXX(xxx)对你说:??????”时,你希望回答
“关于??????的问题,我过后会回答你.”
这就用到了两个匹配结果.第一个是谁TELL的你.另一个是TELL你的内容.(之所以使用谁TELL你,是因为无法保证你发送reply时,可能有别人又TELL你了.所以用TELL命令更好一些.)

这样,设计出的匹配字符串:
%+(%$)对你说:$*%b

遇到有人TELL你,让Ikok替你回答, 回答的命令应该写成
tell %1 %0朋友,关于%2的问题,我过后会回答你的

第三课深化

变量段
每个变量段定一个变量,在变量段中设定该变量的所有可能的值.

%variable

%variable <name>
段实体, 即定义该变量可能出现的值

<name> 只能是"a"到“z”,如果是其它的值,该段将会忽略掉.

前面的值在正文段中用于替换命令内容,后面的则在行为控制段中用于显示匹配.

下面是一个例子
%variable a
a
b
c
d
......
%scene begin
...
100:shengzhe_bc:cast <法术id> on %va
...

%bc shengzhe_bc  <-- 这是一个行为控制段,请参考阅读 BC.txt
......
retry:100:%*一个火球向%*发去......   
<--- 这行显示的内容可能并不正确,只是举例.
next::你得到了( %* )点经验.
......

运行中的变量

* 当开始运行时,所有变量指向第一个值.

* 如果在行为控制段中指定对该变量的模式匹配,那么在成功后该变量的值也指向匹配的值.

当ZRobot发送%scene段中定义的命令时,会先将该命令进行一次替换操作,即把命令句中的"%" + 某些字符的组合替换成特定的内容

下面是在字符串中特定的“%"组合和要替换的内容

基本替换
%v  显示当前值(foreach 会给变量下标+1 )
%i   显示当前值,然后再将下标+1
%var a
a
b
c
foreach a
1::sing %va
loop

loop3
1::sing %ia
endloop
效果一致


变量替换
%v? 使用该变量的右值
%i? 替换成空内容,但该变量的变量值变成了下一个内容.

(?为 "a" - "z")

匹配串替换
如果显示的消息与行为控制段中某行成功匹配,并且指定进行存贮.那么该行中的所有模式匹配结果都将被记录下来,直到重新启动或另一个要求保存的成功匹配.

匹配字符替换
%0, %1 - %9 为对应匹配模式所存储的变量.

在行为控制段中,要进行iking的显示信息与<描述>的比较(即匹配)
在ikok中,两个字符串的匹配分成三种情况

* 一般匹配
就是一般的字符串比较
* 替换区配
用于一些相对固定内容的比较
例如:
如果你的中文名叫 "约定"
那么
匹配描述中直接写,约定说到:大家好
这是固定替换匹配.
* 模式匹配
希望一个<控制命令>能匹配多种消息,会用到这种方式
例如:
%*说到:大家好
那么只要有人说:大家好
都会被认为是匹配的.
对于模式匹配,其结果有时还需要被再次用到,这种情况就是匹配结果的记录,只要匹配成功,就有可能记录下来.

模式匹配

%*  任意的字符串,可以为空
%+  任意的字符串, 但至少要含有一个字符
%#  任意的数字(0-9)组合,至少要有一个
%$  任意的[a-z, A-Z, _]字符组合,至少要有一个

匹配结果的记录
%b  并不参与内容比较,但如果<判断描述>中含有该字符串,则表示,如果该行匹配成功,则记录所有模式匹配产生的结果按顺序记录,供以后通过%0 - %9来使用

例如:
连续的两个消息被匹配成功
%b%+(%$)对你说:%*   AAA对你说
%+回答你:%*         BBB回答你
这时候:
%0是"AAA"而不是"BBB", 尽管第二个消息是后到的.但它没使用%b
发表于 2018-1-15 13:38 | 显示全部楼层
谢谢分享,非常好!
发表于 2018-1-22 23:16 | 显示全部楼层
oreach a
2:kill:kill %va
loop
%bc kill
next::你喝道%*
retry:0.4:这里沒有任何生%*
retry:0.4:那里没有任何人%*
retry:1:你想杀谁%
发表于 2018-1-23 15:18 | 显示全部楼层
好妹子,真感人
发表于 2019-10-1 23:17 | 显示全部楼层
辛苦了谢谢分享经验。
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

QQ|小黑屋|手机版|万王之王 king of kings    

GMT+8, 2019-10-18 15:03

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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