北大侠客行MUD论坛

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

Mush偷学任务招式对比

[复制链接]
发表于 2022-7-22 14:24:36 | 显示全部楼层 |阅读模式
本帖最后由 shenji 于 2022-7-22 02:56 PM 编辑

感谢xxhy的指路

众所周知,偷学任务被魔性般地颠倒语句,因此npc发出的招式和慕容复要求的招式并不能严格匹配。
本来我是破罐子破摔,通过不重复地偷学招式来尽可能完成任务,后来在xxhy的指引下,发现了比较两个数组元素相似度的函数,因此得出下面的方案。

一.比较两个数组的相似度

  1. function levenshtein(strA, strB)
  2.         local tempTb = {}
  3.         for m = 1, (#strA + 1), 1 do
  4.     tempTb[m] = {}
  5.     tempTb[m][1] = m - 1
  6.         end

  7.         for n = 1, (#strB + 1), 1 do
  8.     tempTb[1][n] = n - 1
  9.         end

  10.         for i = 2, (#strA + 1) , 1 do
  11.     for j = 2, (#strB + 1), 1 do
  12.         local x = tempTb[i - 1][j] + 1    --删除
  13.         local y = tempTb[i][j - 1] + 1    --插入
  14.         local z = 0
  15.         if strA[i - 1] == strB[j - 1] then  --替换
  16.             z = tempTb[i -1][j - 1]
  17.         else
  18.             z = tempTb[i -1][j - 1] + 1
  19.         end
复制代码


二.将慕容复需要的招式分割成单个文字存入数组

  1. tx_pfm = {}   --储存需要偷学的招式
  2. tx_c = 1

  3. function tx_split(str)
  4.     local tx_str = tostring(str)
  5.     local str_i_max = tonumber(string.len(str))   --string.len()返回string的单字符长度
  6.     local tx_s = {}
  7.     local i = 1
  8.     while i <= str_i_max do
  9.         table.insert(tx_s,string.sub(tx_str,i,i+1))  --tx_s中存放的是一句招式分割后的所有单个汉字、标点符号
  10.         i = i + 2
  11.     end
  12.     tx_pfm[tx_c] = tx_s --将表格 tx_s嵌套到表格 tx_pfm中,每一句招式存一次
  13.     tx_c = tx_c + 1
复制代码



三.确保不会重复偷学npc的招式

复制代码
function tx(str)
        --Note("开始匹配")
        for k, v in pairs(tx_npfm) do
        if string.find(v, str) ~= nil then
                --Note("第"..k.."招匹配成功")
                break
        elseif string.find(v, str) == nil then
                k = k + 1
                if tx_npfm[k] == nil then
                        table.insert(tx_npfm,str)
                                --Note("开始偷学")
                                tx_cp(str)
                        break
                end
        end
        end
end



四.根据npc招式和慕容复要求之间的相似度决定是否偷学

  1. function tx_cp(str)
  2.     local tx_str = tostring(str)
  3.     local str_i_max = tonumber(string.len(str))
  4.         local tx_s = {}
  5.         local i = 1
  6.     while i <= str_i_max do
  7.         table.insert(tx_s,string.sub(str,i,i+1))   --首先将npc招式分割成单个汉字,存入表格,才能进行下一步的比较
  8.         i = i + 2
  9.     end
  10.         --tprint(tx_s)
  11.         for k, v in pairs(tx_pfm) do
  12.     if levenshtein(tx_pfm[k],tx_s) < 50 then  --这里的50是相似度,如果定得太高,可能会导致匹配不成功学不到所有招式,定得太低,可能会导致学习到不需要的招式,暂定50以观后效
  13.         --Note("第"..k.."招匹配不成功,继续:")
  14.         k = k + 1
  15.         if tx_pfm[k] == nil then
  16.         break
  17.     end
  18.     elseif levenshtein(tx_pfm[k],tx_s) >= 50 then
  19.         --Note("第"..k.."招匹配成功")
  20.         Send("touxue "..GetVariable("tx_id"))  --匹配度达标才进行偷学操作
  21.     break
  22.     end
  23.                 end
  24. end
复制代码


效果:
慕容复在你的耳边悄声说道:
刘雨伏地一个滚翻,一招「伏虎」,听风钢杖挟呼呼风声迅猛扫向高梦香的足胫!
段月叶一招「平地龙飞」,全身滴溜在地溜地上打个大转,举棍向牛圣的胸腹间戳去!
李劲潜运真力,一招「苍龙归海」,钢杖顿时长了数丈,般直矫龙射盖杰的世豪胸口!
龚颖一招「投流」鞭断,钢杖高举,以雷霆万钧之势对准独孤蓉瑾的天灵当头劈下!
柴立颖一招「黄石纳履」,手中钢杖如蜻蜓点水般,招招向豪杰盖世的下盘要害点去!
慕容复在你的耳边悄声说道:其人名曰孔八劲,正在小山村一带活动。


>/tprint(tx_pfm)
1:   1="一"、2="个"、3="滚"、4="翻"、5=","、6="一"、7="招"、8="「"、9="伏"、10="虎"、11="」"、12=","、13="听"、14="风"、15="钢"、16="杖"、17="挟"、18="呼"、19="呼"、20="风"、21="声"、22="迅"、23="猛"、24="扫"、25="向"、26="高"、27="梦"、28="香"、29="的"、30="足"、31="胫"、32="!"
2:   1="招"、2="「"、3="平"、4="地"、5="龙"、6="飞"、7="」"、8=","、9="全"、10="身"、11="滴"、12="溜"、13="在"、14="地"、15="溜"、16="地"、17="上"、18="打"、19="个"、20="大"、21="转"、22=","、23="举"、24="棍"、25="向"、26="牛"、27="圣"、28="的"、29="胸"、30="腹"、31="间"、32="戳"、33="去"、34="!"
3:   1="真"、2="力"、3=","、4="一"、5="招"、6="「"、7="苍"、8="龙"、9="归"、10="海"、11="」"、12=","、13="钢"、14="杖"、15="顿"、16="时"、17="长"、18="了"、19="数"、20="丈"、21=","、22="般"、23="直"、24="矫"、25="龙"、26="射"、27="盖"、28="杰"、29="的"、30="世"、31="豪"、32="胸"、33="口"、34="!"
4:   1="「"、2="投"、3="流"、4="」"、5="鞭"、6="断"、7=","、8="钢"、9="杖"、10="高"、11="举"、12=","、13="以"、14="雷"、15="霆"、16="万"、17="钧"、18="之"、19="势"、20="对"、21="准"、22="独"、23="孤"、24="蓉"、25="瑾"、26="的"、27="天"、28="灵"、29="当"、30="头"、31="劈"、32="下"、33="!"
5:   1="招"、2="「"、3="黄"、4="石"、5 ="纳"、6="履"、7="」"、8=","、9="手"、10="中"、11="钢"、12="杖"、13="如"、14="蜻"、15="蜓"、16="点"、17="水"、18="般"、19=","、20="招"、21="招"、22="向"、23="豪"、24="杰"、25="盖"、26="世"、27="的"、28="下"、29="盘"、30="要"、31="害"、32="点"、33="去"、34="!"

(为了方便查看已经转换方向)

偷学完毕之后
>/tprint(tx_npfm)

1="已学招数"
2="潜运真力,一招「苍龙归海」,铁杖顿时长了数丈,矫龙般直射你的胸口!"        --与要求第式匹配
3="一招「流星赶月」,身棍合一,棍端逼成一条直线,流星般向顶向你的部!"        --多余招式
4="把铁杖平提胸口,一拧身,一招「勒马停锋」,铁杖猛地撩向你的颈部!"        --多余招式
5="一招「流星赶月」,身棍合一,棍端逼成一条直线,流星般向顶向你的部!"        --多余招式、与已学第二式重复(因为确保不重复偷学时用的是严格匹配而不是相似度匹配,这里可以进行优化)
6="一招「投鞭断流」,铁杖高举,以雷霆万钧之势对准你的天灵当头劈下!"        --与要求第式匹配
7="双手持棍划了个天地大圈,一招「红霞贯日」,一棍从圆心正中击出,撞向你的胸口!"        --多余招式
8="一招「平地龙飞」,全身滴溜溜地在地上打个大转,举棍向你的胸腹间戳去!"        --与要求第式匹配
9="伏地一个滚翻,一招「伏虎听风」,铁杖挟呼呼风声迅猛扫向你的足胫!"        --与要求第式匹配
10="一招「黄石纳履」,手中铁杖如蜻蜓点水般,招招向你的下盘要害点去!"        --与要求第式匹配
11="往东离开。"


你向慕容复打听有关『finish』的消息。
你向慕容复细细分说偷学到的『韦驮棍』招式。
慕容复说道:「不错不错,有了这些招式,我的斗转星移肯定能更进一步。」
完成慕容复偷学任务,你获得了8271点经验,4624点潜能和1084点江湖声望的奖励。
你完成了29次慕容偷学任务。



北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2022-7-22 14:27:27 | 显示全部楼层
  1.             App.Quest.Zhuliu.Touxue.Data.Skill = result[1]
  2.             for (var i = 1; i < App.Data.Ask.Replies.length; i++) {
  3.                 var reply = App.Data.Ask.Replies[i]
  4.                 switch (App.Quest.Zhuliu.Touxue.Data.AskMode) {
  5.                     case 0:
  6.                         if (reply == "慕容复在你的耳边悄声说道:")
  7.                             App.Quest.Zhuliu.Touxue.Data.AskMode = 1
  8.                         break
  9.                     case 1:
  10.                         if (reply == "慕容复给了你一张纸,上书:") {
  11.                             App.Quest.Zhuliu.Touxue.Data.Captcha = true
  12.                             App.Quest.Zhuliu.Touxue.Data.AskMode = 2
  13.                             break
  14.                         }
  15.                         var npc = reply.match(renpc)
  16.                         if (npc) {
  17.                             App.Quest.Zhuliu.Touxue.Data.Name = npc[1]
  18.                             App.Quest.Zhuliu.Touxue.Data.Area = npc[2]
  19.                             App.Quest.Zhuliu.Touxue.Data.AskMode = 2
  20.                             break
  21.                         }
  22.                         var perform = {}
  23.                         for (var k = 0; k < reply.length; k++) {
  24.                             perform[reply[k]] = true
  25.                         }
  26.                         App.Quest.Zhuliu.Touxue.Data.Performs.push(perform)
  27.                 }
  28.             }
复制代码
  1.         let line = App.Quest.Zhuliu.Touxue.Data.LastLine + data
  2.         App.Quest.Zhuliu.Touxue.Data.LastLine = data
  3.         for (var i = 0; i < App.Quest.Zhuliu.Touxue.Data.Performs.length; i++) {
  4.             let p = App.Quest.Zhuliu.Touxue.Data.Performs[i]
  5.             let count = 0
  6.             var matched = {}
  7.             for (var k = 0; k < line.length; k++) {
  8.                 let char = line[k]
  9.                 if (matched[char]) {
  10.                     continue
  11.                 }
  12.                 if (p[char]) {
  13.                     count++
  14.                 }
  15.                 matched[char] = true
  16.             }
  17.             if (count >= Object.keys(p).length * trustpercent) {
  18.                 App.Send("touxue " + App.Quest.Zhuliu.Touxue.Data.ID)
  19.                 App.Quest.Zhuliu.Touxue.Data.LastLine = ""
  20.                 App.Quest.Zhuliu.Touxue.Data.Performs.splice(i, 1)
  21.                 break
  22.             }
  23.         }
  24.         if (App.Quest.Zhuliu.Touxue.Data.Performs.length == 0) {
  25.             App.Quest.Zhuliu.Touxue.Data.Finish = true
  26.             App.Send("halt;yield no")
  27.             return
  28.         }
  29.     }
复制代码



北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2022-7-22 14:28:55 | 显示全部楼层
匹配文字覆盖率就行了

因为人眼也是这么做的。

如果真的有人能纯手动作偷学的话……
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
 楼主| 发表于 2022-7-22 14:31:07 | 显示全部楼层
为啥贴上去的代码总是消失。。
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2022-7-22 14:32:56 | 显示全部楼层
另外我没有保存已偷学到的招式

我保存的是需要偷学的

偷学一个,删掉一个,删光结束。

另外还有个超时处理代码,和主题没关系,就不贴了。
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
 楼主| 发表于 2022-7-22 14:38:47 | 显示全部楼层
jarlyyn 发表于 2022-7-22 02:32 PM
另外我没有保存已偷学到的招式

我保存的是需要偷学的

对哦,可以删掉哦
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2022-7-22 14:42:22 | 显示全部楼层
学到了,我直接对比两句话的levenshtein距离,总是误判
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
 楼主| 发表于 2022-7-22 14:57:02 | 显示全部楼层
代码有一个错误,返回招式的字符串长度那里不用*0.5,已更正
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
 楼主| 发表于 2022-7-22 15:47:18 | 显示全部楼层
本帖最后由 shenji 于 2022-8-2 01:22 PM 编辑

受到启发后,发现只需要三个函数就可以了
1.表格之间相似度比较
  1. function levenshtein(strA, strB)
  2.         local tempTb = {}
  3.         for m = 1, (#strA + 1), 1 do
  4.                 tempTb[m] = {}
  5.                 tempTb[m][1] = m - 1
  6.         end

  7.         for n = 1, (#strB + 1), 1 do
  8.                 tempTb[1][n] = n - 1
  9.         end

  10.         for i = 2, (#strA + 1) , 1 do
  11.                 for j = 2, (#strB + 1), 1 do
  12.                         local x = tempTb[i - 1][j] + 1    --删除
  13.                         local y = tempTb[i][j - 1] + 1    --插入
  14.                         local z = 0
  15.                         if strA[i - 1] == strB[j - 1] then  --替换
  16.                                 z = tempTb[i -1][j - 1]
  17.                         else
  18.                                 z = tempTb[i -1][j - 1] + 1
  19.                         end
  20.                         tempTb[i][j] = math.min(x,y,z)
  21.                 end
  22.         end
  23.         --Note("匹配度:")
  24.         --print((1- tempTb[#strA + 1][#strB + 1]/math.max(#strA, #strB))*100)
  25.         return (1- tempTb[#strA + 1][#strB + 1]/math.max(#strA, #strB))*100
  26. end
复制代码


2.对慕容复要求的招式进行分割储存

  1. tx_pfm = {}
  2. --tx_npfm = {"已学招数"}
  3. tx_c = 1
复制代码

  1. function tx_split(str)
  2.         local tx_str = tostring(str)
  3.     local str_i_max = tonumber(string.len(str))
  4.         local tx_s = {}
  5.         local i = 1
  6.     while i <= tonumber(str_i_max - 1) do
  7.                 table.insert(tx_s,string.sub(tx_str,i,i+1))
  8.                 i = i + 2
  9.         end
  10.         tx_pfm[tx_c] = tx_s
  11.         tx_c = tx_c + 1
  12. end
复制代码


3.npc招式分割、比较


复制代码
  1. function tx_cp(str)
  2.     local tx_str = tostring(str)
  3.     local str_i_max = tonumber(string.len(str))
  4.         local tx_s = {}
  5.         local i = 1
  6.     while i <= tonumber(str_i_max - 1) do
  7.                 table.insert(tx_s,string.sub(str,i,i+1))
  8.                 i = i + 2
  9.         end
  10.         --tprint(tx_s)
  11.         for k, v in pairs(tx_pfm) do
  12.                 if levenshtein(tx_pfm[k],tx_s) < 50 then
  13.                     --Note("第"..k.."招匹配不成功,继续:")
  14.                         k = k + 1
  15.                         if tx_pfm[k] == nil then
  16.                                 break
  17.                         end
  18.                 elseif levenshtein(tx_pfm[k],tx_s) >= 50 then
  19.                         --Note("第"..k.."招匹配成功")
  20.                         Send("touxue "..GetVariable("tx_id"))
  21.                         table.remove(tx_pfm, k)
  22.                                 if #tx_pfm == 0 then            --table的元素数量为0,说明已经学完,即可结束
  23.                                         Send("response action 偷学完毕")
  24.                                 end
  25.                         break
  26.                         end
  27.                 end
  28. end
复制代码


希望这次代码不要弄丢

-------------------------------------------------------------------------------------------------------------------------
while 循环里,i应该循环至最后一个双字符的第一个下标,即i <= tonumber(str_i_max - 1)  已更正
-------------------------------------------------------------------------------------------------------------------------
tx_cp(str)函数已在后页更新,论坛吞代码太厉害了,就不在这里进行同步了



北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
 楼主| 发表于 2022-7-22 16:09:19 | 显示全部楼层
本帖最后由 shenji 于 2022-7-22 04:13 PM 编辑

慕容复说道:「神万姬,我近来习武遇到障碍,听说有人擅长天王爪,你去把下面几招学(touxue)下来。」
慕容复在你的耳边悄声说道:
单融嘉一式「捻灯」,弓腰区背底发,足劲,斜身抢到盖向盖杰身侧,单手扣世豪向盖杰脖项!   1.
抓取成功
辛美怪啸喋喋,摄人心魄,一式「妙音」,期进申莎香怀中,双爪环扣,抱向申莎香!   2.
抓取成功
朱重双目半睁半闭,念念口中有词,一式「撞钟」,左手搭在右手之上,右爪合双手之力向盖直催世豪杰的头部!   3.
抓取成功
费多三端坐不动式「,一暗香」,双爪在杰全前虚按,幻出无数爪影,指端真气破空丝丝做响,遥遥罩向盖世豪身杰全!   4.
抓取成功
喻柏三跃起腾空,使一式「清乐」,双爪前后交错出击抓快,一似一抓,逼得亲鹏琨连连倒退!   5.
抓取成功
慕容复在你的耳边悄声说道:其人名曰关慕,正在西湖梅庄一带活动。
关慕 西湖梅庄

-----------------------------------------------------------------
关慕端坐不动,一式「暗香」,双爪在身前虚按,幻出无数爪影,指端真气破空丝丝做响,遥遥罩向你全身!    4.
匹配度:
15.217391304348
匹配度:
13.04347826087
匹配度:
6.25
匹配度:
76.470588235294
匹配度:
76.470588235294

你从关慕身上偷学到了一招!

关慕端坐不动,一式「暗香」,双爪在身前虚按,幻出无数爪影,指端真气破空丝丝做响,遥遥罩向你全身!   重复.
匹配度:
15.217391304348
匹配度:
13.04347826087
匹配度:
6.25
匹配度:
21.739130434783

关慕端坐不动,一式「暗香」,双爪在身前虚按,幻出无数爪影,指端真气破空丝丝做响,遥遥罩向你全身!   重复.
匹配度:
15.217391304348
匹配度:
13.04347826087
匹配度:
6.25
匹配度:
21.739130434783

关慕含胸探身,一式「凝云」,左手在胸前成爪虚护,右爪直探你的面门!    关.
匹配度:
10
匹配度:
19.444444444444
匹配度:
27.083333333333
匹配度:
20

关慕端坐不动,一式「暗香」,双爪在身前虚按,幻出无数爪影,指端真气破空丝丝做响,遥遥罩向你全身!    复.
匹配度:
15.217391304348
匹配度:
13.04347826087
匹配度:
6.25
匹配度:
21.739130434783

关慕端坐不动,一式「暗香」,双爪在身前虚按,幻出无数爪影,指端真气破空丝丝做响,遥遥罩向你全身!    重复.
匹配度:
15.217391304348
匹配度:
13.04347826087
匹配度:
6.25
匹配度:
21.739130434783

关慕腾空跃起,使一式「清乐」,双爪前后交错出击,一抓快似一抓,逼得你连连倒退!   5.
匹配度:
7.5
匹配度:
13.513513513514
匹配度:
16.666666666667
匹配度:
72.5
匹配度:
72.5

你从关慕身上偷学到了一招!

关慕腾空跃起,使一式「清乐」,双爪前后交错出击,一抓快似一抓,逼得你连连倒退!   重复.
匹配度:
7.5
匹配度:
13.513513513514
匹配度:
16.666666666667


关慕含胸探身,一式「凝云」,左手在胸前成爪虚护,右爪直探你的面门!      无关.
匹配度:
10
匹配度:
19.444444444444
匹配度:
27.083333333333

关慕喋喋怪啸,摄人心魄,一式「妙音」,期进你怀中,双爪环扣,抱向你!    2.
匹配度:
12.5
匹配度:
72.222222222222
匹配度:
72.222222222222

你从关慕身上偷学到了一招!

关慕端坐不动,一式「暗香」,双爪在身前虚按,幻出无数爪影,指端真气破空丝丝做响,遥遥罩向你全身!    复.
匹配度:
15.217391304348
匹配度:
6.25
你凌空跃起,如大鹏展翅,以泰山压顶之势逼退了关慕这一招。

关慕一式「捻灯」,弓腰区背,足底发劲,斜身抢到你身侧,单手扣向你脖项!    1.
匹配度:
67.5
匹配度:
67.5

你从关慕身上偷学到了一招!

关慕端坐不动,一式「暗香」,双爪在身前虚按,幻出无数爪影,指端真气破空丝丝做响,遥遥罩向你全身!    复.
匹配度:
6.25

关慕腾空跃起,使一式「清乐」,双爪前后交错出击,一抓快似一抓,逼得你连连倒退!    复.
匹配度:
16.666666666667

关慕含胸探身,一式「凝云」,左手在胸前成爪虚护,右爪直探你的面门!    无关.
匹配度:
27.083333333333

关慕双目半睁半闭,口中念念有词,一式「撞钟」,左手搭在右手之上,右爪合双手之力直催向你的头部!    3.
匹配度:
81.25
匹配度:
81.25

你从关慕身上偷学到了一招!
>
系统回馈:action = 偷学完毕
>
你身行向后一跃,跳出战圈不打了。
>
你决定打架时还手反击。

-------------------------------------------------
有时候会多比较一两次,原因尚不清楚,但似乎不影响运行,根据程序员第一守则,既然代码跑的起来那就这样吧


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

本版积分规则

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

GMT+8, 2024-5-3 07:29 PM , Processed in 0.011492 second(s), 14 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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