szybd 发表于 2014-1-6 12:53:21

问了黄眉僧,黄眉僧做了一些回应,不重要的就不管了,异常情况这里也不提,就只说一种情况:就是黄眉僧答应你去了。有一个情况很关键,我们必须用触发器抓住,后面走迷宫是要用到:
   name = "cjg2"
   match="^[>\\s]*只见黄眉僧偷偷说道:凭借你的易容效果,只要被巡逻僧兵发现(\\S+)次以上就会被识破伪装。.*"
   cmd = "cjgsetyrxgtimes('%1') "
   addmytriggerzz(name,match,cmd)
cjgsetyrxgtimes()就是把易容效果保存下来。同时把自身状态设置为cjgstate = "start"
易容效果保存在变量:cjgyrxgtimes中,当然把中文数目字转换成了整数。

这时我们来到了一个新的位置:第一个迷宫地图的入口处。我们在进入迷宫前,先看一下地图:
Execute("l map")---这个动作是cjgsetyrxgtimes()里的最后一个动作。

szybd 发表于 2014-1-6 13:14:25

这是地图展现在我们面前:
@ @ @ @ @ @ @ @ @
@ @ @ @ @ @ @ @ @
@ @ @ @ @ @ @ @ @
@ @ @ @ @ @ @ @ @
@ @ @ @ @ @ @ @ @
@ @ @ @ @ @ @ @ @
看地图的目的是了解地图:
我们要通过触发器,把上述地图中我们后续需要的信息提取出来:
重要的信息包括:地图的长度,地图的宽度,地图的入口,地图的出口。
当然,地图的每一个位置是否有巡逻僧人也有用,但我们原型系统简化处理,不考虑这个。
这里就用到了我们第三个触发器
   name = "cjg3"
   match="^[>\\s]*([\\*|\\@]\\s){1,100}$"
   cmd = "cjggetmap()"
   addmytriggerzz(name,match,cmd)

cjggetmap()这个函数在地图每呈现一行时执行一遍。
function cjggetmap()
        local line_num = GetLinesInBufferCount()--得到地图内容在显示缓冲区中的行号
        local styles_num = GetLineInfo(line_num,11)--得到该行的style数目
        local linestrlen = GetLineInfo(line_num,2)--得到该行的长度
        local styleinfor = {}
        for i = 1, styles_num do--把每个style的有用内容保存下来
                styleinfor = GetStyleInfo(line_num,i,1)
                styleinfor = GetStyleInfo(line_num,i,2)
                styleinfor = GetStyleInfo(line_num,i,3)
                styleinfor = GetStyleInfo(line_num,i,14)
                styleinfor = GetStyleInfo(line_num,i,15)
        end
        cjgmapwidth = cjgmapwidth + 1--这是地图的宽度,每触发一次增加一,在Execute("l map")前要先置0
        if cjgmapwidth == 1 then--当地图的第一行时
                cjgmaplength = linestrlen/2--得到地图的长度,因为每个字符后面有个空格呢,所以取半
                --Note("地图长度为:"..cjgmaplength)
        else--这是容错用的,可以不用管它
                if cjgmaplength ~= linestrlen/2 then
                        Note("获取的地图信息有误")
                        return
                end
        end
       
        for i = 1, cjgmaplength do--这里把地图记录下来。
                if string.byte(line,i*2-1) == cfgstop then
                        cjgmap = 1
                else
                        cjgmap = 0               
                end
                if cjgmap == 1 then
                        cjgstopnum = cjgstopnum + 1--这里把巡逻僧兵出现的位置记录数量统计出来了
                end
        end
       

        for i = 1, styles_num do--这里对每行地图的样式进行分析,找出入口和出口
