一步一步在北侠做机器人之 Ask篇-学会提问的艺术
本帖最后由 jarlyyn 于 2022-6-24 05:21 PM 编辑前言:ask这块,很基础,但又能体会出 单纯触发条件发射 和分析处理的做机器的区别,就单独做一个篇短文
相信每一个北侠玩家都对ask这个命令映像深刻,毕竟这是一个从新人村 ask you about 闯荡江湖就一直伴随玩家的命令。这个命令是北侠很多任务的起点,所以可以说做机器人第一步往往就是处理ask信息。
北侠的NPC嗓门都比较大,回答问题时会让房间里的人都听到,这样机器没做好容易被别人的机器干捞。这种时候,最简单的方法就是做个多行触发,简单粗暴但有效。
但,ask的触发和响应,到底怎么做比较好呢?
我们能不能针对ask做通用的触发?
我们能不能记录下所有NPC对我们的回答,比如下图呢?
Mud是wiz规划好给人类玩家玩的,所以,最正经的机器人写法就是模拟人类玩家的反应,这样最不容易被wiz的更新干扰
要回答这个问题,我们先要分析下,什么是ask。
我们在丽春院ask命令后,游戏里会发生这些事:
1.向游戏发送
ask wei chunfang about 你真漂亮2.游戏中出现
你向韦春芳打听有关『你真漂亮』的消息。
这句话
3.游戏中出现
韦春芳说道:嗯....这我可不清楚,你最好问问别人吧。
这个响应
普通我那家会在看见 “你向韦春芳打听有关『你真漂亮』的消息。”后,寻找之后的一句或多句回答,这就是我们想要的答案。
好,那我们的机器应该怎么做呢?
首先,找一个变量,储存最后一次ask的内容和ask后的所有回复
App.Core.Ask={}
App.Core.Ask.LastNPC=""
App.Core.Ask.LastQuestion=""
App.Data.Ask={}
App.Core.Ask.MaxReply=10
其次,写一个ask命令,把最后一次ask的npc和问题记录下来
App.Core.AskQuestion=function(npc,question){
App.Core.Ask.LastNPC=npc
App.Core.Ask.LastQuestion=question
App.Send("ask "+npc+" about "+question)
}接着,做一个触发,记录你向NPC题目的内容,表示紧跟在后面是NPC对你的回复
^你向(.{1,10})打听有关『(.*)』的消息。$当然,还有响应的代码
App.Core.Ask.OnAsk=function(name, output, wildcards){
App.Data.Ask.Replies=[]
App.Data.Ask.Lines=[]
App.Data.Ask.Time=Now()
App.Core.Ask.LastNPC=""
App.Core.Ask.LastQuestion=""
App.Data.Ask.NPC=wildcards
App.Data.Ask.Question=wildcards
world.EnableTriggerGroup("core.ask.reply",true)
}在代码里打开了core.ask.reply这个组,开始记录信息
当然,还要做个问的太快重问的触发
^你说话太快,对方听不懂,慢点说吧。$响应代码是
App.Core.Ask.RetryAsk=function(){
if (App.Core.Ask.LastNPC && App.Core.Ask.LastQuestion){
App.Send("ask "+App.Core.Ask.LastNPC+" about "+App.Core.Ask.LastQuestion)
}
}如果没重问,那太棒了,开始记录回答了。我们应该把NPC回答的所有内容都记录下来。当然,有个限制,就加10个限制吧
加个触发
^(.*)$优先度要高点,别被别的触发拦截了
对应代码是
App.Core.Ask.OnReply=function(name, output, wildcards){
if (App.Data.Ask.Replies.length>=App.Core.Ask.MaxReply){
world.EnableTriggerGroup("core.ask.reply",false)
}else{
App.Data.Ask.Replies.push(output)
App.Data.Ask.Lines.push(JSON.parse(DumpOutput(1)))
}
App.Raise("core.reply")
App.RaiseStateEvent("core.reply")
}如果超过长度,就关触发组,不然把回复推到App.Data.Ask.Replies数组里。App.Data.Ask.Lines里放的是带样式信息,以防止需要判断回答里的色彩
App.Raise("core.reply")和App.RaiseStateEvent("core.reply")是发出事件,调用处理代码。这里也可以放类似钩子函数的东西,也可以放直接处理的函数
以我WDJ新人任务为例,大概就是这样一个代码逻辑
switch (output.Words.Text) {
case "说道:「你去提水浇菜地。":
case "说道:「我不是给过你任务了吗?提水浇菜地,快去!":
App.Quest.WDJ.Type = "jiaoshui"
break
case "说道:「你去提水浇田。":
case "说道:「我不是给过你任务了吗?提水浇田,快去!":
App.Quest.WDJ.Type = "jiaoshui2"
break
case "说道:「你去把睡房的便桶全部倒进茅房。":
case "说道:「我不是给过你任务了吗?把睡房的便桶全部倒进茅房,快去!":
App.Quest.WDJ.Type = "maofang"
break
case "说道:「你去弄点烂菜叶喂猪。":
case "说道:「我不是给过你任务了吗?弄点烂菜叶喂猪,快去!":
App.Quest.WDJ.Type = "weizhu"
break
case "说道:「你去把书房书架上的书整理一下。":
case "说道:「我不是给过你任务了吗?把书房书架上的书整理一下,快去!":
App.Quest.WDJ.Type = "zhengli"
break
default:
App.Fail()
return
}
很好,这样一个标准的提问功能就做好了。
正常情况下,大部分任务都不需要为提问做更多的触发了。
下一篇应该是迷宫篇 终于看懂30%,这个思路有启发啊,把所有的ask动作做成一个包。。。恩,我要学着搞搞
页:
[1]