北大侠客行MUD论坛

 找回密码
 注册
搜索
热搜: 新手 wiki 升级
楼主: myu

如何让一个coroutine异常终止

[复制链接]
发表于 2010-12-8 16:37:49 | 显示全部楼层
是的,所以我在用了段zmud721后果断过度为mush,只是由于mush图形界面不是很友好、脚本编辑较复杂,被玩家搁置。由于DoAfterSpeical和多重timer,使得MUSH可以完全取代zmud中的复杂编程问题。
至于各个机器人之间的连接嵌套,可以参考hellua的 ok-end模式,十分方便。
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
 楼主| 发表于 2010-12-8 16:44:35 | 显示全部楼层
mush的强大功能,是zmud望尘莫及的,mush就是太过专业,界面也不太好。
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 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代码,混合了多种代码的东西,看得懂思路就可以了
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2010-12-10 07:28:13 | 显示全部楼层
原帖由 jarlyyn 于 2010-12-10 02:22 AM 发表
我一直觉得,能在大量使用#wait的程序里写好机器人的人,是个很nb的程序员。

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

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


有点意思,不过,要完成这种,要构建一套新的框架了.之前helllua的结构要完全推翻了
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
 楼主| 发表于 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[1]                                         --取得当前内力值
                   if now_neili                        Execute("dazuo 100")                                   --打坐
                       wait.regexp("你运功完毕",60)                      --等待打坐结束
                   else
                       break                                                               --内力到了,跳出
                    end
           until false
      end               

这就是奇妙的wait

[ 本帖最后由 myu 于 2010-12-10 09:03 AM 编辑 ]
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
 楼主| 发表于 2010-12-10 09:08:45 | 显示全部楼层
当然,前面两段代码,必须得在coroutine中执行。也就是必须得在类似这样一种结构中执行
require "wait"
wait.make(function()
        ....
        --打坐到最大内力的3/2
        dazuo_to(GetVariable("max_neili")*3/2)  
        ....
        
end)
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 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 编辑 ]
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2010-12-10 10:12:58 | 显示全部楼层
原帖由 lzkd 于 2010-12-10 07:28 AM 发表


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


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

一个是内部运行层的,,一个是输入控制,就是alias层的……
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2010-12-10 10:16:07 | 显示全部楼层
原帖由 myu 于 2010-12-10 09:02 AM 发表
我倒觉得用wait编程是最不需要水平的,关键它去掉了太复杂的逻辑,和相互引用。
举个简单的例子:
        当你在等待一个busy结束的时候,zmud怎么做,大概是打点提前量吧,本来只有2秒busy,#wait 3000什么的。不 ...


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

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

至于打坐机器人,要么是busytest型的,要么就是触发型的
都比#wait简单和逻辑清晰吧……
没什么人#wait 3000做的吧…………
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2010-12-10 10:17:50 | 显示全部楼层
原帖由 jarlyyn 于 2010-12-10 02:22 AM 发表
而如果是要实现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就是一个开关。呵呵。
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|北大侠客行MUD ( 京ICP备16065414号-1 )

GMT+8, 2024-11-28 07:21 PM , Processed in 0.010071 second(s), 12 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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