lzkd 发表于 2011-1-17 19:51:09

对本文看法之三

  个人觉得,楼主这个东西很大程度上借用了helllua的东西。呃,因为我就对helllua有一点研究,其实我是个学财务的文科生来的,我的机器人水平比较差的说。
  说真的,helllua我马马虎虎能看明白一些,但让我把walk模块剥离出来,这活我可干不了。我看楼主的代码,觉得这应该是楼主自己完成的。从这一点,可以认为楼主可以很轻易的驾御lua,有点——因为很熟练,所以想怎么玩就怎么玩——这个意思。

  呃,如果楼主有兴致,建议楼主在上面代码中多写一些注释。这也算是给大家一个学习的机会嘛。或者,谁对lua有较高兴趣的,也可以自己偿试着写注释,也是一个很好的学习过程。

lzkd 发表于 2011-1-17 20:00:05

对本文看法之四(完)

  最后再写几句,关于——面向对象。(其实,主要是儿子过来了,我得陪儿子玩)

  如果你是才学写机器人的玩家,或者你不是程序员出身的机器人老手。你会觉得楼主的代码很难理解,很乱,很难摸的着头脑。
  其实,这就对了。

  一般,初写机器人的玩家,往往只是用面向过程的方法,也就是说——当我想取一样东西的时候,就get xx from xx,当我想给一样东西的时候,就give xx xx。这种想做动作,就写什么功能的代码的方法,就称之为——面向过程。(我这纯粹是按自己学习过程中的理解说的,各位程序高手不带笑话我的哈)
  面向对象——则完全不是这么一个思路。那,应该是怎么一个思路呢?这个,我讲不了。大家自己找资料学习吧。唯一可以告诉大家的是,大家注意看楼主代码,走路功能的完成,不是存在一个直接完成该功能的代码就可以了。

  好了,就这样吧。要陪儿子玩了,小家伙在催我了。


                                  小刀(lzkd)
                                  2011.1.17

ptouch 发表于 2011-1-17 22:13:23

我谢谢小刀捧场。
其实面向对象也没有想的那么复杂。
简单说就像以前的八股文,文章结构是基本一样的但是内容是不同。
面向对象就是写代码将内容和结构的东西分开考虑,前面类定义就是结构,后面的类的实例就是内容。
通过接口函数(interface)来实现两者衔接.
举个例子说明下
mud 里面去厨房喝杯水
面向过程程序会这么写法
1 先look 下 用触发器定位当前位置,获得到厨房的路径
2 执行路径,跑到厨房 执行命令 get tea drink tea
看下如果用面向对象会怎么写
我先定义了一个walk类,这个类功能就是负责行走的。
然后定义这样操作流程
1 自己当前位置(定位)
2 到达目标房间的路径(地图遍历路径)
3 到达目标所要做的动作(在例子里面就是get tea drink tea)
记住这点类只是定义一个操作流程,具体动作内容是在实例里面去实现的
local w--一个wak 实例声明
w=walk.new()--new 实例 面向对象特有 可以参考下面向对象介绍 new概念
w.walkover=function() --具体内容 行走完要执行的动作
   Send("get tea")
   Send("drink tea")
