shenji 发表于 2022-7-22 14:24:36

Mush偷学任务招式对比

本帖最后由 shenji 于 2022-7-22 02:56 PM 编辑

感谢xxhy的指路

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

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

function <font color="#ff0000">levenshtein</font>(strA, strB)
      local tempTb = {}
      for m = 1, (#strA + 1), 1 do
    tempTb = {}
    tempTb = m - 1
      end

      for n = 1, (#strB + 1), 1 do
    tempTb = n - 1
      end

      for i = 2, (#strA + 1) , 1 do
    for j = 2, (#strB + 1), 1 do
      local x = tempTb + 1    <font color="#4169e1">--删除</font>
      local y = tempTb + 1    <font color="#4169e1">--插入</font>
      local z = 0
      if strA == strB then<font color="#4169e1">--替换</font>
            z = tempTb
      else
            z = tempTb + 1
      end

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

tx_pfm = {}<font color="#4169e1"> --储存需要偷学的招式</font>
tx_c = 1

function <font color="#ff0000">tx_split</font>(str)
    local tx_str = tostring(str)
    local str_i_max = tonumber(string.len(str))<font color="#4169e1"> --string.len()返回string的单字符长度</font>
    local tx_s = {}
    local i = 1
    while i <= str_i_max do
      table.insert(tx_s,string.sub(tx_str,i,i+1))<font color="#4169e1">--tx_s中存放的是一句招式分割后的所有单个汉字、标点符号</font>
      i = i + 2
    end
    tx_pfm = tx_s <font color="#4169e1"> --将表格 tx_s嵌套到表格 tx_pfm中,每一句招式存一次</font>
    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 == nil then
                        table.insert(tx_npfm,str)
                              --Note("开始偷学")
                              tx_cp(str)
                        break
                end
      end
      end
end



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

function <font color="#ff0000">tx_cp</font>(str)
    local tx_str = tostring(str)
    local str_i_max = tonumber(string.len(str))
      local tx_s = {}
      local i = 1
    while i <= str_i_max do
      table.insert(tx_s,string.sub(str,i,i+1))   <font color="#4169e1">--首先将npc招式分割成单个汉字,存入表格,才能进行下一步的比较</font>
      i = i + 2
    end
<font color="#4169e1">      --tprint(tx_s) </font>
      for k, v in pairs(tx_pfm) do
    if <font color="#ff0000">levenshtein</font>(tx_pfm,tx_s) < <font color="#ff0000">50</font> then<font color="#4169e1">--这里的50是相似度,如果定得太高,可能会导致匹配不成功学不到所有招式,定得太低,可能会导致学习到不需要的招式,暂定50以观后效</font>
      <font color="#4169e1">--Note("第"..k.."招匹配不成功,继续:")</font>
      k = k + 1
      if tx_pfm == nil then
      break
    end
    elseif <font color="#ff0000">levenshtein</font>(tx_pfm,tx_s) >= 50 then
      <font color="#4169e1">--Note("第"..k.."招匹配成功")</font>
      Send("touxue "..GetVariable("tx_id"))--匹配度达标才进行偷学操作
    break
    end
                end
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次慕容偷学任务。



jarlyyn 发表于 2022-7-22 14:27:27

            App.Quest.Zhuliu.Touxue.Data.Skill = result
            for (var i = 1; i < App.Data.Ask.Replies.length; i++) {
                var reply = App.Data.Ask.Replies
                switch (App.Quest.Zhuliu.Touxue.Data.AskMode) {
                  case 0:
                        if (reply == "慕容复在你的耳边悄声说道:")
                            App.Quest.Zhuliu.Touxue.Data.AskMode = 1
                        break
                  case 1:
                        if (reply == "慕容复给了你一张纸,上书:") {
                            App.Quest.Zhuliu.Touxue.Data.Captcha = true
                            App.Quest.Zhuliu.Touxue.Data.AskMode = 2
                            break
                        }
                        var npc = reply.match(renpc)
                        if (npc) {
                            App.Quest.Zhuliu.Touxue.Data.Name = npc
                            App.Quest.Zhuliu.Touxue.Data.Area = npc
                            App.Quest.Zhuliu.Touxue.Data.AskMode = 2
                            break
                        }
                        var perform = {}
                        for (var k = 0; k < reply.length; k++) {
                            perform] = true
                        }
                        App.Quest.Zhuliu.Touxue.Data.Performs.push(perform)
                }
            }

      let line = App.Quest.Zhuliu.Touxue.Data.LastLine + data
      App.Quest.Zhuliu.Touxue.Data.LastLine = data
      for (var i = 0; i < App.Quest.Zhuliu.Touxue.Data.Performs.length; i++) {
            let p = App.Quest.Zhuliu.Touxue.Data.Performs
            let count = 0
            var matched = {}
            for (var k = 0; k < line.length; k++) {
                let char = line
                if (matched) {
                  continue
                }
                if (p) {
                  count++
                }
                matched = true
            }
            if (count >= Object.keys(p).length * trustpercent) {
                App.Send("touxue " + App.Quest.Zhuliu.Touxue.Data.ID)
                App.Quest.Zhuliu.Touxue.Data.LastLine = ""
                App.Quest.Zhuliu.Touxue.Data.Performs.splice(i, 1)
                break
            }
      }
      if (App.Quest.Zhuliu.Touxue.Data.Performs.length == 0) {
            App.Quest.Zhuliu.Touxue.Data.Finish = true
            App.Send("halt;yield no")
            return
      }
    }



jarlyyn 发表于 2022-7-22 14:28:55

匹配文字覆盖率就行了

因为人眼也是这么做的。

如果真的有人能纯手动作偷学的话……

shenji 发表于 2022-7-22 14:31:07

为啥贴上去的代码总是消失。。

jarlyyn 发表于 2022-7-22 14:32:56

另外我没有保存已偷学到的招式

我保存的是需要偷学的

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

另外还有个超时处理代码,和主题没关系,就不贴了。

shenji 发表于 2022-7-22 14:38:47

jarlyyn 发表于 2022-7-22 02:32 PM
另外我没有保存已偷学到的招式

我保存的是需要偷学的


对哦,可以删掉哦

loveg 发表于 2022-7-22 14:42:22

学到了,我直接对比两句话的levenshtein距离,总是误判

shenji 发表于 2022-7-22 14:57:02

代码有一个错误,返回招式的字符串长度那里不用*0.5,已更正

shenji 发表于 2022-7-22 15:47:18

本帖最后由 shenji 于 2022-8-2 01:22 PM 编辑

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

      for n = 1, (#strB + 1), 1 do
                tempTb = n - 1
      end

      for i = 2, (#strA + 1) , 1 do
                for j = 2, (#strB + 1), 1 do
                        local x = tempTb + 1    --删除
                        local y = tempTb + 1    --插入
                        local z = 0
                        if strA == strB then--替换
                              z = tempTb
                        else
                              z = tempTb + 1
                        end
                        tempTb = math.min(x,y,z)
                end
      end
      --Note("匹配度:")
      --print((1- tempTb[#strA + 1][#strB + 1]/math.max(#strA, #strB))*100)
      return (1- tempTb[#strA + 1][#strB + 1]/math.max(#strA, #strB))*100
end

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

tx_pfm = {}
--tx_npfm = {"已学招数"}
tx_c = 1

function tx_split(str)
      local tx_str = tostring(str)
    local str_i_max = tonumber(string.len(str))
      local tx_s = {}
      local i = 1
    while <span style="background-color: rgb(255, 255, 255);">i <= tonumber(str_i_max - 1) </span> do
                table.insert(tx_s,string.sub(tx_str,i,i+1))
                i = i + 2
      end
      tx_pfm = tx_s
      tx_c = tx_c + 1
end

3.npc招式分割、比较



function tx_cp(str)
    local tx_str = tostring(str)
    local str_i_max = tonumber(string.len(str))
      local tx_s = {}
      local i = 1
    while i <= tonumber(str_i_max - 1) do
                table.insert(tx_s,string.sub(str,i,i+1))
                i = i + 2
      end
      --tprint(tx_s)
      for k, v in pairs(tx_pfm) do
                if levenshtein(tx_pfm,tx_s) < 50 then
                  --Note("第"..k.."招匹配不成功,继续:")
                        k = k + 1
                        if tx_pfm == nil then
                              break
                        end
                elseif levenshtein(tx_pfm,tx_s) >= 50 then
                        --Note("第"..k.."招匹配成功")
                        Send("touxue "..GetVariable("tx_id"))
                        table.remove(tx_pfm, k)
                              if #tx_pfm == 0 then          <font color="#4169e1">--table的元素数量为0,说明已经学完,即可结束</font>
                                        Send("response action 偷学完毕")
                              end
                        break
                        end
                end
end


希望这次代码不要弄丢{:7_276:}

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



shenji 发表于 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 = 偷学完毕
>
你身行向后一跃,跳出战圈不打了。
>
你决定打架时还手反击。

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


页: [1] 2
查看完整版本: Mush偷学任务招式对比