北大侠客行MUD论坛

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

关于机器的效率问题

[复制链接]
发表于 2015-5-13 11:04:08 | 显示全部楼层 |阅读模式
最近一直在思考一个问题,就是机器的效率问题

昨天写了一个函数,是一个特殊路径,从某地去一个岛的路径

去这个岛需要2个条件:
1、身上有锋刃的武器,可以切木头
2、买到道具“粗绳子”,或者捡到也行(经常地上有很多)
两者齐全之后,就可以制作木筏,飘向神龙岛
大体就是这样一个流程

但是写代码的时候就有点麻烦了,我最开始是这么做的
首先装备武器,切木头,如果回应没有装备到武器,或者武器不是锋刃的,那么我就调用“检查武器”的函数,去研究为什么武器不好用(我理论上身上有斧头有剑,应该可以的,武器不全是错,可以去买),如果身上的确没有正确的武器,那么就重新返回任务分配表,并把买武器的任务优先度调高到比去神龙岛更高,这样就会去买武器了。
于此同时,显示身上的物品,如果身上有粗绳子,就什么都不做,否则就买绳子,并拣绳子。
然后判断返回值:
如果返回买到粗绳子,那么说明绳子有了,继续
如果返回商人忙,那么再试
如果返回商人不在,那么返回失败
如果返回商人身上绳子不足,那么返回失败
然后再判断捡绳子的返回值:
如果捡起了绳子,继续
如果地上没绳子,返回失败

如果捡绳子和买绳子都失败,那么确定失败,回去放弃任务

然后再制作木筏,然后坐木筏,下一步流程

这是我本来的打算


但我思考再三,参考了zmud的bot,感觉这么做的效率有点低
砍树得等返回值,买绳子捡绳子得等返回值,制作木筏的时候可能正好刷新,砍的木头没了怎么办,还得考虑进去,导致程序极其复杂,而且还慢

所以我目前的打算是:
一次性执行买绳子捡绳子砍树做木筏跳上木筏一系列指令
然后首先判断是否跳上了木筏,如果跳上去了,一切好说
如果没跳上去,分析原因,是绳子的问题,还是木头的问题
如果是木头的问题,研究怎么解决
如果是绳子的问题,研究怎么解决
这样,是一种非模块化的,事后诸葛亮的方式来进行,但我觉得虽然结构不那么清晰,但是更适合实际需要

我觉得,mush很多时候太过于注重模块,而实际效果不是很好,至少效率方面除了能点对点直达以外,没什么提升,甚至还不如zmud
所以,我觉得mush写得太正规反而不利于bot的效率。
个人想法,请前辈们指点,多谢

北大侠客行MUD,中国最好的MUD
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 2015-5-13 11:09:02 | 显示全部楼层
又比如从神龙岛回来,得向“陆高轩”偷令牌,交给船夫才能回来
这里存在几个问题:
1.陆高轩在不在
2.陆高轩晕没晕
3.令牌偷到的有成功率的
4.船夫在不在
5.船夫晕没晕

这些都是问题
如果我以前的想法,肯定是一个个的wait.regexp扔过去,然后一步步的走
但我现在的做法是这样
首先偷5次令牌,然后给船夫,跳上船
这些指令执行完毕之后,如果返回上船了,那么一切ok
如果失败了,再研究怎么失败的,怎么解决
换句话说,就不是一步步的做,而是一口气做完,再研究结果。因为大部分情况下,一次性都能做完,所以问题应该不大,而出错的时候是小概率事件,没必要为了小概率事件而一步步的谨慎的执行-等反馈-执行
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2015-5-13 14:00:35 | 显示全部楼层
我觉得写机器,首先考虑的不应该是这些细节问题,而是机器的整体框架。
框架的设计上,要便于后续的修改和维护,要做到单独修改某个具体函数或模块的实现,不会影响整体功能。
比如:
1,假设编写胡一刀任务模块,需要调用遍历神龙岛模块,遍历神龙岛模块分为go神龙岛模块、travel神龙岛模块、back神龙岛模块。
2,一开始编写go神龙岛模块和back神龙岛模块的时候,只需要使用楼主所说的,直接执行一系列指令即可,甚至不用管执行完之后到底是否成功,大不了失败了,手动一下嘛。
3,这样很快整个机器将可以顺利运行起来,只是在某些意外情况下,需要人工干预。
4,然后再慢慢修改go、back等等模块,让它们能够处理某些意外情况,达到真正的自动。

