北大侠客行MUD论坛

 找回密码
 注册
搜索
热搜: 新手 wiki 升级
查看: 2697|回复: 9

一步一步在北侠做机器人 行走限制版

[复制链接]
发表于 2022-1-10 23:31:03 | 显示全部楼层 |阅读模式
年底较忙,外加更新客户端API,机器人没有什么更新

上线倒是发现有个行走限制的Patch,看了下,机器人也受影响,决定修正下。

其实修正的内容很简单,就是行走的时候计算下走了多少步,超过限制就进入和怕汉中失败一样的重试状态就行,说干就干,快马加鞭


北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 2022-1-10 23:34:37 | 显示全部楼层
本帖最后由 jarlyyn 于 2022-1-11 01:11 PM 编辑

首先,我们明显需要统计最近的行走部数,因此,我们需要先添加一个计时器

  1. [[Timers]]
  2.   ID = "gc"
  3.   Name = "gc"
  4.   Enabled = true
  5.   Hour = 0
  6.   Minute = 0
  7.   Second = 0.2
  8.   Send = ""
  9.   Script = "App.OnTimerGC"
  10.   AtTime = false
  11.   SendTo = 0
  12.   ActionWhenDisconnectd = true
  13.   Temporary = false
  14.   OneShot = false
  15.   Group = ""
  16.   Variable = ""
  17.   OmitFromLog = false
  18.   OmitFromOutput = false  
复制代码

用于清理过期的统计数据

入口代码里也要加一个相应的相应代码

  1. App.OnTimerGC=function(name){
  2.     App.Raise("gc")
  3. }
复制代码

触发一个gc事件

北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 2022-1-10 23:39:05 | 显示全部楼层
本帖最后由 jarlyyn 于 2022-1-11 01:11 PM 编辑

然后,我们在move.js里,需要统计一下最新的移动步数

  1.     app.GetMoved=function(){
  2.         gc()
  3.         return moved.length
  4.     }
  5.     var moved=[]
  6.     var gc=function(){
  7.         newmoved=[]
  8.         var now=(new Date()).getTime()
  9.         moved.forEach(function(ts){
  10.             if ((now-ts)<500){
  11.                 newmoved.push(ts)
  12.             }
  13.         })
  14.         moved=newmoved
  15.     }
  16.     app.RegisterCallback("core.move.gc", function () {
  17.         gc()
  18.     })   
  19.     app.Bind("gc","core.move.gc")
  20.     app.RegisterCallback("core.move.onroomobjend", function () {
  21.         moved.push((new Date()).getTime())
  22.         app.OnStateEvent("move.onRoomObjEnd")
  23.     })
复制代码


很明显,我们创建了一个内部变量moved,用于储存近期行走的房间

在onRoomObjEnd里,负责向moved里推时间戳

把内部函数gc注册到gc事件里

然后增加一个App.Moved函数,用于调用gc,获取移动成功步数,

注意,gc事件在目前的代码里并不必要,只是为了以后可能会主动发送命令做准备

然后,在retry(行走失败)和 ignore(忽略的房间描述)的触发了,弹出最后一个时间戳

  1.     app.Core.OnMoveRetry=function(name, output, wildcards){
  2.         moved.splice(-1)
  3.         app.OnStateEvent("move.retry")
  4.     }
  5.     app.Core.OnMoveIgnore=function(name, output, wildcards){
  6.         moved.splice(-1)
  7.         app.OnStateEvent("move.ignore")
  8.     }
复制代码

移动指令就修改完了。



北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 2022-1-10 23:42:12 | 显示全部楼层
最后,我们修改发送的频率。

很明显,我们修改的是移动发送的模式,按照我们的基础篇里,这明显就是载具负责的事情。

我们添加一个慢悠悠的载具slow

  1. (function (app) {
  2.     let Vehicle = Include("core/vehicle/vehicle.js")
  3.     let Slow = function () {
  4.         Vehicle.call(this)
  5.         this.ID="slow"
  6.         this.MultiStep=false
  7.         this.Fly=true
  8.         this.Sender=function(cmd){
  9.             if (app.GetMoved()<5){
  10.                 app.Send(cmd)
  11.             }else{
  12.                 app.OnStateEvent("move.retry")
  13.             }
  14.         }
  15.     }
  16.     Slow.prototype = Object.create(Vehicle.prototype)
  17.     return Slow
  18. })(App)
复制代码

和run一样区别是禁止多步,发送时判断一下已经发送的是否大等于5

需要休息的话就触发个move状态的retry时间

否者直接发送

