littleknife 发表于 2010-12-8 16:37:49

是的,所以我在用了段zmud721后果断过度为mush,只是由于mush图形界面不是很友好、脚本编辑较复杂,被玩家搁置。由于DoAfterSpeical和多重timer,使得MUSH可以完全取代zmud中的复杂编程问题。
至于各个机器人之间的连接嵌套,可以参考hellua的 ok-end模式,十分方便。

myu 发表于 2010-12-8 16:44:35

mush的强大功能,是zmud望尘莫及的,mush就是太过专业,界面也不太好。

jarlyyn 发表于 2010-12-10 02:22:07

我一直觉得,能在大量使用#wait的程序里写好机器人的人,是个很nb的程序员。

最起码是多线程编程啊……

如果一定要实现类似wait的功能。
我觉得可以做个每秒一次的cron,计划任务。
检查一个lua全局的数组。
数组包括时间和命令

最好能作成队列的模式。

这样对程序来说可控性最好。xkx的mud 端就是基于这样的原理的吧

无数个wait,或者do_after漫天飞,这样的程序我是没能力去维护的。

而如果是要实现zmud那样的wait。
其实根本不改用到线程什么。
而是建立一个解析器。x举个例子来说。

用do_after_special sendto 来做#wait功能。
那么做一个函数 myexec(string)
function myexec(command)
waitpos=%pos(command,"#wait "。
//这里写验证#wait前后的内容的代码,并取得wait time
send strbeforewait
do_after_special(waittime,"myexec("+strafterwait+" )"

把剩下的字符串指定在xx秒后解析就可以了。
当然,最后对strafterwait做些处理,避免引号问题。
似乎可以用base64 encode decode下?

以上非lua代码,混合了多种代码的东西,看得懂思路就可以了

lzkd 发表于 2010-12-10 07:28:13

原帖由 jarlyyn 于 2010-12-10 02:22 AM 发表 http://www.pkuxkx.com/forum/images/common/back.gif
我一直觉得,能在大量使用#wait的程序里写好机器人的人,是个很nb的程序员。

最起码是多线程编程啊……

如果一定要实现类似wait的功能。
我觉得可以做个每秒一次的cron,计划任务。
检查一个lua全局的数组。 ...

有点意思,不过,要完成这种,要构建一套新的框架了.之前helllua的结构要完全推翻了

myu 发表于 2010-12-10 09:02:30

我倒觉得用wait编程是最不需要水平的,关键它去掉了太复杂的逻辑,和相互引用。
举个简单的例子:
      当你在等待一个busy结束的时候,zmud怎么做,大概是打点提前量吧,本来只有2秒busy,#wait 3000什么的。不用wait的mush怎么做,使用DoAfter?而一旦过多地使用DoAfter,逻辑关系就一团糟吧,绕来绕去容易绕出问题来,也不好维护。
       但你如果使用wait.lua,问题就变得局部化、简单化了。

       --下面这段代码等待一个busy的结束,与其它任何代码没有关联性,非常独立地完成一个功能
       repeat
                  Execute("eat busy")
                  local l,w = wait.regexp("你身上没有busy这样食物|你现在正忙着呢",1)
                  if l~=nil and string.find(l,"没有busy") then
                           break
                  end
       until false

       --你也可以非常独立地完成一个打坐的功能模块,任何时候任何地方都可以调用,与其它代码完全没有关联,多么干净
       --稍微简化一下,大致如下
       function dazuo_to(neili)                                                --打坐到规定内力
            repeat
                   Execute("hp")                                                      --执行HP,得到目前内力
                   local l,w = wait.regexp("内力:\\s*(\\d+)", 2)--正则有点难看
                   local now_neili=w                                       --取得当前内力值
                   if now_neili<neili   then                                    --如果内力值未到要求值
                     Execute("dazuo 100")                                 --打坐
                     wait.regexp("你运功完毕",60)                      --等待打坐结束
                   else
                     break                                                               --内力到了,跳出
                  end
         until false
      end               

这就是奇妙的wait

[ 本帖最后由 myu 于 2010-12-10 09:03 AM 编辑 ]

myu 发表于 2010-12-10 09:08:45

当然,前面两段代码,必须得在coroutine中执行。也就是必须得在类似这样一种结构中执行
require "wait"
wait.make(function()
      ....
      --打坐到最大内力的3/2
      dazuo_to(GetVariable("max_neili")*3/2)
      ....
      
end)

littleknife 发表于 2010-12-10 10:06:42

核心关键问题:就是wait的功能分析。

其实为什么用wait,这里面有个核心关键问题:就是wait的功能分析:
我的理解如下:命令结束后等待一段时间(即所谓挂起)然后再执行下一个命令。
为什么这么理解,因为mud的核心操作方式就是一个一个命令的输入。所以wait其本质就是一种间断,一种暂停而已。

基于这种理解,用自定义触发结合DoAfter(注意这里的DoAfter的核心思想就是一个开关而已,开启触发或关闭触发)来实现暂停或间断。

还有至于具体的机器人,Helllua的思路(我的理解)就是完全用busy-test方式去检查状态,用ok-end模式去连接各个机器人,无需任何触发辅助。

比如大多数机器人的设计思路,无非就是是否满足条件,满足的话干什么,不满足的话干什么。
所以,向打坐的机器人,完全只是触发抓个状态hp,就可以完成全部打坐内容了。其他的就是busytest。
所以我认为,用线程来解决这个问题,1、有点牛刀杀鸡;2、不容易深入理解(起码我没完全弄懂)


学习ing....关注---

[ 本帖最后由 littleknife 于 2010-12-10 10:26 AM 编辑 ]

jarlyyn 发表于 2010-12-10 10:12:58

原帖由 lzkd 于 2010-12-10 07:28 AM 发表 http://www.pkuxkx.com/forum/images/common/back.gif


有点意思,不过,要完成这种,要构建一套新的框架了.之前helllua的结构要完全推翻了

hellua里后来不是也有了套自己解析的东西么,没去弄#wait而已,不会推翻啊

一个是内部运行层的,,一个是输入控制,就是alias层的……

jarlyyn 发表于 2010-12-10 10:16:07

原帖由 myu 于 2010-12-10 09:02 AM 发表 http://www.pkuxkx.com/forum/images/common/back.gif
我倒觉得用wait编程是最不需要水平的,关键它去掉了太复杂的逻辑,和相互引用。
举个简单的例子:
      当你在等待一个busy结束的时候,zmud怎么做,大概是打点提前量吧,本来只有2秒busy,#wait 3000什么的。不 ...

zmud做这种打坐机器人应该不是用#wait的,用timer就可以了。这也是大部分的机器人的标准做法吧?

#wait就是在一串连续输入的字符串里编辑延迟,之前和之后的输出隔几秒。

至于打坐机器人,要么是busytest型的,要么就是触发型的
都比#wait简单和逻辑清晰吧……
没什么人#wait 3000做的吧…………

littleknife 发表于 2010-12-10 10:17:50

原帖由 jarlyyn 于 2010-12-10 02:22 AM 发表 http://pkuxkx.com/forum/images/common/back.gif
而如果是要实现zmud那样的wait。
其实根本不改用到线程什么。
而是建立一个解析器。x举个例子来说。

用do_after_special sendto 来做#wait功能。
那么做一个函数 myexec(string)
function myexec(command)
waitpos=%pos(command,"#wait "。
//这里写验证#wait前后的内容的代码,并取得wait time
send strbeforewait
do_after_special(waittime,"myexec("+strafterwait+" )"



大侠的这种思路,我个人觉得和我参考前辈们的用MUSH的DoAfter开关自定义触发,如出一辙。我这里说的自定义触发就是“send strbeforewait”,而DoAfter就是一个开关。呵呵。
页: 1 [2] 3
查看完整版本: 如何让一个coroutine异常终止