--                Note("第"..i.."个样式")
--                Note("样式内容"..styleinfor)
--                Note("样式内容长度"..styleinfor)
--                Note("样式开始列"..styleinfor)
--                Note("样式字符颜色RBG:"..styleinfor)
--                Note("样式背景颜色RGB:"..styleinfor)
               
                if styleinfor == cjgredrgb then--如果样色的颜色是红色,预设的cjgredrgb
                        if cjgmapwidth == 1 then--第一行地图,就对应出口位置
                                cjgoutweizhi = (styleinfor+1)/2
                                --Note("地图出口在第"..cjgoutweizhi.."列")
                        else--不是第一行就对应入口位置
                                cjgenterweizhi = (styleinfor+1)/2
                                --Note("地图入口在第"..cjgenterweizhi.."列")
                                if cjgstopnum <= 0 then--如果地图上没有标出巡逻僧兵,继续l map,直到巡逻僧兵被标注出来了。
                                        --Note("地图出口行出现,巡逻护寺僧人尚未出现,继续观察地图")
                                        AMNote("地图出口在第"..cjgoutweizhi.."列")
                                        AMNote("地图入口在第"..cjgenterweizhi.."列")
                                        AMNote("地图长,宽为:"..cjgmaplength..","..cjgmapwidth)
                                        Execute("l map")
                                else--这时就可以过地图了
                                        --Note("一切准备就绪,过地图吧")
                                        cjggotoposition(cjgenterweizhi,cjgmapwidth+1)--该位置为入口南面一格。把这个位置记录下来
                                        cjgmap1walk()---开始行走。
                                end
                        end
                end
        end
end

szybd 发表于 2014-1-6 13:21:03

上面我们把地图的问题解决了。同时又出现了几个重要的全局变量:(后面要用到的)
cjgoutweizhi--出口位置
cjgenterweizhi--入口位置
cjgmaplength--地图长度
cjgmapwidth--地图宽度
--------------------------------------------
同时出现了两个新函数:
cjggotoposition(x,y)--记录当前位置在地图中的坐标
cjgmap1walk()--在第一个地图中的行走函数。
地图1中可能踩中地雷,出现僧兵和长老需要战斗,可能发现巡逻僧兵可能被识破,即使不被识破,还会被busy。到底该怎么走呢?

szybd 发表于 2014-1-6 13:27:36

先把自身状态设定为在地图1中行走:cjgstate = "map1walk"
然后checkbusy,在不忙的情况下,执行真正的行走过程。
function cjgmap1walk()
        cjgstate = "map1walk"
        checkbusystart()--启动checkbusy机制
        addunbusyfunc(cjgwalkunbusydo)--注册不忙情况下执行的函数
        checkbusyon()--发送checkbusy命令
end
--如何实现checkbusy的这里不展开讨论。
真正的行走动作在函数cjgwalkunbusydo()中

szybd 发表于 2014-1-6 13:40:02

