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