如何利用数据库制作全自动解谜机器人(转)
zmud吧
全部回复
仅看楼主
level 6
PKUXKX 楼主
作者:八级风(转自:西游奇旅)
第一章 制作全自动解谜机器人的途径
在XYJ里,如何快速增长道行,是一个困扰许多玩家的大问题,
PK、NK、打花、解谜……PK要甘冒天下之大不韪;NK到了后期很难找到合适的NPC对象;
打花的确是个好方法,我曾经8小时打了430多年,不过很多站点被cut了,
:(。只有解迷,成了一个最可靠的方法。无论去哪个站点,
只要能熟练掌握解谜方法和技巧,都能较快的成长。
然而,解谜的繁琐和辛苦程度令很多玩家望而却步。解谜手册的熟记,
解谜物品的准备,问谜,解谜,清谜,再问谜,再解谜,精神 高度集中,
键盘敲个不停,就象一只陀螺,疲惫地转个不休。一个全自动的解谜机器人,
无疑是所有痴迷XYJ的玩家的梦想。把解谜变成一件轻松的事情,
留下更多时间享受聊天乐趣,让全自动机器人的梦想成真,就是这篇文章的目的。
据我了解与尝试,在现有的条件下,制作全自动解谜机器人大致
可以走以下几条路:
1、把所有任务列入Trigger中,根据问谜的结果触发,完成解谜任务;
2、利用Zmud本身提供的DDE(Dynamic Data Exchange,动态数据交换)
函数来开发一个外部程序,通过外部程序来控制Zmud的运行,实现自动解谜功能;
3、利用Zmud V5.55及其更高版本提供的Zmudapi.dll来开发一个控制Zmud运行的外部程序。
4、利用Zmud V5.x及其更高版本提供的数据库模块构建解谜数据库,配合Trigger来控制解谜。
下面我们来分析一下各种方法的利弊与可行性。
1、现有的很多所谓自动解谜机器人就是这种类型的。有些是专门做
一种解谜任务的,有些更全一点,最好的好象可以做四种任务。
说到底,这样的机器人不过是简单的触发堆积,Trigger庞大的要命,把机器拖的半死,
完成解谜任务又相当刻板,对于XYJ2000的解谜系统根本不适合的。我认为,
这样的Trigger只能拿来给新手做解谜的辅助与提示,没有更大的实际意义。
2、DDE的支持从Zmud很早的版本就开始了,当然DDE本身也是个老古董了。
对于大家常用的4.62版本来说,是除了方法1之外的唯一途径了。
当年浙大西游记的郭大路(henry)曾经用Delphi开发了一个自动解谜的外部控制程序的雏形。
他之所以选用Delphi开发,理由是:
Zmud是用delphi编写的,所以用Delphi最好,VC太复杂,VB的DDE控件不行,
只有Delphi的DDE控件与它联系起来最方便。
雏形出世的时候我还没有开始玩XYJ,同时这个雏形也没有引起太多人的注意。
所以henry的计划随着他去清华读博夭折了。
用DDE开发自动解谜机器人,无疑比方法1迈进了很大一步,
但是,在开发上的难度是相当大的。
3、从Zmud V5.55开始,ZuggSoft公司提供了一个叫Zmudapi.dll的动态链接库。
这个DLL本来是提供给Zmud用户来开发各种插件(Plugin)的。
我在连到ZuggSoft站点下载Zmud 5.55的时候注意到了它的介绍。
(在Zmud 5.55中还附带了Zmudapi.hlp,这个帮助文件简单介绍了该
DLL的功能与用途。在更高版本里不提供这个帮助文件。)
它提供了对Zmud的命令控制、数据传送(单向)以及其他一些功能的函数。
当时我就决定通过调用这个DLL来替代DDE实现外部控制程序,
可惜,我用VC无论如何也无法正常调用DLL提供的函数。这也促使我转向寻找其他方法。
不过,会用Delphi的朋友可以去试一下,Zuggsoft是推荐用Delphi开发的。
4、我的目光焦点是最后转向这个方法的。从Zmud 5.x开始,提供数据库功能,
而这个数据库对于庞大的解谜系统无疑是十分适合的。
解谜的任务如果不包括玩家送物和玩家拜贤,数目接近2000个,用现成的数
据库来处理要比自己编写专门的数据处理程序要便捷的多,处理速度上也有优势。
虽然Zmud提供的数据库功能并不强大,但对于我们编写自动解谜数据库而言足矣,

2009年07月01日 10点07分 1
level 6
PKUXKX 楼主
我们知道,食物、送物、拜贤、灭妖、武器、盔甲、募捐七种任
务对应的云彩分别为红、青、绿、黄、蓝、粉、白。输?quot;Quest"命令
查看当前任务的时候,可以知道身上有哪几朵彩云。我们可以利用函
数%pos(para1,para2)来得到Cloud字段的值。例如:
“慢慢地一小团红白两色祥云在你的身边升起。”
我们就得到一个Colorlist=“红白”,%pos(红,@colorlist)可
以返回“红”这个字在字符串“红白”中的位置,如果不存在则返回值为零。
因为Cloud字段为布尔量,如果需要查找的字存在于字符串中,则返回值非零,
赋给Cloud就为一;反之则为零。利用这个方法
我们可以得知哪些任务有相应的云彩存在,哪些没有,为选择任务打 好基础。
建好了这两个数据库,我们可以开始构建上层建筑了。后面,我们继续讨论:
第三章 任务选择机制的实现
为了实现自动解谜,我们首先考虑机器人的工作流程。
我们可以知道,选择这一环节至关重要,它就是整个自动解谜系统的大脑。
下面我们来初步实现选择这一功能。
首先,这个流程需要一个起点,在图中“问谜”这一步引起了Quest.db的更新,
从而引发后续的整个过程,相应地,我们从游戏里也要找到这个起点。
我选择的是命令"quests"。
当下命令quests后,会显示当前需要完成的七项任务。我们通过Trigger来获取这些任务,
并将数据传送到Quest.db中。数据库中有个命令#LoadDB,这个命令用于加载一个数据库。
如果这个数据库还没有加载到内存,就从文件中读取并加载;如果这个数据库已经被加载了,
就将它作为当前的数据库激活,那么后面的数据库操作都是在这个数据库中执行。
我们用#LoadDB
命令把当前的数据库置为Quest.db,然后输入"quests"指令。接下去,
下面的Trigger会自动更新数据库内容。
#TR {^????食物:(%x)}
{food=%1;0.Name=@food;0.Nodo=@red}
#TR {^????送物:(%x) (%x)}
{yin=%1;thing=%2;1.Name=@yin;1.Nodo=@cyan}
#TR {^????拜贤:(%x)}
{baixian=%1;2.Name=%1;2.Nodo=@green}
#TR {^????灭妖:(%x)}
{hu=%1;3.Name=@hu;3.Nodo=@yellow}
#TR {^????武器:(%x)}
{weapon=%1;4.Name=@weapon;4.Nodo=@blue}
#TR {^????盔甲:(%x)}
{armor=%1;5.Name=@armor;5.Nodo=@pink}
#TR {^????募捐:(%x)}
{lan=%1;6.Name=@lan;6.Nodo=@white}
其中诸如0.Name之类的变量代表数据库中编号为0的记录的Name字段。
而red、cyan、green等变量是我在Trigger里用来对某个任务未完成次数记数的,
每完成一个任务,对应的任务的记数置成零,其他任务记数加一。
那么,这个数字越大的,就代表越久没有完成。
然后,根据判断Cloud字段的值。
#TR {^????你的身上徐徐飘浮起一小团(%x)祥云。}
{colorlist=%1;
0.Cloud=%pos( 红, @colorlist);
1.Cloud=%pos( 青, @colorlist);
2.Cloud=%pos( 绿, @colorlist);
3.Cloud=%pos( 黄, @colorlist);
4.Cloud=%pos( 蓝, @colorlist);
5.Cloud=%pos( 粉, @colorlist);
6.Cloud=%pos( 白, @colorlist)
}
#TR {^????慢慢地一小团(%x)色祥云在你的身边升起。}
{colorlist=%1;
0.Cloud=%pos( 红, @colorlist);
1.Cloud=%pos( 青, @colorlist);
2.Cloud=%pos( 绿, @colorlist);
3.Cloud=%pos( 黄, @colorlist);
4.Cloud=%pos( 蓝, @colorlist);
5.Cloud=%pos( 粉, @colorlist);
6.Cloud=%pos( 白, @colorlist)
}
这个时候,Quest.db的数据已经全部被更新,我们可以通过下面的方法来选择任务:
1、在数据库Quest.db中建立一张视图,取名为order。order视图按照{Cloud|Nodo}排序,
也就是排序优先级先Cloud,再Nodo。

2009年07月01日 10点07分 3
level 6
PKUXKX 楼主
2、下命令#View,将在Zmud中显示这张视图,排在第一行的就是我们所选取要执行的命令。
3、用Trigger得到该命令。
图例如下
#View order {Cloud|Nodo}
#View
0 食物 鹫肉 - 20
2 拜贤 王孙 - 5
1 送物 孙三叔 - 4
6 募捐 雕木斜靠椅 - 3
5 盔甲 王八甲 - 1
3 灭妖 笑波儿天 - 0
4 武器 月牙弯刀 X 2
(显示"-"代表没有云彩,"X"代表有云彩)
然后,我取得下面要做的任务名为“鹫肉”,将当前数据库切换为Record.db,
用#Query命令对该任务进行查询,获得应该执行的命令。
(关于查询请参考帮助文件,这里不作赘述。)
这样,一个简单的自动解谜机器人的框架搭好了。
但是这样的模型离投入使用的成品还相差太远,需要我们一步步加以优化和调整。
最重要的还是提高“选择”的正确性,因为任务的选择直接关系到奖励的高低即Trigger的效率。
第四章 解谜技巧的应用
为了提高解谜所获得的奖励,我们要合理选择需要完成的任务,
并且将它与Trigger 的可实现性结合起来,也就是说,
判断的条件必须是可以通过Trigger 实现的,否则,
再完美的技巧也无法应用在我们的自动解谜机器人中。
首先,我们假设机器人运行在一种理想状态之下,所有的谜都是可以完成的。
那么我们将遇到下面两种情况:
一、云彩数目小于七朵。这时,下一个要执行的任务应该是没有对应的云彩的那项。
我们知道,解谜的奖励和云彩数目关系密切,云彩越多,获得奖励越多,
机器人效率也越 高。因此,任务的选择首先必须符合倾向云彩增多的原则。
例如:你的身上有青绿黄蓝粉白六彩祥云,那我们可以通过触发器判断得知缺少红色云彩,
即下一个任务应该做猪八戒的食物。做完食物这一项,就可以将云彩累积到最大数目。
二、云彩达到最大数,即七彩祥云。这种情况下我们应
该遵循FDFD(First Done First Do即最先完成最早执行)原则。
让我们先来看看上一章提到的Nodo记数,它的机理如下:
设置七个变量red、cyan、green、yellow、blue、pink、white
分别对应该种云彩对应的任务记数。当完成某项任务,则将 相应变量置零,
其他变量加一。例如:
#Trigger {^????陈光蕊对你说道:多谢这位}
{quest_type=拜贤;green=0;#add cyan 1;#add blue 1;
#add yellow 1;
#add red 1;#
add white 1;#add pink 1}
这样我们可以通过这七个变量的值了解到某种类型的任务有多久没有完成。
因为云彩的存在是有时限的,自它产生以来,经历8次记数,也就是变量值为9的时候,
这朵云彩就消失了。
所以我们应该优先执行记数大的任务,以保证云彩维持在七彩。
上面提出的两种原则已经在我们的模型中采用了,即按照“Cloud|Nodo”的次序进行排序,
先考虑是否有云,然后考虑做最久未做的任务。但是,在实际解谜中,我们并不可
能完成所有的任务,一定会遇到有些谜无法完成。
所以我们在数据库Record和Quest中引入一个新的字段:CanDo。
这个字段为一,表示该任务可以完成,这个字段为零,则说明是无法完成的。
随着Player的成长,可以手动的对这个字段进行修改。
比如Player早期很难完成一些灭妖以及菩提祖师的拜贤、羊脂玉净瓶等任务,
到了后期,就可以调整为可以执行。
此外,我们对何时清谜做一个考虑。如果因为某些任务无法完成,
只能保持在较少数目云彩下解谜,奖励会降低;
而清谜会造成两个损失,一是随机减少一朵云,二是时间上的等待,
但清谜之后可以抛开那些挡路的任务,为七彩云创造条件。有得必有失,
如何选择清谜时机呢?根据我的解谜经验,六彩以下的任务是不值得做的。
我们可以判断,如果根据排序,最优先的两个任务无法完成,就可以去清谜了。

2009年07月01日 10点07分 4
1