end
w:go(厨房) --行走
------------------------这个lua 代码里面用到了 lua的一些特性,对lua不了解的人会比较难以理解
1 lua 协同程序 (可以看看mushclient 爱好者有关wait 函数介绍)
2 metatable (lua 特有)
setmetatable(w,{__index=walk)
具体 programming in lua (中文版) 参考下
-----------------------------------------------------------------------------------------------------------
如果只是为了到厨房喝水没必要搞得这么复杂。
但是你想做的是一个通用机器人的话,这么做就是有好处的。
面向对象实现了共性个性分离
定位 行走 动作 这个流程是在mud经常用到,提取出来,可以实现大量代码精简重用

[ 本帖最后由 ptouch 于 2011-1-17 10:43 PM 编辑 ]

littleknife 发表于 2011-1-18 02:34:09

ttk_00 半夜也来学。yct60

ptouch 发表于 2011-1-18 10:29:42

这个walk 类使用起来很方便
以前我看到有人提出 需要一步一步走 ,有些人需要10步一走。
通过类的参数设置就能实现这个功能
local w
w=walk.new()
w.Max_Step=1 --一次发送一个方向 系统默认是一次发送10个方向 然后停顿下,继续发送直到结束
w.walkover=function() --具体内容 行走完要执行的动作
   Send("get tea")
   Send("drink tea")
end
w:go(厨房) --行走

[ 本帖最后由 ptouch 于 2011-1-18 10:39 AM 编辑 ]

zhuking 发表于 2011-1-18 12:08:46

原帖由 lzkd 于 2011-1-17 08:00 PM 发表 http://pkuxkx.net/forum/images/common/back.gif
  最后再写几句,关于——面向对象。(其实,主要是儿子过来了,我得陪儿子玩)

  如果你是才学写机器人的玩家,或者你不是程序员出身的机器人老手。你会觉得楼主的代码很难理解,很乱,很难摸的着头脑。
  ...


从兴趣来说,当然是面向过程比较容易吸引新手,毕竟能够马上解决一个问题,比较有成就感。
但,作为大型程序的开发来说,还是要面向对象了,
就像小刀打的比方,
乐高大厦不可能所有的结构都用唯一的积木来搭成。

myu 发表于 2011-1-18 15:33:00

使用面向对象编mud机器人,算一家之言,且不置评。
楼主的coroutine用的很熟练,不过我倒觉得直接用gammon的wait就很好了,没必要到处使用yield,resume,太麻烦了,而且使程序变得难懂。
代码没仔细看,但是下面这段,bug得有点太明显了。
-------------输出路径--------------
   for i,p in ipairs(result) do
      local result_path=""
      result_path=result.."set walk off"
      world.Execute(result_path)
      --print("挂起")
      coroutine.yield() --挂起
   end

ptouch 发表于 2011-1-18 15:58:39

原帖由 myu 于 2011-1-18 03:33 PM 发表 http://pkuxkx.net/forum/images/common/back.gif
使用面向对象编mud机器人,算一家之言,且不置评。
楼主的coroutine用的很熟练,不过我倒觉得直接用gammon的wait就很好了,没必要到处使用yield,resume,太麻烦了,而且使程序变得难懂。
代码没仔细看,但是下面这 ...

代码原来是这样的,复制到论坛里面自动把【】去掉了 表类型
result_path=result\.."set walk off"    ---这里是result【i】 发布时候莫名其妙去掉了 是表类型

协同 对用户来说是封装掉的
他不用了解walk怎么实现的
只要知道怎么使用就可以了

myu 发表于 2011-1-18 16:03:09

原帖由 ptouch 于 2011-1-18 03:58 PM 发表 http://www.pkuxkx.net/forum/images/common/back.gif


代码原来是这样的,复制到论坛里面自动把【】去掉了 表类型
result_path=result\.."set walk off"      ---这里是result【i】 发布时候莫名其妙去掉了 是表类型

协同 对用户来说是封装掉的
他不用了解walk ...

你直接写成result_path=p.."set walk off"不就成了。呵呵,我刚才写成result_path=p..";set walk off", 是没看你前面代码,已加了分号的。
你研究一下wait.lua,真的很好用。

[ 本帖最后由 myu 于 2011-1-18 04:43 PM 编辑 ]

myu 发表于 2011-1-18 16:59:15

刚才仔细看了一遍代码,楼主的构思还是很巧妙的,看懂下面这三行,整个程序就应该看懂了

       --下面这句增加一个触发,当抓到 '设定环境变量:walk = off‘这句话时,执行walk.walkoff()
       world.AddTriggerEx ("walkoff", "^(> |)设定环境变量:walk \\= \\\"off\\\"$", "walk.walkoff()", trigger_flag.RegularExpression +trigger_flag.Enabled + trigger_flag.Replace, custom_colour.NoChange, 0, "", "", 12, 99)

      --下面这句创健一个协程,名为walk.output_path,但不执行
      self:step()

      --下面这句是传入path参数,开始执行walk.output_path协程
      coroutine.resume(walk.output_path,path)

工作机制是这样的:
       walk.go()方法生成路径,创建并执行output_path协程。
       walk.output_path是个走路的协程。当它执行完Max_Step步以后,会执行set walk off并挂起
       set walk off触发walk.walkoff()
       walk.walkoff()延迟规定的秒数以后,唤醒output_path协程。继续走路。

不知我说明白了没有

[ 本帖最后由 myu 于 2011-1-18 05:05 PM 编辑 ]
页: 1 [2] 3
查看完整版本: lua 面向对象开发写机器人