然后在载具的vehicle.js里进行调整

引入slow载具,设置为默认载具,

  1.     let slow = Include("core/vehicle/slow.js")

  2.     app.Vehicle=null
  3.     app.Vehicles={
  4.         Run:new run(),
  5.         Go:new go(),
  6.         Cart:new cart(),
  7.         Slow:new slow(),
  8.     }
  9.     app.DefaultVehicle=app.Vehicles.Slow
  10.     app.Vehicle=app.DefaultVehicle
  11.     app.Drive=function(id){
  12.         if(id){
  13.             for (let key in app.Vehicles) {
  14.                                 if (app.Vehicles[key].ID == id){
  15.                     app.Vehicle=app.Vehicles[key]
  16.                     return
  17.                 }
  18.                         }
  19.             throw "未知的载具 " +id
  20.         }else{
  21.             app.Vehicle=app.DefaultVehicle
  22.         }
  23.     }
复制代码


好了。修改完毕。



北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 2022-1-10 23:44:33 | 显示全部楼层
最后,测试下机器人

walk.partor,locate都没问题,不需要改代码

明显会走4步停0.5秒

修改完毕

具体的patch 见

https://github.com/hellclient-sc ... 03381c841f5840ac136

很明显,良好的架构对于一个机器的扩展和维护有很重要的价值。
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2022-1-11 12:15:39 | 显示全部楼层
厉害。希望我能有看懂的一天。
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2022-1-11 12:54:47 | 显示全部楼层
虽然程序我不懂,但是喜欢楼主这种分享编程思路的方式
赞一个
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2022-1-11 13:04:23 | 显示全部楼层
厉害,学习了
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 2022-6-16 12:47:08 | 显示全部楼层
之前不玩北侠,光这样改还是有点问题的。

首先,移动记录要有个全局的,同时也要有个buff缓冲,就是与其在mud里缓存,不如自己缓存

代码大体如下

  1.     var moved=[]
  2.     var movebuff=[]
  3.     var gc=function(){
  4.         newmoved=[]
  5.         var now=(new Date()).getTime()
  6.         moved.forEach(function(ts){
  7.             if ((now-ts)<600){
  8.                 newmoved.push(ts)
  9.             }
  10.         })
  11.         moved=newmoved
  12.     }
  13.    
  14.     App.RegisterCallback("core.move.gc", function () {
  15.         gc()
  16.         if (moved.length<3&&movebuff.length){
  17.             App.Send(movebuff.shift())
  18.             moved.push((new Date()).getTime())
  19.         }
  20.     })
  21.     App.SendToMoveBuff=function(cmd){
  22.         gc()
  23.         if (moved.length<3){
  24.             App.Send(cmd)
  25.             moved.push((new Date()).getTime())
  26.         }else{
  27.             movebuff.push(cmd)
  28.         }
  29.     }
  30.     App.Bind("gc","core.move.gc")
复制代码
每0.6秒行走3次就堆入缓冲,这样在不太卡的情况下,任何一个一秒内不会连续发送超过6个移动命令(1.2秒周期,超过一秒)

其次,修改基础载具

  1. (function(App){
  2.     let _drivepath=Include("include/drivepath.js")
  3.     let Vehicle=function(){
  4.         this.TagDrive=false
  5.         this.MultiStep=false
  6.         this.ID=""
  7.         this.RetryInterval=0.5
  8.         this.Fly=false
  9.         this.Sender=function(cmd){
  10.             App.SendToMoveBuff(cmd)
  11.         }
  12.     }
  13.     Vehicle.prototype.Send=function(cmd){
  14.         this.Sender(cmd)
  15.     }
  16.     Vehicle.prototype.ConvertDrivePath=function(cmd,path){
  17.         let p=_drivepath[path]
  18.         if (!p){
  19.             throw "无效的drivepath"+path
  20.         }
  21.         p=p.replace("%1",cmd)
  22.         return p
  23.     }
  24.     return Vehicle
  25. })(App)
复制代码

让所有的行走都走这个SendToMoveBuff,收工。

为了以防万一,也就是卡顿的情况下,在移动时出发的[命令加入缓冲],直接发送一个"move.retry"状态事件 到当前状态

当作爬山时需要等一等重走的busy一样处理。

这样尽可能的能解决移动时进入缓冲的问题


北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 2022-6-16 12:47:46 | 显示全部楼层
另外之后应该还会更新三篇

大体是

武当新人人物篇

迷宫篇

战斗篇。
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-27 01:12 AM , Processed in 0.010379 second(s), 14 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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