其实cjgwalkunbusydo()就做了两件事:
第一,判断是否走到了第一个地图的出口处,如果到了,将当前状态设置为:cjgstate = "map1out"
用"set cjg gooutmap1"命令做一下过渡,简化处理过程。
第二,观察:观察周边有没有巡逻僧兵。为选择行动方向准备信息。
function cjgwalkunbusydo()
        checkbusyend()--终止checkbusy机制
        if cjgcurrentx == cjgoutweizhi and cjgcurrenty == 1 then
                AMNote("已经到达第一个地图出口")
                cjgstate = "map1out"
                Execute("set cjg gooutmap1")
                return
        end
       
        if cjgcurrenty <= 0 orcjgcurrenty > cjgmapwidth+1 or cjgcurrentx <=0 or cjgcurrentx > cjgmaplength then
                Note("当前位置发生错误"..cjgcurrentx.."    "..cjgcurrenty)
                return
        elseif cjgcurrenty == cjgmapwidth+1 and cjgcurrentx ~= cjgenterweizhi then
                Note("当前入口位置发生错误"..cjgcurrentx.."    "..cjgcurrenty)
                return       
        elseif cjgcurrenty == cjgmapwidth+1 and cjgcurrentx == cjgenterweizhi then
                Note("当前位置在入口,唯一的行走方向enter,检查里面有没有巡逻僧兵")
                cjgxunluosengbingflag = {east = "no",south = "no",west = "no",north = "no",}
                cjglooktimes = 1
                Execute("look enter;set cjg cjglooknorth")
                return
        elseif cjgcurrenty == cjgmapwidth and cjgcurrentx == 1 then
                Note("当前位置在地图西南角,检查东面和北面有无阻挡")
                cjgxunluosengbingflag = {east = "no",south = "no",west = "no",north = "no",}
                cjglooktimes = 2
                Execute("look east;set cjg cjglookeast;look north;set cjg cjglooknorth")
                return
        elseif cjgcurrenty == cjgmapwidth and cjgcurrentx == cjgmaplength then
                Note("当前位置在地图东南角,检查西面和北面有无阻挡")
                cjgxunluosengbingflag = {east = "no",south = "no",west = "no",north = "no",}
                cjglooktimes = 2
                Execute("look west;set cjg cjglookwest;look north;set cjg cjglooknorth")
                return
        elseif cjgcurrenty == cjgmapwidth and cjgcurrentx < cjgmaplength and cjgcurrentx > 1 then
                Note("当前位置在最南面,且不在角落,检查东、西、北面有无阻挡")
                cjgxunluosengbingflag = {east = "no",south = "no",west = "no",north = "no",}
                cjglooktimes = 3
                Execute("look east;set cjg cjglookeast;look west;set cjg cjglookwest;look north;set cjg cjglooknorth")
                return
        elseif cjgcurrenty == 1 and cjgcurrentx == 1 then
                Note("当前位置在地图西北角,检查东面和南面有无阻挡")
                cjgxunluosengbingflag = {east = "no",south = "no",west = "no",north = "no",}
                cjglooktimes = 2
                Execute("look east;set cjg cjglookeast;look south;set cjg cjglooksouth")
                return               
        elseif cjgcurrenty == 1 and cjgcurrentx == cjgmaplength then
                Note("当前位置在地图东北角,检查西面和南面有无阻挡")
                cjgxunluosengbingflag = {east = "no",south = "no",west = "no",north = "no",}
                cjglooktimes = 2
                Execute("look south;set cjg cjglooksouth;look west;set cjg cjglookwest")
                return
        elseif cjgcurrenty > 1 and cjgcurrentx == cjgmaplength then
                Note("当前位置在地图东边,检查西面和南面和北面有无阻挡")
                cjgxunluosengbingflag = {east = "no",south = "no",west = "no",north = "no",}
                cjglooktimes = 3
                Execute("look south;set cjg cjglooksouth;look west;set cjg cjglookwest;look north;set cjg cjglooknorth")
                return
        elseif cjgcurrenty > 1 and cjgcurrentx == 1 then
                Note("当前位置在地图西边,检查东面和南面和北面有无阻挡")
                cjgxunluosengbingflag = {east = "no",south = "no",west = "no",north = "no",}
                cjglooktimes = 3
                Execute("look east;set cjg cjglookeast;look south;set cjg cjglooksouth;look north;set cjg cjglooknorth")
                return               
        elseif cjgcurrenty == 1 and cjgcurrentx < cjgmaplength and cjgcurrentx > 1 then
                Note("当前位置在最北面,且不在角落,检查东、西、南面有无阻挡")
                cjgxunluosengbingflag = {east = "no",south = "no",west = "no",north = "no",}
                cjglooktimes = 3
                Execute("look east;set cjg cjglookeast;look south;set cjg cjglooksouth;look west;set cjg cjglookwest")
                return
        elseif cjgcurrenty > 1 and cjgcurrenty < cjgmapwidth and cjgcurrentx < cjgmaplength and cjgcurrentx > 1 then
                Note("当前位置在地图中央,检查四面阻挡情况")
                cjgxunluosengbingflag = {east = "no",south = "no",west = "no",north = "no",}
                cjglooktimes = 4
                Execute("look east;set cjg cjglookeast;look south;set cjg cjglooksouth;look west;set cjg cjglookwest;look north;set cjg cjglooknorth")
                return
        else
                Note(cjgcurrentx..","..cjgcurrenty)
        end