所以我们一开始应该处理的是整个机器运行的结构或者说框架,设计得好的框架应该是这样的:
1,一开始你调用的go_shenlongdao函数,只是send一系列的指令,后来你的go_shenlongdao函数,
会在send一系列执行之后,检查结果,如果结果失败,讲重新执行,再后来你的go_shenlongdao函数,
开始调用其他模块,比如切木头模块、粗绳子模块。
2,虽然go_shenlongdao函数,经历了上面的一系列修改,但是你的job_huyidao函数,却不需要做
任何修改,依旧只要调用go_shenlongdao函数即可,而不用去关心它具体是用什么方式实现的,是用
alias?是用wait?都不是问题。
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 2015-5-13 23:43:16 | 显示全部楼层
回复 3# cmud


抱歉,我可能没说明白
整体框架我已经搭建起来了,至少走路这一部分。
实际上,整个地图我基本已经画完了,我目前收录了2758个节点,比如第2758节点内容如下:
[2758] = {
        area = "神龙岛",
        descriptions = {
            [1] = "此处是赤龙门的卧室,屋中的布置很简单,只有几只大床靠墙放着,",
            [2] = "供本门教众休息之用。",
        },
        exits = {
            west = {
                cmd = "w",
                gto = 2756,
            },
        },
        location = {
            [1] = "",
            [2] = "",
            [3] = "赤龙门议事厅-----卧室",
            [4] = "",
            [5] = "",
        },
        name = "卧室",
    },

目前已经做到了点对点直达,我需要做的是处理一些特殊路径的细节问题(其实也基本处理完了,去神龙岛只是比较复杂而已)
我单独有“跑路”模块,之后还要写“快速行走”模块和“遍历”模块
“跑路”模块:点对点直达,中间不做任何其他地方。实际上我是点到多个点的直达,自动行走到多个点中最近的一个点。这样利于去吃饭、喝水、买武器、取钱、做任务。因为可以自动找到最近的一个。

“快速行走”模块:点对多个点逐个直达。核心调用“跑路”模块,对多个点逐个直达,即从S地,向A、B、C、D......等地点以最短距离挨个直达,指令不停,不等反馈,并可以在每个地点的指令中加上其他指令。相当于
“跑路”{A、B、C、D};送信
“跑路”{B、C、D};送信
“跑路”{C、D};送信
“跑路”{D};送信
(假设A、B、C、D逐个越来越远,需要加的指令是送信)
以上整个指令不等反馈一气呵成的输入,这样方便在区域内找人、送信、找东西等
如果其他指令(比如送信)没有成功(比如如果目标busy,则送信不成功,我跑过了),同时会记录目标NPC(或者物品)的位置将会被记录,这样我一口气跑完,如果信没送到(或者人没杀到等等),那么可以直接知道目标当前位置,然后直接点对点的直接找到目标所在地,然后去做其他操作。

“遍历”模块:跟“快速行走”模块类似,但是每走一步,都判断一下,就是传统的遍历了。速度慢,但是有很多场合这么做更适合,比如有些任务NPC只要你从他身边走过却没理他,就算任务失败。

说远了,不过我目前已经早就到了开始研究细节的情况了。
机器人的总体框架还没写,我目前只写了“跑路”模块,包括画地图,而特殊路径处理,是属于“地图”中的一部分,或者说是“跑路”模块的一部分。
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-14 11:22 PM , Processed in 0.010662 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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