end

szybd 发表于 2014-1-6 13:58:17

请注意,在处理周边环境观察时,用了一个小小的技巧:
set cjg cjglookxxx。
每看一个方向,执行一遍set cjg cjglookxxx。看到
               设定环境变量:cjg = "cjglookxxx"
就知道,这个look的动作完成了。
用全局量cjglooktimes保存我观察的方向总数,如果看到观察完成的数目达到cjglooktimes标定的次数,就知道已经观察完成了,可以执行下一个动作了。
这里就涉及了第四个触发器:
   name = "cjg4"
   match="^[>\\s]*设定环境变量:cjg = \"cjglook(\\w+)\".*"
   cmd = "cjglookdirection('%1') "
   addmytriggerzz(name,match,cmd)
还有第五个触发器:--需要观察的内容,是否有巡逻僧人的存在
   name = "cjg5"
   match="^[>\\s]*巡逻僧人\\(Husi sengren\\).*"
   cmd = "cjgfindsengren()"
   addmytriggerzzhp(name,match,cmd)

在观察周边之前,设定当前位置的所有方向都没有巡逻僧人。
cjgxunluosengbingflag = {east = "no",south = "no",west = "no",north = "no",}
在观察某个方向前:设置当前没有巡逻僧兵。
cjgxunluosengbingstatus = "no"
-----------------------------------------------------
发现了巡逻僧兵,就将cjgxunluosengbingstatus 设置为yes.
function cjgfindsengren()
        cjgxunluosengbingstatus = "yes"       
end

当该方向观察完成:就把各个方向是否有巡逻僧兵给记录下来了。
function cjglookdirection(direction)
        --以下是测试代码
        --local temp = math.random(2)
        --Note(temp)
        --if temp == 1 then
        --        cjgxunluosengbingstatus = "yes"
        --else
        --        cjgxunluosengbingstatus = "no"
        --end
        --以上是测试代码
       
        if direction == "east" then
                cjgxunluosengbingflag.east = cjgxunluosengbingstatus
                if cjgxunluosengbingflag.east == "yes" then
                        Note("东面有巡逻僧人")
                end
        elseif direction == "south" then
                cjgxunluosengbingflag.south = cjgxunluosengbingstatus
                if cjgxunluosengbingflag.south == "yes" then
                        Note("南面有巡逻僧人")
                end
        elseif direction == "west" then
                cjgxunluosengbingflag.west = cjgxunluosengbingstatus
                if cjgxunluosengbingflag.west == "yes" then
                        Note("西面有巡逻僧人")
                end
        elseif direction == "north" then
                cjgxunluosengbingflag.north = cjgxunluosengbingstatus
                if cjgxunluosengbingflag.north == "yes" then
                        Note("北面有巡逻僧人")
                end
        end
        cjgxunluosengbingstatus = "no"
        cjglooktimes = cjglooktimes - 1
        if cjglooktimes == 0 then
                Note("观察周边完毕")
                cjggetnextstep()
        end
end

szybd 发表于 2014-1-6 14:00:44

当所有方向都观察完毕,就执行 cjggetnextstep()来获取下一步的行走方向

szybd 发表于 2014-1-6 14:07:55

决定下一步怎么走,有些复杂,这已经是选择了最简单方案的结果。具体方案最早的时候讨论过:
当前位置和出口位置作为对角组成一个矩形,
优先沿矩形长边方向向出口接近,
如果该方向下一步有巡逻僧人,短边方向无巡逻僧人,则走短边方向向出口接近
如果断面方向也有巡逻僧人,则看易容效果能否扛得住,
如果扛得住,还是沿长边方向走一步。
如果易容效果扛不住了,就停下来,一秒钟后再观察周边状态,根据新的状态再 确定行动方案。

function cjggetnextstep()
        cjgnextx = cjgcurrentx
        cjgnexty = cjgcurrenty
        if cjgcurrenty == cjgmapwidth + 1 then
                Note("起点位置,只能enter")
                cjgcurrentstep = "enter"
                cjgnexty = cjgcurrenty -1
        elseif math.abs(cjgcurrentx - cjgoutweizhi) >= cjgcurrenty -1 then -------->说明横着是长边
                if cjgcurrentx > cjgoutweizhi then --------->说明向西是靠近
                        if cjgxunluosengbingflag.west == "no" then ---->西面没有巡逻僧人
                                cjgcurrentstep = "west"-->向西走
                                cjgnextx = cjgcurrentx -1
                        else----->西面有巡逻僧人
                                if cjgcurrenty > 1 then -->北面还能走
                                        if cjgxunluosengbingflag.north == "no" then ---->北面没有巡逻僧人
                                                cjgcurrentstep = "north"-->向北走
                                                cjgnexty = cjgcurrenty -1
                                        else-->北面也有巡逻僧人
                                                if cjgyrxgtimes > 1 then -->易容效果还存在,还是往西走吧
                                                        cjgcurrentstep = "west"-->向西走
                                                        cjgnextx = cjgcurrentx -1
                                                else -->没法接近了,等会儿再走吧。
                                                        Note("没法接近了,等待巡逻僧兵换位址后再走")
                                                        cjgstate = "map1wait"
                                                end
                                        end
                                else -->北面到顶了
                                        if cjgyrxgtimes > 1 then -->易容效果还存在,还是往西走吧
                                                cjgcurrentstep = "west"-->向西走
                                                cjgnextx = cjgcurrentx -1
                                        else -->没法接近了,等会儿再走吧。
                                                Note("没法接近了,等待巡逻僧兵换位址后再走")
                                                cjgstate = "map1wait"
                                        end
                                end
                        end
                elseif cjgcurrentx < cjgoutweizhi then --------->说明向东是靠近
                        if cjgxunluosengbingflag.east == "no" then ---->东面没有巡逻僧人
                                cjgcurrentstep = "east"-->向东走
                                cjgnextx = cjgcurrentx + 1
                        else----->东面有巡逻僧人
                                if cjgcurrenty > 1 then -->北面还能走
                                        if cjgxunluosengbingflag.north == "no" then ---->北面没有巡逻僧人
                                                cjgcurrentstep = "north"-->向北走
                                                cjgnexty = cjgcurrenty -1
                                        else-->北面也有巡逻僧人
                                                if cjgyrxgtimes > 1 then -->易容效果还存在,还是往东走吧
                                                        cjgcurrentstep = "east"-->向东走
                                                        cjgnextx = cjgcurrentx + 1
                                                else -->没法接近了,等会儿再走吧。
                                                        Note("没法接近了,等待巡逻僧兵换位址后再走")
                                                        cjgstate = "map1wait"
                                                end
                                        end
                                else -->北面到顶了
                                        if cjgyrxgtimes > 1 then -->易容效果还存在,还是往东走吧
                                                cjgcurrentstep = "east"-->向东走
                                                cjgnextx = cjgcurrentx + 1
                                        else -->没法接近了,等会儿再走吧。
                                                Note("没法接近了,等待巡逻僧兵换位址后再走")
                                                cjgstate = "map1wait"
                                        end
                                end
                        end
                elseif cjgcurrentx == cjgoutweizhi then --------->说明只能向北
                        if cjgcurrenty > 1 then -->北面还能走
                                if cjgxunluosengbingflag.north == "no" then ---->北面没有巡逻僧人
                                        cjgcurrentstep = "north"-->向北走
                                        cjgnexty = cjgcurrenty -1
                                else-->北面也有巡逻僧人
                                        if cjgyrxgtimes > 1 then -->易容效果还存在,还是往北走吧
                                                cjgcurrentstep = "north"-->向北走
                                                cjgnexty = cjgcurrenty -1
                                        else -->没法接近了,等会儿再走吧。
                                                Note("没法接近了,等待巡逻僧兵换位址后再走")
                                                cjgstate = "map1wait"
                                        end
                                end
                        else -->北面到顶了,说明已经到达出口
                                Note("已经到达出口")
                                cjgstate = "map1out"
                                Execute("out")
                                Execute("set cjg gooutmap1")
                                return
                        end
                end
        else--竖着是长边,优先向北走
                if cjgxunluosengbingflag.north == "no" then ---->北面没有巡逻僧人
                        cjgcurrentstep = "north"-->向北走
                        cjgnexty = cjgcurrenty -1
                else
                        if cjgcurrentx > cjgoutweizhi then --------->说明向西是靠近
                                if cjgxunluosengbingflag.west == "no" then ---->西面没有巡逻僧人
                                        cjgcurrentstep = "west"-->向西走
                                        cjgnextx = cjgcurrentx - 1
                                else----->西面有巡逻僧人
                                        if cjgyrxgtimes > 1 then -->易容效果还存在,还是往北走吧
                                                cjgcurrentstep = "north"-->向北走
                                                cjgnexty = cjgcurrenty -1
                                        else -->没法接近了,等会儿再走吧。
                                                Note("没法接近了,等待巡逻僧兵换位址后再走")
                                                cjgstate = "map1wait"
                                        end
                                end
                        elseif cjgcurrentx < cjgoutweizhi then --------->说明向东是靠近
                                if cjgxunluosengbingflag.east == "no" then ---->东面没有巡逻僧人
                                        cjgcurrentstep = "east"-->向东走
                                        cjgnextx = cjgcurrentx + 1
                                else----->东面有巡逻僧人
                                        if cjgyrxgtimes > 1 then -->易容效果还存在,还是往北走吧
                                                cjgcurrentstep = "north"-->向北走
                                                cjgnexty = cjgcurrenty -1
                                        else -->没法接近了,等会儿再走吧。
                                                Note("没法接近了,等待巡逻僧兵换位址后再走")
                                                cjgstate = "map1wait"
                                        end
                                end
                        elseif cjgcurrentx == cjgoutweizhi then
                                if cjgyrxgtimes > 1 then -->易容效果还存在,还是往北走吧
                                        cjgcurrentstep = "north"-->向北走
                                        cjgnexty = cjgcurrenty -1
                                else -->没法接近了,等会儿再走吧。
                                        Note("没法接近了,等待巡逻僧兵换位址后再走")
                                        cjgstate = "map1wait"
                                end
                        end
                end
        end

        if cjgstate == "map1walk" then
                cjggonext()
        elseif cjgstate == "map1wait" then
                wait.make(function()
                        wait.time(1)
                        cjgmap1walk()
                end)
        end
end

szybd 发表于 2014-1-6 14:13:15

整半天,到现在还是没有走,只是决定了走的方向。怎么走?
cjggonext()实现。
因为走到下一步可能
oooO ↘┏━┓ ↙ Oooo
( 踩)→┃你┃ ←(死 )
\ ( →┃√┃ ← ) /
  \_)↗┗━┛ ↖(_/

可能会出好多敌人,必须在走之前保持最佳状态,并先把刀耍起来。
没敌人不是白耍吗?
呵呵,白耍谁不耍啊?大不了停下来呗。
function cjggonext()
        cjgfindenemyflag = "none"
        Execute(cjgcurrentstep)
        cjggotoposition(cjgnextx,cjgnexty)
        Execute("yun qi")
        Execute("yun powerup")
        cjgbusy()
        Execute("set cjg cjgwalk")
end

szybd 发表于 2014-1-6 14:14:08

下面就是战斗过程了,当然也是最简化的,毕竟是原型嘛。
页: 1 2 3 [4] 5 6 7 8 9 10
查看完整版本: 渡深百M留念,共享藏经阁任务机器人制作全过程